Compare commits

...
Author SHA1 Message Date
apion 6d67256632 Added delta functions and some cleanup 2024-11-03 01:55:44 -04:00
apion be0753109c Merge branch 'refs/heads/implement_pokemon' into action-effects-improved 2024-11-02 03:48:43 -04:00
apion 0ee36b705e Merge remote-tracking branch 'refs/remotes/origin/move-effects' into action-effects-improved 2024-11-02 03:48:34 -04:00
apion 396a827b37 Added molang query for distance between entities 2024-11-02 03:01:56 -04:00
apion b146892b50 Exposed entity info in action effect 2024-11-02 00:17:09 -04:00
apion 0f41194d22 Better molang function adding 2024-11-01 21:29:15 -04:00
apion 5797838711 Moved to molang for pose conditions in charmander 2024-11-01 21:27:53 -04:00
apion 36b1e926a9 Made CodecBackedAdapter work for serializing too. 2024-11-01 18:29:53 -04:00
Hiroku b80b27e8f9 Merge branch 'en_us-fixes' into 'main'
en_us Fixes

See merge request cable-mc/cobblemon!1228
2024-11-01 11:21:40 +00:00
Hiroku 755ca9d261 Merge branch 'sound' into 'main'
Updates to evolution and trading sounds

See merge request cable-mc/cobblemon!1233
2024-11-01 11:21:32 +00:00
mia 24f64da512 fix(lang): hopefully every move now uses proper description 2024-11-01 06:42:31 -04:00
mia b11f553af0 fix(lang): abilities use official descriptions, some move description fixes 2024-11-01 06:42:31 -04:00
mia bce33acbc5 fix(lang): fix hydrosteam lang keys 2024-11-01 06:42:31 -04:00
mia a42b88f22f fix(lang): remove unneeded "'s" 2024-11-01 06:42:31 -04:00
mia fe7d3a51f9 fix(lang): make all moves use official descriptions 2024-11-01 06:42:31 -04:00
Sterrezo c260594865 Trade sound updates 2024-11-01 11:40:57 +01:00
Hiroku 89a25ab03e Merge branch 'Shipwrecks-and-Stuff' into 'main'
Shipwrecks and stuff

See merge request cable-mc/cobblemon!1232
2024-11-01 10:38:44 +00:00
Hiroku b97589c934 Merge branch 'PvP_Flat_Level_Battling' into 'main'
PvP flat level battling

See merge request cable-mc/cobblemon!1157
2024-11-01 10:22:17 +00:00
Sterrezo b3ffcdd039 Merge branch 'main' into sound 2024-11-01 11:14:01 +01:00
Hiroku 51e81d207e Update CHANGELOG.md 2024-11-01 10:13:53 +00:00
Slippy 50a3aa6a4f Adjusted more things for new 1.6 structure 2024-11-01 04:45:52 -05:00
Slippy f84cb41f28 Updates to new 1.6 structures 2024-11-01 04:32:50 -05:00
Slippy 6c95b3e50c Toppled Pillars log spam fix 2024-11-01 04:04:42 -05:00
Slippy 60667794a7 Village Pokecenter fixes 2024-11-01 03:59:19 -05:00
Slippy f39f2c3e4a What??? Last minute structures in 1.6??? 2024-11-01 03:17:59 -05:00
Slippy d104342df1 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2024-11-01 03:12:17 -05:00
Hiroku 1d9f540198 Merge branch 'bugfix/hiro-fixes-more-bugs' into 'main'
Bugfixes

Closes #1092 and #1032

See merge request cable-mc/cobblemon!1231
2024-11-01 07:38:07 +00:00
Paul ec34f51ead Fixed case where pokemon couldn't add relearn moves after forgetting a move, closes #1032 2024-11-01 15:55:29 +10:00
Paul fa284636ed Merge remote-tracking branch 'origin/main' into bugfix/hiro-fixes-more-bugs 2024-11-01 14:48:13 +10:00
Hiroku 306ac74cd8 Merge branch 'trade' into 'main'
Trading animation

See merge request cable-mc/cobblemon!1230
2024-11-01 04:40:13 +00:00
TestandHiroku ff65613ffd Trading animation 2024-11-01 04:40:13 +00:00
Apion 1b41cc04eb Merge branch 'feature/fixes-and-tweaks' into 'main'
fix a NF crash and introduce small mixing to enhance search in creative

Closes #1128

See merge request cable-mc/cobblemon!1227
2024-10-31 22:38:31 +00:00
PolymetaandApion 45e7d8fe81 fix a NF crash and introduce small mixing to enhance search in creative 2024-10-31 22:38:31 +00:00
Tyzillion e048e8a58d Updated particles for Status Effects, Stat buffs/debuffs, Protect, Sand Attack, Quick Attack, and Gastly.
Added the "top" universal locator.
2024-10-31 10:02:34 -04:00
Tyzillion 3656513255 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into move-effects
# Conflicts:
#	common/src/main/resources/assets/cobblemon/sounds.json
2024-10-31 07:52:01 -04:00
Wi2tert 2734f1d00c Update Bulbasaur Ivysaur Venusaur Animation 2024-10-31 12:20:53 +08:00
Sterrezo 2ff406453f Update evolution_full.ogg
yeah
2024-10-31 01:04:10 +01:00
mia 29a9d3caba fix(lang): rename "tree" variation to "wood" 2024-10-30 11:35:39 -04:00
tmetcalfe89andmia f6ae1b8a69 lang'd the rod tooltip parts 2024-10-30 11:35:39 -04:00
mia b2b4c934a2 fix(lang): add missing punctuation, focus sash --> focus band 2024-10-30 11:35:39 -04:00
mia b1815bc0cd fix(lang): 'Hydro Stream' --> 'Hydro Steam' 2024-10-30 11:35:39 -04:00
mia 8c431f2af5 fix(lang): consistent apostrophe use 2024-10-30 11:35:39 -04:00
mia 04bcb0d41e fix(lang): remove unneeded trailing whitespaces 2024-10-30 11:35:39 -04:00
mia d1e119ac9b fix(lang): hydrosnipe mixup, add drum solo 2024-10-30 11:35:39 -04:00
mia 7db059d4ba fix(lang): punctuation for two gmax moves 2024-10-30 11:34:46 -04:00
mia a930a71a3a fix(lang): more x_items --> battle_items 2024-10-30 11:34:46 -04:00
mia 87f0c6cf7a fix merge conflicts 2024-10-30 11:34:39 -04:00
mia 54037fc499 fix(lang): remove light_orb 2024-10-30 11:18:29 -04:00
mia e2f6c02ad9 fix(lang): grey --> gray 2024-10-30 11:18:29 -04:00
mia 1fc24a5ee3 fix(lang): smithing templates, pokerod smithing slot 2024-10-30 11:18:29 -04:00
tmetcalfe89 e66069b270 swapped smeargle colors right way around 2024-10-30 01:49:28 -07:00
tmetcalfe89 a661575451 de-dyed smeargle 2024-10-29 23:16:22 -07:00
Carmendar a23017cd1f Updated scaling of a handful of pokemon, gave pory line dummy sleep cries, fixed mantine antennae, and onix has math.mod now.
- Removed Herobrine.
2024-10-29 22:13:20 -05:00
tmetcalfe89 0df19ce18a integrated retro's changes
Fixed Bellsprout's GEO ("arns" to "arms", "foor" to "foot", etcetera).
Altered Weepinbell's Scale and Hitbox
Altered Victreebel's Walk Speed and Hitbox.
2024-10-29 15:22:53 -07:00
Wi2ter 5a751546ec Update Changelog 2024-10-29 18:38:25 +08:00
Carmendar ee9e1cabc1 remodeled Poliwhirl, Poliwrath, Riolu & Lucario. Added animations for Bagon line, Shellder line, Kecleon, Furret & Spinda. Updated changelog.
- Removed Herobrine.
2024-10-29 01:44:02 -05:00
Wi2ter d78b46155f Update Klink Line animation 2024-10-28 17:26:14 +08:00
阿鱼andWeblate bf0f553b5e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (6388 of 6388 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2024-10-28 09:05:18 +00:00
Alexis SalgueiroandWeblate 6b525a2ffe Translated using Weblate (French)
Currently translated at 100.0% (6388 of 6388 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-28 09:05:17 +00:00
Felipe Bermudes OrmeñoandWeblate aa91c9e311 Translated using Weblate (Spanish (Mexico))
Currently translated at 27.7% (1771 of 6388 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2024-10-28 09:05:17 +00:00
Wi2ter 1afd61d517 Update Dreepy Drakloak Animation 2024-10-28 16:27:57 +08:00
Carmendar 97a5083ff5 Updated swim speeds for some water mons & merged main into implement. 2024-10-27 19:43:51 -05:00
Carmendar 0d31e74790 Merge branch 'main' into implement_pokemon 2024-10-27 17:42:35 -05:00
Carmendar 02214196f4 Merge remote-tracking branch 'origin/main' 2024-10-27 17:40:11 -05:00
Carmendar aae268cfc5 New water pokemon can actually water now. 2024-10-27 17:05:46 -05:00
Carmendar 20f37d8799 Third coming of Klawf. (fixed the cry for real this time. 2024-10-27 15:52:46 -05:00
Carmendar 0b825bcda3 The second coming of Klawf (its cry), animation updates for a handful of mons, Portrait/Picture & scale fixes for a handful of mons, added species feature for three-segment dudunsparce, added dummy animation file for sleep cries, and added cries for Magikarp & Gyarados.
- Removed Herobrine.
2024-10-27 15:48:29 -05:00
阿鱼andWeblate 55349229d5 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (6386 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2024-10-27 07:31:31 +00:00
MiaandWeblate 1408ff26a3 Translated using Weblate (German)
Currently translated at 92.3% (5900 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2024-10-27 07:31:30 +00:00
GottvaterNougatKoenigandWeblate 646234b90b Translated using Weblate (German)
Currently translated at 92.3% (5900 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2024-10-27 07:31:30 +00:00
Hiroku 7abedb0e60 Merge branch 'egg-on-yer-face' into 'main'
Added Egg events for devs

See merge request cable-mc/cobblemon!1194
2024-10-27 06:01:58 +00:00
Paul d2d9647295 Merge remote-tracking branch 'origin/main' into egg-on-yer-face
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/events/CobblemonEvents.kt
2024-10-27 15:54:39 +10:00
Hiroku 2edbfc2870 Merge branch 'whatsy/bugfixes' into 'main'
various bugfixes

Closes #1030, #1022, #1007, and #1021

See merge request cable-mc/cobblemon!1212
2024-10-27 05:53:52 +00:00
Paul 1a50ff829b Corrected messaging for evolve message so it also displays for entity-less-evos 2024-10-27 15:45:54 +10:00
Paul c617e98f33 Fixed really well grown berries causing crashes (lol), fixes #1124 2024-10-27 15:32:34 +10:00
GenotypeXD-Dev aba3bd22c7 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-26 22:02:04 -06:00
GenotypeXD-Dev b1fc33f5a1 Added Klawf 2024-10-26 22:01:39 -06:00
MoeBoy76 54aef4d66b Removed cancellable from non-cancellable event 2024-10-27 14:09:22 +11:00
Paul 76d35914c0 Fixed some log spam that could occur when boxing pokemon 2024-10-27 10:37:26 +10:00
apion 664cdc0937 Revert "fix mint bounding blocks being randomly -0.9 in size"
This reverts commit 97c2711eb8.
2024-10-26 19:34:07 -04:00
Apion e3913d1231 Merge branch 'one-seex-events' into 'main'
Serverside events & Fishing event function registry

See merge request cable-mc/cobblemon!1193
2024-10-26 22:58:42 +00:00
amoandApion 24b00e0839 Serverside events & Fishing event function registry 2024-10-26 22:58:42 +00:00
Hiroku 92ce7fd395 Merge branch 'ys/lang-fixes' into 'main'
Clear smog lang

Closes #1120

See merge request cable-mc/cobblemon!1225
2024-10-26 21:19:36 +00:00
Yaseen 3e0b280456 Clear positive and negative boosts from battle context 2024-10-26 18:00:42 +01:00
Yaseen ee419596ce broadcast the message foe clear smog 2024-10-26 16:24:44 +01:00
Yaseen 732eb344af - clear smog 2024-10-26 16:01:19 +01:00
Hiroku 3c7c820622 Merge branch 'braaaaains' into 'main'
Added configurable NPC brains

See merge request cable-mc/cobblemon!1221
2024-10-25 21:47:01 +00:00
tmetcalfe89 f2033f5e33 fix alakazam json poser 2024-10-25 12:51:57 -07:00
tmetcalfe89 6c600b7bdb alakazam - kt->json 2024-10-25 12:27:33 -07:00
Paul 5d2f8edcb0 Merge remote-tracking branch 'origin/main' into braaaaains
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/npc/NPCClass.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/npc/NPCPreset.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/adapters/NPCClassAdapter.kt
2024-10-25 21:36:32 +10:00
Wi2ter e93bfb7f0f Update Kleavor Animation 2024-10-25 18:25:09 +08:00
Wi2ter 8976909742 Update Alomomola Animation 2024-10-25 18:23:06 +08:00
Wi2ter 30a9c2f53e Update Mantyke Mantine Animation 2024-10-25 18:18:58 +08:00
Paul 5a5a9113e9 Fixed Oinkologne being unable to be female and reworked gender checking from properties, closes #1092 2024-10-25 17:20:58 +10:00
Wi2ter ea60790865 I forgot to change the poser! 😭 2024-10-25 11:36:38 +08:00
Wi2ter f906fac8f3 Update Buneary and Lopunny animation 2024-10-25 11:28:57 +08:00
Wi2ter 05b324a3cb Remodel Swinub Piloswine Mamoswine [big guy] 2024-10-25 09:40:37 +08:00
Carmendar 8ce1c7ccf5 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-24 19:06:09 -05:00
Carmendar a37f93241f Slowed Numel, and fixed shiny Staryu emissive texture. 2024-10-24 19:05:14 -05:00
Paul 7149116a68 Merge remote-tracking branch 'origin/braaaaains' into braaaaains 2024-10-25 09:43:45 +10:00
Paul 7a40e71123 Documentation for brain stuff 2024-10-25 09:43:27 +10:00
Hiroku d1554f1ae5 Merge branch 'toobig' into 'main'
mint trees / berry bushes now respect whether they're on tilled or wild land

See merge request cable-mc/cobblemon!1195
2024-10-24 23:25:54 +00:00
Hiroku e15f4f8ad1 Merge branch 'sterr/bugfixes' into 'main'
Audio bugfixes

Closes #1045

See merge request cable-mc/cobblemon!1222
2024-10-24 23:24:13 +00:00
阿鱼andWeblate f9afd30577 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.2% (6083 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2024-10-24 19:55:03 +00:00
Wi2terandWeblate 7f0d7d8e1a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.2% (6083 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2024-10-24 19:55:03 +00:00
Zack the GhastandWeblate b63d7d8f3f Translated using Weblate (Portuguese (Portugal))
Currently translated at 26.8% (1712 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2024-10-24 19:55:01 +00:00
Adam IdriciandWeblate a7ba8953ab Translated using Weblate (French)
Currently translated at 100.0% (6386 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-24 19:55:01 +00:00
Alexis SalgueiroandWeblate 1ea87c6cc7 Translated using Weblate (French)
Currently translated at 100.0% (6386 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-24 19:55:01 +00:00
Felipe Bermudes OrmeñoandWeblate f68966ce90 Translated using Weblate (Spanish (Mexico))
Currently translated at 27.2% (1743 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2024-10-24 19:55:00 +00:00
GottvaterNougatKoenigandWeblate 744e6faa53 Translated using Weblate (German)
Currently translated at 92.3% (5898 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2024-10-24 19:54:59 +00:00
Wi2ter 6689663ca9 remodel Snivy Servin Serperior 🌿 🐍 2024-10-24 19:10:37 +08:00
Carmendar 959b81a58f flashy new models for ✨ Dwebble & Crustle ✨ 2024-10-24 01:27:11 -05:00
Carmendar 62e607b44e Forgot to remove magby line & onix from the kotlin model repository. 2024-10-23 23:22:19 -05:00
Carmendar 407bb6b977 Merge remote-tracking branch 'origin/main' 2024-10-23 20:07:59 -05:00
Carmendar a9efd327b8 Magby line & Onix are now beautiful. 2024-10-23 19:58:34 -05:00
Carmendar 64cb4d2ff8 Removed Herobrine 2024-10-23 00:36:52 -05:00
FrankTheFarmer 54786fa82e I forgot the changelog again 😔 2024-10-23 15:06:56 +10:00
FrankTheFarmer ecab1b7825 Porygon line poser fixes 🖥🦆 2024-10-23 14:57:22 +10:00
FrankTheFarmer 75d7106f46 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-23 14:37:28 +10:00
Carmendar 6f82c09afa angry crying 😠😢 2024-10-22 23:21:40 -05:00
Carmendar 778e5e219c Everyone is crying 😢 so sad. 2024-10-22 22:05:42 -05:00
FrankTheFarmer f4682e0bd2 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-23 11:07:21 +10:00
Tyzillion 906d487ffc Added rootBone to all existing json posers. 2024-10-22 08:08:31 -04:00
Tyzillion 817b801bf7 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	common/src/main/resources/assets/cobblemon/bedrock/pokemon/animations/0006_charizard/charizard.animation.json
#	common/src/main/resources/assets/cobblemon/bedrock/pokemon/posers/0595_joltik/joltik.json
2024-10-22 07:44:07 -04:00
Sterrezo e401b11ab9 Added a sound keyframe to absol.animation.json 2024-10-22 10:21:08 +02:00
Carmendar 165f70e01d Updated changelog 2024-10-22 02:05:50 -05:00
GenotypeXD-Dev fddfbfb4ed Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-21 20:03:46 -06:00
GenotypeXD-Dev 03e229c511 Implemented Absol and Veluza. Fixed Charizard sleep crash 2024-10-21 20:02:26 -06:00
Natchakot ChuchokjatupornandWeblate 8e84ce7615 Translated using Weblate (Thai)
Currently translated at 78.8% (5038 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/th/
2024-10-22 00:09:52 +00:00
Adam IdriciandWeblate 1c5745c174 Translated using Weblate (French)
Currently translated at 100.0% (6386 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-22 00:09:52 +00:00
Adam IdriciandWeblate d357aff7dc Translated using Weblate (French)
Currently translated at 99.7% (6372 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-21 22:48:27 +00:00
Zack the GhastandWeblate e2ea9cd199 Translated using Weblate (Portuguese (Portugal))
Currently translated at 26.4% (1689 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2024-10-21 22:45:36 +00:00
Adam IdriciandWeblate 59d32e8254 Translated using Weblate (French)
Currently translated at 99.2% (6335 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-21 22:45:36 +00:00
Alexis SalgueiroandWeblate 3091e5b198 Translated using Weblate (French)
Currently translated at 99.2% (6335 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-21 22:45:36 +00:00
Felipe Bermudes OrmeñoandWeblate 9c71e3cfd5 Translated using Weblate (Spanish (Mexico))
Currently translated at 25.9% (1656 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2024-10-21 22:45:35 +00:00
Xander Forrest 68427df817 remove sneaky debug 2024-10-21 21:28:00 +07:00
Sterrezo c08cc48449 Merge branch 'main' into sterr/bugfixes 2024-10-21 12:38:28 +02:00
Paul 628941aa0e Fixed NPCs not using the NPC battle theme hook, closes #1094 2024-10-21 17:45:05 +10:00
MoeBoy76 74bb66fd2b Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into egg-on-yer-face 2024-10-21 18:36:15 +11:00
Paul 6b3d60fccc Fixed NPC owned pokemon persisting and becoming wild 2024-10-21 17:35:28 +10:00
MoeBoy76 d733b1de68 Updated egg events for API requirements 2024-10-21 18:35:14 +11:00
Hiroku b4e402c83d Update NPCBrain.kt 2024-10-21 07:15:46 +00:00
Paul 4b2b2f24ee Fixed Frillish T-pose while sleeping, closes #1102 2024-10-21 17:09:34 +10:00
Paul f95389b01b Fixed R being able to open the battle menu while in battle and the GUI is hidden using F1, closes #1104 2024-10-21 17:06:59 +10:00
Paul 8a94a6126a Fixed crash from loading world in specific pasture scenario, closes #1105 2024-10-21 17:02:50 +10:00
Paul 4cbd5c1745 Fixed crashes from modelPart being null in JSON poser loading, closes #1112 2024-10-21 17:00:21 +10:00
Paul f003406ffe Lots more brain setup, now with presets for combat and chatting and action effects 2024-10-21 16:40:55 +10:00
Hiroku 164207ee10 Merge branch 'feature/posing-shenanigans' into 'main'
attempt in fixing particles in json posers being higher up than intended

Closes #1106

See merge request cable-mc/cobblemon!1219
2024-10-21 03:11:59 +00:00
Hiroku df1ff47e0e Merge branch 'feature/restore-mod-compat' into 'main'
restored modcompat with dynamic lights and adorn

Closes #775

See merge request cable-mc/cobblemon!1210
2024-10-21 01:18:56 +00:00
Sterrezo 0b08372407 Pushed an updated cry checker script. Corrected cries for Smearlge, Ledyba, Ledian, Sunkern, Sunflora, Smeargle.
Thanks to Polymeta for saving the script
2024-10-21 00:43:33 +02:00
Polymeta a2add409c2 introduce ability to manually define rootBone on model, otherwise we assume it's Pokémon name (filename) by default for backwards compatibility
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-10-20 21:36:07 +01:00
Adam IdriciandWeblate 49aa5b4824 Translated using Weblate (French)
Currently translated at 97.1% (6203 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:59:00 +00:00
Alexis SalgueiroandWeblate 8b8db92ace Translated using Weblate (French)
Currently translated at 97.1% (6203 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:59:00 +00:00
Alexis SalgueiroandWeblate cd6c4fe732 Translated using Weblate (French)
Currently translated at 97.1% (6202 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:58:35 +00:00
Adam IdriciandWeblate c0d889a4eb Translated using Weblate (French)
Currently translated at 97.1% (6202 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:58:35 +00:00
Alexis SalgueiroandWeblate 851854d675 Translated using Weblate (French)
Currently translated at 97.1% (6201 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:58:04 +00:00
Adam IdriciandWeblate 8f8864eb38 Translated using Weblate (French)
Currently translated at 97.1% (6201 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:58:04 +00:00
Zack the GhastandWeblate 22e55d97d3 Translated using Weblate (Portuguese (Portugal))
Currently translated at 26.2% (1674 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2024-10-20 13:57:41 +00:00
Adam IdriciandWeblate 95dad9a5d1 Translated using Weblate (French)
Currently translated at 97.0% (6200 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:57:40 +00:00
Alexis SalgueiroandWeblate dbab502150 Translated using Weblate (French)
Currently translated at 97.0% (6200 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:57:40 +00:00
Alexis SalgueiroandWeblate 4a25894e68 Translated using Weblate (French)
Currently translated at 96.9% (6189 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:44:25 +00:00
Adam IdriciandWeblate c88bdf6060 Translated using Weblate (French)
Currently translated at 96.9% (6189 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:44:25 +00:00
Zack the GhastandWeblate 8f14bba7f4 Translated using Weblate (Portuguese (Portugal))
Currently translated at 26.0% (1661 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2024-10-20 13:42:34 +00:00
Adam IdriciandWeblate c46995fe88 Translated using Weblate (French)
Currently translated at 96.9% (6190 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:42:33 +00:00
Alexis SalgueiroandWeblate 804f0fa807 Translated using Weblate (French)
Currently translated at 96.9% (6190 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-20 13:42:33 +00:00
Sterrezo 869216c8c8 Fixed log spam and fixed Petilil Hisui bias missing a cry 2024-10-20 12:26:15 +02:00
Sterrezo 4a21d8f1ef Doesn't crash now! 2024-10-20 12:00:49 +02:00
Sterrezo 8e7a599d9d Merge branch 'main' into sterr/bugfixes 2024-10-20 11:28:40 +02:00
Sterrezo 6996f8d07d Merge branch 'main' into sterr/bugfixes 2024-10-20 11:25:04 +02:00
Carmendar 6d26b5de20 Joltik can now blink while walking without blowing up your game. 2024-10-20 02:16:00 -05:00
Carmendar ef179410f9 Joltik can now blink while walking without blowing up your game. 2024-10-20 02:08:30 -05:00
Hiroku a4d331dc77 Merge branch 'sound' into 'main'
Massive update to sound assets and sounds.json

See merge request cable-mc/cobblemon!1217
2024-10-20 04:04:45 +00:00
Hiroku e635d92cfc Merge branch 'more-things' into 'main'
updates and fixes

See merge request cable-mc/cobblemon!1218
2024-10-20 02:05:46 +00:00
TestandHiroku 3c38b954a8 updates and fixes 2024-10-20 02:05:46 +00:00
Sterrezo 3ebbabd22a Fixed missing item interaction sounds 2024-10-20 01:22:02 +02:00
Hiroku 4ff1379f06 Merge branch 'shoulder-scan-2' into 'main'
Shoulder Scan 2 - Electric Boogaloo

Closes #1078

See merge request cable-mc/cobblemon!1208
2024-10-19 23:04:00 +00:00
JordanandHiroku 5d8515a756 Shoulder Scan 2 - Electric Boogaloo 2024-10-19 23:04:00 +00:00
Wi2terandWeblate 5a1f2df5f1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 91.8% (5866 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2024-10-19 21:41:51 +00:00
Natchakot ChuchokjatupornandWeblate e5a3bf7b4f Translated using Weblate (Thai)
Currently translated at 78.9% (5041 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/th/
2024-10-19 21:41:51 +00:00
Zack the GhastandWeblate 09f8932f90 Translated using Weblate (Portuguese (Portugal))
Currently translated at 25.9% (1655 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2024-10-19 21:41:50 +00:00
Felipe Bermudes OrmeñoandWeblate 91574143e9 Translated using Weblate (Spanish (Mexico))
Currently translated at 25.8% (1653 of 6386 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2024-10-19 21:41:50 +00:00
Landon 25084a6616 Merge branch 'pokedex-camera' into 'main'
Improve camera zooming controls

See merge request cable-mc/cobblemon!1207
2024-10-19 20:21:36 +00:00
Paul 34ead9472d Added animation reflex check for valid expressions 2024-10-19 19:45:18 +10:00
Paul dc54895a6d Lots and lots of work on brain JSON framework 2024-10-19 19:23:59 +10:00
Hiroku 8be3843359 Merge branch 'Structure-Fixes-1.6' into 'main'
Structure Generation Reworks

See merge request cable-mc/cobblemon!1198
2024-10-19 02:13:15 +00:00
Hiroku b83dbfce33 Merge branch 'implement_pokemon' into 'main'
He has a gun help

See merge request cable-mc/cobblemon!1215
2024-10-19 02:06:33 +00:00
Frank The FarmerandHiroku 2d7a0a09ea He has a gun help 2024-10-19 02:06:33 +00:00
Sterrezo 2391830f56 Merge branch 'main' into sound 2024-10-18 23:55:41 +02:00
Wi2terandWeblate 8537ebac3b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 90.3% (5768 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2024-10-18 20:41:49 +00:00
Natchakot ChuchokjatupornandWeblate e54597ba5d Translated using Weblate (Thai)
Currently translated at 78.4% (5006 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/th/
2024-10-18 20:41:49 +00:00
Zack the GhastandWeblate 716187c61b Translated using Weblate (Portuguese (Portugal))
Currently translated at 25.6% (1639 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2024-10-18 20:41:49 +00:00
Alexis SalgueiroandWeblate b5eea5ad2c Translated using Weblate (French)
Currently translated at 96.8% (6185 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-18 20:41:49 +00:00
Felipe Bermudes OrmeñoandWeblate 1c76c237a3 Translated using Weblate (Spanish (Mexico))
Currently translated at 25.8% (1648 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2024-10-18 20:41:49 +00:00
Sterrezo 144f4fd267 Merge branch 'main' into sound 2024-10-18 15:31:36 +02:00
Sterrezo 11e45e2def Small fix to berries + more changelog 2024-10-18 15:20:55 +02:00
Sterrezo 822a8c97fd Changelog, reordered fishing sounds in sounds.json 2024-10-18 15:02:46 +02:00
Sterrezo 68dc8282b3 Renamed sound events for all blocks and Gimmighoul interactions 2024-10-18 15:00:51 +02:00
Sterrezo 5ee195bac8 Reorganized berry harvesting and mulch sounds 2024-10-18 14:42:55 +02:00
Sterrezo 51929e6bcc Reorganized item interaction sounds and sound events 2024-10-18 13:43:45 +02:00
Hiroku 28418c767d Merge branch 'feature/smaller-fixes-additions' into 'main'
fix eye height and small dex additions

Closes #1100 and #1098

See merge request cable-mc/cobblemon!1211
2024-10-18 10:58:45 +00:00
Hiroku 56b7c619a2 Merge branch 'pokemon-properties-helditem-check' into 'main'
added a check on the helditem for pokemon properties

See merge request cable-mc/cobblemon!1214
2024-10-18 08:22:37 +00:00
FrankTheFarmer 194f6e019a Bellsprout line remodeled and animated 2024-10-18 16:29:15 +10:00
FrankTheFarmer 1f933827b9 Merge branch 'main' into implement_pokemon 2024-10-18 16:08:20 +10:00
Hiroku bde2e5ba60 Merge branch 'MasterBallFireImmunity' into 'main'
Master Ball Fire Immunity

See merge request cable-mc/cobblemon!1216
2024-10-18 05:33:39 +00:00
JazzMcNade 70893ddfe1 Restored Fire Immunity to the Master Ball 2024-10-18 00:25:02 -05:00
FrankTheFarmer 28765bb2ce Merge branch 'main' into implement_pokemon 2024-10-18 13:29:35 +10:00
FrankTheFarmer 136391db04 👨‍🌾🔫🐲 2024-10-18 13:27:26 +10:00
Wi2ter 0cc39e71fc revamp Klink Klang and Klingklang 2024-10-18 10:11:53 +08:00
tmetcalfe89 3e746d5009 i hate scoped returns 2024-10-17 18:58:21 -07:00
tmetcalfe89 a4e4fb6bc7 partial match instead 2024-10-17 16:18:36 -07:00
Hiroku f26c939f8a Merge branch 'tim/gmax-move-desc-fixes' into 'main'
small fixes for g-max lang entries

See merge request cable-mc/cobblemon!1213
2024-10-17 22:52:36 +00:00
tmetcalfe89 36b8119972 fixed missing drum solo, grammar, hydro snipe user 2024-10-17 15:37:58 -07:00
Natchakot ChuchokjatupornandWeblate 6cb1ff0abe Translated using Weblate (Thai)
Currently translated at 77.4% (4941 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/th/
2024-10-17 19:50:48 +00:00
Adam IdriciandWeblate 9b18aabe94 Translated using Weblate (French)
Currently translated at 96.4% (6155 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-17 19:50:48 +00:00
Alexis SalgueiroandWeblate 48328416bf Translated using Weblate (French)
Currently translated at 96.4% (6155 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-17 19:50:47 +00:00
Felipe Bermudes OrmeñoandWeblate 745866093e Translated using Weblate (Spanish (Mexico))
Currently translated at 24.5% (1565 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2024-10-17 19:50:47 +00:00
Sterrezo 7c17888a13 Renamed shiny sounds to match the assets 2024-10-17 19:05:25 +02:00
Sterrezo 2536a90ecc Added sound events for Rage Powder 2024-10-17 18:55:14 +02:00
Sterrezo 675e1eb39f Restructured all powder move sound events to make them unique
Also removed an underscore in "non_volatile"
2024-10-17 17:58:17 +02:00
Sterrezo 9e61b2fb6b Restructured status sound assets and sound events 2024-10-17 17:37:24 +02:00
Sterrezo 8d12897bc3 Removed unused files and sound events 2024-10-17 17:06:35 +02:00
Sterrezo c14fc285e1 Fixed Flamethrower missing sounds and renamed sound events for consistency 2024-10-17 17:02:35 +02:00
Sterrezo c06e5618ef Removed unused impact layers and moved them to the assets repository 2024-10-17 16:56:23 +02:00
FrankTheFarmer d65cc08793 Several data fixes for posers and hitboxes 2024-10-17 23:11:43 +10:00
GenotypeXD-Dev a1729a0266 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-17 01:43:17 -06:00
GenotypeXD-Dev 8505634df3 Implement Charmander, Charmeleon, And Charizard Remodels + Gyarados Poser Fixes 2024-10-17 01:42:40 -06:00
FrankTheFarmer 02047c1ec0 Like a bajillion data fixes for posers and hitboxes 2024-10-17 17:24:39 +10:00
tmetcalfe89 1d15dc37e4 added component *exact* matching 2024-10-16 18:07:23 -07:00
FrankTheFarmer 068fa4b2ef Updated Firefox. Make sure to update yours too! 2024-10-17 09:48:45 +10:00
Natchakot ChuchokjatupornandWeblate 7033948b4e Translated using Weblate (Thai)
Currently translated at 75.8% (4839 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/th/
2024-10-16 22:41:40 +00:00
Spaidy NatorandWeblate 156ca6bd1b Translated using Weblate (Russian)
Currently translated at 94.4% (6031 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2024-10-16 22:41:40 +00:00
Adam IdriciandWeblate 39c5d9b179 Translated using Weblate (French)
Currently translated at 96.1% (6137 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-16 22:41:39 +00:00
Alexis SalgueiroandWeblate 362538b1c0 Translated using Weblate (French)
Currently translated at 96.1% (6137 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-16 22:41:39 +00:00
Polymeta ad84a9a967 add arbok variation to dex
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-10-16 22:48:42 +01:00
Polymeta 487eeadccd dont show shiny default and start with main ability instead of ha in display
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-10-16 22:20:17 +01:00
tmetcalfe89 a626f62ae5 WIP - check if Pokemon held item matches
unsure how to check the NBT/components matching
2024-10-16 11:56:40 -07:00
Carmendar bfd266a40e Updated Toxapex, revamped Porygon line, remodeled Gastly and Haunter, updated portraits & pictures for many pokemon. 2024-10-15 23:54:34 -05:00
FrankTheFarmer 6367d4e2aa Tweaked Regional Pokédex orders to allow for proper ordering of the National Pokédex. 2024-10-16 12:59:16 +10:00
Natchakot ChuchokjatupornandWeblate 249486e8bb Translated using Weblate (Thai)
Currently translated at 74.6% (4762 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/th/
2024-10-15 20:41:47 +00:00
Zack the GhastandWeblate 8ccbe3ee8e Translated using Weblate (Portuguese (Portugal))
Currently translated at 25.5% (1629 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2024-10-15 20:41:47 +00:00
YasitoandWeblate 20174aab11 Translated using Weblate (French)
Currently translated at 92.7% (5918 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-15 20:41:47 +00:00
Alexis SalgueiroandWeblate b47da36c80 Translated using Weblate (French)
Currently translated at 92.7% (5918 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-15 20:41:47 +00:00
Felipe Bermudes OrmeñoandWeblate 34519870b4 Translated using Weblate (Spanish (Mexico))
Currently translated at 24.2% (1550 of 6383 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2024-10-15 20:41:47 +00:00
Sterrezo 756396ceb6 Update CHANGELOG.md 2024-10-15 16:37:49 +02:00
Sterrezo dec88e34c5 Gave powder moves less generic names, Spore now has a separate sound event
"powder.stun.actor" has been renamed to "move.stunspore.actor," same with other moves with the same naming convention.
Spore now has a unique sound event, but uses the same audio file as before. This lets it be changed with resource packs.
2024-10-15 16:32:32 +02:00
Sterrezo 4e68d81bbd Renamed "attacks" to "move" in the sounds folder, powder moves and spore now have their own folder
Consistency with Minecraft and already existing sound events
2024-10-15 16:24:35 +02:00
FrankTheFarmer f8a680f381 :*: **:** *:*:* :: :***: :;: 2024-10-15 22:32:01 +10:00
Polymeta 02f1edd695 remove todo for it has been in fact done
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-10-15 09:54:34 +01:00
Sterrezo 0a586c31f4 Changelog (for later) 2024-10-15 02:06:23 +02:00
Test 536ae20d1f Merge branch 'sound' into 'main'
Audio bugfixes and volume adjustments

See merge request cable-mc/cobblemon!1209
2024-10-15 00:03:57 +00:00
SterrezoandTest 38b0551a2d Audio bugfixes and volume adjustments 2024-10-15 00:03:57 +00:00
Polymeta 98416e9cbc commit of shame
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-10-15 01:01:33 +01:00
Test afc1b9aaba clean 2024-10-14 19:50:44 -04:00
Polymeta 3aaef40d07 more dex calculators, debug command and small fix with using calculators server-side
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-10-15 00:45:04 +01:00
Test 9a509f8a80 clean 2024-10-14 19:39:07 -04:00
Sterrezo 7a9a12ac29 Removed unused variables and arguments from functions 2024-10-15 01:13:17 +02:00
Polymeta bc3d3702c9 fix eye height not scaling with hitbox size like it should
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-10-15 00:07:28 +01:00
Polymeta 6c1b9d31f7 adorn compat restored (doesnt work in-dev but in proper jars)
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-10-14 21:39:56 +01:00
Polymeta bed47c7f04 dynamic light compat restored
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-10-14 21:36:46 +01:00
PolymetaandWeblate f4746207d0 Translated using Weblate (German)
Currently translated at 92.3% (5895 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2024-10-14 17:41:47 +00:00
MiaandWeblate 9aa6831a20 Translated using Weblate (German)
Currently translated at 92.3% (5895 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2024-10-14 17:41:47 +00:00
Felipe Bermudes OrmeñoandWeblate 71f4345deb Translated using Weblate (Spanish (Mexico))
Currently translated at 24.0% (1537 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2024-10-14 17:41:47 +00:00
Zack the GhastandWeblate b9cd951c36 Translated using Weblate (Portuguese (Portugal))
Currently translated at 25.2% (1612 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2024-10-14 17:41:47 +00:00
Alexis SalgueiroandWeblate 38d20dd69a Translated using Weblate (French)
Currently translated at 92.2% (5888 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-14 17:41:47 +00:00
Natchakot ChuchokjatupornandWeblate caa46f13be Translated using Weblate (Thai)
Currently translated at 73.5% (4695 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/th/
2024-10-14 17:41:47 +00:00
Sterrezo 54c0f2438c Sendout sound no longer unintentionally plays when a wild Pokemon breaks out
+ a bunch of volume tweaks in sounds.json
2024-10-14 19:25:50 +02:00
Sterrezo e2ee2f60c6 Small corrections to the latest Pokedex sound source change 2024-10-14 18:48:14 +02:00
Sterrezo 517841c2fa Pokedex sounds now come from UI and not the player channel
+ a bunch of volume tweaks
2024-10-14 18:21:28 +02:00
Sterrezo 28e9d89ae3 Merge branch 'main' into sound 2024-10-14 16:28:51 +02:00
GenotypeXD-Dev 81750e6eb9 Added Implemented tag to Finizen and Palafin 2024-10-14 02:17:18 -06:00
GenotypeXD-Dev 818cf682bf Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-14 02:15:11 -06:00
GenotypeXD-Dev 3112a0650f Implemented Finizen and Palafin (+Hero form) 2024-10-14 02:14:51 -06:00
FrankTheFarmer 747ef94f04 Fixed baltoy and claydol exploding the game when scanned. 2024-10-14 15:56:38 +10:00
FrankTheFarmer dbacada48c Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-14 15:16:12 +10:00
FrankTheFarmer 26db8a40cc Un deleted female oinkolognes. This will affect the oinkologne population. 2024-10-14 15:15:30 +10:00
GenotypeXD-Dev 6e5feda00e Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-13 23:12:07 -06:00
GenotypeXD-Dev f04330074b Added implemented tag to all currently implemented 1.6 pokemon 2024-10-13 23:11:46 -06:00
FrankTheFarmer 80d733d329 Merge branch 'main' into implement_pokemon 2024-10-14 14:18:08 +10:00
FrankTheFarmer 0099dcf5c5 Alolan Exeggutor will now appear in front of all pokemon in the dex no matter what lol 2024-10-14 14:16:42 +10:00
Paul 3edb7fbd3a More brain config for NPCs 2024-10-14 13:56:32 +10:00
GenotypeXD-Dev 0a30551b7d Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-13 19:23:49 -06:00
GenotypeXD-Dev e4ee0227fd Reapply "Implement Magikarp and Gyarados Remodels + Jump Variants"
This reverts commit 4ec7168499.
2024-10-13 19:22:35 -06:00
GenotypeXD-Dev 4ec7168499 Revert "Implement Magikarp and Gyarados Remodels + Jump Variants"
This reverts commit 650647e94b.
2024-10-13 19:20:46 -06:00
GenotypeXD-Dev 650647e94b Implement Magikarp and Gyarados Remodels + Jump Variants 2024-10-13 19:19:46 -06:00
Landon Wills 892a5a8fd3 Install new 48 MP camera lens into pro max model with better zooming capabilities 2024-10-13 20:32:21 -04:00
Landon Wills ba155b99a2 Upgrade camera drivers for pro max model 2024-10-13 20:06:04 -04:00
Paul 6df544c279 Merge remote-tracking branch 'origin/main' 2024-10-14 10:01:55 +10:00
Paul 44a1e5ae69 Added NPC AI outlining (WIP), added canDespawn property to NPC classes and presets 2024-10-14 10:01:42 +10:00
Hiroku cf70263a22 Merge branch 'JayceTRD-main-patch-32373' into 'main'
Added cobblemon.battle.end.neutralizinggas to en_us.json

See merge request cable-mc/cobblemon!1205
2024-10-13 23:29:33 +00:00
JayceTRD 536a241f90 Added cobblemon.battle.end.neutralizinggas to en_us.json 2024-10-13 23:27:27 +00:00
Hiroku a61eb1a847 Merge branch 'feature/fix-sign-crash' into 'main'
make sure hanging signs are allowed for hanging sign block entity

Closes #1086

See merge request cable-mc/cobblemon!1204
2024-10-13 21:12:38 +00:00
PolymetaandHiroku 672b72c091 make sure hanging signs are allowed for hanging sign block entity 2024-10-13 21:12:38 +00:00
Hiroku 6ec312ca5e Merge branch 'ys/fix-evo-animation-cancel' into 'main'
Dont clear active animations that should endure primary animations

Closes #1064

See merge request cable-mc/cobblemon!1201
2024-10-13 21:07:56 +00:00
Hiroku 265e4495ef Merge branch 'issue-983' into 'main'
Fix issue with pasture pokemon despawning

Closes #983

See merge request cable-mc/cobblemon!1203
2024-10-13 21:07:44 +00:00
Carmendar a5371f4b5d Updated Tepig line & Baltoy line. 2024-10-13 16:03:10 -05:00
Test 36c355d5cd Merge branch 'pokedex-spin-fix' into 'main'
Fix pokemon spinning unreasonably fast when dragged

See merge request cable-mc/cobblemon!1202
2024-10-13 20:52:33 +00:00
MiaandTest 9c6cb90b93 Fix pokemon spinning unreasonably fast when dragged 2024-10-13 20:52:33 +00:00
Landon Wills cf6a997cfd Fix issue with pasture pokemon despawning 2024-10-13 16:50:16 -04:00
Yaseen 5d437dcb2a less code 2024-10-13 16:03:02 +01:00
Yaseen 450517cba3 Merge branch 'main' into ys/fix-evo-animation-cancel 2024-10-13 15:56:38 +01:00
Yaseen 9a7428841f Dont clear active animations that should endure primary animations 2024-10-13 15:52:38 +01:00
Hiroku 654c4341ef Merge branch 'bugfix/hiro-fixes-packets' into 'main'
Delay deserialization of Pokemon S2C codec until it's in the handler for...

See merge request cable-mc/cobblemon!1196
2024-10-13 09:40:48 +00:00
Hiroku 2c3112d0d4 Merge branch 'FishingSendoutFix' into 'main'
Closes #1011 Fishing sendout fix

Closes #1011

See merge request cable-mc/cobblemon!1200
2024-10-13 07:06:42 +00:00
JazzMcNade bb4d0298a6 Merge branch 'main' into FishingSendoutFix 2024-10-13 01:46:44 -05:00
JazzMcNade b5f9dfd66d Fixed player pokemon being sent out at the player's feet when initiating a fishing battle. 2024-10-13 01:42:54 -05:00
Paul 0d8bc4351a Merge remote-tracking branch 'origin/main' 2024-10-13 16:08:15 +10:00
Paul f4276bbcc0 Removed temporary raft code, indirectly closes #1087 2024-10-13 16:08:00 +10:00
Paul a2c6d6fa30 Fixed shoulder renderer not applying a pokemon context, closes #1083 2024-10-13 16:03:40 +10:00
Wi2ter d47e7fb3c4 Implemented Corphish Crawdaunt 2024-10-13 12:32:27 +08:00
Carmendar ef983e17fe Implemented Palossand, updated Bulbasaur texture, Ivysaur model & texture, Mudkip model & texture. Fixed portraits, pictures & scales for many Pokemon. 2024-10-12 22:42:41 -05:00
Patch Notes GuyandWeblate 2c3ac5da05 Translated using Weblate (Czech)
Currently translated at 24.0% (1533 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/cs/
2024-10-13 02:45:20 +00:00
Patch Notes GuyandWeblate ad9c86372d Translated using Weblate (Japanese)
Currently translated at 91.5% (5841 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2024-10-13 02:45:20 +00:00
Patch Notes GuyandWeblate f531c1eb64 Translated using Weblate (Chinese (Traditional Han script, Hong Kong))
Currently translated at 67.6% (4318 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant_HK/
2024-10-13 02:45:20 +00:00
Patch Notes GuyandWeblate 0a8743158d Translated using Weblate (Portuguese (Portugal))
Currently translated at 24.0% (1533 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate d344ad0bc6 Translated using Weblate (Italian)
Currently translated at 85.8% (5477 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/it/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate 62c3ec8c72 Translated using Weblate (Thai)
Currently translated at 72.9% (4653 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/th/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate b4919fea4d Translated using Weblate (English (United Kingdom))
Currently translated at 0.1% (9 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/en_GB/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate 2ebb8e64c4 Translated using Weblate (English (en_PT))
Currently translated at 24.0% (1533 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/en_PT/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate 379bddc338 Translated using Weblate (Korean)
Currently translated at 86.9% (5551 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate 0335eccfb5 Translated using Weblate (Russian)
Currently translated at 94.4% (6028 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate 0497489292 Translated using Weblate (Spanish (Mexico))
Currently translated at 24.0% (1533 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate 2c168bbce0 Translated using Weblate (Esperanto (eo_EO))
Currently translated at 17.2% (1099 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/eo_EO/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate f6dcbc0d26 Translated using Weblate (Greek (el_CY))
Currently translated at 24.0% (1533 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/el_CY/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate cc54eb8f3f Translated using Weblate (Hungarian)
Currently translated at 24.0% (1533 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/hu/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate 65314f7d1d Translated using Weblate (Spanish)
Currently translated at 85.7% (5470 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate bf7f84a94e Translated using Weblate (French)
Currently translated at 91.9% (5871 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2024-10-13 02:45:19 +00:00
MiaandWeblate da64a9c186 Translated using Weblate (German)
Currently translated at 91.8% (5865 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate a8147beae1 Translated using Weblate (Polish)
Currently translated at 24.0% (1533 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pl/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate 25da152ebf Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 71.2% (4550 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2024-10-13 02:45:19 +00:00
Patch Notes GuyandWeblate 1cc3d64c79 Translated using Weblate (Ukrainian)
Currently translated at 88.7% (5663 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/uk/
2024-10-13 02:45:18 +00:00
Patch Notes GuyandWeblate 30063e96b5 Translated using Weblate (Dutch)
Currently translated at 24.0% (1533 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/nl/
2024-10-13 02:45:18 +00:00
Patch Notes GuyandWeblate 3bd7d09b34 Translated using Weblate (Portuguese (Brazil))
Currently translated at 24.0% (1533 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2024-10-13 02:45:18 +00:00
Patch Notes GuyandWeblate c3d5773cc9 Translated using Weblate (Turkish)
Currently translated at 11.2% (718 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/tr/
2024-10-13 02:45:18 +00:00
Patch Notes GuyandWeblate c688fbabc4 Translated using Weblate (Swedish)
Currently translated at 17.2% (1099 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/sv/
2024-10-13 02:45:18 +00:00
Patch Notes GuyandWeblate 4b313ef54c Translated using Weblate (French (Canada))
Currently translated at 88.7% (5664 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2024-10-13 02:45:18 +00:00
Patch Notes GuyandWeblate 01c2c4efae Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 90.3% (5767 of 6382 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2024-10-13 02:45:18 +00:00
Hiroku aab6fcf891 Merge branch 'Fix1035RestorationExplosions' into 'main'
Closes #1035 restoration explosions

Closes #1035

See merge request cable-mc/cobblemon!1199
2024-10-13 01:53:03 +00:00
JazzMcNade 86ae831d74 Merge branch 'main' into Fix1035RestorationExplosions 2024-10-12 20:35:04 -05:00
JazzMcNade 9d12ce8a33 Fixed tank drops in survival/creative. Reduced code. 2024-10-12 20:34:38 -05:00
Paul 57ef15dea2 Remove reference to non-existent preset 2024-10-13 10:30:56 +10:00
Paul 5650cdc6ed Fixed NPC presets loading from NPCs folder (OOPS), fixed variations not applying to NPC classes, fixed variations not updating aspects after init 2024-10-13 10:30:27 +10:00
Paul 0048622693 Fixed WeightedAspect adapter not being registered for NPC presets 2024-10-13 09:08:44 +10:00
Paul 7940b60d77 Fixed Amaura fossil crash, closes #1085 2024-10-13 08:43:52 +10:00
Paul 886c0c7026 Fixed presets not able to deserialize variation providers 2024-10-13 07:40:25 +10:00
Hiroku 199ab9f4ee Merge branch 'RemoveUnnecessaryGenericHitEffects' into 'main'
Moves with Action Effects no longer display the generic hit effect.

See merge request cable-mc/cobblemon!1197
2024-10-12 21:33:29 +00:00
Paul 573b8cbcf9 Fix SpawnPokemonPacket decoding Species on net thread 2024-10-13 07:32:28 +10:00
JazzMcNade 6583168366 Moves with Action Effects no longer display the generic hit effect. Created generic effect for non-move damage sources. 2024-10-12 14:49:29 -05:00
GenotypeXD-Dev d78975be6e Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-12 01:15:01 -06:00
GenotypeXD-Dev 19a264870c Implemented Scraggy, Scrafty, Hatenna, Hattrem, Hatterene, Wattrel, Kilowattrel, Alola_bias cubone. Fixed Resolver typo from last Push 2024-10-12 01:14:11 -06:00
Slippy ca71fe141a Significantly changed how fossils structures generate in order to avoid generating on top of each other and on top of vanilla structures. 2024-10-11 13:47:31 -05:00
Slippy d1028a79ed Drastic change to how ruins generate. They should avoid any vanilla structures that generate in their respective biomes. 2024-10-11 13:21:37 -05:00
Sterrezo 112a3b9963 Updated 4 cries
Quality updates to Chansey, Crobat, Hoothoot and Noctowl
2024-10-11 15:36:01 +02:00
Sterrezo 444f1e9f69 Merge branch 'main' into sound 2024-10-11 15:33:36 +02:00
Xander Forrest 97c2711eb8 fix mint bounding blocks being randomly -0.9 in size
make berries / mint trees have a lower bounding box if planted, if wild, normal, all looks nice
vanilla MC doesn't actually move the bounding box down on tilled soil, so maybe we shouldn't either
2024-10-11 17:31:16 +07:00
Carmendar ee1753de67 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-10-11 01:28:24 -05:00
Carmendar 742354b2cb Implemented Slakoth, Vigoroth, Slaking. Adjusted Larvitar scale. 2024-10-11 01:24:30 -05:00
Slippy c25f3ce430 Updated Rooted Arch Ruins Structure 2024-10-11 01:02:20 -05:00
MoeBoy76 2ef13cf556 Fixed import 2024-10-11 13:43:35 +11:00
MoeBoy76 9bb594f07d Added Egg events for devs 2024-10-11 13:35:02 +11:00
GenotypeXD-Dev e2f6aaa4de Shelgon Basescale adjustment 2024-10-10 18:53:12 -06:00
GenotypeXD-Dev abc2911059 Implemented Bagon, Shelgon, Salamence, Pikipek, Trumbeak, Toucannon, Dondozo, Alolan Marowak 2024-10-10 17:46:09 -06:00
Slippy 559a30da29 Updated eroded pillar 2 nbt file 2024-10-10 11:10:41 -05:00
Slippy e896067428 Updated Plains Pokecenter & suspicious_mound3 NBT Files 2024-10-10 10:48:28 -05:00
Slippy d1914dd434 Suspicious Mound Fix 2024-10-09 20:43:40 -05:00
FrankTheFarmer d76caf7093 i forgot to write implemented 😩 2024-10-10 10:37:38 +10:00
FrankTheFarmer bf859f8435 Sand castle :) 2024-10-10 10:06:19 +10:00
Sterrezo 8756ef5034 Zoom sound now checks for a variable, instead of a hardcoded value 2024-10-07 08:50:35 +02:00
JazzMcNade 4cfaf27ac7 Fixes 1035 2024-10-06 19:58:38 -05:00
Slippy 8728e3a69a Hopefully this fixed village centers 2024-10-04 23:03:47 -05:00
FrankTheFarmer b31c10cc52 Took Venusaurs foot off the pedal (bone name changes) 2024-10-04 09:30:45 +10:00
FrankTheFarmer 89e3c7d8b0 Sealeo zfight fix 2024-10-04 08:52:20 +10:00
FrankTheFarmer 167b09f24f Fixed Diggersby using its walk animation in its battle portrait 2024-10-01 21:18:09 +10:00
FrankTheFarmer 39165266d5 🎬🔴👗 👠 2024-10-01 20:35:01 +10:00
FrankTheFarmer 7405f2de75 💍⚡🕶️⚡🧋 2024-10-01 20:34:20 +10:00
FrankTheFarmer 762fe87454 ✨🎡🧣 2024-10-01 20:33:41 +10:00
FrankTheFarmer ebbc81b605 💋🎙️🇫🇷 🎩 2024-10-01 20:33:01 +10:00
FrankTheFarmer 12d41aada1 👁️🍧👁️ 2024-10-01 20:32:20 +10:00
FrankTheFarmer 61fe9c23ce 💅 🪨 👜 🐩 2024-10-01 20:31:20 +10:00
FrankTheFarmer 945c9c60a9 Mmm monkey 2024-10-01 20:30:10 +10:00
FrankTheFarmer 8413b0392e Venusaur scaling stuff for Jazz 😈 2024-10-01 16:26:55 +10:00
FrankTheFarmer 868edcd392 Looped Walreins temp idle animation 2024-10-01 16:21:43 +10:00
FrankTheFarmer a3b2f9b6fc Rotom assets for future implementation 2024-10-01 16:07:26 +10:00
FrankTheFarmer 12b444bb41 Kecleon Assets for future implementation 2024-10-01 16:06:57 +10:00
FrankTheFarmer 0e814fd567 Added Flamigo 🔫🦩 2024-10-01 16:05:42 +10:00
FrankTheFarmer 7b083aa038 Added Walrein 🗡️ 🦭 2024-10-01 15:56:16 +10:00
FrankTheFarmer 4e0a4c84b5 Added Sealeo 🦭 2024-10-01 15:54:30 +10:00
FrankTheFarmer 2d9b47e645 Added Spheal 🪩 2024-10-01 15:53:38 +10:00
FrankTheFarmer 39a2182736 Added Toxapex ☂️ 2024-10-01 15:51:23 +10:00
FrankTheFarmer 5a996abbf3 Added Mareanie ☂️ 2024-10-01 15:50:31 +10:00
FrankTheFarmer a20def5161 Snail textures woops 2024-10-01 15:09:31 +10:00
FrankTheFarmer 030f370290 Added Gastrodon 🐌 2024-10-01 11:15:43 +10:00
FrankTheFarmer f3ade3cb82 Added Shellos 🐌 2024-10-01 11:14:14 +10:00
FrankTheFarmer 315cb6a1ac Added Lumineon 🐠 2024-10-01 10:48:35 +10:00
FrankTheFarmer 60615d32f5 Added Finneon 🐟 2024-10-01 10:48:18 +10:00
FrankTheFarmer 1d27d9cf5b Added Clawitzer 🔫🦞 2024-10-01 10:40:21 +10:00
FrankTheFarmer 2ba760d0f9 Added Clauncher 🦞 2024-10-01 10:38:35 +10:00
FrankTheFarmer c31ec3b418 Added Bruxish 🪥🐟🌈 2024-10-01 10:30:52 +10:00
FrankTheFarmer d0afab9604 Added Wugtrio 🪱🪱🪱 2024-10-01 10:16:39 +10:00
FrankTheFarmer 4e9f8fe1c0 Added Wiglett 🪱 2024-10-01 10:16:18 +10:00
Lily 8f40ab45db Added missing Custap Berry message. Closes #1030 2024-09-30 19:27:12 -04:00
Lily 1a1cf3ab7b Pokemon given through /giveallpokemon now have an Original Trainer. Closes #1022 2024-09-30 19:23:00 -04:00
Lily 3231c92baa Evolution message now sends after the animation is complete. Closes #1007
Reject AcceptEvolutionPacket if the Pokemon is busy. Closes #1021
2024-09-30 19:20:35 -04:00
FrankTheFarmer 803f93aa73 Added Corsola 🪸 2024-09-30 17:21:31 +10:00
FrankTheFarmer 853940d009 Added Pincurchin 🦔 2024-09-30 17:16:38 +10:00
FrankTheFarmer 6ddb746d49 Fired for not using indents of 2 again 2024-09-30 17:05:47 +10:00
FrankTheFarmer 2b86b15132 Added Liepard 🐆 2024-09-30 17:05:34 +10:00
FrankTheFarmer 5f0f5d0aa5 Added Purrloin 🐈 2024-09-30 17:02:17 +10:00
FrankTheFarmer 136aab872a Added Mantine 🌊🥞 2024-09-30 17:00:04 +10:00
FrankTheFarmer a1d4702af0 Added Mantyke 🥞 2024-09-30 16:59:33 +10:00
FrankTheFarmer b2777c13b8 Added Milotic 🐍 2024-09-30 16:55:33 +10:00
FrankTheFarmer 26cb473b9d Added Feebas 🎣 2024-09-30 16:55:09 +10:00
FrankTheFarmer 907c639e28 Added Octillery 🐙 2024-09-30 16:52:21 +10:00
FrankTheFarmer 80d2eafed7 Added Remoraid 🐟 2024-09-30 16:51:40 +10:00
FrankTheFarmer 519122e5be Little bit of Rhyhorn line resizing 2024-09-29 22:45:59 +10:00
FrankTheFarmer c211768d5c Forgor to remove Rhyhorn line kotlin posers 2024-09-29 22:45:35 +10:00
FrankTheFarmer 908f318eeb Carvanha remodel 2024-09-29 22:40:27 +10:00
FrankTheFarmer 0143f93577 Rhyperior remodel 🌤🦏 2024-09-29 22:31:46 +10:00
FrankTheFarmer f8615aeb82 Rhyhorn remodel 🦏 2024-09-29 22:26:06 +10:00
FrankTheFarmer b113448a9c Rhydon remodel 🦏 2024-09-29 22:23:56 +10:00
FrankTheFarmer 2930a11c75 Garchomp remodel ✈ 2024-09-29 22:13:00 +10:00
FrankTheFarmer 982de7f5c7 Gabite remodel 🦈 2024-09-29 22:12:08 +10:00
FrankTheFarmer bfdb5e9787 Gible remodel 🐟 2024-09-29 22:11:27 +10:00
FrankTheFarmer d5ea945c6b Krookodile remodel 2024-09-29 22:00:52 +10:00
FrankTheFarmer 5a18d038a2 Wigglytuff remodel 🍎 2024-09-29 21:51:56 +10:00
FrankTheFarmer d0389d6c9c Jigglypuff remodel 🎤 2024-09-29 21:51:32 +10:00
FrankTheFarmer c9bc6e24fe Igglybuff remodel 2024-09-29 21:50:39 +10:00
FrankTheFarmer 8b4a8e9534 oop. Tatsugiri resolver fix 2024-09-29 21:46:25 +10:00
FrankTheFarmer 5adfd00509 Tatsugiri model update 🍙🐟 2024-09-29 21:26:31 +10:00
FrankTheFarmer 4090e038ae Cloyster model update 2024-09-29 21:25:33 +10:00
FrankTheFarmer f3ab282fd1 Shellder model update 2024-09-29 21:25:16 +10:00
FrankTheFarmer 40b97d3c1e Merge branch 'main' into implement_pokemon 2024-09-29 21:17:27 +10:00
FrankTheFarmer 829b97270d Seaking model update 2024-09-29 21:16:49 +10:00
FrankTheFarmer 61111c8038 Goldeen model update 2024-09-29 21:16:34 +10:00
FrankTheFarmer 1f4fbaa177 oop. relicanth resolver update 2024-09-29 21:16:16 +10:00
FrankTheFarmer 9e8ef7e875 Relicanth remodel 2024-09-29 21:15:35 +10:00
FrankTheFarmer 190d90a966 Empoleon remodel 2024-09-29 20:56:38 +10:00
FrankTheFarmer 5a07c82a5d Prinplup remodel 2024-09-29 20:55:57 +10:00
FrankTheFarmer 9c2e56ee8b Cinderace remodel 2024-09-29 20:52:27 +10:00
FrankTheFarmer c83f194dc9 Scorbunny remodel 2024-09-29 20:52:06 +10:00
FrankTheFarmer b9bcb66d2a Swampert remodel 2024-09-29 20:47:43 +10:00
FrankTheFarmer b72050da1d Marshtomp remodel 2024-09-29 20:46:36 +10:00
FrankTheFarmer 82522ad6ab Mudkip remodel 💙 2024-09-29 20:46:02 +10:00
FrankTheFarmer d40e2e6103 Changelog for incoming implementation 2024-09-29 11:41:52 +10:00
FrankTheFarmer 96715770a7 Incineroar Remodel 🔥🧍‍♂️ 2024-09-29 11:41:09 +10:00
FrankTheFarmer 48fa67c2e4 Torracat Remodel 🔥🐆 2024-09-29 11:40:31 +10:00
FrankTheFarmer 9a6217f755 Litten Remodel 🔥🐈 2024-09-29 11:39:38 +10:00
FrankTheFarmer f1f035b5f9 Fired for not using double spaced (2)JSON indents 2024-09-29 11:31:44 +10:00
FrankTheFarmer 19aa53effc Horsea Remodel 2024-09-29 11:24:46 +10:00
FrankTheFarmer be7cb4583c Seadra Remodel 2024-09-29 11:24:36 +10:00
FrankTheFarmer 887891f74d Kingdra Remodel 2024-09-29 11:24:19 +10:00
FrankTheFarmer d83cd34bf4 Removed several pokemon from PokemonModelRepository as they have JSON posers now! 2024-09-28 20:08:54 +10:00
FrankTheFarmer bee41a90f9 Venusaur remodel 2024-09-28 19:59:28 +10:00
FrankTheFarmer 79afe9d812 Ivysaur remodel 2024-09-28 19:59:07 +10:00
FrankTheFarmer 9fe55c5692 Bulbasaur remodel 2024-09-28 19:58:44 +10:00
FrankTheFarmer feddce2575 Merge branch 'main' into implement_pokemon 2024-09-28 19:39:36 +10:00
JazzMcNade 9ae31a3f5d Simplified adjust level rules 2024-09-28 01:31:56 -05:00
FrankTheFarmer 4ddc5e3a93 Cetitan can now cry and walk/sleep at the same time! Unfortunately relatable! 2024-09-28 06:43:47 +10:00
FrankTheFarmer f63f1764ab Merge branch 'main' into implement_pokemon 2024-09-28 06:35:49 +10:00
Paul bc6c9f5df8 Dude don't format stuff like that 2024-09-27 20:38:57 +10:00
Paul 1231e1b0f6 Merge remote-tracking branch 'origin/main' into PvP_Flat_Level_Battling 2024-09-27 12:54:12 +10:00
JazzMcNade b99822e7da Merge branch 'main' into PvP_Flat_Level_Battling 2024-09-26 20:09:02 -05:00
FrankTheFarmer 7c694e9733 Corrected Dachsbun's resolver name. Was using Fidough 2024-09-25 21:19:58 +10:00
FrankTheFarmer 21b6977387 Merge branch 'main' into implement_pokemon 2024-09-25 21:09:08 +10:00
FrankTheFarmer 408735399c Merge branch 'main' into implement_pokemon 2024-09-24 21:13:15 +10:00
FrankTheFarmer f6c856d161 Merge branch 'main' into implement_pokemon 2024-09-24 08:23:07 +10:00
JazzMcNade 167e22cb9c Small refactor and fixed some text 2024-09-19 01:40:45 -05:00
JazzMcNade 5fe2ae9af1 Flat level battling rough draft 2024-09-18 20:53:35 -05:00
FrankTheFarmer 8173cf13a8 data updates for walking wake and iron leaves 2024-09-17 22:28:39 +10:00
FrankTheFarmer 7d0becf1bd Fixed that one elekid thing that was breaking the thingy™ 2024-09-17 09:45:15 +10:00
FrankTheFarmer 9b4a87ce68 Merge branch 'main' into implement_pokemon 2024-09-16 14:51:53 +10:00
Hiroku 464c4d349d Update CHANGELOG.md 2024-09-15 09:31:47 +00:00
Hiroku a35d3131f8 Update CHANGELOG.md 2024-09-15 09:30:28 +00:00
FrankTheFarmer 9d99d3c331 Merge branch 'main' into implement_pokemon 2024-09-14 19:49:29 +10:00
Paul b100516b24 Fixed JSON posed mons having _issues_ when evolved 2024-09-14 12:31:40 +10:00
FrankTheFarmer 8da5396443 Merge branch 'main' into implement_pokemon 2024-09-13 20:58:59 +10:00
FrankTheFarmer 5d2a727311 Chest Gimmighoul quirk fixes 2024-09-13 20:01:19 +10:00
FrankTheFarmer d7f03215e2 Merge branch 'main' into implement_pokemon 2024-09-13 15:18:46 +10:00
FrankTheFarmer d366471e71 Merge branch 'main' into implement_pokemon 2024-09-12 20:17:22 +10:00
FrankTheFarmer e5163f154a The "true".asExpressionLike fix for the bird wing visibility 2024-09-12 20:16:20 +10:00
FrankTheFarmer cfc497d8ed Consistency update for the first few json posers 2024-09-11 18:39:58 +10:00
FrankTheFarmer 35f8ab0257 Removed life ending comma 2024-09-11 17:35:25 +10:00
FrankTheFarmer e890743c86 Merge branch 'main' into implement_pokemon 2024-09-11 17:34:19 +10:00
FrankTheFarmer ffec6e307d Move over poser! 2024-09-11 16:16:01 +10:00
FrankTheFarmer 7c35db7eaa Temp horse data 2024-09-11 16:15:38 +10:00
FrankTheFarmer 9f0c2296bc Fixed the wing flap placeholder animation 2024-09-09 10:32:27 +10:00
FrankTheFarmer 6b0a06c64d I have restored the named animations. i think they got lost. 2024-09-08 15:18:12 +10:00
FrankTheFarmer 160186931f Merge branch 'main' into implement_pokemon 2024-09-08 14:23:54 +10:00
FrankTheFarmer 22c4a14fbe Changelog and maybe added fortnite 2024-09-08 14:22:14 +10:00
FrankTheFarmer 241a82764b Removal of Kingler kotlin poser. im too lazy to do krabby rn lol 2024-09-08 14:18:58 +10:00
FrankTheFarmer 6e4d48bb07 Cramorant remodel 🐟 2024-09-08 14:16:55 +10:00
FrankTheFarmer 7a383f419a 🦀🦀 Krabby & Kingler updates 🦀🦀 2024-09-08 13:30:16 +10:00
FrankTheFarmer 933b99d349 Wobbuffet! 💁‍♀️ 2024-09-08 11:03:30 +10:00
FrankTheFarmer 72d78084f6 Merge branch 'main' into implement_pokemon 2024-09-08 10:21:30 +10:00
FrankTheFarmer fcee4d2774 Merge branch 'main' into implement_pokemon 2024-09-08 07:47:04 +10:00
FrankTheFarmer 61c7f3bc13 sunkern line look animation fixes 2024-09-08 07:45:15 +10:00
FrankTheFarmer 3830637f3c Stupid ass dinosaur crying in his sleep 2024-09-08 07:45:14 +10:00
FrankTheFarmer 45f8049521 💖🌱Sunkern & Sunflora🌻✨ given Retro's placeholder assets and data 2024-09-06 16:47:43 +10:00
FrankTheFarmer 823774bcfe Merge branch 'main' into implement_pokemon 2024-09-06 10:48:03 +10:00
FrankTheFarmer 920e5211c0 Somebody forgot the changelog again 2024-09-06 10:47:02 +10:00
FrankTheFarmer 7da61e3d8d Fixed the look animations for the ledyba line 2024-09-06 10:41:34 +10:00
FrankTheFarmer 754b60b15c fixed Maushold faints not playing 2024-09-03 21:29:09 +10:00
FrankTheFarmer 839454bfd6 Fixed Slowking battle idle not playing properly 2024-09-03 20:31:41 +10:00
FrankTheFarmer 3b6a0667d6 Adjusted Grafaiai walk speed to reduce feet sliding 2024-09-03 20:05:56 +10:00
FrankTheFarmer f298adaea8 Vivillon will stop being naked when removing Vivillon addons 2024-09-03 09:36:53 +10:00
FrankTheFarmer 641206b811 Merge branch 'main' into implement_pokemon 2024-09-02 14:52:59 +10:00
Tyzillion 117f13b056 Added sounds to mud sport and water sport. 2024-08-10 14:54:26 -04:00
Tyzillion 93a94b4900 Updated model for Beedrill and Kingler.
Implement Cramorant.
2024-08-05 17:43:24 -04:00
Tyzillion 40363c2ea1 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-08-04 14:09:00 -04:00
Tyzillion 056252d2bb Implemented particles for psychic, mudsport, watersport, and updated confusion attack particles. 2024-08-04 13:58:04 -04:00
FrankTheFarmer 6f15d65d90 Unbiases your hisuian starter evolution methods 2024-07-15 16:37:53 +10:00
FrankTheFarmer 02f9b21cff Small changelog tweak. I didn't forget i promise. 2024-07-15 12:56:41 +10:00
FrankTheFarmer 79cf154304 What if we take bikini bottom and push it somewhere else?! 2024-07-15 12:19:29 +10:00
FrankTheFarmer a650683d45 Merge remote-tracking branch 'origin/main' into implement_pokemon 2024-07-15 10:54:23 +10:00
Apion 311dc3dc9c Merge branch 'json-poser-conversion' into 'implement_pokemon'
Json poser conversion

See merge request cable-mc/cobblemon!1081
2024-06-27 23:50:31 +00:00
FrankTheFarmer bda1f80ecc Corrected Zangoose's egg moves being in its leveled move list. 2024-06-26 14:28:03 +10:00
FrankTheFarmer 817796bf40 Corrected Klevin's stats to match current databases post S/V patch 2024-06-26 10:22:02 +10:00
FrankTheFarmer 8a48eeab8b Merge branch 'main' into implement_pokemon 2024-06-23 20:48:59 +10:00
FrankTheFarmer 0061104c0d I did not forget the changelog this time 2024-06-23 20:47:37 +10:00
FrankTheFarmer 5110a1be17 Removed Chikorita's ability to look due to some awkward pivots and head structure 2024-06-23 20:28:37 +10:00
FrankTheFarmer 4cbb998106 Adjusted Shroomish's Yaw range for looks. Yeehaw 2024-06-23 20:24:20 +10:00
FrankTheFarmer 17de3f496c Adjusted Bellossom shoulder pose to clip a lot less than before. 2024-06-23 20:08:22 +10:00
FrankTheFarmer b54181e93a Glimmet and Tatsugiri are now shoulder mountable 2024-06-23 20:05:21 +10:00
FrankTheFarmer eaf7edcd94 Fletchling, Skrelp, Klefki, Fomantis, Morelull and Shroodle are now shoulder mountable 2024-06-23 19:46:16 +10:00
FrankTheFarmer cdf1631e2b ZORUA 2 STOP FLOATING 2024-06-23 18:51:40 +10:00
FrankTheFarmer 841f49553e Pidove, Petilil, Hisui Bias Petilil, Zorua, Zorua 2 and Elgyem are now shoulder mountable 2024-06-23 18:51:22 +10:00
FrankTheFarmer 57d7d5a1b9 Minun, Beldum, Starly, Buneary, Combee and Pachirisu are now shoulder mountable 2024-06-23 17:46:41 +10:00
FrankTheFarmer b1f2ab2ed7 Merge branch 'main' into implement_pokemon 2024-06-23 17:26:01 +10:00
FrankTheFarmer f629d95844 Spearow, Murkrow, Mew, Larvitar, Taillow and Plusleare now shoulder mountable 2024-06-23 16:58:37 +10:00
FrankTheFarmer 30904fbdda Caterpie, Weedle, and Smoochum are now shoulder mountable 2024-06-23 16:00:14 +10:00
FrankTheFarmer 9a3be6a85a Roaming Gimmighoul is now shoulder mountable 2024-06-23 15:01:17 +10:00
FrankTheFarmer 88c91d9bdd Reverted Hisuian Zoroark stats to be different from base Zoroark 2024-06-23 09:50:05 +10:00
FrankTheFarmer 5d2efe3e6b Merge branch 'main' into implement_pokemon 2024-06-23 09:41:59 +10:00
FrankTheFarmer d6354d3d94 Fixed Duskull and Dusclops spawn data 2024-06-14 11:51:33 +10:00
FrankTheFarmer 4ddfdd828c Merge branch 'main' into implement_pokemon 2024-06-14 11:30:43 +10:00
FrankTheFarmer 06b70c6204 After nearly 2 years, the Magby line received their placeholder walks 2024-06-12 14:05:54 +10:00
FrankTheFarmer 2dc9d11f79 Merge branch 'main' into implement_pokemon 2024-06-12 14:00:10 +10:00
FrankTheFarmer fbb161c511 I FORGOT THE CHANGELOG 2024-06-04 14:36:35 +10:00
FrankTheFarmer f84bc62d61 Dreepy can now float on your shoulders 2024-06-04 14:17:39 +10:00
FrankTheFarmer 2e20554d1e Fixed Chimchar and Monferno sleeping T pose 2024-06-04 13:55:16 +10:00
apion bb9fcc64ed Started working on Aerodactyl JSON poser 2024-05-24 21:52:16 -04:00
apion 2d908468ea Fixed issue where singular conditions not met, abra is now completely working with a JSON poser 2024-05-24 11:21:01 -04:00
apion c9ae148d86 Moved Abra to JSON poser, pose conditions not properly working 2024-05-24 10:24:50 -04:00
2377 changed files with 310188 additions and 121252 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ common/src/main/resources/assets/cobblemon/showdown
/fabric/src/generated/resources/cobblemon-common.accesswidener
/.ignored/
common/.fabric
.kotlin/
# MacOS
.DS_Store
.kotlin/sessions/kotlin-compiler-16609242564043830292.salive
-1
View File
@@ -1 +0,0 @@
LambDynamicLights compat needs to be restored
+323 -51
View File
@@ -7,18 +7,18 @@
- Added Lure Ball functionality, increasing the catch rate of Pokémon that were caught on a fishing rod.
- Added Repeat Ball functionality, increasing the catch rate of Pokémon that are already registered as caught in a player's Pokédex.
- Added property chaining support for duplicate CustomPokemonPropertyType elements.
- Added flat level battling with options to set all Pokemon to level 50, 100, or 5 for the duration of a battle. No experience or EVs are granted for a flat battle.
- Added `aspect` and `unaspect` PokemonProperty arguments (which also includes commands such as `/pokemonedit`, `/spawnpokemon`, and `/givepokemon`) to allow forcing or un-forcing an aspect on a Pokémon.
- Added `type` alternatively `elemental_type` PokemonProperty argument, this is only used for filtering and is not applied to Pokémon. Example `type=fire` would be true for Charmander but false for Squirtle.
- Added support for Double Battles, Triple Battles, and Multi-battles.
- Added support for Double Battles, Triple Battles, and Multi-battles.
- CriticalCaptures and Pokédex progress capture multiplier now work with the Pokédex.
- Added extra visuals to early berry growth stages.
- Hidden Power now displays its effective typing.
- Moves impacted by the abilities Pixelate, Refrigerate, Aerilate, Galvanize, and Normalize now display as their altered typing.
- Added Polished Tumblestone and Tumblestone Brick block sets from Tumblestone, Black Tumblestone, and Sky Tumblestone.
- Added Metronome, Protective Pads, Punching Glove, Room Service, Scope Lens, Shed Shell, Terrain Extender, Throat Spray, Utility Umbrella, Wide Lens, and Zoom Lens held items
- Added particles for moves: Watersport, Mud Sport, and Psychic.
- Added Fire, Water, Thunder, Leaf, Ice, Sun, Moon, Shiny, Dawn, and Dusk Stone storage blocks.
- Added Eject Pack, Metronome, Protective Pads, Punching Glove, Room Service, Scope Lens, Shed Shell, Terrain Extender, Throat Spray, Utility Umbrella, Wide Lens, and Zoom Lens held items
- Moves can now be benched without specifying a replacement move, allowing for empty move slots.
- Moves learned via Sketch now persist after battle.
- Added `stonjourner_henge_ruins`, `luna_henge_ruins`, and `sol_henge_ruins` structures.
- Added a `battleInvulnerability` gamerule to make players invulnerable to any damage during a battle.
- Added a `mobTargetInBattle` gamerule to exclude players from being targeted by mobs during a battle.
@@ -31,8 +31,17 @@
- `/freezepokemon` command to pause a Pokémon's animation at a specific point in time.
- Added `no_ai` and `freeze_frame` options to the `/spawnpokemon` command.
- Added shiny Pokémon particles with sound effects.
- Added animation for trading.
- Added shiny Pokémon effects.
- Added effects for the burn status effect.
- Added effects for the moves: Psychic, Water Sport, and Mud Sport.
- Added a new universal locator called "top".
### Pokémon Added
#### Gen 1
- Alola Bias Cubone
- Alolan Marowak
#### Gen 2
- Ledyba
- Ledian
@@ -40,19 +49,238 @@
- Sunflora
- Wobbuffet
- Girafarig
- Corsola
- Remoraid
- Octillery
- Mantine
- Smeargle
- Remoraid
- Octillery
- Mantine
- Corsola
#### Gen 3
- Slakoth
- Vigoroth
- Slaking
- Corphish
- Crawdaunt
- Feebas
- Milotic
- Wynaut
- Absol
- Spheal
- Sealeo
- Walrein
- Bagon
- Shelgon
- Salamence
#### Gen 4
- Shellos [East Sea form]
- Gastrodon [East Sea form]
- Finneon
- Lumineon
- Mantyke
- Feebas
- Milotic
- Spheal
- Sealeo
- Walrein
- Kecleon
#### Gen 4
- Mantyke
- Finneon
- Lumineon
- Shellos
- Gastrodon
- Rotom
#### Gen 5
- Purrloin
- Liepard
- Scraggy
- Scrafty
#### Gen 6
- Clauncher
- Clawitzer
#### Gen 7
- Pikipek
- Trumbeak
- Toucannon
- Mareanie
- Toxapex
- Sandygast
- Palossand
- Bruxish
#### Gen 8
- Cramorant
- Hatenna
- Hattrem
- Hatterene
- Bruxish
- Mareanie
- Toxapex
#### Gen 8
- Cramorant
- Pincurchin
#### Gen 9
- Wattrel
- Kilowattrel
- Wiglett
- Wugtrio
- Flamigo
- Veluza
- Farigiraf
- Klawf
- Finizen
- Palafin
- Wiglett
- Wugtrio
- Flamigo
#### Unique Forms
- Magikarp Jump Variants
- Gyarados Jump Variants
### Added cries to the following Pokémon
- Sandshrew, Sandslash
- Magnemite, Magneton, Magnezone
- Gastly, Haunter, Gengar
- Rhyhorn, Rhydon, Rhyperior
- Happiny, Chansey
- Horsea, Seadra, Kingdra
- Magby, Magmar, Magmortar
- Porygon, Porygon2, Porygon-Z
- Sentret, Furret
- Misdreavus, Mismagius
- Corsola
- Mantyke, Mantine
- Girafarig, Farigiraf
- Wynaut, Wobbuffet
- Lunatone
- Solrock
- Corphish, Crawdaunt
- Feebas, Milotic
- Kecleon
- Absol
- Spheal, Sealeo, Walrein
- Relicanth
- Bagon, Shelgon, Salamence
- Munchlax
- Finneon, Lumineon
- Purrloin, Liepard
- Timburr, Gurdurr, Conkeldurr
- Joltik, Galvantula
- Elgyem, Beheeyem
- Golett, Golurk
- Deino, Zweilous, Hydreigon
- Flabébé, Floette, Florges
- Clauncher, Clawitzer
- Mareanie, Toxapex
- Wimpod, Golisopod
- Bruxish
- Hatenna, Hattrem, Hatterene
- Pincurchin
- Klawf
- Finizen, Palafin [Zero], Palafin [Hero]
- Dondozo
### Added shoulder mounts for the following Pokémon
- Weedle
- Caterpie
- Spearow
- Mew
- Murkrow
- Smoochum
- Larvitar
- Tailow
- Plusle
- Minun
- Beldum
- Starly
- Buneary
- Combee
- Pachirisu
- Pidove
- Petilil, Hisui Bias Petilil
- Zorua, Hisui Bias Zorua
- Elgyem
- Fletchling
- Skrelp
- Klefki
- Fomantis
- Morelull
- Dreepy
- Shroodle
- Tatsugiri
- Glimmet
- Gimmighoul [Roaming]
### Animation updates for the following Pokémon
- Bellsprout, Weepinbel, Victreebel
- Shellder, Cloyster
- Porygon, Porygon2, Porygon-Z
- Furret
- Swinub, Piloswine, Mamoswine
- Skarmory
- Spinda
- Torkoal
- Nincada, Ninjask
- Lunatone
- Solrock
- Buneary, Lopunny
- Alomomola
- Dreepy, Drakloak
- Kleavor
### Model updates for the following Pokémon
- Bulbasaur, Ivysaur, Venusaur
- Charmander, Charmeleon, Charizard
- Kakuna, Beedrill
- Porygon, Porygon2, Porygon-Z
- Igglybuff, Jigglypuff, Wigglytuff
- Poliwhirl, Poliwrath
- Bellsprout, Weepinbell, Victreebel
- Shellder, Cloyster
- Gastly, Haunter
- Onix
- Krabby, Kingler
- Rhyhorn, Rhydon, Rhyperior
- Horsea, Seadra, Kingdra
- Goldeen, Seaking
- Magby, Magmar, Magmortar
- Magikarp, Gyarados
- Munchlax, Snorlax
- Swinub, Piloswine, Mamoswine
- Mudkip, Marshtomp, Swampert
- Baltoy, Claydol
- Carvanha
- Relicanth
- Prinplup, Empoleon
- Gible, Gabite, Garchomp
- Riolu, Lucario
- Snivy, Servine, Serperior
- Tepig, Pignite, Emboar
- Krookodile
- Dwebble, Crustle
- Joltik, Galvantula
- Klink, Klang, Klinglang
- Golett, Golurk
- Fennekin, Braixen, Delphox
- Phantump, Trevenant
- Litten, Torracat, Incineroar
- Popplio, Brionne, Primarina
- Lurantis
- Scorbunny, Cinderace
- Quaxly
- Tatsugiri
### Changes
- Buffed Dusk Ball catch multipliers: Increased multiplier to 3.5 (from 3.0) in light level 0. Increased multiplier to 3.0 (from 1.5) in light levels 1-7.
@@ -60,14 +288,13 @@
- Adjusted some berry balance values like yield and growth times.
- Adjusted volumes of sounds made by Display Cases, Berry Bushes, Energy Root, Medicinal Leek, Vivichoke, Mints, Revival Herbs and Gilded Chests.
- Changes to mulch buffs/durations.
- Dreepy is now shoulder mountable.
- Updated potion sprites.
- Weedle, Caterpie, Spearow, Smoochum, Mew, Murkrow, Larvitar, Taillow, Plusle, Minun, Beldum, Starly, Buneary, Combee, Pachirisu, Pidove, Petilil, Hisui Bias Petilil, Zorua, Hisuian Zorua, Elgyem, Fletchling, Skrelp, Klefki, Fomantis, Morelull, Dreepy, Shroodle, Tatsugiri, Glimmet, and Roaming Gimmighoul are now shoulder mountable.
- Link Cable recipe has been redesigned.
- Updated sounds for Medicinal Leeks, Big Roots, Energy Roots and Revival Herbs.
- Updated UI sounds for clicking and evolving Pokémon.
- Updated cries for Chansey, Crobat, Hoothoot, Noctowl.
- Removed the interchangeable evolution results for the first stage Hisuian starters to prevent confusion. The method still exists for stage 2 to 3, but stage 1 to 2 was not distinguishable enough for many users.
- Kakuna, Beedrill, Snorlax, Munchlax, Krabby, Kingler, and Lurantis received model updates.
- Bulbasaur, Ivysaur, Venusaur, Kakuna, Beedrill, Snorlax, Munchlax, Krabby, Kingler, Lurantis, Horsea, Seadra, Kingdra, Litten, Torracat, Incineroar, Mudkip, Marshtomp, Swampert, Scorbunny, Cinderace, Prinplup, Empoleon, Relicanth, Goldeen, Seaking, Shellder, Cloyster, Tatsugiri, Igglybuff, Jigglypuff, Wigglytuff, Krookodile, Gible, Gabite, Garchomp, Rhyhorn, Rhydon, Rhyperior, and Carvanha received model updates.
- Vivillon wings will stop being clear when you remove any Vivillon related resourcepacks. The default pattern will be the meadow wings.
- Adjusted Pokémon sendout positions for single battles.
- Wild Pokémon interaction range increased to 12 blocks (from 10 blocks).
@@ -79,13 +306,26 @@
- Updated dialogue GUI assets with proper assets.
- Updated party switching interface when in battle.
- Relic coin pouches can now be waterlogged.
- Pokemon Name (and level) labels are now only visible when crouching by default, set the `displayEntityLabelsWhenCrouchingOnly` to `false` to always them even when not crouching
- The "Press R to start battle prompt" will now disappear after a player's first battle has been won
- Pokémon name and level labels are now only visible when crouching by default. Set the `displayEntityLabelsWhenCrouchingOnly` config to `false` to always have them displayed.
- The "Press R to start battle prompt" will now disappear after a player's first battle has been won.
- The default number of digits for the Pokédex number in the summary has been increased, from 3 to 4.
- The pasture block model's screen is now off by default.
- The Poké Balls creative tab is now named Utility Items as it also encompasses Poké Rod and Pokédex items.
- Moves can now be benched without specifying a replacement move, allowing for empty move slots.
- Moves learned via Sketch now persist after battle.
- Updated potion sprites
- Removed the interchangeable evolution results for the first stage Hisuian starters to prevent confusion. The method still exists for stage 2 to 3, but stage 1 to 2 was not distinguishable enough for many users.
- Hidden Power now displays its effective typing.
- Updated particles for moves: Confusion, Protect, Sand Attack, and Quick Attack.
- Updated particles for status effects: Paralysis, Poison, and Sleep.
- Updated particles on Gastly.
- Revamped stat buff and de-buff particles.
### Fixes
- Scaled down Amaura's fetus model to avoid clipping through the tank while animating.
- Fixed Cubone's cry not having a sound.
- Fixed the sendout sound erronously playing when a wild Pokémon breaks out of a Poké ball.
- Flamethrower is no longer missing sounds.
- Fixed the Seafloor spawning context not being a usable context.
- Fixed Pokemon spawning in non-full blocks like slabs.
- Fixed Gilded Chests not dropping the chest itself when broken, only the contents.
@@ -94,9 +334,10 @@
- Fixed Chimchar and Monferno T-posing whenever they sleep.
- Fixed the Magby line not having any placeholder walk animations.
- Fixed Duskull and Dusclops using skylight levels for their nether spawn data. There is no sun in the Nether!
- Fixed Hisuian Zoroark using base Zoroark stats.
- Fixed Hisuian Zoroark using base Zoroark stats.
- Fixed Bellossom clipping into the player head when shoulder mounted.
- Fixed Shroomish's look range to prevent it from looking higher than it should.
- Fixed Shroomish's look range to prevent it from looking higher than it should.
- Fixed Cetitan's cry breaking its walk and sleep animations.
- Fixed Crumbling Arch not blending in with the world.
- Fixed Energy Root applying being usable on a fainted Pokémon.
- Fixed Pokémon entity not spawning when starting a battle while recalling said Pokémon.
@@ -127,9 +368,14 @@
- Fixed Hisuian Zoroark using base Zoroark stats.
- Fixed Bellossom clipping into the player head when shoulder mounted.
- Fixed Shroomish's look range to prevent it from looking higher than it should.
- Fixed Maushold's faint animations not playing. It's sadder than Tandemaus!
- Fixed Slowking's battle idle.
- Fixed Grafaiai's walk speed to prevent model sliding.
- Fixed Maushold's faint animations not playing. It's sadder than Tandemaus!
- Fixed Slowking's battle idle.
- Fixed Grafaiai's walk speed to prevent model sliding.
- Fixed Alolan Exeggutor's tail not showing in the party UI. It will now also stand in front of all Pokémon in the party menu :)
- Fixed Timburr duplicating its log while fainting.
- Fixed reviving items throwing an exception when used in battle.
- Fixed messages for Focus Sash, Confusion, Mummy, Ice Face, Own Tempo, and Revive.
- Improve error handling when loading spawn-sets to ensure invalid configurations don't crash the server.
@@ -144,7 +390,9 @@
- Pokémon whose current owner is not its Original Trainer now gains extra experience.
- Fixed Fossil Resurrection advancement not being granted.
- Fixed village generation caps not applying for berry farms. You were not meant to see more than two berry farms per village!
- Fixed the Ice Face ability activation being displayed incorrectly in a battle
- Fixed the Ice Face ability activation being displayed incorrectly in a battle.
- Fixed edge case of F1 and R locking you in battle with no R functionality (requiring ESC to get out).
- Fixed Poké Ball render orientation in battle interface when capturing.
### Developer
- `SpawnCause` is now an implementation of `SpawningInfluence`.
@@ -157,21 +405,44 @@
- Serialization of PokemonStores and Pokemon themselves now require registry access, which will break some sidemods. This sucked for us more than it will suck for you! If you have a world or player instance, you can get it from there.
- ``TeraTypes`` now implements ``Iterable``.
- PokemonBattle now starts on turn 0.
- All sounds related to evolving Pokémon have been moved to the "sounds/evolution" folder.
- Added `forcedAspects` to Pokémon to make it easier to easily add basic aspects to a Pokémon in a way that persists. We already know that everyone is going to overuse this.
- Made the `Pokemon.aspects` setter private. This could technically break side-mods but if you are affected by this then you were using it wrong! Use `Pokemon.forcedAspects` to fix it.
- Cobblemon's main logger is properly static now.
- PokemonEntity.enablePoseTypeRecalculation can be used to disable automatic pose type recalculation.
- Added CollectEggEvent and HatchEggEvent for compatibility usage.
- Added events for:
- Showdown Instructions
- Mega Showdown Instruction
- Terastallize Showdown Instruction
- ZPower Showdown Instruction
- Bait Consumed, Bait Set, and an event to register custom BaitEffect Functions
- Bobber Bucket Chosen
- Bobber Spawn Pokémon
- Pokérod Cast
- Pokérod Reel
- Pokémon Heal (with context)
- Added HealingSource, an interface applied to all sources of healing from player actions, for easier tracking of healing sources.
- Move Change
### Data Pack & Resource Pack Creators
- Added support for "shedders" similar to Shedinja's evolution logic.
- Fixed the placeholder `WingFlapIdle` animation so the wings are not rotating opposite to each other.
- 'player' type dialogue faces can now be explicitly stated so that NPC mods that use fake players can show in dialogue portraits.
- Added `isLeftSide` field for dialogue faces. This determines what side of dialogue box the portrait is on.
- "sounds/attacks" folder has been renamed to "sounds/move"
- Moves sharing generic sounds now have unique sound events, allowing them to be changed with resource packs.
- All move sound events have been renamed to "move.NAME.SOURCE" for consistency.
- Status moves have been moved out of the 'attacks' folder and split into volatile and nonvolatile.
- 'status.badlypoison.actor' sound event has been renamed to "status.toxpoison.actor"
- Mulch and berry harvesting sound events have been renamed and moved to their respective folders in "sounds/block."
- All sounds related to evolving Pokémon have been moved to the "sounds/evolution" folder.
- Sound events for all blocks now start with "block."
- Gimmighoul chest and item interaction sounds have been moved to where its cry is.
- Unused sound files and sound events have been removed.
### Localization
- Updated translations for:
- Czech, German, Greek, Spanish, Mexican Spanish, French, Canadian French, Hungarian, Italian, Japanese, Korean, Dutch, Polish, Portuguese, Brazilian Portuguese, Russian, Ukrainian, Simplified Chinese, and Traditional Chinese
- Czech, German, Greek, Spanish, Mexican Spanish, French, Canadian French, Hungarian, Italian, Japanese, Korean, Dutch, Polish, Portuguese, Brazilian Portuguese, Russian, Ukrainian, Simplified Chinese, and Traditional Chinese
- Migrated translation project to Weblate at https://lang.cobblemon.com/projects/cobblemon/mod/
@@ -211,7 +482,7 @@
### Changes
- Sounds for Relic Coin Sacks have been correctly renamed. Relic Coin Pouches received new sounds for breaking and placing.
- Readjusted Petilil portraits so they fit a bit better.
- Improved handling of Pokémon taken from the Restoration Tank block to be a bit more stable.
- Improved handling of Pokémon taken from the Restoration Tank block to be a bit more stable.
- Made Mulch cheaper to craft.
### Fixes
@@ -223,19 +494,19 @@
- Fixed Supplementaries incompatibility.
- Fixed Fossil Compartment crash with Jade / WAILA forks.
- Fixed pasture block PC lookups when the player is offline.
- Fixed an untranslated battle message that occurs when using a move that just ran out of PP (e.g. Fire Blast that just got spited mid-turn).
- Fixed an untranslated battle message that occurs when using a move that just ran out of PP (e.g. Fire Blast that just got spited mid-turn).
- Fixed held items being eaten even when the held item evolutions are already unlocked.
- Fixed Hisuian Decidueye not being Grass/Fighting.
- Fixed both Decidueye forms learning both Triple Arrows and Spirit Shackle.
- Fixed Pineco being unable to evolve into Shulker Forretress.
- Fixed Kabutops T-posing when underwater. It doesn't have proper swimming animations yet, though.
- Fixed Kabutops T-posing when underwater. It doesn't have proper swimming animations yet, though.
- Fixed Pidgey's missing walk animation.
- Fixed Cyndaquil's hidden flames clipping if it was swimming.
- Fixed Chimecho and Chingling being unable to spawn near bells. They are meant to!
- Fixed Tyrantrum and Wailord Party Overlay models peeking through the chat box. It was kinda funny though.
- Fixed hitbox sizes for Seedot, Nuzleaf, and Shiftry.
- Fixed Budew and Lechonk sliding if they walked for too long.
- Fixed Shedinja T-posing in battle.
- Fixed Budew and Lechonk sliding if they walked for too long.
- Fixed Shedinja T-posing in battle.
- Fixed recoil evolution condition not working, making things like Basculegion unobtainable.
- Fixed issue where poser debug tools didn't work on JSON posers.
- Fixed issue where gilded chests don't close when going far away.
@@ -253,7 +524,7 @@
- Fixed generic battle effect sounds not sounding the way they were intended to.
- Fixed particle effects often not having access to some specific entity functions from MoLang.
- Fixed particles sometimes lasting a single tick too long, causing (very quick) visual glitches.
- Fixed particle rotations being inverted.
- Fixed particle rotations being inverted.
- Fixed particle events not spawning at the instigating particle's location.
- Fixed a bunch of spam during world generation.
- Fixed a bug in which throwing a Poké Ball at a player owned Pokémon with the ability Illusion would reveal its true species. Hilarious meta strategy.
@@ -272,13 +543,13 @@
- Added parametric motion and rotation support to particle effects.
- Added entity_scale as a molang var for particles (likely only applicable to Pokemon)
- Added support for primary quirk animations using the following format:
`JSON
{
"quirks": [
"q.bedrock_primary_quirk('<pokemon>', '<animation>', <minSeconds>, <maxSeconds>, <loopTimes>, '<excludedLabels>', q.curve('<waveFunction>'))"
]
}
`
`JSON
{
"quirks": [
"q.bedrock_primary_quirk('<pokemon>', '<animation>', <minSeconds>, <maxSeconds>, <loopTimes>, '<excludedLabels>', q.curve('<waveFunction>'))"
]
}
`
- Added support for custom stashes, similar to Gimmighoul's coin and scrap stashes.
### Localization
@@ -578,7 +849,7 @@ These are our compromise for having both regular and Hisuian forms of these Pok
- Fixed thrown Poké Balls technically having no name.
- Fixed very many issues with Bedrock particle effects. There are probably many more. Life goes on.
- Fixed Arbok patterns not being as specific in spawning as they were intended to be.
- Fixed Pokémon not avoiding danger at all when pathfinding.
- Fixed Pokémon not avoiding danger at all when pathfinding.
- Fixed Pokémon pathing over snow layers and carpets.
- Fixed the Sobble line not being able to swim or breathe underwater.
- Fixed mod incompatibility with [Just Enough Resources](https://modrinth.com/mod/just-enough-resources-jer).
@@ -587,7 +858,7 @@ These are our compromise for having both regular and Hisuian forms of these Pok
- Fixed the data set on Pokémon when abilities are given via properties such as in `/spawnpokemon`.
- Fixed Pokémon sometimes losing hidden abilities when evolving. This fix will only take effect for newly created Pokémon because of technical reasons that were explained to me but which I then forgot.
- Fixed capture messages not displaying in battle.
- Fixed the Illusion ability causing the wrong Pokémon to be targeted in battle.
- Fixed the Illusion ability causing the wrong Pokémon to be targeted in battle.
- Fixed battles started with fainted party members causing a soft-lock on defeat.
- Fixed some issues with eyes in the faint animations of Hitmonlee and Phantump
- Fixed missing evolution moves, for example Stone Axe for Kleavor.
@@ -602,7 +873,7 @@ These are our compromise for having both regular and Hisuian forms of these Pok
- Added a new "advancement" evolution variant that takes an advancement identifier and succeeds if the player has the advancement.
- Made the spawning API capable of non-entity spawning. You can make it 'spawn' commands if you want. Go nuts.
- Made `PokemonProperties.parse` more interoperable with Java. Save yourself and stop using Java.
- Added the `HeldItemEvent`, this comes with 2 implementation `HeldItemEvent.Pre` and `HeldItemEvent.Post`.
- Added the `HeldItemEvent`, this comes with 2 implementation `HeldItemEvent.Pre` and `HeldItemEvent.Post`.
- Corrections to the ability implementation have been made that make `Ability.forced` function as intended and never reroll an ability for a Pokémon, please check your implementations to ensure the corrected behavior is intended for your use case.
- `Pokemon.ability` no longer has a public setter. Please migrate to using `Pokemon#updateAbility`, this handles the ability coordinate storage for you when necessary.
- `Ability.forced`, `Ability.index` and `Ability.priority` have all had their setters internalized, there is no longer any need to manually adjust these migrate to the method mentioned above to handle that process for you.
@@ -616,14 +887,14 @@ These are our compromise for having both regular and Hisuian forms of these Pok
### Datapack & Resourcepack Creators
- The maximum amount of fossils that can fit in the Fossil Analyzer can be adjusted in the config.
- Custom fossils can be defined using a list of items and the resulting Pokémon. An example of `aerodactyl.json`:
`JSON
{
"result": "aerodactyl",
"fossils": [
"cobblemon:old_amber_fossil"
]
}
`
`JSON
{
"result": "aerodactyl",
"fossils": [
"cobblemon:old_amber_fossil"
]
}
`
- Fetus models can be defined in `bedrock/fossils`.
- Fetus textures can be defined in `textures/fossils`.
- Fuel for the Restoration Machine is registered inside the `natural_materials` folder. To register more fuels, create a JSON file containing an array of objects. Each object supports the following fields:
@@ -635,16 +906,16 @@ These are our compromise for having both regular and Hisuian forms of these Pok
- Added dialogue datapack folder and `/opendialogue` command.
- Added the item tag `cobblemon:held/leaves_leftovers` this can be used to flag apple-like items that can create leftovers when eaten.
- You can now add support for dynamic lighting implementations, Cobblemon ships with a default implementation for [LambDynamicLights](https://modrinth.com/mod/lambdynamiclights) and the [Dynamic Lights Reforged](https://www.curseforge.com/minecraft/mc-mods/dynamiclights-reforged), add the following to any species or form:
`JSON
{
"lightingData": {
"lightLevel": 14,
"_lightLevelCommentRemoveMe": "Above supports 0 to 15",
"liquidGlowMode": "LAND",
"_liquidGlowModeCommentRemoveMe": "Above supports LAND, UNDERWATER or BOTH"
`JSON
{
"lightingData": {
"lightLevel": 14,
"_lightLevelCommentRemoveMe": "Above supports 0 to 15",
"liquidGlowMode": "LAND",
"_liquidGlowModeCommentRemoveMe": "Above supports LAND, UNDERWATER or BOTH"
}
}
}
`
`
- Following up on this change `light_source` was removed as a possible shoulder effect due to becoming unnecessary and never having had a default implementation.
- Added the item tag `cobblemon:ability_changers`, contains the `cobblemon:ability_capsule` & `cobblemon:ability_patch` by default.
- Added the item tag `cobblemon:held/is_friendship_booster`, allows items to give the Soothe Bell effect of a boost of 1.5x Friendship gained, contains `cobblemon:soothe_bell` by default.
@@ -731,7 +1002,7 @@ These are our compromise for having both regular and Hisuian forms of these Pok
- Fixed an exploit that could convert a single piece of Blaze Powder into an extra Medicinal Brew on the Forge version.
- Fixed an issue where health percentages would show incorrectly after healing
- Fixed the move Revival Blessing not allowing you to select from fainted party members.
- Fixed villagers not being able to pick up and plant mint seeds, vivichoke seeds, and revival herbs.
- Fixed villagers not being able to pick up and plant mint seeds, vivichoke seeds, and revival herbs.
- Fixed Exeggcute faint.
- Fixed various spawn configuration issues across the board.
- Fixed a possible visual duplication of sent out Pokémon.
@@ -751,7 +1022,7 @@ These are our compromise for having both regular and Hisuian forms of these Pok
### Developer
- Fixed the `SpawnEvent` not respecting usage of `Cancelable#cancel`.
- Added the `EvolutionTestedEvent`, this allows listening and overriding the final result of evolution requirement tests.
- Rebuilt the scheduling API to more clearly force side choices and allow more local temporal frames of reference for tasks.
- Rebuilt the scheduling API to more clearly force side choices and allow more local temporal frames of reference for tasks.
- Added utility script that can be used to generate all Spawn JSONS for all pokemon from the spawning spreadsheet in 1 click ([cobblemon_spawn_csv_to_json.py](utilityscripts%2Fcobblemon_spawn_csv_to_json.py)).
- The `HeldItemManager` has a new method `shouldConsumeItem`, this will return false by default to prevent breaking changes, see the documentation and update your implementations as needed.
- Added and implemented minSkyLight and maxSkyLight as config options for SpawnConditions
@@ -777,7 +1048,7 @@ These are our compromise for having both regular and Hisuian forms of these Pok
- Dutch
- Ukrainian
- Russian
Thank you so much to all of our community translators that bring the mod to the rest of the world!
## [1.4.0 - The Friends and Farms Update (October 13th, 2023)](#1-4-0)
@@ -1188,7 +1459,7 @@ Thank you so much to all of our community translators that bring the mod to the
- Species and FormData have had their evolutions, pre-evolution and labels properties exposed. It is still recommended to work using a Pokémon instance when possible.
- Added capture check to BattleVictoryEvent.
- The various hardcoded potion shoulder effects have been removed, make use of PotionBaseEffect.
- Added ContextManager for tracking causes and contexts of conditions created during a battle. See BattleContext for types of conditions that are tracked.
- Added ContextManager for tracking causes and contexts of conditions created during a battle. See BattleContext for types of conditions that are tracked.
- Added MongoDB support for storing Pokémon and Player data. Must be enabled in config, requires MongoDB core and sync drivers (4.10.0+).
- CobblemonShowdown updated to version 10.
- Generation of a battle can be set in BattleFormat.
@@ -1587,3 +1858,4 @@ Thank you so much to all of our community translators that bring the mod to the
## [1.0.0 (November 12th, 2022)](#1-0-0)
- Initial release.
@@ -13,11 +13,15 @@ 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.api.DynamicLightHandler;
import dev.lambdaurora.lambdynlights.api.DynamicLightHandlers;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.EntityType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import net.minecraft.util.Tuple;
import net.minecraft.world.entity.player.Player;
// Java class due to relying on entrypoint on Fabric side
@@ -29,44 +33,32 @@ public class LambDynamicLightsCompat {
// Make sure not to call anything Fabric specific :)
public static void hookCompat() {
// Pokémon entities
// DynamicLightHandlers.registerDynamicLightHandler(
// CobblemonEntities.POKEMON,
// DynamicLightHandler.makeHandler(
// pokemon -> resolvedPokemonLightLevel(pokemon, false),
// pokemon -> true
// )
// );
// DynamicLightHandlers.registerDynamicLightHandler(
// CobblemonEntities.POKEMON,
// DynamicLightHandler.makeHandler(
// pokemon -> resolvedPokemonLightLevel(pokemon, true),
// pokemon -> false
// )
// );
DynamicLightHandlers.registerDynamicLightHandler(
CobblemonEntities.POKEMON,
DynamicLightHandler.makeHandler(
LambDynamicLightsCompat::resolvedPokemonLightLevel,
pokemon -> false
)
);
// Shouldered Pokémon
// DynamicLightHandlers.registerDynamicLightHandler(
// EntityType.PLAYER,
// DynamicLightHandler.makeHandler(
// player -> resolvedShoulderLightLevel(player, false),
// player -> true
// )
// );
// DynamicLightHandlers.registerDynamicLightHandler(
// EntityType.PLAYER,
// DynamicLightHandler.makeHandler(
// player -> resolvedShoulderLightLevel(player, true),
// player -> false
// )
// );
DynamicLightHandlers.registerDynamicLightHandler(
EntityType.PLAYER,
DynamicLightHandler.makeHandler(
LambDynamicLightsCompat::resolvedShoulderLightLevel,
player -> false
)
);
}
private static int resolvedPokemonLightLevel(PokemonEntity pokemon, boolean underwater) {
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);
}
private static int resolvedShoulderLightLevel(Player player, boolean underwater) {
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));
@@ -10,11 +10,14 @@ package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.client.CobblemonClient;
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding;
import com.cobblemon.mod.common.item.PokedexItem;
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Local;
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 org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@@ -24,12 +27,20 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MouseHandler.class)
public class PartyScrollMixin {
public class MouseHandlerMixin {
@Shadow
private double accumulatedScrollY;
@Shadow @Final private Minecraft minecraft;
@Shadow @Final private SmoothDouble smoothTurnY;
@Shadow @Final private SmoothDouble smoothTurnX;
@Shadow private double accumulatedDX;
@Shadow private double accumulatedDY;
@Inject(
method = "onScroll",
at = @At(
@@ -74,4 +85,27 @@ public class PartyScrollMixin {
}
}
}
@WrapWithCondition(
method = "turnPlayer",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/player/LocalPlayer;turn(DD)V"
)
)
public boolean cobblemon$modifyRotation(LocalPlayer player, double cursorDeltaX, double cursorDeltaY, @Local(argsOnly = true) double d) {
// I know this technically doesn't need to be a WrapWithCondition, but it'll make things easier later for riding.
PokedexUsageContext usageContext = CobblemonClient.INSTANCE.getPokedexUsageContext();
if (usageContext.getScanningGuiOpen()) {
this.smoothTurnY.reset();
this.smoothTurnX.reset();
var defaultSensitivity = this.minecraft.options.sensitivity().get() * 0.6000000238418579 + 0.20000000298023224;
var spyglassSensitivity = Math.pow(defaultSensitivity, 3);
var lookSensitivity = spyglassSensitivity * 8.0;
var sensitivity = Mth.lerp(usageContext.getFovMultiplier(), spyglassSensitivity, lookSensitivity);
player.turn(this.accumulatedDX * sensitivity, (this.accumulatedDY * sensitivity));
return false;
}
return true;
}
}
@@ -12,15 +12,23 @@ import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.CobblemonItems;
import com.cobblemon.mod.common.api.events.CobblemonEvents;
import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent;
import com.cobblemon.mod.common.api.storage.NoPokemonStoreException;
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies;
import com.cobblemon.mod.common.api.storage.party.PartyStore;
import com.cobblemon.mod.common.api.tags.CobblemonItemTags;
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData;
import com.cobblemon.mod.common.pokedex.scanner.ScannableEntity;
import com.cobblemon.mod.common.pokemon.FormData;
import com.cobblemon.mod.common.pokemon.Gender;
import com.cobblemon.mod.common.pokemon.Pokemon;
import com.cobblemon.mod.common.pokemon.Species;
import com.cobblemon.mod.common.util.CompoundTagExtensionsKt;
import com.cobblemon.mod.common.util.CompoundTagUtilities;
import com.cobblemon.mod.common.util.DataKeys;
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
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.EntityType;
@@ -30,19 +38,24 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.food.FoodProperties;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.Opcodes;
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 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.stream.Collectors;
@Mixin(Player.class)
public abstract class PlayerMixin extends LivingEntity {
public abstract class PlayerMixin extends LivingEntity implements ScannableEntity {
@Shadow public abstract CompoundTag getShoulderEntityLeft();
@@ -68,16 +81,16 @@ public abstract class PlayerMixin extends LivingEntity {
@Inject(method = "respawnEntityOnShoulder", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;create(Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/world/level/Level;)Ljava/util/Optional;"), cancellable = true)
private void cobblemon$removePokemon(CompoundTag nbt, CallbackInfo ci) {
if (CompoundTagExtensionsKt.isPokemonEntity(nbt)) {
final UUID uuid = this.getPokemonID(nbt);
if (this.isShoulderPokemon(this.getShoulderEntityRight())) {
final UUID uuidRight = this.getPokemonID(this.getShoulderEntityRight());
final UUID uuid = CompoundTagUtilities.getPokemonID(nbt);
if (CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityRight())) {
final UUID uuidRight = CompoundTagUtilities.getPokemonID(this.getShoulderEntityRight());
if (uuid.equals(uuidRight)) {
this.recallPokemon(uuidRight);
this.setShoulderEntityRight(new CompoundTag());
}
}
if (this.isShoulderPokemon(this.getShoulderEntityLeft())) {
final UUID uuidLeft = this.getPokemonID(this.getShoulderEntityLeft());
if (CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityLeft())) {
final UUID uuidLeft = CompoundTagUtilities.getPokemonID(this.getShoulderEntityLeft());
if (uuid.equals(uuidLeft)) {
this.recallPokemon(uuidLeft);
this.setShoulderEntityLeft(new CompoundTag());
@@ -101,22 +114,17 @@ public abstract class PlayerMixin extends LivingEntity {
// We want to allow both of these to forcefully remove the entities
if (this.isSpectator() || this.isDeadOrDying())
return;
if (!this.isShoulderPokemon(this.getShoulderEntityLeft())) {
if (!CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityLeft())) {
this.respawnEntityOnShoulder(this.getShoulderEntityLeft());
this.setShoulderEntityLeft(new CompoundTag());
}
if (!this.isShoulderPokemon(this.getShoulderEntityRight())) {
if (!CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityRight())) {
this.respawnEntityOnShoulder(this.getShoulderEntityRight());
this.setShoulderEntityRight(new CompoundTag());
}
ci.cancel();
}
private UUID getPokemonID(CompoundTag nbt) {
return nbt.getCompound(DataKeys.POKEMON)
.getUUID(DataKeys.POKEMON_UUID);
}
private void recallPokemon(UUID uuid) {
// We need to do this cause the Entity doesn't store a reference to its storage
final PartyStore party = Cobblemon.INSTANCE.getStorage().getParty(this.getUUID(), this.registryAccess());
@@ -127,10 +135,6 @@ public abstract class PlayerMixin extends LivingEntity {
}
}
private boolean isShoulderPokemon(CompoundTag nbt) {
return CompoundTagExtensionsKt.isPokemonEntity(nbt);
}
@Inject(
method = "eat",
at = @At(
@@ -171,4 +175,49 @@ public abstract class PlayerMixin extends LivingEntity {
}
}
}
@Override @Nullable
public PokedexEntityData resolvePokemonScan() {
if(CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityRight())){
return getDataFromShoulderPokemon(this.getShoulderEntityRight());
}
if(CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityLeft())){
return getDataFromShoulderPokemon(this.getShoulderEntityLeft());
}
return null;
}
@Nullable @Unique
private PokedexEntityData getDataFromShoulderPokemon(CompoundTag shoulderTag) {
CompoundTag pokemonTag = shoulderTag.getCompound(DataKeys.POKEMON);
if(pokemonTag.isEmpty()) return null;
Species species = PokemonSpecies.INSTANCE.getByIdentifier(ResourceLocation.parse(pokemonTag.getString(DataKeys.POKEMON_SPECIES_IDENTIFIER)));
if(species == null) return null;
String formId = pokemonTag.getString(DataKeys.POKEMON_FORM_ID);
FormData form = species.getStandardForm();
List<FormData> formList = species.getForms().stream().filter(it -> it.formOnlyShowdownId().equals(formId)).toList();
if(!formList.isEmpty()) form = formList.getFirst();
if(form == null) return null;
String genderString = pokemonTag.getString(DataKeys.POKEMON_GENDER);
if(genderString.isEmpty()) return null;
Gender gender = Gender.valueOf(genderString);
boolean shiny = pokemonTag.getBoolean(DataKeys.POKEMON_SHINY);
int level = pokemonTag.getInt(DataKeys.POKEMON_LEVEL);
Set<String> aspects = shoulderTag.getList(DataKeys.SHOULDER_ASPECTS, Tag.TAG_STRING).stream().map(Tag::getAsString).collect(Collectors.toSet());
return new PokedexEntityData(
species,
form,
gender,
aspects,
shiny,
level,
this.getUUID()
);
}
@Override
public LivingEntity resolveEntityScan() {
return this;
}
}
@@ -9,6 +9,8 @@
package com.cobblemon.mod.common.mixin.invoker;
import java.util.List;
import com.cobblemon.mod.common.integration.AdornCompatibility;
import juuxel.adorn.block.variant.BlockVariantSet;
import juuxel.adorn.block.variant.BlockVariantSets;
import org.spongepowered.asm.mixin.Final;
@@ -26,7 +28,7 @@ public abstract class AdornRegisterInvoker {
private static List<BlockVariantSet> variantSets;
@Inject(method = "register()V", at = @At("HEAD"), remap = false)
void register(CallbackInfo ci) {
// variantSets.add(AdornCompatibility.INSTANCE);
private static void register(CallbackInfo ci) {
variantSets.add(new AdornCompatibility());
}
}
@@ -97,6 +97,7 @@ 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.BattleCloneProperty
import com.cobblemon.mod.common.pokemon.properties.tags.PokemonFlagProperty
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
@@ -273,6 +274,7 @@ object Cobblemon {
FlagSpeciesFeatureProvider(keys = listOf(DataKeys.HAS_BEEN_SHEARED), default = false))
CustomPokemonProperty.register(UncatchableProperty)
CustomPokemonProperty.register(BattleCloneProperty)
CustomPokemonProperty.register(PokemonFlagProperty)
CustomPokemonProperty.register(HiddenAbilityPropertyType)
CustomPokemonProperty.register(AspectPropertyType)
@@ -12,10 +12,10 @@ import net.minecraft.world.entity.schedule.Activity
object CobblemonActivities {
val activities = mutableListOf<Activity>()
val BATTLING_ACTIVITY = Activity("pokemon_battling")
val NPC_BATTLING = Activity("npc_battling")
val NPC_ACTION_EFFECT = Activity("npc_action_effect")
val NPC_CHATTING = Activity("npc_chatting")
val BATTLING_ACTIVITY = register(Activity("pokemon_battling"))
val NPC_BATTLING = register(Activity("npc_battling"))
val NPC_ACTION_EFFECT = register(Activity("npc_action_effect"))
val NPC_CHATTING = register(Activity("npc_chatting"))
fun register(activity: Activity): Activity {
activities.add(activity)
@@ -38,8 +38,6 @@ import net.minecraft.world.level.material.PushReaction
@Suppress("SameParameterValue", "HasPlatformType", "MemberVisibilityCanBePrivate", "unused")
object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<Block>>, Block>() {
override val registry: Registry<Block> = BuiltInRegistries.BLOCK
override val resourceKey: ResourceKey<Registry<Block>> = Registries.BLOCK
@@ -117,8 +115,8 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val APRICORN_FENCE = this.create("apricorn_fence", FenceBlock(BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
@JvmField
val APRICORN_FENCE_GATE = this.create("apricorn_fence_gate", FenceGateBlock(APRICORN_WOOD_TYPE, BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
@JvmField // Note At the time of 1.20.0 we don't need our own BlockSetType for Apricorn wood
val APRICORN_BUTTON = this.create("apricorn_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
@JvmField
val APRICORN_BUTTON = this.create("apricorn_button", BlocksInvoker.createWoodenButtonBlock(APRICORN_BLOCK_SET_TYPE))
@JvmField
val APRICORN_PRESSURE_PLATE = this.create("apricorn_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(APRICORN_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).noCollission().strength(0.5f).sound(SoundType.WOOD)))
@JvmField
@@ -191,453 +189,113 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val SMALL_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("small_budding_black_tumblestone", GrowableStoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_BLACK_TUMBLESTONE)
@JvmField
val TUMBLESTONE_BLOCK = this.create("tumblestone_block", Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val TUMBLESTONE_BLOCK = this.create("tumblestone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SKY_TUMBLESTONE_BLOCK = this.create("sky_tumblestone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val SKY_TUMBLESTONE_BLOCK = this.create("sky_tumblestone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val BLACK_TUMBLESTONE_BLOCK = this.create("black_tumblestone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val BLACK_TUMBLESTONE_BLOCK = this.create("black_tumblestone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val POLISHED_TUMBLESTONE = this.create("polished_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val POLISHED_TUMBLESTONE = this.create("polished_tumblestone", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val POLISHED_TUMBLESTONE_STAIRS = this.create("polished_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(POLISHED_TUMBLESTONE.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(POLISHED_TUMBLESTONE)))
@JvmField
val POLISHED_TUMBLESTONE_SLAB = this.create("polished_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val POLISHED_TUMBLESTONE_SLAB = this.create("polished_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val POLISHED_TUMBLESTONE_WALL = this.create("polished_tumblestone_wall", WallBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val POLISHED_TUMBLESTONE_WALL = this.create("polished_tumblestone_wall", WallBlock(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val CHISELED_POLISHED_TUMBLESTONE = this.create("chiseled_polished_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val CHISELED_POLISHED_TUMBLESTONE = this.create("chiseled_polished_tumblestone", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SMOOTH_TUMBLESTONE = this.create("smooth_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val SMOOTH_TUMBLESTONE = this.create("smooth_tumblestone", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SMOOTH_TUMBLESTONE_STAIRS = this.create("smooth_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(SMOOTH_TUMBLESTONE.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(SMOOTH_TUMBLESTONE)))
@JvmField
val SMOOTH_TUMBLESTONE_SLAB = this.create("smooth_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val SMOOTH_TUMBLESTONE_SLAB = this.create("smooth_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val TUMBLESTONE_BRICKS = this.create("tumblestone_bricks", Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val TUMBLESTONE_BRICKS = this.create("tumblestone_bricks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val TUMBLESTONE_BRICK_STAIRS = this.create("tumblestone_brick_stairs", StairsBlockInvoker.`cobblemon$create`(TUMBLESTONE_BRICKS.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(TUMBLESTONE_BRICKS)))
@JvmField
val TUMBLESTONE_BRICK_SLAB = this.create("tumblestone_brick_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
@JvmField
val TUMBLESTONE_BRICK_WALL = this.create("tumblestone_brick_wall", WallBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val TUMBLESTONE_BRICK_SLAB = this.create("tumblestone_brick_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val CHISELED_TUMBLESTONE_BRICKS = this.create("chiseled_tumblestone_bricks",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val TUMBLESTONE_BRICK_WALL = this.create("tumblestone_brick_wall", WallBlock(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val POLISHED_SKY_TUMBLESTONE = this.create("polished_sky_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val CHISELED_TUMBLESTONE_BRICKS = this.create("chiseled_tumblestone_bricks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val POLISHED_SKY_TUMBLESTONE = this.create("polished_sky_tumblestone", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val POLISHED_SKY_TUMBLESTONE_STAIRS = this.create("polished_sky_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(POLISHED_SKY_TUMBLESTONE.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(POLISHED_SKY_TUMBLESTONE)))
@JvmField
val POLISHED_SKY_TUMBLESTONE_SLAB = this.create("polished_sky_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
@JvmField
val POLISHED_SKY_TUMBLESTONE_WALL = this.create("polished_sky_tumblestone_wall", WallBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val POLISHED_SKY_TUMBLESTONE_SLAB = this.create("polished_sky_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val CHISELED_POLISHED_SKY_TUMBLESTONE = this.create("chiseled_polished_sky_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val POLISHED_SKY_TUMBLESTONE_WALL = this.create("polished_sky_tumblestone_wall", WallBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SMOOTH_SKY_TUMBLESTONE = this.create("smooth_sky_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val CHISELED_POLISHED_SKY_TUMBLESTONE = this.create("chiseled_polished_sky_tumblestone", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SMOOTH_SKY_TUMBLESTONE = this.create("smooth_sky_tumblestone", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SMOOTH_SKY_TUMBLESTONE_STAIRS = this.create("smooth_sky_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(SMOOTH_SKY_TUMBLESTONE.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(SMOOTH_SKY_TUMBLESTONE)))
@JvmField
val SMOOTH_SKY_TUMBLESTONE_SLAB = this.create("smooth_sky_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val SMOOTH_SKY_TUMBLESTONE_SLAB = this.create("smooth_sky_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SKY_TUMBLESTONE_BRICKS = this.create("sky_tumblestone_bricks",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val SKY_TUMBLESTONE_BRICKS = this.create("sky_tumblestone_bricks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SKY_TUMBLESTONE_BRICK_STAIRS = this.create("sky_tumblestone_brick_stairs", StairsBlockInvoker.`cobblemon$create`(
SKY_TUMBLESTONE_BRICKS.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(SKY_TUMBLESTONE_BRICKS)))
val SKY_TUMBLESTONE_BRICK_STAIRS = this.create("sky_tumblestone_brick_stairs", StairsBlockInvoker.`cobblemon$create`(SKY_TUMBLESTONE_BRICKS.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(SKY_TUMBLESTONE_BRICKS)))
@JvmField
val SKY_TUMBLESTONE_BRICK_SLAB = this.create("sky_tumblestone_brick_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val SKY_TUMBLESTONE_BRICK_SLAB = this.create("sky_tumblestone_brick_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SKY_TUMBLESTONE_BRICK_WALL = this.create("sky_tumblestone_brick_wall", WallBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val SKY_TUMBLESTONE_BRICK_WALL = this.create("sky_tumblestone_brick_wall", WallBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val CHISELED_SKY_TUMBLESTONE_BRICKS = this.create("chiseled_sky_tumblestone_bricks",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val CHISELED_SKY_TUMBLESTONE_BRICKS = this.create("chiseled_sky_tumblestone_bricks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val POLISHED_BLACK_TUMBLESTONE = this.create("polished_black_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val POLISHED_BLACK_TUMBLESTONE = this.create("polished_black_tumblestone", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val POLISHED_BLACK_TUMBLESTONE_STAIRS = this.create("polished_black_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(POLISHED_BLACK_TUMBLESTONE.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(POLISHED_BLACK_TUMBLESTONE)))
@JvmField
val POLISHED_BLACK_TUMBLESTONE_SLAB = this.create("polished_black_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
@JvmField
val POLISHED_BLACK_TUMBLESTONE_WALL = this.create("polished_black_tumblestone_wall", WallBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val POLISHED_BLACK_TUMBLESTONE_SLAB = this.create("polished_black_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val CHISELED_POLISHED_BLACK_TUMBLESTONE = this.create("chiseled_polished_black_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val POLISHED_BLACK_TUMBLESTONE_WALL = this.create("polished_black_tumblestone_wall", WallBlock(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SMOOTH_BLACK_TUMBLESTONE = this.create("smooth_black_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val CHISELED_POLISHED_BLACK_TUMBLESTONE = this.create("chiseled_polished_black_tumblestone", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SMOOTH_BLACK_TUMBLESTONE = this.create("smooth_black_tumblestone", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val SMOOTH_BLACK_TUMBLESTONE_STAIRS = this.create("smooth_black_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(SMOOTH_BLACK_TUMBLESTONE.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(SMOOTH_BLACK_TUMBLESTONE)))
@JvmField
val SMOOTH_BLACK_TUMBLESTONE_SLAB = this.create("smooth_black_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val SMOOTH_BLACK_TUMBLESTONE_SLAB = this.create("smooth_black_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val BLACK_TUMBLESTONE_BRICKS = this.create("black_tumblestone_bricks",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val BLACK_TUMBLESTONE_BRICKS = this.create("black_tumblestone_bricks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val BLACK_TUMBLESTONE_BRICK_STAIRS = this.create("black_tumblestone_brick_stairs", StairsBlockInvoker.`cobblemon$create`(
BLACK_TUMBLESTONE_BRICKS.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(BLACK_TUMBLESTONE_BRICKS)))
val BLACK_TUMBLESTONE_BRICK_STAIRS = this.create("black_tumblestone_brick_stairs", StairsBlockInvoker.`cobblemon$create`(BLACK_TUMBLESTONE_BRICKS.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(BLACK_TUMBLESTONE_BRICKS)))
@JvmField
val BLACK_TUMBLESTONE_BRICK_SLAB = this.create("black_tumblestone_brick_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val BLACK_TUMBLESTONE_BRICK_SLAB = this.create("black_tumblestone_brick_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val BLACK_TUMBLESTONE_BRICK_WALL = this.create("black_tumblestone_brick_wall", WallBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
val BLACK_TUMBLESTONE_BRICK_WALL = this.create("black_tumblestone_brick_wall", WallBlock(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val CHISELED_BLACK_TUMBLESTONE_BRICKS = this.create("chiseled_black_tumblestone_bricks",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
val CHISELED_BLACK_TUMBLESTONE_BRICKS = this.create("chiseled_black_tumblestone_bricks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
@JvmField
val FIRE_STONE_BLOCK = this.create("fire_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.FIRE)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
@JvmField
val WATER_STONE_BLOCK = this.create("water_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.WATER)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
val FIRE_STONE_BLOCK = this.create("fire_stone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.FIRE).strength(1.0F).sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BIT).lightLevel{13}))
@JvmField
val THUNDER_STONE_BLOCK = this.create("thunder_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.GLOW_LICHEN)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
val WATER_STONE_BLOCK = this.create("water_stone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.WATER).strength(1.0F).sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BIT)))
@JvmField
val LEAF_STONE_BLOCK = this.create("leaf_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_GREEN)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
val THUNDER_STONE_BLOCK = this.create("thunder_stone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.GLOW_LICHEN).strength(1.0F).sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BIT).lightLevel{8}))
@JvmField
val ICE_STONE_BLOCK = this.create("ice_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.ICE)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
val LEAF_STONE_BLOCK = this.create("leaf_stone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_GREEN).strength(1.0F).sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BIT)))
@JvmField
val SUN_STONE_BLOCK = this.create("sun_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
val ICE_STONE_BLOCK = this.create("ice_stone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.ICE).strength(1.0F).sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BIT)))
@JvmField
val MOON_STONE_BLOCK = this.create("moon_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.DEEPSLATE)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
val SUN_STONE_BLOCK = this.create("sun_stone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BIT).lightLevel{5}))
@JvmField
val SHINY_STONE_BLOCK = this.create("shiny_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.QUARTZ)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
val MOON_STONE_BLOCK = this.create("moon_stone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.DEEPSLATE).strength(1.0F).sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BIT)))
@JvmField
val DAWN_STONE_BLOCK = this.create("dawn_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.DIAMOND)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
val SHINY_STONE_BLOCK = this.create("shiny_stone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.QUARTZ).strength(1.0F).sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BIT).lightLevel{15}))
@JvmField
val DUSK_STONE_BLOCK = this.create("dusk_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.WARPED_HYPHAE)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
val DAWN_STONE_BLOCK = this.create("dawn_stone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.DIAMOND).strength(1.0F).sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BIT).lightLevel{15}))
@JvmField
val DUSK_STONE_BLOCK = this.create("dusk_stone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.WARPED_HYPHAE).strength(1.0F).sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BIT)))
@JvmField
val BLACK_APRICORN = apricornBlock("black_apricorn", Apricorn.BLACK)
@@ -655,188 +313,48 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val YELLOW_APRICORN = apricornBlock("yellow_apricorn", Apricorn.YELLOW)
@JvmField
val RELIC_COIN_POUCH = create(
"relic_coin_pouch",
CoinPouchBlock(
BlockBehaviour.Properties.of()
.sound(CobblemonSounds.RELIC_COIN_POUCH_SOUNDS)
.pushReaction(PushReaction.DESTROY)
.noOcclusion(), true
)
)
val RELIC_COIN_POUCH = create("relic_coin_pouch", CoinPouchBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.RELIC_COIN_POUCH_SOUNDS).pushReaction(PushReaction.DESTROY).noOcclusion(), true))
@JvmField
val RELIC_COIN_SACK = create(
"relic_coin_sack",
CoinPouchBlock(
BlockBehaviour.Properties.of()
.sound(CobblemonSounds.RELIC_COIN_SACK_SOUNDS)
.pushReaction(PushReaction.DESTROY)
.strength(0.4f), false
))
val RELIC_COIN_SACK = create("relic_coin_sack", CoinPouchBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.RELIC_COIN_SACK_SOUNDS).pushReaction(PushReaction.DESTROY).strength(0.4f), false))
@JvmField
val GILDED_CHEST = create(
"gilded_chest",
GildedChestBlock(
BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.RED
)
)
val GILDED_CHEST = create("gilded_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.RED))
@JvmField
val BLUE_GILDED_CHEST = create("blue_gilded_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.BLUE))
@JvmField
val BLACK_GILDED_CHEST = create("black_gilded_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.BLACK))
@JvmField
val YELLOW_GILDED_CHEST = create("yellow_gilded_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.YELLOW))
@JvmField
val WHITE_GILDED_CHEST = create("white_gilded_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.WHITE))
@JvmField
val GREEN_GILDED_CHEST = create("green_gilded_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.GREEN))
@JvmField
val PINK_GILDED_CHEST = create("pink_gilded_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.PINK))
@JvmField
val GIMMIGHOUL_CHEST = create("gimmighoul_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.FAKE))
@JvmField
val BLUE_GILDED_CHEST = create(
"blue_gilded_chest",
GildedChestBlock(
BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.BLUE
)
)
val MONITOR = create("monitor", MonitorBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).lightLevel { if (it.getValue(MonitorBlock.SCREEN) != MonitorBlock.MonitorScreen.OFF) 15 else 0 }))
@JvmField
val FOSSIL_ANALYZER = create("fossil_analyzer", FossilAnalyzerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).noOcclusion()))
@JvmField
val RESTORATION_TANK = create("restoration_tank", RestorationTankBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.GLASS).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).noOcclusion()))
@JvmField
val BLACK_GILDED_CHEST = create(
"black_gilded_chest",
GildedChestBlock(
BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.BLACK
)
)
val HEALING_MACHINE = create("healing_machine", HealingMachineBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).strength(2f).noOcclusion().lightLevel { if (it.getValue(HealingMachineBlock.CHARGE_LEVEL) >= HealingMachineBlock.MAX_CHARGE_LEVEL) 7 else 2 }))
@JvmField
val YELLOW_GILDED_CHEST = create(
"yellow_gilded_chest",
GildedChestBlock(
BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.YELLOW
)
)
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 WHITE_GILDED_CHEST = create(
"white_gilded_chest",
GildedChestBlock(
BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.WHITE
)
)
val LECTERN = create("lectern", LecternBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).sound(SoundType.WOOD).strength(2.5F).ignitedByLava()))
@JvmField
val GREEN_GILDED_CHEST = create(
"green_gilded_chest",
GildedChestBlock(
BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.GREEN
)
)
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 PINK_GILDED_CHEST = create(
"pink_gilded_chest",
GildedChestBlock(
BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.PINK
)
)
@JvmField
val GIMMIGHOUL_CHEST = create(
"gimmighoul_chest",
GildedChestBlock(
BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.FAKE
)
)
@JvmField
val MONITOR = create(
"monitor",
MonitorBlock(
BlockBehaviour.Properties.of()
.mapColor(MapColor.METAL)
.sound(SoundType.METAL)
.pushReaction(PushReaction.BLOCK)
.requiresCorrectToolForDrops()
.strength(5.0F, 6.0F)
.lightLevel { if (it.getValue(MonitorBlock.SCREEN) != MonitorBlock.MonitorScreen.OFF) 15 else 0 }
)
)
@JvmField
val FOSSIL_ANALYZER = create(
"fossil_analyzer",
FossilAnalyzerBlock(
BlockBehaviour.Properties.of()
.mapColor(MapColor.METAL)
.sound(SoundType.METAL)
.pushReaction(PushReaction.BLOCK)
.requiresCorrectToolForDrops()
.strength(5.0F, 6.0F)
.noOcclusion()
)
)
@JvmField
val RESTORATION_TANK = create(
"restoration_tank",
RestorationTankBlock(
BlockBehaviour.Properties.of()
.mapColor(MapColor.METAL)
.sound(SoundType.GLASS)
.pushReaction(PushReaction.BLOCK)
.requiresCorrectToolForDrops()
.strength(5.0F, 6.0F)
.noOcclusion()
)
)
@JvmField
val HEALING_MACHINE = create(
"healing_machine",
HealingMachineBlock(
BlockBehaviour.Properties.of()
.mapColor(MapColor.METAL)
.sound(SoundType.METAL)
.pushReaction(PushReaction.BLOCK)
.strength(2f)
.noOcclusion()
.lightLevel { if (it.getValue(HealingMachineBlock.CHARGE_LEVEL) >= HealingMachineBlock.MAX_CHARGE_LEVEL) 7 else 2 }
)
)
@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 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)
)
)
val PASTURE = create("pasture", PastureBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BROWN).sound(SoundType.WOOD).strength(2F).noOcclusion().pushReaction(PushReaction.BLOCK).lightLevel { if ((it.getValue(PastureBlock.ON) as Boolean) && (it.getValue(PastureBlock.PART) == PastureBlock.PasturePart.TOP)) 10 else 0 }))
val RED_MINT = create("red_mint", MintBlock(MintType.RED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_RED).noCollission().randomTicks().instabreak().sound(CobblemonSounds.MINT_SOUNDS).pushReaction(PushReaction.DESTROY)))
@JvmField
@@ -850,20 +368,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val WHITE_MINT = create("white_mint", MintBlock(MintType.WHITE, BlockBehaviour.Properties.of().mapColor(MapColor.SNOW).noCollission().randomTicks().instabreak().sound(CobblemonSounds.MINT_SOUNDS).pushReaction(PushReaction.DESTROY)))
@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 }
)
)
@JvmField
val VIVICHOKE_SEEDS = this.create("vivichoke_seeds", VivichokeBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.PLANT).noCollission().randomTicks().instabreak().sound(CobblemonSounds.VIVICHOKE_SOUNDS)))
@JvmField
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.ai.config.BrainConfig
import com.cobblemon.mod.common.api.ai.config.task.TaskConfig
import com.cobblemon.mod.common.api.data.DataRegistry
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.util.adapters.ActivityAdapter
import com.cobblemon.mod.common.util.adapters.BrainConfigAdapter
import com.cobblemon.mod.common.util.adapters.ExpressionAdapter
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
import com.cobblemon.mod.common.util.adapters.TaskConfigAdapter
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.entity.schedule.Activity
object CobblemonBrainConfigs : JsonDataRegistry<List<BrainConfig>> {
override val gson: Gson = GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(Activity::class.java, ActivityAdapter)
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(BrainConfig::class.java, BrainConfigAdapter)
.registerTypeAdapter(TaskConfig::class.java, TaskConfigAdapter)
.create()
override val typeToken = TypeToken.getParameterized(List::class.java, BrainConfig::class.java) as TypeToken<List<BrainConfig>>
override val resourcePath = "brain_presets"
override val id: ResourceLocation = cobblemonResource("brain_presets")
override val type = PackType.SERVER_DATA
override val observable = SimpleObservable<CobblemonBrainConfigs>()
val presets = mutableMapOf<ResourceLocation, List<BrainConfig>>()
override fun sync(player: ServerPlayer) {
// TODO implement probs ay
}
override fun reload(data: Map<ResourceLocation, List<BrainConfig>>) {
presets.clear()
presets.putAll(data)
}
}
@@ -20,6 +20,7 @@ object CobblemonCommands {
SpawnNPCCommand.register(dispatcher)
GivePokemon.register(dispatcher)
TakePokemon.register(dispatcher)
ChangeEyeHeight.register(dispatcher)
ChangeScaleAndSize.register(dispatcher)
ChangeWalkSpeed.register(dispatcher)
TestCommand.register(dispatcher)
@@ -153,20 +153,21 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val ANCIENT_ORIGIN_BALL = pokeBallItem(PokeBalls.ANCIENT_ORIGIN_BALL)
val pokedexes = mutableListOf<PokedexItem>()
@JvmField
val POKEDEX_BLACK = create("pokedex_black", PokedexItem(PokedexTypes.BLACK))
val POKEDEX_BLACK = pokedexItem(PokedexTypes.BLACK)
@JvmField
val POKEDEX_BLUE = create("pokedex_blue", PokedexItem(PokedexTypes.BLUE))
val POKEDEX_BLUE = pokedexItem(PokedexTypes.BLUE)
@JvmField
val POKEDEX_GREEN = create("pokedex_green", PokedexItem(PokedexTypes.GREEN))
val POKEDEX_GREEN = pokedexItem(PokedexTypes.GREEN)
@JvmField
val POKEDEX_PINK = create("pokedex_pink", PokedexItem(PokedexTypes.PINK))
val POKEDEX_PINK = pokedexItem(PokedexTypes.PINK)
@JvmField
val POKEDEX_RED = create("pokedex_red", PokedexItem(PokedexTypes.RED))
val POKEDEX_RED = pokedexItem(PokedexTypes.RED)
@JvmField
val POKEDEX_WHITE = create("pokedex_white", PokedexItem(PokedexTypes.WHITE))
val POKEDEX_WHITE = pokedexItem(PokedexTypes.WHITE)
@JvmField
val POKEDEX_YELLOW = create("pokedex_yellow", PokedexItem(PokedexTypes.YELLOW))
val POKEDEX_YELLOW = pokedexItem(PokedexTypes.YELLOW)
@JvmField
val VIVICHOKE = compostableItem("vivichoke")
@@ -1247,6 +1248,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
return item
}
private fun pokedexItem(type: PokedexTypes): PokedexItem {
val item = create("pokedex_${type.name.lowercase()}", PokedexItem(type))
pokedexes.add(item)
return item
}
private fun heldItem(name: String, remappedName: String? = null): CobblemonItem = create(
name,
CobblemonItem(Item.Properties()).also {
@@ -51,13 +51,7 @@ import com.cobblemon.mod.common.client.net.storage.pc.OpenPCHandler
import com.cobblemon.mod.common.client.net.storage.pc.SetPCBoxPokemonHandler
import com.cobblemon.mod.common.client.net.storage.pc.SetPCPokemonHandler
import com.cobblemon.mod.common.client.net.toast.ToastPacketHandler
import com.cobblemon.mod.common.client.net.trade.TradeAcceptanceChangedHandler
import com.cobblemon.mod.common.client.net.trade.TradeCancelledHandler
import com.cobblemon.mod.common.client.net.trade.TradeCompletedHandler
import com.cobblemon.mod.common.client.net.trade.TradeOfferExpiredHandler
import com.cobblemon.mod.common.client.net.trade.TradeOfferNotificationHandler
import com.cobblemon.mod.common.client.net.trade.TradeStartedHandler
import com.cobblemon.mod.common.client.net.trade.TradeUpdatedHandler
import com.cobblemon.mod.common.client.net.trade.*
import com.cobblemon.mod.common.net.PacketRegisterInfo
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
import com.cobblemon.mod.common.net.messages.client.animation.PlayPosableAnimationPacket
@@ -100,13 +94,6 @@ import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyPokemo
import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyReferencePacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.*
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
import com.cobblemon.mod.common.net.messages.client.trade.TradeCompletedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferExpiredPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferNotificationPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeUpdatedPacket
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
import com.cobblemon.mod.common.net.messages.client.ui.PokedexUIPacket
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
@@ -141,11 +128,6 @@ import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePartyPokemonT
import com.cobblemon.mod.common.net.messages.server.storage.pc.ReleasePCPokemonPacket
import com.cobblemon.mod.common.net.messages.server.storage.pc.SwapPCPokemonPacket
import com.cobblemon.mod.common.net.messages.server.storage.pc.UnlinkPlayerFromPCPacket
import com.cobblemon.mod.common.net.messages.server.trade.AcceptTradeRequestPacket
import com.cobblemon.mod.common.net.messages.server.trade.CancelTradePacket
import com.cobblemon.mod.common.net.messages.server.trade.ChangeTradeAcceptancePacket
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
import com.cobblemon.mod.common.net.serverhandling.*
import com.cobblemon.mod.common.net.serverhandling.battle.BattleSelectActionsHandler
import com.cobblemon.mod.common.net.serverhandling.battle.RemoveSpectatorHandler
@@ -180,15 +162,13 @@ import com.cobblemon.mod.common.net.serverhandling.storage.pc.MovePartyPokemonTo
import com.cobblemon.mod.common.net.serverhandling.storage.pc.ReleasePartyPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.storage.pc.SwapPCPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.storage.pc.UnlinkPlayerFromPCHandler
import com.cobblemon.mod.common.net.serverhandling.trade.AcceptTradeRequestHandler
import com.cobblemon.mod.common.net.serverhandling.trade.CancelTradeHandler
import com.cobblemon.mod.common.net.serverhandling.trade.ChangeTradeAcceptanceHandler
import com.cobblemon.mod.common.net.serverhandling.trade.OfferTradeHandler
import com.cobblemon.mod.common.net.serverhandling.trade.UpdateTradeOfferHandler
import com.cobblemon.mod.common.net.messages.client.pokedex.ServerConfirmedRegisterPacket
import com.cobblemon.mod.common.net.messages.client.trade.*
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.FinishScanningPacket
import com.cobblemon.mod.common.net.messages.server.trade.*
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.FinishScanningHandler
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.StartScanningHandler
import com.cobblemon.mod.common.net.serverhandling.trade.*
import com.cobblemon.mod.common.util.server
import net.minecraft.server.level.ServerPlayer
@@ -297,6 +277,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(BattleChallengeExpiredPacket.ID, BattleChallengeExpiredPacket::decode, BattleChallengeExpiredHandler))
list.add(PacketRegisterInfo(BattleReplacePokemonPacket.ID, BattleReplacePokemonPacket::decode, BattleReplacePokemonHandler))
list.add(PacketRegisterInfo(BattleTransformPokemonPacket.ID, BattleTransformPokemonPacket::decode, BattleTransformPokemonHandler))
list.add(PacketRegisterInfo(BattleAppendTargetedEntityPacket.ID, BattleAppendTargetedEntityPacket::decode, BattleSetTargetedEntityHandler))
// MultiBattleTeam Packets
list.add(PacketRegisterInfo(TeamRequestNotificationPacket.ID, TeamRequestNotificationPacket::decode, TeamRequestNotificationHandler))
@@ -341,6 +322,7 @@ object CobblemonNetwork {
// Trade packets
list.add(PacketRegisterInfo(TradeAcceptanceChangedPacket.ID, TradeAcceptanceChangedPacket::decode, TradeAcceptanceChangedHandler))
list.add(PacketRegisterInfo(TradeProcessStartedPacket.ID, TradeProcessStartedPacket::decode, TradeProcessStartedHandler))
list.add(PacketRegisterInfo(TradeCancelledPacket.ID, TradeCancelledPacket::decode, TradeCancelledHandler))
list.add(PacketRegisterInfo(TradeCompletedPacket.ID, TradeCompletedPacket::decode, TradeCompletedHandler))
list.add(PacketRegisterInfo(TradeUpdatedPacket.ID, TradeUpdatedPacket::decode, TradeUpdatedHandler))
@@ -428,6 +410,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(AcceptTradeRequestPacket.ID, AcceptTradeRequestPacket::decode, AcceptTradeRequestHandler))
list.add(PacketRegisterInfo(CancelTradePacket.ID, CancelTradePacket::decode, CancelTradeHandler))
list.add(PacketRegisterInfo(ChangeTradeAcceptancePacket.ID, ChangeTradeAcceptancePacket::decode, ChangeTradeAcceptanceHandler))
list.add(PacketRegisterInfo(PerformTradePacket.ID, PerformTradePacket::decode, PerformTradeHandler))
list.add(PacketRegisterInfo(OfferTradePacket.ID, OfferTradePacket::decode, OfferTradeHandler))
list.add(PacketRegisterInfo(UpdateTradeOfferPacket.ID, UpdateTradeOfferPacket::decode, UpdateTradeOfferHandler))
@@ -25,6 +25,8 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
@JvmField
val GUI_CLICK = this.create("gui.click")
@JvmField
val GUI_TRADE = this.create("gui.trade")
@JvmField
val PC_ON = this.create("pc.on")
@@ -42,7 +44,7 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
@JvmField
val VILLAGER_WORK_NURSE = this.create("entity.villager.work_nurse")
@JvmField
val HEALING_MACHINE_ACTIVE = this.create("healing_machine.active")
val HEALING_MACHINE_ACTIVE = this.create("block.healing_machine.active")
@JvmField
val POKE_BALL_CAPTURE_STARTED = this.create("poke_ball.capture_started")
@@ -107,61 +109,56 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
val PVW_BATTLE = this.create("battle.pvw.default")
@JvmField
val MEDICINE_HERB_USE = this.create("medicine_herb.use")
val MEDICINE_HERB_USE = this.create("item.medicine.herb.use")
@JvmField
val MEDICINE_LIQUID_USE = this.create("medicine_liquid.use")
val MEDICINE_LIQUID_USE = this.create("item.medicine.liquid.use")
@JvmField
val MEDICINE_PILLS_USE = this.create("medicine_pills.use")
val MEDICINE_PILLS_USE = this.create("item.medicine.pills.use")
@JvmField
val MEDICINE_SPRAY_USE = this.create("medicine_spray.use")
val MEDICINE_SPRAY_USE = this.create("item.medicine.spray.use")
@JvmField
val MEDICINE_FEATHER_USE = this.create("medicine_feather.use")
val MEDICINE_FEATHER_USE = this.create("item.medicine.feather.use")
@JvmField
val BERRY_HARVEST = this.create("berry.harvest")
val MULCH_PLACE = this.create("block.mulch.place")
@JvmField
val BERRY_EAT = this.create("berry.eat")
val MULCH_REMOVE = this.create("block.mulch.remove")
@JvmField
val MULCH_PLACE = this.create("mulch.place")
val FOSSIL_MACHINE_ACTIVATE = this.create("block.fossil_machine.activate")
@JvmField
val MULCH_REMOVE = this.create("mulch.remove")
val FOSSIL_MACHINE_ACTIVE_LOOP = this.create("block.fossil_machine.active_loop")
@JvmField
val FOSSIL_MACHINE_ASSEMBLE = this.create("block.fossil_machine.assemble")
@JvmField
val FOSSIL_MACHINE_DNA_FULL = this.create("block.fossil_machine.dna_full")
@JvmField
val FOSSIL_MACHINE_FINISHED = this.create("block.fossil_machine.finished")
@JvmField
val FOSSIL_MACHINE_INSERT_DNA = this.create("block.fossil_machine.insert_dna")
@JvmField
val FOSSIL_MACHINE_INSERT_DNA_SMALL = this.create("block.fossil_machine.insert_dna_small")
@JvmField
val FOSSIL_MACHINE_INSERT_FOSSIL = this.create("block.fossil_machine.insert_fossil")
@JvmField
val FOSSIL_MACHINE_RETRIEVE_FOSSIL = this.create("block.fossil_machine.retrieve_fossil")
@JvmField
val FOSSIL_MACHINE_RETRIEVE_POKEMON = this.create("block.fossil_machine.retrieve_pokemon")
@JvmField
val FOSSIL_MACHINE_UNPROTECTED = this.create("block.fossil_machine.unprotected")
@JvmField
val FOSSIL_MACHINE_ACTIVATE = this.create("fossil_machine.activate")
val RELIC_COIN_SACK_BREAK = this.create("block.relic_coin_sack.break")
@JvmField
val FOSSIL_MACHINE_ACTIVE_LOOP = this.create("fossil_machine.active_loop")
val RELIC_COIN_SACK_HIT = this.create("block.relic_coin_sack.hit")
@JvmField
val FOSSIL_MACHINE_ASSEMBLE = this.create("fossil_machine.assemble")
val RELIC_COIN_SACK_STEP = this.create("block.relic_coin_sack.step")
@JvmField
val FOSSIL_MACHINE_DNA_FULL = this.create("fossil_machine.dna_full")
val RELIC_COIN_SACK_PLACE = this.create("block.relic_coin_sack.place")
@JvmField
val FOSSIL_MACHINE_FINISHED = this.create("fossil_machine.finished")
val RELIC_COIN_POUCH_BREAK = this.create("block.relic_coin_pouch.break")
@JvmField
val FOSSIL_MACHINE_INSERT_DNA = this.create("fossil_machine.insert_dna")
@JvmField
val FOSSIL_MACHINE_INSERT_DNA_SMALL = this.create("fossil_machine.insert_dna_small")
@JvmField
val FOSSIL_MACHINE_INSERT_FOSSIL = this.create("fossil_machine.insert_fossil")
@JvmField
val FOSSIL_MACHINE_RETRIEVE_FOSSIL = this.create("fossil_machine.retrieve_fossil")
@JvmField
val FOSSIL_MACHINE_RETRIEVE_POKEMON = this.create("fossil_machine.retrieve_pokemon")
@JvmField
val FOSSIL_MACHINE_UNPROTECTED = this.create("fossil_machine.unprotected")
@JvmField
val RELIC_COIN_SACK_BREAK = this.create("relic_coin_sack.break")
@JvmField
val RELIC_COIN_SACK_HIT = this.create("relic_coin_sack.hit")
@JvmField
val RELIC_COIN_SACK_STEP = this.create("relic_coin_sack.step")
@JvmField
val RELIC_COIN_SACK_PLACE = this.create("relic_coin_sack.place")
@JvmField
val RELIC_COIN_POUCH_BREAK = this.create("relic_coin_pouch.break")
@JvmField
val RELIC_COIN_POUCH_PLACE = this.create("relic_coin_pouch.place")
val RELIC_COIN_POUCH_PLACE = this.create("block.relic_coin_pouch.place")
@JvmField
val FISHING_NOTIFICATION = this.create("fishing.notification")
@@ -179,73 +176,78 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
val FISHING_BAIT_ATTACH = this.create("fishing.bait_attach")
@JvmField
val FISHING_BAIT_DETACH = this.create("fishing.bait_detach")
@JvmField
val TUMBLESTONE_BREAK = this.create("tumblestone.break")
@JvmField
val TUMBLESTONE_BLOCK_BREAK = this.create("tumblestone.block_break")
@JvmField
val TUMBLESTONE_HIT = this.create("tumblestone.hit")
@JvmField
val TUMBLESTONE_PLACE = this.create("tumblestone.place")
@JvmField
val TUMBLESTONE_STEP = this.create("tumblestone.step")
@JvmField
val EVOLUTION_STONE_BLOCK_BREAK = this.create("evolution_stone_block.break")
val TUMBLESTONE_BREAK = this.create("block.tumblestone.break")
@JvmField
val EVOLUTION_STONE_BLOCK_HIT = this.create("evolution_stone_block.hit")
val TUMBLESTONE_BLOCK_BREAK = this.create("block.tumblestone.block_break")
@JvmField
val EVOLUTION_STONE_BLOCK_PLACE = this.create("evolution_stone_block.place")
val TUMBLESTONE_HIT = this.create("block.tumblestone.hit")
@JvmField
val EVOLUTION_STONE_BLOCK_STEP = this.create("evolution_stone_block.step")
val TUMBLESTONE_PLACE = this.create("block.tumblestone.place")
@JvmField
val TUMBLESTONE_STEP = this.create("block.tumblestone.step")
@JvmField
val GIMMIGHOUL_GIVE_ITEM_SMALL = this.create("gimmighoul.give_item_small")
val EVOLUTION_STONE_BLOCK_BREAK = this.create("block.evolution_stone_block.break")
@JvmField
val GIMMIGHOUL_REVEAL = this.create("gimmighoul.reveal")
val EVOLUTION_STONE_BLOCK_HIT = this.create("block.evolution_stone_block.hit")
@JvmField
val EVOLUTION_STONE_BLOCK_PLACE = this.create("block.evolution_stone_block.place")
@JvmField
val EVOLUTION_STONE_BLOCK_STEP = this.create("block.evolution_stone_block.step")
@JvmField
val BERRY_BUSH_BREAK = this.create("berry_bush.break")
val GIMMIGHOUL_GIVE_ITEM = this.create("pokemon.gimmighoul.give_item")
@JvmField
val BERRY_BUSH_PLACE = this.create("berry_bush.place")
val GIMMIGHOUL_REVEAL = this.create("pokemon.gimmighoul.reveal")
@JvmField
val BIG_ROOT_BREAK = this.create("big_root.break")
val BERRY_BUSH_BREAK = this.create("block.berry_bush.break")
@JvmField
val ENERGY_ROOT_PLACE = this.create("energy_root.place")
val BERRY_BUSH_PLACE = this.create("block.berry_bush.place")
@JvmField
val BERRY_HARVEST = this.create("block.berry_bush.harvest")
@JvmField
val BERRY_EAT = this.create("item.berry.eat")
@JvmField
val VIVICHOKE_BREAK = this.create("vivichoke.break")
val BIG_ROOT_BREAK = this.create("block.big_root.break")
@JvmField
val VIVICHOKE_PLACE = this.create("vivichoke.place")
val ENERGY_ROOT_PLACE = this.create("block.energy_root.place")
@JvmField
val MINT_BREAK = this.create("mint.break")
val VIVICHOKE_BREAK = this.create("block.vivichoke.break")
@JvmField
val MINT_PLACE = this.create("mint.place")
val VIVICHOKE_PLACE = this.create("block.vivichoke.place")
@JvmField
val REVIVAL_HERB_BREAK = this.create("revival_herb.break")
val MINT_BREAK = this.create("block.mint.break")
@JvmField
val REVIVAL_HERB_PLACE = this.create("revival_herb.place")
val MINT_PLACE = this.create("block.mint.place")
@JvmField
val MEDICINAL_LEEK_BREAK = this.create("medicinal_leek.break")
val REVIVAL_HERB_BREAK = this.create("block.revival_herb.break")
@JvmField
val MEDICINAL_LEEK_PLACE = this.create("medicinal_leek.plant")
val REVIVAL_HERB_PLACE = this.create("block.revival_herb.place")
@JvmField
val GILDED_CHEST_OPEN = this.create("gilded_chest.open")
val MEDICINAL_LEEK_BREAK = this.create("block.medicinal_leek.break")
@JvmField
val GILDED_CHEST_CLOSE = this.create("gilded_chest.close")
val MEDICINAL_LEEK_PLACE = this.create("block.medicinal_leek.plant")
@JvmField
val GILDED_CHEST_STEP = this.create("gilded_chest.step")
val GILDED_CHEST_OPEN = this.create("block.gilded_chest.open")
@JvmField
val GILDED_CHEST_HIT = this.create("gilded_chest.hit")
val GILDED_CHEST_CLOSE = this.create("block.gilded_chest.close")
@JvmField
val GILDED_CHEST_BREAK = this.create("gilded_chest.break")
val GILDED_CHEST_STEP = this.create("block.gilded_chest.step")
@JvmField
val GILDED_CHEST_PLACE = this.create("gilded_chest.place")
val GILDED_CHEST_HIT = this.create("block.gilded_chest.hit")
@JvmField
val GILDED_CHEST_BREAK = this.create("block.gilded_chest.break")
@JvmField
val GILDED_CHEST_PLACE = this.create("block.gilded_chest.place")
@JvmField
val RELIC_COIN_SACK_SOUNDS = SoundType(1f, 1.1f,
@@ -401,17 +403,17 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
)
@JvmField
val DISPLAY_CASE_ADD_ITEM = this.create("display_case.add_item")
val DISPLAY_CASE_ADD_ITEM = this.create("block.display_case.add_item")
@JvmField
val DISPLAY_CASE_REMOVE_ITEM = this.create("display_case.remove_item")
val DISPLAY_CASE_REMOVE_ITEM = this.create("block.display_case.remove_item")
@JvmField
val DISPLAY_CASE_BREAK = this.create("display_case.break")
val DISPLAY_CASE_BREAK = this.create("block.display_case.break")
@JvmField
val DISPLAY_CASE_HIT = this.create("display_case.hit")
val DISPLAY_CASE_HIT = this.create("block.display_case.hit")
@JvmField
val DISPLAY_CASE_PLACE = this.create("display_case.place")
val DISPLAY_CASE_PLACE = this.create("block.display_case.place")
@JvmField
val DISPLAY_CASE_STEP = this.create("display_case.step")
val DISPLAY_CASE_STEP = this.create("block.display_case.step")
@JvmField
val DISPLAY_CASE_SOUNDS = SoundType(1f, 1f,
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai
import com.google.common.collect.ImmutableList
import com.mojang.datafixers.util.Pair
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.Mob
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.schedule.Activity
class ActivityConfigurationContext(val activity: Activity) {
val tasks = mutableListOf<Pair<Int, BehaviorControl<in LivingEntity>>>()
fun addTasks(weight: Int, vararg tasks: BehaviorControl<in LivingEntity>) {
this.tasks.addAll(tasks.map { Pair.of(weight, it) })
}
fun apply(entity: LivingEntity) {
entity.brain.addActivity(activity, ImmutableList.copyOf(tasks))
}
}
@@ -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.api.ai
import com.cobblemon.mod.common.api.ai.config.BrainConfig
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.schedule.Activity
import net.minecraft.world.entity.schedule.Schedule
class BrainConfigurationContext {
var defaultActivity = Activity.IDLE
var coreActivities = setOf(Activity.CORE)
val activities = mutableListOf<ActivityConfigurationContext>()
val schedule = Schedule.EMPTY
fun getOrCreateActivity(activity: Activity): ActivityConfigurationContext {
return activities.firstOrNull { it.activity == activity } ?: ActivityConfigurationContext(activity).also(activities::add)
}
fun apply(entity: LivingEntity, brainConfigs: List<BrainConfig>) {
val brain = entity.brain
// Setup the brain config
brainConfigs.forEach { it.configure(entity, this) }
// Apply the brain config
activities.forEach { it.apply(entity) }
brain.setCoreActivities(coreActivities)
brain.setDefaultActivity(defaultActivity)
brain.schedule = schedule
brain.setActiveActivityIfPossible(defaultActivity)
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class WrapperLivingEntityTask<T : LivingEntity>(val task: BehaviorControl<T>, val clazz: Class<T>) : BehaviorControl<LivingEntity> {
override fun tryStart(level: ServerLevel, entity: LivingEntity, gameTime: Long): Boolean {
if (clazz.isInstance(entity)) {
return task.tryStart(level, entity as T, gameTime)
} else {
return false
}
}
override fun debugString() = task.debugString()
override fun tickOrStop(level: ServerLevel, entity: LivingEntity, gameTime: Long) {
task.tickOrStop(level, entity as T, gameTime)
}
override fun getStatus() = task.status
override fun doStop(level: ServerLevel, entity: LivingEntity, gameTime: Long) = task.doStop(level, entity as T, gameTime)
}
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.ai.config.task.TaskConfig
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.schedule.Activity
class AddTasksToActivity : BrainConfig {
val activity = Activity.IDLE
val condition = "true".asExpressionLike()
val tasksByPriority = mutableMapOf<Int, List<TaskConfig>>()
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {
val runtime = MoLangRuntime().setup()
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return
val activity = brainConfigurationContext.getOrCreateActivity(activity)
tasksByPriority.forEach { (priority, taskConfigs) ->
val tasks = taskConfigs.flatMap { it.createTasks(entity, brainConfigurationContext) }
activity.addTasks(priority, *tasks.toTypedArray())
}
}
}
@@ -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.api.ai.config
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonBrainConfigs
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.LivingEntity
class ApplyPresets : BrainConfig {
val condition = "true".asExpressionLike()
val presets = mutableListOf<ResourceLocation>()
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {
val runtime = MoLangRuntime().setup()
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return
val presetConfigs = presets.flatMap { CobblemonBrainConfigs.presets[it] ?: return Cobblemon.LOGGER.warn("Preset $it not found") }
presetConfigs.forEach { it.configure(entity, brainConfigurationContext) }
}
}
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import net.minecraft.world.entity.LivingEntity
/**
* Something that contributes to the construction of an entity's brain. Implementations are expected to make
* their changes using the provided [BrainConfigurationContext] which helps stage the details of the entity's
* brain before locking into the highly immutable structure that Mojang uses.
*
* A brain config has access to the [LivingEntity] it's for but note that this is, in most cases, an extremely
* young version of the entity that is not fully initialized and might die if you try getting exotic with it.
*
* @see BrainConfigurationContext
* @author Hiroku
* @since October 13th, 2024
*/
interface BrainConfig {
companion object {
val types = mutableMapOf<String, Class<out BrainConfig>>(
"script" to ScriptBrainConfig::class.java,
"add_tasks_to_activity" to AddTasksToActivity::class.java,
"apply_presets" to ApplyPresets::class.java,
"set_default_activity" to SetDefaultActivity::class.java,
"set_core_activities" to SetCoreActivities::class.java
)
}
// fun encode(buffer: RegistryFriendlyByteBuf)
// fun decode(buffer: RegistryFriendlyByteBuf)
fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext)
}
@@ -0,0 +1,16 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import net.minecraft.world.entity.LivingEntity
object DummyBrainConfig : BrainConfig {
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {}
}
@@ -0,0 +1,89 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.ai.ActivityConfigurationContext
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.activityRegistry
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.resolve
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Pair
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class ScriptBrainConfig : BrainConfig {
val condition = "true".asExpressionLike()
val script = cobblemonResource("dummy")
override fun configure(entity: LivingEntity, context: BrainConfigurationContext) {
val runtime = MoLangRuntime().setup()
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return
val struct = createBrainStruct(entity, context)
val script = CobblemonScripts.scripts[this.script]
?: run {
Cobblemon.LOGGER.error("Tried loading script $script as part of an entity brain but that script does not exist")
return
}
runtime.resolve(script, mapOf("brain" to struct))
}
fun createBrainStruct(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): QueryStruct {
return QueryStruct(hashMapOf()).addStandardFunctions()
.addFunction("entity") { (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()) }
.addFunction("create_activity") { params ->
val name = params.getString(0).asIdentifierDefaultingNamespace()
val activity = entity.level().activityRegistry.get(name) ?: return@addFunction run {
Cobblemon.LOGGER.error("Tried loading activity $name as part of an entity brain but that activity does not exist")
DoubleValue.ZERO
}
val existingActivityBuilder = brainConfigurationContext.activities.find { it.activity == activity }
if (existingActivityBuilder != null) {
return@addFunction createActivityStruct(existingActivityBuilder)
} else {
val activityConfigurationContext = ActivityConfigurationContext(activity)
brainConfigurationContext.activities.add(activityConfigurationContext)
return@addFunction createActivityStruct(activityConfigurationContext)
}
}
.addFunction("set_core_activities") { params ->
brainConfigurationContext.coreActivities = params.params.map { (it as ObjectValue<ActivityConfigurationContext>).obj.activity }.toSet()
return@addFunction DoubleValue.ONE
}
.addFunction("set_default_activity") { params ->
brainConfigurationContext.defaultActivity = params.get<ObjectValue<ActivityConfigurationContext>>(0).obj.activity
return@addFunction DoubleValue.ONE
}
}
fun createActivityStruct(activityConfigurationContext: ActivityConfigurationContext): ObjectValue<ActivityConfigurationContext> {
val struct = ObjectValue(activityConfigurationContext)
struct.addStandardFunctions()
.addFunction("add_task") { params ->
val priority = params.getInt(0)
val task = params.get(1) as ObjectValue<BehaviorControl<in LivingEntity>>
activityConfigurationContext.tasks.add(Pair(priority, task.obj))
}
return struct
}
}
@@ -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.api.ai.config
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.schedule.Activity
class SetCoreActivities : BrainConfig {
val activities = mutableListOf<Activity>()
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {
brainConfigurationContext.coreActivities = activities.toSet()
}
}
@@ -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.api.ai.config
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.schedule.Activity
class SetDefaultActivity : BrainConfig {
val activity: Activity = Activity.IDLE
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {
brainConfigurationContext.defaultActivity = activity
}
}
@@ -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.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class AllOfTaskConfig : TaskConfig {
val condition = "true".asExpressionLike()
val tasks: List<TaskConfig> = emptyList()
override fun createTasks(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): List<BehaviorControl<in LivingEntity>> {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return emptyList()
return tasks.flatMap { it.createTasks(entity, brainConfigurationContext) }
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.ai.AttackAngryAtTask
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class AttackAngryAtTaskConfig : SingleTaskConfig {
val condition = "true".asExpressionLike()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return AttackAngryAtTask.create()
}
}
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.resolveInt
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.DoNothing
class DoNothingTaskConfig : SingleTaskConfig {
val condition: ExpressionLike = "true".asExpressionLike()
val minDurationTicks = "40".asExpression()
val maxDurationTicks = "80".asExpression()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return DoNothing(runtime.resolveInt(minDurationTicks), runtime.resolveInt(maxDurationTicks))
}
}
@@ -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.api.ai.config.task
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.ai.FollowWalkTargetTask
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.resolveInt
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class FollowWalkTargetTaskConfig : SingleTaskConfig {
val condition: ExpressionLike = "true".asExpressionLike()
val minRunTime: Expression = "150".asExpression()
val maxRunTime: Expression = "250".asExpression()
override fun createTask(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): BehaviorControl<LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return WrapperLivingEntityTask(
FollowWalkTargetTask(runtime.resolveInt(minRunTime), runtime.resolveInt(maxRunTime)),
PathfinderMob::class.java
)
}
}
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.ai.GetAngryAtAttackerTask
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class GetAngryAtAttackerTaskConfig : SingleTaskConfig {
val condition: ExpressionLike = "true".asExpressionLike()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return GetAngryAtAttackerTask.create()
}
}
@@ -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.api.ai.config.task
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.npc.ai.GoToHealingMachineTask
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class GoToHealingMachineTaskConfig(
val condition: ExpressionLike = "true".asExpressionLike(),
val horizontalSearchRange: Expression = "10".asExpression(),
val verticalSearchRange: Expression = "5".asExpression(),
val speedMultiplier: Expression = "0.33".asExpression(),
val completionRange: Expression = "1".asExpression()
) : SingleTaskConfig {
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return GoToHealingMachineTask.create(
horizontalSearchRange = horizontalSearchRange,
verticalSearchRange = verticalSearchRange,
speedMultiplier = speedMultiplier,
completionRange = completionRange
)
}
}
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.npc.ai.HealUsingHealingMachineTask
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class HealUsingHealingMachineTaskConfig : SingleTaskConfig {
val condition: ExpressionLike = "true".asExpressionLike()
val horizontalUseRange = "3".asExpression()
val verticalUseRange = "2".asExpression()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return HealUsingHealingMachineTask(horizontalUseRange, verticalUseRange)
}
}
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.npc.ai.LookAtBattlingPokemonTask
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.resolveInt
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class LookAtBattlingPokemonTaskConfig : SingleTaskConfig {
val minDurationTicks = "40".asExpression()
val maxDurationTicks = "80".asExpression()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
return LookAtBattlingPokemonTask.create(
minDurationTicks = runtime.resolveInt(minDurationTicks),
maxDurationTicks = runtime.resolveInt(maxDurationTicks)
)
}
}
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.resolveFloat
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.SetEntityLookTarget
class LookAtEntitiesTaskConfig : SingleTaskConfig {
val condition: ExpressionLike = "true".asExpressionLike()
val maxDistance = "15".asExpression()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return SetEntityLookTarget.create(runtime.resolveFloat(maxDistance))
}
}
@@ -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.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.entity.npc.ai.LookAtSpeakerTask
import net.minecraft.world.entity.LivingEntity
class LookAtSpeakerTaskConfig : SingleTaskConfig {
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
) = LookAtSpeakerTask.create()
}
@@ -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.api.ai.config.task
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.resolveInt
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.Mob
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.LookAtTargetSink
class LookAtTargetTaskConfig : SingleTaskConfig {
val condition: ExpressionLike = "true".asExpressionLike()
val minDurationTicks: Expression = "40".asExpression()
val maxDurationTicks: Expression = "80".asExpression()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return WrapperLivingEntityTask(LookAtTargetSink(runtime.resolveInt(minDurationTicks), runtime.resolveInt(maxDurationTicks)), Mob::class.java)
}
}
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.npc.ai.MeleeAttackTask
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class MeleeAttackTaskConfig : SingleTaskConfig {
val condition = "true".asExpressionLike()
val range = "1.5".asExpression()
val cooldownTicks = "30".asExpression()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return MeleeAttackTask.create(
range = range,
cooldownTicks = cooldownTicks
)
}
}
@@ -0,0 +1,27 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.entity.ai.MoveToAttackTargetTask
import com.cobblemon.mod.common.util.asExpression
import net.minecraft.world.entity.LivingEntity
class MoveToAttackTargetTaskConfig : SingleTaskConfig {
val speedMultiplier = "0.5".asExpression()
val closeEnoughDistance = "1".asExpression()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
) = MoveToAttackTargetTask.create(
speedMultiplier = speedMultiplier,
closeEnoughDistance = closeEnoughDistance
)
}
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.toDF
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.DoNothing
import net.minecraft.world.entity.ai.behavior.RunOne
/**
* A task where each time the brain is ticked, a different task might run. This differs from [RandomTaskConfig] in that
* the same entity can run all of the different possibilities, rather than [RandomTaskConfig] where once the entity
* spawns, it will only use whichever was selected at the time of spawning.
*
* This is most useful for making a single entity randomly choose what to do at a given moment.
*
* @author Hiroku
* @since October 19th, 2024
*/
class OneOfTaskConfig : SingleTaskConfig {
class OneOfTaskOption {
val weight: Int = 1
val task: TaskConfig = SingleTaskConfig { _, _ -> DoNothing(0, 1) }
}
val condition: ExpressionLike = "true".asExpressionLike()
val options = mutableListOf<OneOfTaskOption>()
override fun createTask(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return RunOne(options.map { it.task.createTasks(entity, brainConfigurationContext).first() toDF it.weight })
}
}
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.weightedSelection
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.DoNothing
/**
* Randomly chooses one of the possible tasks to add to the brain. This differs from [OneOfTaskConfig] in that
* the randomization happens before the brain is created, rather than [OneOfTaskConfig] where the randomization
* happens each time the brain is ticked.
*
* This is most useful when the goal is to apply something like a specialization to an entity where it varies
* but once put on the entity, it sticks.
*
* @author Hiroku
* @since October 19th, 2024
*/
class RandomTaskConfig : TaskConfig {
class RandomTaskChoice {
val weight = 1.0
val task: TaskConfig = SingleTaskConfig { _, _ -> DoNothing(0, 1) }
}
val condition: ExpressionLike = "true".asExpressionLike()
val choices = mutableListOf<RandomTaskChoice>()
override fun createTasks(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): List<BehaviorControl<in LivingEntity>> {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return emptyList()
val task = choices.weightedSelection { it.weight }?.task ?: throw IllegalStateException("No tasks to choose from in random_task config")
return task.createTasks(entity, brainConfigurationContext)
}
}
@@ -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.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
fun interface SingleTaskConfig : TaskConfig {
override fun createTasks(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): List<BehaviorControl<in LivingEntity>> {
return createTask(entity, brainConfigurationContext)?.let { listOf(it) } ?: emptyList()
}
fun createTask(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): BehaviorControl<in LivingEntity>?
}
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.ai.StayAfloatTask
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.resolveFloat
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class StayAfloatTaskConfig : SingleTaskConfig {
val condition: ExpressionLike = "true".asExpressionLike()
val chance: Expression = "0.01".asExpression()
override fun createTask(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): BehaviorControl<LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
val chance = runtime.resolveFloat(chance)
return WrapperLivingEntityTask(
StayAfloatTask(chance),
PathfinderMob::class.java
)
}
}
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.StopBeingAngryIfTargetDead
class StopBeingAngryIfAttackerDeadTaskConfig : SingleTaskConfig {
val condition: ExpressionLike = "true".asExpressionLike()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return StopBeingAngryIfTargetDead.create()
}
}
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.entity.npc.ai.SwitchFromActionEffectTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.schedule.Activity
class SwitchFromActionEffectTaskConfig : SingleTaskConfig {
val activity = Activity.IDLE
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
) = SwitchFromActionEffectTask.create(activity)
}
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
import net.minecraft.world.entity.schedule.Activity
class SwitchFromChattingTaskConfig : SingleTaskConfig {
val activity = Activity.IDLE
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
) = BehaviorBuilder.create {
it.group(
it.absent(CobblemonMemories.DIALOGUES)
).apply(it) { _ ->
Trigger { world, entity, _ ->
entity.brain.setActiveActivityIfPossible(activity)
return@Trigger true
}
}
}
}
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.schedule.Activity
class SwitchFromFightTaskConfig : SingleTaskConfig {
val activity = Activity.IDLE
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
) = BehaviorBuilder.create {
it.group(
it.absent(MemoryModuleType.ATTACK_TARGET)
).apply(it) { _ ->
Trigger { world, entity, _ ->
entity.brain.setActiveActivityIfPossible(activity)
return@Trigger true
}
}
}
}
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.entity.npc.ai.SwitchFromBattleTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.schedule.Activity
class SwitchFromNPCBattleTaskConfig : SingleTaskConfig {
val activity: Activity = Activity.IDLE
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
return SwitchFromBattleTask.create(activity)
}
}
@@ -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.api.ai.config.task
import com.cobblemon.mod.common.CobblemonActivities
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
class SwitchToActionEffectTaskConfig : SingleTaskConfig {
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
return BehaviorBuilder.create {
it.group(
it.absent(CobblemonMemories.ACTIVE_ACTION_EFFECT)
).apply(it) { _ ->
Trigger { world, entity, time ->
entity.brain.setActiveActivityIfPossible(CobblemonActivities.NPC_ACTION_EFFECT)
return@Trigger true
}
}
}
}
}
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.CobblemonActivities
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class SwitchToChattingTaskConfig : SingleTaskConfig {
val condition = "true".asExpressionLike()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
) = BehaviorBuilder.create {
it.group(
it.present(CobblemonMemories.DIALOGUES),
it.registered(MemoryModuleType.WALK_TARGET)
).apply(it) { _, walkTarget ->
Trigger { world, entity, _ ->
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return@Trigger false
walkTarget.erase()
entity.brain.setActiveActivityIfPossible(CobblemonActivities.NPC_CHATTING)
return@Trigger true
}
}
}
}
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.Difficulty
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.schedule.Activity
class SwitchToFightTaskConfig : SingleTaskConfig {
val condition = "true".asExpressionLike()
val activity = Activity.FIGHT
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
) = BehaviorBuilder.create {
it.group(
it.present(MemoryModuleType.ATTACK_TARGET)
).apply(it) { _ ->
Trigger { world, entity, _ ->
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return@Trigger false
if (entity.commandSenderWorld.getCurrentDifficultyAt(entity.blockPosition()).difficulty == Difficulty.PEACEFUL) return@Trigger false
entity.brain.setActiveActivityIfPossible(activity)
return@Trigger true
}
}
}
}
@@ -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.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.entity.npc.ai.SwitchToBattleTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class SwitchToNPCBattleTaskConfig : SingleTaskConfig {
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity> = SwitchToBattleTask.create()
}
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
/**
* A configuration for a brain task. Its purpose is to generate a list of tasks to add to the brain of
* an entity when it spawns.
*
* This is essentially a builder for tasks.
*
* @author Hiroku
* @since October 14th, 2024
*/
fun interface TaskConfig {
companion object {
val types = mutableMapOf<String, Class<out TaskConfig>>(
"one_of" to OneOfTaskConfig::class.java,
"wander" to WanderTaskConfig::class.java,
"look_at_target" to LookAtTargetTaskConfig::class.java,
"follow_walk_target" to FollowWalkTargetTaskConfig::class.java,
"random" to RandomTaskConfig::class.java,
"stay_afloat" to StayAfloatTaskConfig::class.java,
"look_at_entities" to LookAtEntitiesTaskConfig::class.java,
"do_nothing" to DoNothingTaskConfig::class.java,
"get_angry_at_attacker" to GetAngryAtAttackerTaskConfig::class.java,
"stop_being_angry_if_attacker_dead" to StopBeingAngryIfAttackerDeadTaskConfig::class.java,
"switch_npc_to_battle" to SwitchToNPCBattleTaskConfig::class.java,
"look_at_battling_pokemon" to LookAtBattlingPokemonTaskConfig::class.java,
"switch_npc_from_battle" to SwitchFromNPCBattleTaskConfig::class.java,
"go_to_healing_machine" to GoToHealingMachineTaskConfig::class.java,
"heal_using_healing_machine" to HealUsingHealingMachineTaskConfig::class.java,
"all_of" to AllOfTaskConfig::class.java,
"attack_angry_at" to AttackAngryAtTaskConfig::class.java,
"move_to_attack_target" to MoveToAttackTargetTaskConfig::class.java,
"melee_attack" to MeleeAttackTaskConfig::class.java,
"switch_from_fight" to SwitchFromFightTaskConfig::class.java,
"switch_to_fight" to SwitchToFightTaskConfig::class.java,
"switch_to_chatting" to SwitchToChattingTaskConfig::class.java,
"switch_from_chatting" to SwitchFromChattingTaskConfig::class.java,
"look_at_speaker" to LookAtSpeakerTaskConfig::class.java,
"switch_to_action_effect" to SwitchToActionEffectTaskConfig::class.java,
"switch_from_action_effect" to SwitchFromActionEffectTaskConfig::class.java,
)
val runtime = MoLangRuntime().setup()
}
val runtime: MoLangRuntime
get() = Companion.runtime
/** Given the entity in construction, returns a list of tasks. */
fun createTasks(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): List<BehaviorControl<in LivingEntity>>
}
@@ -0,0 +1,71 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.resolveDouble
import com.cobblemon.mod.common.util.resolveFloat
import com.cobblemon.mod.common.util.resolveInt
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.BlockPosTracker
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.WalkTarget
import net.minecraft.world.entity.ai.util.LandRandomPos
class WanderTaskConfig : SingleTaskConfig {
val condition: ExpressionLike = "true".asExpressionLike()
val shouldWander: ExpressionLike = "math.random(0, 20 * 8) <= 1".asExpressionLike()
val horizontalRange: Expression = "10".asExpression()
val verticalRange: Expression = "5".asExpression()
val speedMultiplier: Expression = "0.35".asExpression()
val completionRange: Expression = "1".asExpression()
val lookTargetYOffset: Expression = "1.5".asExpression()
override fun createTask(
entity: LivingEntity,
brainConfigurationContext: BrainConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(condition)) return null
return BehaviorBuilder.create {
it.group(
it.absent(MemoryModuleType.WALK_TARGET),
it.registered(MemoryModuleType.LOOK_TARGET)
).apply(it) { walkTarget, lookTarget ->
Trigger { world, entity, time ->
if (entity !is PathfinderMob) {
return@Trigger false
}
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
if (!runtime.resolveBoolean(shouldWander)) return@Trigger false
val targetVec = LandRandomPos.getPos(entity, runtime.resolveInt(horizontalRange), runtime.resolveInt(verticalRange)) ?: return@Trigger false
walkTarget.set(WalkTarget(targetVec, runtime.resolveFloat(speedMultiplier), runtime.resolveInt(completionRange)))
lookTarget.set(BlockPosTracker(targetVec.add(0.0, runtime.resolveDouble(lookTargetYOffset), 0.0)))
return@Trigger true
}
}
}
}
}
@@ -25,6 +25,7 @@ import com.cobblemon.mod.common.api.events.battles.BattleFledEvent
import com.cobblemon.mod.common.api.moves.Moves
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.api.text.red
import com.cobblemon.mod.common.api.text.yellow
@@ -83,6 +84,8 @@ open class PokemonBattle(
val onEndHandlers: MutableList<(PokemonBattle) -> Unit> = mutableListOf()
val battlePartyStores = mutableListOf<PlayerPartyStore>()
init {
side1.battle = this
side2.battle = this
@@ -371,6 +374,13 @@ open class PokemonBattle(
}
fun dispatchWaitingToFront(delaySeconds: Float = 1F, dispatcher: () -> Unit) {
dispatches.addFirst(BattleDispatch {
dispatcher()
WaitDispatch(delaySeconds)
})
}
fun dispatchGo(dispatcher: () -> Unit) {
dispatch {
dispatcher()
@@ -172,7 +172,8 @@ class Berry(
val treeEntity = world.getBlockEntity(pos) as BerryBlockEntity
if (BerryBlock.getMulch(treeEntity) == MulchVariant.RICH) {
//I hope the upper bound isnt exclusive, especially when there's a method called nextBetweenExclusive
yield += world.random.nextIntBetweenInclusive(1, 3)
// update: it was meant to be exclusive, which caused #1124. I've lowered the upper bound from 3 to 2.
yield += world.random.nextIntBetweenInclusive(1, 2)
treeEntity.decrementMulchDuration(world, pos, state)
}
val event = BerryYieldCalculationEvent(this, world, state, pos, placer, yield, bonus.second)
@@ -13,6 +13,9 @@ import com.cobblemon.mod.common.api.events.battles.BattleFledEvent
import com.cobblemon.mod.common.api.events.battles.BattleStartedPostEvent
import com.cobblemon.mod.common.api.events.battles.BattleStartedPreEvent
import com.cobblemon.mod.common.api.events.battles.BattleVictoryEvent
import com.cobblemon.mod.common.api.events.battles.instruction.MegaEvolutionEvent
import com.cobblemon.mod.common.api.events.battles.instruction.TerastallizationEvent
import com.cobblemon.mod.common.api.events.battles.instruction.ZMoveUsedEvent
import com.cobblemon.mod.common.api.events.berry.BerryHarvestEvent
import com.cobblemon.mod.common.api.events.berry.BerryMutationOfferEvent
import com.cobblemon.mod.common.api.events.berry.BerryMutationResultEvent
@@ -23,6 +26,7 @@ import com.cobblemon.mod.common.api.events.entity.PokemonEntitySaveEvent
import com.cobblemon.mod.common.api.events.entity.PokemonEntitySaveToWorldEvent
import com.cobblemon.mod.common.api.events.entity.SpawnEvent
import com.cobblemon.mod.common.api.events.farming.ApricornHarvestEvent
import com.cobblemon.mod.common.api.events.fishing.*
import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent
import com.cobblemon.mod.common.api.events.pokeball.PokeBallCaptureCalculatedEvent
import com.cobblemon.mod.common.api.events.pokeball.PokemonCatchRateEvent
@@ -33,15 +37,14 @@ import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionAcceptedEv
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionCompleteEvent
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionDisplayEvent
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionTestedEvent
import com.cobblemon.mod.common.api.events.pokemon.healing.PokemonHealedEvent
import com.cobblemon.mod.common.api.events.pokemon.interaction.ExperienceCandyUseEvent
import com.cobblemon.mod.common.api.events.pokemon.interaction.HeldItemUpdatedEvent
import com.cobblemon.mod.common.api.events.pokemon.interaction.PokemonInteractionGUICreationEvent
import com.cobblemon.mod.common.api.events.starter.StarterChosenEvent
import com.cobblemon.mod.common.api.events.storage.ReleasePokemonEvent
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
import com.cobblemon.mod.common.api.reactive.Observable
import com.cobblemon.mod.common.api.reactive.Observable.Companion.filter
import com.cobblemon.mod.common.api.reactive.Observable.Companion.map
import com.cobblemon.mod.common.api.reactive.SimpleObservable
@@ -80,8 +83,6 @@ object CobblemonEvents {
val POKEMON_CAPTURED = EventObservable<PokemonCapturedEvent>()
@JvmField
val FOSSIL_REVIVED = EventObservable<FossilRevivedEvent>()
// @JvmField
// val EGG_HATCH = EventObservable<HatchEggEvent>()
@JvmField
val BATTLE_STARTED_PRE = CancelableObservable<BattleStartedPreEvent>()
@JvmField
@@ -93,6 +94,14 @@ object CobblemonEvents {
@JvmField
val BATTLE_FAINTED = EventObservable<BattleFaintedEvent>()
// instructions
@JvmField
val MEGA_EVOLUTON = EventObservable<MegaEvolutionEvent>()
@JvmField
val TERASTALLIZATION = EventObservable<TerastallizationEvent>()
@JvmField
val ZPOWER_USED = EventObservable<ZMoveUsedEvent>()
@JvmField
val POKEMON_SENT_PRE = CancelableObservable<PokemonSentPreEvent>()
@JvmField
@@ -106,6 +115,9 @@ object CobblemonEvents {
@JvmField
val LEVEL_UP_EVENT = EventObservable<LevelUpEvent>()
@JvmField
val POKEMON_HEALED = CancelableObservable<PokemonHealedEvent>()
@JvmField
/** CLIENT ONLY! */
val POKEMON_INTERACTION_GUI_CREATION = EventObservable<PokemonInteractionGUICreationEvent>()
@@ -174,4 +186,35 @@ object CobblemonEvents {
val POKEMON_GAINED = EventObservable<PokemonGainedEvent>()
@JvmField
val POKEMON_SEEN = EventObservable<PokemonSeenEvent>()
// Fishing
@JvmField
val BAIT_SET = CancelableObservable<BaitSetEvent>()
@JvmField
val BAIT_SET_PRE = CancelableObservable<BaitSetEvent>()
@JvmField
val BAIT_CONSUMED = CancelableObservable<BaitConsumedEvent>()
@JvmField
val POKEROD_CAST_PRE = CancelableObservable<PokerodCastEvent.Pre>()
@JvmField
val POKEROD_CAST_POST = EventObservable<PokerodCastEvent.Post>()
@JvmField
val POKEROD_REEL = CancelableObservable<PokerodReelEvent>()
@JvmField
val BOBBER_BUCKET_CHOSEN = EventObservable<BobberBucketChosenEvent>()
@JvmField
val BOBBER_SPAWN_POKEMON_PRE = CancelableObservable<BobberSpawnPokemonEvent.Pre>()
@JvmField
val BOBBER_SPAWN_POKEMON_MODIFY = EventObservable<BobberSpawnPokemonEvent.Modify>()
@JvmField
val BOBBER_SPAWN_POKEMON_POST = EventObservable<BobberSpawnPokemonEvent.Post>()
@JvmField
val BAIT_EFFECT_REGISTRATION = EventObservable<BaitEffectFunctionRegistryEvent>()
@JvmField
val COLLECT_EGG = CancelableObservable<CollectEggEvent>()
@JvmField
val HATCH_EGG_PRE = CancelableObservable<HatchEggEvent.Pre>()
@JvmField
val HATCH_EGG_POST = EventObservable<HatchEggEvent.Post>()
}
@@ -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.api.events.battles.instruction
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
/**
* Event that is fired when a Pokemon Mega Evolves.
* @param battle The Pokemon Battle.
* @param pokemon The Pokemon that Mega Evolves.
*/
data class MegaEvolutionEvent(val battle: PokemonBattle, val pokemon: BattlePokemon)
@@ -0,0 +1,25 @@
/*
* 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.battles.instruction
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.types.tera.TeraType
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
/**
* Event that is fired when a Pokemon Terastallizes.
* @param battle The Pokemon Battle.
* @param pokemon The Pokemon that Terastallizes.
* @param teraType The TeraType of the Terastallization.
*/
data class TerastallizationEvent(
val battle: PokemonBattle,
val pokemon: BattlePokemon,
val teraType: TeraType
)
@@ -0,0 +1,19 @@
/*
* 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.battles.instruction
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
/**
* Event that is fired when a Pokemon uses a Z-Move.
* @param battle The Pokemon Battle.
* @param pokemon The Pokemon that uses the Z-Move.
*/
data class ZMoveUsedEvent(val battle: PokemonBattle, val pokemon: BattlePokemon)
@@ -0,0 +1,18 @@
/*
* 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 net.minecraft.world.item.ItemStack
/**
* Event that is fired when a bait is consumed.
* @param rod The ItemStack of the rod that consumed the bait.
*/
class BaitConsumedEvent(val rod: ItemStack) : Cancelable()
@@ -0,0 +1,26 @@
/*
* 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.fishing.FishingBait
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
*/
class BaitEffectFunctionRegistryEvent {
val functions = mutableMapOf<ResourceLocation, (PokemonEntity, FishingBait.Effect) -> Unit>()
fun registerFunction(id: ResourceLocation, function: (PokemonEntity, FishingBait.Effect) -> Unit) {
functions[id] = function
}
}
@@ -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.api.events.fishing
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.api.reactive.CancelableObservable
import net.minecraft.world.item.ItemStack
/**
* Event that is fired when a bait is set on a fishing rod.
* @param rod The ItemStack of the rod that the bait is set on.
* @param bait The ItemStack of the bait that is set on the rod.
*/
class BaitSetEvent(val rod: ItemStack, val bait: ItemStack) : Cancelable()
@@ -0,0 +1,19 @@
/*
* 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.spawning.SpawnBucket
/**
* Event that is fired when a bucket is chosen by the bobber.
* @param chosenBucket The bucket that is chosen.
* @param buckets The list of buckets that the bobber can choose from.
* @param luckOfTheSeaLevel The level of the Luck of the Sea enchantment on the rod.
*/
class BobberBucketChosenEvent(var chosenBucket: SpawnBucket, val buckets: MutableList<SpawnBucket>, val luckOfTheSeaLevel: Int)
@@ -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 BobberSpawnPokemonEvent {
/**
* 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,
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
}
@@ -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.api.events.fishing
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.entity.fishing.PokeRodFishingBobberEntity
import net.minecraft.world.item.ItemStack
/**
* Event that is fired when a fishing rod is cast.
*/
interface PokerodCastEvent {
val rod: ItemStack
/**
* Event that is fired before a fishing rod is cast.
* @param rod The ItemStack of the rod that is being cast.
* @param bobber The PokeRodFishingBobberEntity that is being cast.
* @param bait The ItemStack of the bait that is set on the rod.
*/
data class Pre(
override var rod: ItemStack,
var bobber: PokeRodFishingBobberEntity,
var bait: ItemStack
) : PokerodCastEvent, Cancelable()
/**
* Event that is fired after a fishing rod is cast.
* @param rod The ItemStack of the rod that is being cast.
* @param bobber The PokeRodFishingBobberEntity that is being cast.
* @param bait The ItemStack of the bait that is set on the rod.
*/
data class Post(
override var rod: ItemStack,
var bobber: PokeRodFishingBobberEntity,
var bait: ItemStack
) : PokerodCastEvent
}
@@ -0,0 +1,18 @@
/*
* 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 net.minecraft.world.item.ItemStack
/**
* Event that is fired when a fishing rod is reeled.
* @param rod The ItemStack of the rod that is being reeled.
*/
class PokerodReelEvent(val rod: ItemStack) : Cancelable()
@@ -8,14 +8,14 @@
package com.cobblemon.mod.common.api.events.pokedex.scanning
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData
import com.cobblemon.mod.common.pokedex.scanner.ScannableEntity
import net.minecraft.server.level.ServerPlayer
data class PokemonScannedEvent(val player: ServerPlayer, val scannedEntity: PokemonEntity) {
val pokemon: Pokemon
get() = scannedEntity.pokemon
data class PokemonScannedEvent(val player: ServerPlayer, val scannedPokemonEntityData: PokedexEntityData, val scannedEntity: ScannableEntity) {
val pokedexEntityData: PokedexEntityData
get() = scannedPokemonEntityData
val isOwned: Boolean
get() = pokemon.getOwnerPlayer() == player
get() = scannedPokemonEntityData.ownerUUID == player.uuid
}
@@ -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.api.events.pokemon
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.server.level.ServerPlayer
class CollectEggEvent (
val egg : PokemonProperties,
val maleParent : Pokemon,
val femaleParent : Pokemon,
val player : ServerPlayer
) : Cancelable()
@@ -8,7 +8,15 @@
package com.cobblemon.mod.common.api.events.pokemon
//data class HatchEggEvent (
// val pokemon: Pokemon,
// val player: ServerPlayer
//)
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import net.minecraft.server.level.ServerPlayer
interface HatchEggEvent {
val egg: PokemonProperties
val player: ServerPlayer
data class Pre(override var egg : PokemonProperties, override var player: ServerPlayer) : HatchEggEvent, Cancelable()
data class Post(override var egg : PokemonProperties, override var player: ServerPlayer) : HatchEggEvent
}
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.events.pokemon.healing
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.item.HealingSource
import com.cobblemon.mod.common.item.berry.HealingBerryItem
import com.cobblemon.mod.common.item.interactive.PotionItem
import com.cobblemon.mod.common.item.interactive.PotionType
import com.cobblemon.mod.common.pokemon.Pokemon
/**
* Event that is fired when a Pokemon is healed.
* @param pokemon The Pokemon that is being healed.
* @param amount The amount of healing that is being applied. If -1, the Pokemon is fully healed.
* @param source The HealingSource that is being used to heal the Pokemon.
*
* @see HealingSource
*/
class PokemonHealedEvent(
val pokemon: Pokemon,
var amount: Int = -1,
val source: HealingSource = HealingSource.Force
) : Cancelable() {
fun isFullHeal() = amount == -1
fun isHealed() = amount > 0
}
@@ -8,11 +8,16 @@
package com.cobblemon.mod.common.api.fishing
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
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.core.Registry
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.Entity
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
@@ -75,6 +80,7 @@ data class FishingBait(
}
object Effects {
private val EFFECT_FUNCTIONS: MutableMap<ResourceLocation, (PokemonEntity, Effect) -> Unit> = mutableMapOf()
val NATURE = cobblemonResource("nature")
val IV = cobblemonResource("iv")
val EV = cobblemonResource("ev")
@@ -87,6 +93,28 @@ data class FishingBait(
val POKEMON_CHANCE = cobblemonResource("pokemon_chance")
val FRIENDSHIP = cobblemonResource("friendship")
val INERT = cobblemonResource("inert")
fun registerEffect(type: ResourceLocation, effect: (PokemonEntity, Effect) -> Unit) {
EFFECT_FUNCTIONS[type] = effect
}
fun getEffectFunction(type: ResourceLocation): ((PokemonEntity, Effect) -> Unit)? {
return EFFECT_FUNCTIONS[type]
}
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[TERA] = { entity, effect -> FishingSpawnCause.alterTeraAttempt(entity, effect) }
EFFECT_FUNCTIONS[HIDDEN_ABILITY_CHANCE] = { entity, _ -> FishingSpawnCause.alterHAAttempt(entity) }
EFFECT_FUNCTIONS[FRIENDSHIP] = { entity, effect -> FishingSpawnCause.alterFriendshipAttempt(entity, effect) }
CobblemonEvents.BAIT_EFFECT_REGISTRATION.post(BaitEffectFunctionRegistryEvent()) { event ->
EFFECT_FUNCTIONS.putAll(event.functions)
}
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.item
import com.cobblemon.mod.common.item.interactive.PotionItem
/**
* Interface that represents a source of healing.
*/
interface HealingSource {
/**
* A source of healing that is forced, i.e it has no specific source.
*/
object Force : HealingSource
}
@@ -28,9 +28,13 @@ 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.scripting.CobblemonScripts
import com.cobblemon.mod.common.api.storage.party.PartyStore
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunctions
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.PokemonMoveControl
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.*
@@ -52,6 +56,7 @@ 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.Entity
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.level.Level
@@ -191,6 +196,7 @@ object MoLangFunctions {
map.put("is_in_water") { _ -> DoubleValue(entity.isUnderWater) }
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) }
@@ -207,10 +213,18 @@ object MoLangFunctions {
map.put("velocity_x") { _ -> DoubleValue(entity.deltaMovement.x) }
map.put("velocity_y") { _ -> DoubleValue(entity.deltaMovement.y) }
map.put("velocity_z") { _ -> DoubleValue(entity.deltaMovement.z) }
map.put("width") { DoubleValue(entity.boundingBox.xsize) }
map.put("height") { DoubleValue(entity.boundingBox.ysize) }
map.put("entity_size") { DoubleValue(entity.boundingBox.run { if (xsize > ysize) xsize else ysize }) }
map.put("entity_width") { DoubleValue(entity.boundingBox.xsize) }
map.put("entity_height") { DoubleValue(entity.boundingBox.ysize) }
map.put("horizontal_velocity") { _ -> DoubleValue(entity.deltaMovement.horizontalDistance()) }
map.put("vertical_velocity") { DoubleValue(entity.deltaMovement.y) }
map.put("is_on_ground") { _ -> DoubleValue(entity.onGround()) }
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
@@ -318,6 +332,43 @@ object MoLangFunctions {
}
)
val pokemonFunctions = mutableListOf<(Pokemon) -> HashMap<String, java.util.function.Function<MoParams, Any>>>(
{ pokemon ->
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
map.put("is_wild") { DoubleValue(pokemon.isWild()) }
map.put("is_shiny") { DoubleValue(pokemon.shiny) }
map.put("form") { StringValue(pokemon.form.name) }
map.put("weight") { DoubleValue(pokemon.species.weight.toDouble()) }
map
}
)
val pokemonEntityFunctions = mutableListOf<(PokemonEntity) -> HashMap<String, java.util.function.Function<MoParams, Any>>>(
{ pokemonEntity ->
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
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("has_aspect") { DoubleValue(it.getString(0) in pokemonEntity.aspects) }
map
}
)
val partyFunctions = mutableListOf<(PartyStore) -> HashMap<String, java.util.function.Function<MoParams, Any>>>(
{ party ->
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
map.put("get_pokemon") { params ->
val index = params.getInt(0)
val pokemon = party.get(index) ?: return@put DoubleValue.ZERO
val struct = VariableStruct()
pokemon.writeVariables(struct)
return@put struct
}
map.put("healing_remainder_percent") { _ -> DoubleValue(party.getHealingRemainderPercent()) }
return@mutableListOf map
})
fun Holder<Biome>.asBiomeMoLangValue() = asMoLangValue(Registries.BIOME).addFunctions(biomeFunctions)
fun Holder<Level>.asWorldMoLangValue() = asMoLangValue(Registries.DIMENSION).addFunctions(worldFunctions)
fun Holder<Block>.asBlockMoLangValue() = asMoLangValue(Registries.BLOCK).addFunctions(blockFunctions)
@@ -372,6 +423,30 @@ object MoLangFunctions {
return this
}
fun QueryStruct.addEntityFunctions(entity: LivingEntity): QueryStruct {
val addedFunctions = entityFunctions
.flatMap { it.invoke(entity).entries }
.associate { it.key to it.value }
functions.putAll(addedFunctions)
return this
}
fun QueryStruct.addPokemonFunctions(pokemon: Pokemon): QueryStruct {
val addedFunctions = pokemonFunctions
.flatMap { it.invoke(pokemon).entries }
.associate { it.key to it.value }
functions.putAll(addedFunctions)
return this
}
fun QueryStruct.addPokemonEntityFunctions(pokemonEntity: PokemonEntity): QueryStruct {
val addedFunctions = pokemonEntityFunctions
.flatMap { it.invoke(pokemonEntity).entries }
.associate { it.key to it.value }
functions.putAll(addedFunctions)
return this
}
fun <T : QueryStruct> T.addFunctions(functions: Map<String, java.util.function.Function<MoParams, Any>>): T {
this.functions.putAll(functions)
return this
@@ -35,6 +35,14 @@ class BenchedMoves : Iterable<BenchedMove> {
emit = previousEmit
}
fun copyFrom(other: BenchedMoves) {
doWithoutEmitting {
clear()
other.forEach { add(it) }
}
update()
}
fun doThenEmit(action: () -> Unit) {
doWithoutEmitting(action)
update()
@@ -56,16 +56,12 @@ abstract class MultiblockBlock(properties: Properties) : BaseEntityBlock(propert
return super.useWithoutItem(state, world, pos, player, hit)
}
override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
val result = super.playerWillDestroy(world, pos, state, player)
if (!world.isClientSide) {
val entity = world.getBlockEntity(pos)
if (entity is MultiblockEntity && entity.multiblockStructure != null) {
entity.multiblockStructure!!.playerWillDestroy(world, pos, state, player)
}
entity?.setRemoved()
override fun onRemove(state: BlockState, level: Level, pos: BlockPos, newState: BlockState, movedByPiston: Boolean) {
val entity = level.getBlockEntity(pos)
if (entity is MultiblockEntity && entity.multiblockStructure != null && state.block != newState.block) {
entity.multiblockStructure!!.playerWillDestroy(level, pos, state, null)
}
return result
super.onRemove(state, level, pos, newState, movedByPiston)
}
override fun newBlockEntity(pos: BlockPos, state: BlockState): BlockEntity? {
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.npc
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.api.ai.config.BrainConfig
import com.cobblemon.mod.common.api.npc.configuration.NPCBattleConfiguration
import com.cobblemon.mod.common.api.npc.configuration.NPCConfigVariable
import com.cobblemon.mod.common.api.npc.configuration.NPCInteractConfiguration
@@ -39,13 +40,15 @@ class NPCClass {
var aspects: MutableSet<String> = mutableSetOf() // These only make sense when applied via presets
var hitbox = EntityDimensions.scalable(0.6F, 1.8F)
var battleConfiguration = NPCBattleConfiguration()
var aiScripts: MutableList<ResourceLocation> = mutableListOf()
var interaction: NPCInteractConfiguration? = null
var canDespawn = true
var variations: MutableMap<String, NPCVariationProvider> = mutableMapOf()
var config: MutableList<NPCConfigVariable> = mutableListOf()
var variables = mutableMapOf<String, MoValue>() // Questionable whether this should be here.
var party: NPCPartyProvider? = null
var skill: Int = 0
var battleTheme: ResourceLocation? = null
var ai: MutableList<BrainConfig> = mutableListOf()
// If you're adding stuff here, add it to NPCPreset and NPCClassAdapter too
@@ -56,7 +59,6 @@ class NPCClass {
buffer.writeFloat(this.hitbox.height)
buffer.writeBoolean(this.hitbox.fixed)
battleConfiguration.encode(buffer)
buffer.writeCollection(aiScripts) { _, v -> buffer.writeString(v.toString()) }
buffer.writeNullable(interaction) { _, value ->
buffer.writeString(value.type)
value.encode(buffer)
@@ -79,6 +81,7 @@ class NPCClass {
buffer.writeString(key)
buffer.writeString(value.asString())
}
buffer.writeNullable(battleTheme) { _, v -> buffer.writeIdentifier(v) }
}
fun decode(buffer: RegistryFriendlyByteBuf) {
@@ -90,7 +93,6 @@ class NPCClass {
hitbox = if (fixed) EntityDimensions.fixed(length, width) else EntityDimensions.scalable(length, width)
battleConfiguration = NPCBattleConfiguration()
battleConfiguration.decode(buffer)
aiScripts = buffer.readList { ResourceLocation.parse(buffer.readString()) }.toMutableList()
interaction = buffer.readNullable {
val type = buffer.readString()
val configType = NPCInteractConfiguration.types[type] ?: return@readNullable null
@@ -123,5 +125,6 @@ class NPCClass {
return@readMapK key to StringValue(value)
}
}
battleTheme = buffer.readNullable { buffer.readIdentifier() }
}
}
@@ -8,9 +8,12 @@
package com.cobblemon.mod.common.api.npc
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.ai.SleepDepth
import com.cobblemon.mod.common.api.ai.config.BrainConfig
import com.cobblemon.mod.common.api.ai.config.task.TaskConfig
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.drop.DropEntry
@@ -37,6 +40,7 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
import net.minecraft.world.entity.EntityDimensions
import net.minecraft.world.entity.schedule.Activity
import net.minecraft.world.item.Item
import net.minecraft.world.level.biome.Biome
import net.minecraft.world.level.block.Block
@@ -60,12 +64,16 @@ object NPCClasses : JsonDataRegistry<NPCClass> {
.registerTypeAdapter(CompoundTag::class.java, NbtCompoundAdapter)
.registerTypeAdapter(NPCPartyProvider::class.java, NPCPartyProviderAdapter)
.registerTypeAdapter(NPCInteractConfiguration::class.java, NPCInteractConfigurationAdapter)
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(NPCVariationProvider::class.java, NPCVariationProviderAdapter)
.registerTypeAdapter(MoValue::class.java, MoValueAdapter)
.registerTypeAdapter(NPCClass::class.java, NPCClassAdapter)
.registerTypeAdapter(Activity::class.java, ActivityAdapter)
.registerTypeAdapter(Component::class.java, TextAdapter)
.registerTypeAdapter(NPCVariationProvider::class.java, NPCVariationProviderAdapter)
.registerTypeAdapter(WeightedAspect::class.java, WeightedAspectAdapter)
.registerTypeAdapter(BrainConfig::class.java, BrainConfigAdapter)
.registerTypeAdapter(TaskConfig::class.java, TaskConfigAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Block::class.java).type, BlockLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.api.npc
import com.cobblemon.mod.common.api.ai.config.BrainConfig
import com.cobblemon.mod.common.api.npc.configuration.NPCConfigVariable
import com.cobblemon.mod.common.api.npc.configuration.NPCInteractConfiguration
import com.cobblemon.mod.common.api.npc.variation.NPCVariationProvider
@@ -22,11 +23,13 @@ class NPCPreset {
var variations: Map<String, NPCVariationProvider>? = null
var config: List<NPCConfigVariable>? = null
var party: NPCPartyProvider? = null
var aiScripts: List<ResourceLocation>? = null
var canDespawn: Boolean? = null
var interaction: NPCInteractConfiguration? = null
var names: MutableSet<Component>? = null
var hitbox: EntityDimensions? = null
var ai: List<BrainConfig>? = null
var skill: Int? = null
var battleTheme: ResourceLocation? = null
fun applyTo(npcClass: NPCClass) {
resourceIdentifier?.let { npcClass.resourceIdentifier = it }
@@ -38,10 +41,13 @@ class NPCPreset {
}
variations?.entries?.forEach { (key, value) -> npcClass.variations[key] = value }
party?.let { npcClass.party = it }
aiScripts?.let { npcClass.aiScripts.addAll(it) }
canDespawn?.let { npcClass.canDespawn = it }
// aiScripts?.let { npcClass.aiScripts.addAll(it) }
interaction?.let { npcClass.interaction = it }
names?.let { npcClass.names.addAll(it) }
hitbox?.let { npcClass.hitbox = it }
skill?.let { npcClass.skill = it }
battleTheme?.let { npcClass.battleTheme = it }
ai?.let { npcClass.ai.addAll(it) }
}
}
@@ -8,8 +8,11 @@
package com.cobblemon.mod.common.api.npc
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.api.ai.SleepDepth
import com.cobblemon.mod.common.api.ai.config.BrainConfig
import com.cobblemon.mod.common.api.ai.config.task.TaskConfig
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.drop.DropEntry
@@ -17,6 +20,8 @@ import com.cobblemon.mod.common.api.drop.ItemDropMethod
import com.cobblemon.mod.common.api.entity.EntityDimensionsAdapter
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.npc.configuration.NPCInteractConfiguration
import com.cobblemon.mod.common.api.npc.variation.NPCVariationProvider
import com.cobblemon.mod.common.api.npc.variation.WeightedAspect
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.api.spawning.TimeRange
@@ -32,6 +37,7 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
import net.minecraft.world.entity.EntityDimensions
import net.minecraft.world.entity.schedule.Activity
import net.minecraft.world.item.Item
import net.minecraft.world.level.biome.Biome
import net.minecraft.world.level.block.Block
@@ -54,10 +60,16 @@ object NPCPresets : JsonDataRegistry<NPCPreset> {
.registerTypeAdapter(DropEntry::class.java, DropEntryAdapter)
.registerTypeAdapter(CompoundTag::class.java, NbtCompoundAdapter)
.registerTypeAdapter(NPCPartyProvider::class.java, NPCPartyProviderAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(NPCInteractConfiguration::class.java, NPCInteractConfigurationAdapter)
.registerTypeAdapter(WeightedAspect::class.java, WeightedAspectAdapter)
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(NPCVariationProvider::class.java, NPCVariationProviderAdapter)
.registerTypeAdapter(Activity::class.java, ActivityAdapter)
.registerTypeAdapter(MoValue::class.java, MoValueAdapter)
.registerTypeAdapter(Component::class.java, TextAdapter)
.registerTypeAdapter(BrainConfig::class.java, BrainConfigAdapter)
.registerTypeAdapter(TaskConfig::class.java, TaskConfigAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Block::class.java).type, BlockLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
@@ -67,7 +79,7 @@ object NPCPresets : JsonDataRegistry<NPCPreset> {
.create()
override val typeToken: TypeToken<NPCPreset> = TypeToken.get(NPCPreset::class.java)
override val resourcePath = "npcs"
override val resourcePath = "npc_presets"
override val observable = SimpleObservable<NPCPresets>()
private val npcPresetsByIdentifier = mutableMapOf<ResourceLocation, NPCPreset>()
@@ -73,6 +73,7 @@ any number of presets and the properties of those presets will be merged into th
"battleConfiguration": {
"canChallenge": true
},
"canDespawn": false,
"skill": 5,
"party": {
"type": "simple",
@@ -231,6 +232,10 @@ in this file. The script property can be a single string or an array of strings
### battleConfiguration
I don't really know whether this is going to stay tbh
### canDespawn
Whether or not regular entity despawning logic applies. By default, NPCs will despawn over time. If the value
of this property is set to false, the NPC will never despawn over time.
### skill
The skill level when this NPC is used in battle. This is a number from 1 to 5, with 5 being most difficult
to beat. This does not control their Pokémon's levels or moves, but it does control how well they use them.
@@ -15,6 +15,7 @@ object CobblemonPermissions {
private const val COMMAND_PREFIX = "command."
private val permissions = arrayListOf<Permission>()
val CHANGE_EYE_HEIGHT = this.create("${COMMAND_PREFIX}changeeyeheight", PermissionLevel.ALL_COMMANDS)
val CHANGE_SCALE_AND_SIZE = this.create("${COMMAND_PREFIX}changescaleandsize", PermissionLevel.ALL_COMMANDS)
val CHANGE_WALK_SPEED = this.create("${COMMAND_PREFIX}changewalkspeed", PermissionLevel.ALL_COMMANDS)
val CHECKSPAWNS = this.create("${COMMAND_PREFIX}checkspawns", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@@ -12,8 +12,8 @@ import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import com.cobblemon.mod.common.api.pokedex.entry.PokedexForm
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData
import com.cobblemon.mod.common.pokemon.Gender
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import net.minecraft.resources.ResourceLocation
@@ -47,8 +47,8 @@ abstract class AbstractPokedexManager {
}
}
fun getHighestKnowledgeForSpecies(pokemon: Pokemon): PokedexEntryProgress {
val speciesRecord = getSpeciesRecord(pokemon.species.resourceIdentifier)
fun getHighestKnowledgeForSpecies(pokemonId: ResourceLocation): PokedexEntryProgress {
val speciesRecord = getSpeciesRecord(pokemonId)
return speciesRecord?.getKnowledge() ?: PokedexEntryProgress.NONE
}
@@ -86,16 +86,16 @@ abstract class AbstractPokedexManager {
}
}
fun getNewInformation(pokemon: Pokemon): PokedexLearnedInformation {
val speciesRecord = getSpeciesRecord(pokemon.species.resourceIdentifier)
fun getNewInformation(pokedexEntityData: PokedexEntityData): PokedexLearnedInformation {
val speciesRecord = getSpeciesRecord(pokedexEntityData.species.resourceIdentifier)
if (speciesRecord == null || speciesRecord.getKnowledge() == PokedexEntryProgress.NONE) {
return PokedexLearnedInformation.SPECIES
}
val formRecord = speciesRecord.getFormRecord(pokemon.form.name)
val formRecord = speciesRecord.getFormRecord(pokedexEntityData.form.name)
if (formRecord == null || formRecord.knowledge == PokedexEntryProgress.NONE) {
return PokedexLearnedInformation.FORM
}
if (pokemon.aspects.none(speciesRecord::hasAspect) || pokemon.gender !in formRecord.getGenders() || !formRecord.hasSeenShinyState(pokemon.shiny)) {
if (pokedexEntityData.aspects.none(speciesRecord::hasAspect) || pokedexEntityData.gender !in formRecord.getGenders() || !formRecord.hasSeenShinyState(pokedexEntityData.shiny)) {
return PokedexLearnedInformation.VARIATION
}
return PokedexLearnedInformation.NONE
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.pokedex
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.struct.VariableStruct
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData
import com.cobblemon.mod.common.pokemon.Gender
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.readEnumConstant
@@ -77,6 +78,12 @@ class FormDexRecord {
}
}
fun encountered(pokedexEntityData: PokedexEntityData) {
if (wouldBeDifferent(pokedexEntityData, PokedexEntryProgress.ENCOUNTERED)) {
addInformation(pokedexEntityData, PokedexEntryProgress.ENCOUNTERED)
}
}
fun caught(pokemon: Pokemon) {
if (wouldBeDifferent(pokemon, PokedexEntryProgress.CAUGHT)) {
addInformation(pokemon, PokedexEntryProgress.CAUGHT)
@@ -108,6 +115,16 @@ class FormDexRecord {
speciesDexRecord.onFormRecordUpdated(this)
}
private fun addInformation(pokedexEntityData: PokedexEntityData, knowledge: PokedexEntryProgress) {
genders.add(pokedexEntityData.gender)
seenShinyStates.add(if (pokedexEntityData.shiny) "shiny" else "normal")
if (knowledge.ordinal > this.knowledge.ordinal) {
this.knowledge = knowledge
}
speciesDexRecord.addInformation(pokedexEntityData, knowledge)
speciesDexRecord.onFormRecordUpdated(this)
}
/** Returns whether the given [Pokemon] and [knowledge] would add new information to the Pokédex.*/
fun wouldBeDifferent(pokemon: Pokemon, knowledge: PokedexEntryProgress): Boolean {
return pokemon.gender !in genders
@@ -117,6 +134,14 @@ class FormDexRecord {
|| speciesDexRecord.wouldBeDifferent(pokemon)
}
fun wouldBeDifferent(pokedexEntityData: PokedexEntityData, knowledge: PokedexEntryProgress): Boolean {
return pokedexEntityData.gender !in genders
|| (pokedexEntityData.shiny && "shiny" !in seenShinyStates)
|| (!pokedexEntityData.shiny && "normal" !in seenShinyStates)
|| knowledge.ordinal > this.knowledge.ordinal
|| speciesDexRecord.wouldBeDifferent(pokedexEntityData)
}
fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeCollection(genders) { _, it -> buffer.writeEnumConstant(it) }
buffer.writeCollection(seenShinyStates) { _, it -> buffer.writeString(it) }
@@ -10,13 +10,11 @@ package com.cobblemon.mod.common.api.pokedex
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.storage.player.InstancedPlayerData
import com.cobblemon.mod.common.api.storage.player.PlayerInstancedDataStoreType
import com.cobblemon.mod.common.api.storage.player.PlayerInstancedDataStoreTypes
import com.cobblemon.mod.common.api.storage.player.client.ClientPokedexManager
import com.cobblemon.mod.common.net.messages.client.SetClientPlayerDataPacket
import com.cobblemon.mod.common.pokemon.FormData
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.Species
import com.cobblemon.mod.common.util.getPlayer
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.PrimitiveCodec
@@ -35,6 +33,12 @@ class PokedexManager(
getOrCreateSpeciesRecord(speciesId).getOrCreateFormRecord(formName).encountered(pokemon)
}
fun encounter(pokedexEntityData: PokedexEntityData) {
val speciesId = pokedexEntityData.species.resourceIdentifier
val formName = pokedexEntityData.form.name
getOrCreateSpeciesRecord(speciesId).getOrCreateFormRecord(formName).encountered(pokedexEntityData)
}
fun catch(pokemon: Pokemon) {
val speciesId = pokemon.species.resourceIdentifier
val formName = pokemon.form.name
@@ -49,6 +53,7 @@ class PokedexManager(
}
override fun onSpeciesRecordUpdated(speciesDexRecord: SpeciesDexRecord) {
super.onSpeciesRecordUpdated(speciesDexRecord)
uuid.getPlayer()?.sendPacket(
SetClientPlayerDataPacket(
type = PlayerInstancedDataStoreTypes.POKEDEX,
@@ -8,17 +8,29 @@
package com.cobblemon.mod.common.api.pokedex
import com.cobblemon.mod.common.api.pokedex.entry.DexEntries
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import net.minecraft.resources.ResourceLocation
/**
* Interface that serves for various calculations can be done around Pokédex. The output of these gets cached and invalidated when the Pokédex of a user updates.
* As opposed to the [GlobalPokedexValueCalculator] this interface is always called on a specific dex definition (e.g. galar, kanto)
*/
interface PokedexValueCalculator<T> {
fun calculate(dexManager: AbstractPokedexManager, dex: Map<ResourceLocation, PokedexEntry>): T
}
/**
* Interface that serves for various calculations can be done around Pokédex. The output of these gets cached and invalidated when the Pokédex of a user updates.
* The calculation of this interface is aimed to consider all available Pokédex entries and is not limited or filtered to a particular dex
*/
interface GlobalPokedexValueCalculator<T> {
fun calculate(dexManager: AbstractPokedexManager): T
}
/**
* Calculates the amount of caught Pokémon (globally or per dex)
*/
object CaughtCount : PokedexValueCalculator<Int>, GlobalPokedexValueCalculator<Int> {
override fun calculate(dexManager: AbstractPokedexManager): Int {
return dexManager.speciesRecords.values.count { it.getKnowledge() == PokedexEntryProgress.CAUGHT }
@@ -29,6 +41,9 @@ object CaughtCount : PokedexValueCalculator<Int>, GlobalPokedexValueCalculator<I
}
}
/**
* Calculates the amount of seen Pokémon (globally or per dex)
*/
object SeenCount : PokedexValueCalculator<Int>, GlobalPokedexValueCalculator<Int> {
override fun calculate(dexManager: AbstractPokedexManager): Int {
return dexManager.speciesRecords.values.count { it.getKnowledge() != PokedexEntryProgress.NONE }
@@ -37,4 +52,30 @@ object SeenCount : PokedexValueCalculator<Int>, GlobalPokedexValueCalculator<Int
override fun calculate(dexManager: AbstractPokedexManager, dex: Map<ResourceLocation, PokedexEntry>): Int {
return dex.entries.map { it.value }.count { dexManager.getKnowledgeForSpecies(it.speciesId) != PokedexEntryProgress.NONE }
}
}
/**
* Calculates the seen percentage globally or relative to a particular dex
*/
object SeenPercent : PokedexValueCalculator<Float>, GlobalPokedexValueCalculator<Float> {
override fun calculate(dexManager: AbstractPokedexManager): Float {
return dexManager.speciesRecords.values.count { it.getKnowledge() != PokedexEntryProgress.NONE }.toFloat() / DexEntries.entries.count().toFloat() * 100F
}
override fun calculate(dexManager: AbstractPokedexManager, dex: Map<ResourceLocation, PokedexEntry>): Float {
return dex.entries.map { it.value }.count { dexManager.getKnowledgeForSpecies(it.speciesId) != PokedexEntryProgress.NONE }.toFloat() / DexEntries.entries.count().toFloat() * 100F
}
}
/**
* Calculates the caught percentage globally or relative to a particular dex
*/
object CaughtPercent : PokedexValueCalculator<Float>, GlobalPokedexValueCalculator<Float> {
override fun calculate(dexManager: AbstractPokedexManager): Float {
return dexManager.speciesRecords.values.count { it.getKnowledge() == PokedexEntryProgress.CAUGHT }.toFloat() / DexEntries.entries.count().toFloat().toFloat() * 100F
}
override fun calculate(dexManager: AbstractPokedexManager, dex: Map<ResourceLocation, PokedexEntry>): Float {
return dex.entries.map { it.value }.count { dexManager.getKnowledgeForSpecies(it.speciesId) == PokedexEntryProgress.CAUGHT }.toFloat() / DexEntries.entries.count().toFloat().toFloat() * 100F
}
}
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.pokedex
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.readString
import com.cobblemon.mod.common.util.writeString
@@ -19,7 +20,6 @@ import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.ListCodec
import com.mojang.serialization.codecs.PrimitiveCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import java.util.UUID
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
@@ -90,6 +90,10 @@ class SpeciesDexRecord {
aspects.addAll(pokemon.aspects)
}
fun addInformation(pokedexEntityData: PokedexEntityData, knowledge: PokedexEntryProgress) {
aspects.addAll(pokedexEntityData.aspects)
}
fun addAspects(addedAspects: Set<String>) {
aspects.addAll(addedAspects)
}
@@ -97,6 +101,8 @@ class SpeciesDexRecord {
/** Returns true if the given Pokémon contains new information. Internal because it's only to be called from [FormDexRecord.wouldBeDifferent]. */
internal fun wouldBeDifferent(pokemon: Pokemon) = pokemon.aspects.any { it !in aspects }
internal fun wouldBeDifferent(pokedexEntityData: PokedexEntityData) = pokedexEntityData.aspects.any { it !in aspects }
fun getOrCreateFormRecord(formName: String): FormDexRecord {
return formRecords.getOrPut(formName.lowercase()) {
val record = FormDexRecord()
@@ -8,6 +8,8 @@
package com.cobblemon.mod.common.api.pokedex.filter
import com.cobblemon.mod.common.api.pokedex.AbstractPokedexManager
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
@@ -18,11 +20,11 @@ import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
* @since September 4th, 2024
* @param searchString The string to use when checking.
*/
class SearchFilter(val searchString: String) : EntryFilter() {
class SearchFilter(val pokedexManager: AbstractPokedexManager, val searchString: String) : EntryFilter() {
override fun test(entry: PokedexEntry): Boolean {
if (searchString == "") return true
val species = PokemonSpecies.getByIdentifier(entry.speciesId) ?: return false
if (pokedexManager.getHighestKnowledgeFor(entry) == PokedexEntryProgress.NONE) return false
return species.translatedName.string.contains(searchString.trim(), true)
}
@@ -49,7 +49,6 @@ import kotlin.random.Random
import net.minecraft.ResourceLocationException
import net.minecraft.commands.arguments.item.ItemParser
import net.minecraft.core.HolderLookup
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag
import net.minecraft.nbt.StringTag
@@ -505,6 +504,22 @@ open class PokemonProperties {
originalTrainer?.takeIf { it != pokemon.originalTrainer }?.let { return false }
originalTrainerType?.takeIf { it != pokemon.originalTrainerType }?.let { return false }
moves?.takeIf { it.any { move -> pokemon.moveSet.none { it.template.name == move } } }?.let { return false }
heldItem?.takeIf { itemKey ->
val server = server() ?: return@takeIf true
val parser = ItemParser(server.registryAccess())
val result = parser.parse(StringReader(itemKey))
if (!pokemon.heldItem.`is`(result.item)) return@takeIf true
for (entry in result.components.entrySet()) {
val targetPropValue = pokemon.heldItem.get(entry.key)
if (targetPropValue != entry.value.get()) {
return@takeIf true
}
}
return@takeIf false
}?.let { return false }
return true
}
@@ -31,6 +31,7 @@ import com.cobblemon.mod.common.pokemon.evolution.variants.LevelUpEvolution
import com.cobblemon.mod.common.pokemon.evolution.variants.TradeEvolution
import com.cobblemon.mod.common.util.lang
import com.cobblemon.mod.common.util.party
import net.minecraft.client.Minecraft
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.network.protocol.game.ClientboundSoundPacket
import net.minecraft.sounds.SoundSource
@@ -154,10 +155,13 @@ interface Evolution : EvolutionLike {
pokemon.tryRecallWithAnimation()
}
val preEvoName = pokemon.getDisplayName()
val evolveMessage = lang("ui.evolve.into", preEvoName, pokemon.species.translatedName)
val pokemonEntity = pokemon.entity
if (pokemonEntity == null || !useEvolutionEffect) {
pokemon.getOwnerPlayer()?.playNotifySound(CobblemonSounds.EVOLUTION_UI, SoundSource.PLAYERS, 1F, 1F)
evolutionMethod(pokemon)
pokemon.getOwnerPlayer()?.sendSystemMessage(evolveMessage)
} else {
pokemonEntity.busyLocks.add("evolving")
pokemonEntity.navigation.stop()
@@ -170,6 +174,7 @@ interface Evolution : EvolutionLike {
pokemonEntity.after( seconds = 12F ) {
cryAnimation(pokemonEntity)
pokemonEntity.busyLocks.remove("evolving")
pokemon.getOwnerPlayer()?.sendSystemMessage(evolveMessage)
}
}
}
@@ -10,6 +10,10 @@ package com.cobblemon.mod.common.api.spawning.fishing
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.Cobblemon.LOGGER
import com.cobblemon.mod.common.api.Priority
import com.cobblemon.mod.common.api.abilities.Abilities
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.fishing.BobberSpawnPokemonEvent
import com.cobblemon.mod.common.api.fishing.FishingBait
import com.cobblemon.mod.common.api.pokemon.Natures
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
@@ -26,9 +30,9 @@ import com.cobblemon.mod.common.item.interactive.PokerodItem
import com.cobblemon.mod.common.pokemon.Gender
import com.cobblemon.mod.common.pokemon.abilities.HiddenAbility
import com.cobblemon.mod.common.util.cobblemonResource
import kotlin.random.Random.Default.nextInt
import net.minecraft.world.entity.Entity
import net.minecraft.world.item.ItemStack
import kotlin.random.Random.Default.nextInt
/**
* A spawning cause that is embellished with fishing information. Could probably also
@@ -45,6 +49,95 @@ class FishingSpawnCause(
) : SpawnCause(spawner, bucket, entity) {
companion object {
const val FISHED_ASPECT = "fished"
fun shinyReroll(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
if (pokemonEntity.pokemon.shiny) return
val shinyOdds = Cobblemon.config.shinyRate.toInt()
if (shinyOdds <= 0) {
return
}
val randomNumber = nextInt(0, shinyOdds + 1)
if (randomNumber <= effect.value.toInt()) {
pokemonEntity.pokemon.shiny = true
}
}
fun alterNatureAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
val baitStat = effect.subcategory?.let { it1 -> Stats.getStat(it1.path).identifier } ?: run {
LOGGER.warn("One of your nature baits is missing a subcategory and failed to effect a fished Pokemon")
return
}
// TIMNOTE: This replaces the static lists. It's less performant because it's being reviewed every time,
// but also it's not something that goes off too often.
val possibleNatures = Natures.all().filter { it.increasedStat?.identifier == baitStat }
if (possibleNatures.isEmpty() || possibleNatures.any { it == pokemonEntity.pokemon.nature }) return
val takenNature = possibleNatures.random()
pokemonEntity.pokemon.nature = Natures.getNature(takenNature.name.path) ?: return
}
fun alterIVAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
val iv = effect.subcategory ?: return
if ((pokemonEntity.pokemon.ivs[Stats.getStat(iv.path)] ?: 0) + effect.value > 31) // if HP IV is already less than 3 away from 31
pokemonEntity.pokemon.ivs.set(Stats.getStat(iv.path), 31)
else
pokemonEntity.pokemon.ivs.set(Stats.getStat(iv.path), (pokemonEntity.pokemon.ivs[Stats.getStat(iv.path)] ?: 0) + (effect.value).toInt())
}
fun alterGenderAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
if (pokemonEntity.pokemon.species.maleRatio > 0 && pokemonEntity.pokemon.species.maleRatio < 1) // if the pokemon is allowed to be male or female
when (effect.subcategory) {
cobblemonResource("male") -> if (pokemonEntity.pokemon.gender != Gender.MALE) pokemonEntity.pokemon.gender = Gender.MALE
cobblemonResource("female") -> if (pokemonEntity.pokemon.gender != Gender.FEMALE) pokemonEntity.pokemon.gender = Gender.FEMALE
}
}
fun alterLevelAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
var level = pokemonEntity.pokemon.level + effect.value.toInt()
if (level > Cobblemon.config.maxPokemonLevel)
level = Cobblemon.config.maxPokemonLevel
pokemonEntity.pokemon.level = level
}
fun alterTeraAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
if (pokemonEntity.pokemon.teraType == effect.subcategory?.let { TeraTypes.get(it.path) } ||
TeraTypes.get(effect.subcategory!!.path) == null) return
pokemonEntity.pokemon.teraType = TeraTypes.get(effect.subcategory.path)!!
}
fun alterHAAttempt(pokemonEntity: PokemonEntity) {
//val species = pokemonEntity.pokemon.species.let { PokemonSpecies.getByName(it.name) } ?: return
//val ability = species.abilities.mapping[Priority.LOW]?.first()?.template?.name ?: return
//pokemonEntity.pokemon.ability = Abilities.get(ability)?.create(false) ?: return
// Old code from Licious that might be helpful if the above proves to not work
// This will iterate from highest to lowest priority
pokemonEntity.pokemon.form.abilities.mapping.values.forEach { abilities ->
abilities.filterIsInstance<HiddenAbility>()
.randomOrNull ()
?.let { ability ->
// No need to force, this is legal
pokemonEntity.pokemon.ability = ability.template.create(false)
return
}
}
// There was never a hidden ability :( possible but not by default
return
}
fun alterFriendshipAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
if (pokemonEntity.pokemon.friendship + effect.value > 255)
pokemonEntity.pokemon.setFriendship(255)
else
pokemonEntity.pokemon.setFriendship(pokemonEntity.pokemon.friendship + effect.value.toInt())
}
}
val rodItem = rodStack.item as? PokerodItem
@@ -57,16 +150,7 @@ class FishingSpawnCause(
bait?.effects?.forEach { it ->
if (Math.random() > it.chance) return
when (it.type) {
FishingBait.Effects.SHINY_REROLL -> shinyReroll(entity, it)
FishingBait.Effects.NATURE -> alterNatureAttempt(entity, it)
FishingBait.Effects.IV -> alterIVAttempt(entity, it)
FishingBait.Effects.GENDER_CHANCE -> alterGenderAttempt(entity, it)
FishingBait.Effects.LEVEL_RAISE -> alterLevelAttempt(entity, it)
FishingBait.Effects.TERA -> alterTeraAttempt(entity, it)
FishingBait.Effects.HIDDEN_ABILITY_CHANCE -> alterHAAttempt(entity)
FishingBait.Effects.FRIENDSHIP -> alterFriendshipAttempt(entity, it)
}
FishingBait.Effects.getEffectFunction(it.type)?.invoke(entity, it)
}
// Some of the bait actions might have changed the aspects and we need it to be
@@ -74,6 +158,7 @@ class FishingSpawnCause(
// with the old aspects.
// New aspects copy into the entity data only on the next tick.
entity.entityData.set(PokemonEntity.ASPECTS, entity.pokemon.aspects)
CobblemonEvents.BOBBER_SPAWN_POKEMON_MODIFY.post(BobberSpawnPokemonEvent.Modify(bucket, rodStack, entity))
}
}
@@ -97,93 +182,5 @@ class FishingSpawnCause(
return super.affectWeight(detail, ctx, weight)
}
private fun shinyReroll(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
if (pokemonEntity.pokemon.shiny) return
val shinyOdds = Cobblemon.config.shinyRate.toInt()
if (shinyOdds <= 0) {
return
}
val randomNumber = nextInt(0, shinyOdds + 1)
if (randomNumber <= effect.value.toInt()) {
pokemonEntity.pokemon.shiny = true
}
}
private fun alterNatureAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
val baitStat = effect.subcategory?.let { it1 -> Stats.getStat(it1.path).identifier } ?: run {
LOGGER.warn("One of your nature baits is missing a subcategory and failed to effect a fished Pokemon")
return
}
// TIMNOTE: This replaces the static lists. It's less performant because it's being reviewed every time,
// but also it's not something that goes off too often.
val possibleNatures = Natures.all().filter { it.increasedStat?.identifier == baitStat }
if (possibleNatures.isEmpty() || possibleNatures.any { it == pokemonEntity.pokemon.nature }) return
val takenNature = possibleNatures.random()
pokemonEntity.pokemon.nature = Natures.getNature(takenNature.name.path) ?: return
}
private fun alterIVAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
val iv = effect.subcategory ?: return
if ((pokemonEntity.pokemon.ivs[Stats.getStat(iv.path)] ?: 0) + effect.value > 31) // if HP IV is already less than 3 away from 31
pokemonEntity.pokemon.ivs.set(Stats.getStat(iv.path), 31)
else
pokemonEntity.pokemon.ivs.set(Stats.getStat(iv.path), (pokemonEntity.pokemon.ivs[Stats.getStat(iv.path)] ?: 0) + (effect.value).toInt())
}
private fun alterGenderAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
if (pokemonEntity.pokemon.species.maleRatio > 0 && pokemonEntity.pokemon.species.maleRatio < 1) // if the pokemon is allowed to be male or female
when (effect.subcategory) {
cobblemonResource("male") -> if (pokemonEntity.pokemon.gender != Gender.MALE) pokemonEntity.pokemon.gender = Gender.MALE
cobblemonResource("female") -> if (pokemonEntity.pokemon.gender != Gender.FEMALE) pokemonEntity.pokemon.gender = Gender.FEMALE
}
}
private fun alterLevelAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
var level = pokemonEntity.pokemon.level + effect.value.toInt()
if (level > Cobblemon.config.maxPokemonLevel)
level = Cobblemon.config.maxPokemonLevel
pokemonEntity.pokemon.level = level
}
private fun alterTeraAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
if (pokemonEntity.pokemon.teraType == effect.subcategory?.let { TeraTypes.get(it.path) } ||
TeraTypes.get(effect.subcategory!!.path) == null) return
pokemonEntity.pokemon.teraType = TeraTypes.get(effect.subcategory.path)!!
}
private fun alterHAAttempt(pokemonEntity: PokemonEntity) {
//val species = pokemonEntity.pokemon.species.let { PokemonSpecies.getByName(it.name) } ?: return
//val ability = species.abilities.mapping[Priority.LOW]?.first()?.template?.name ?: return
//pokemonEntity.pokemon.ability = Abilities.get(ability)?.create(false) ?: return
// Old code from Licious that might be helpful if the above proves to not work
// This will iterate from highest to lowest priority
pokemonEntity.pokemon.form.abilities.mapping.values.forEach { abilities ->
abilities.filterIsInstance<HiddenAbility>()
.randomOrNull ()
?.let { ability ->
// No need to force, this is legal
pokemonEntity.pokemon.ability = ability.template.create(false)
return
}
}
// There was never a hidden ability :( possible but not by default
return
}
private fun alterFriendshipAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
if (pokemonEntity.pokemon.friendship + effect.value > 255)
pokemonEntity.pokemon.setFriendship(255)
else
pokemonEntity.pokemon.setFriendship(pokemonEntity.pokemon.friendship + effect.value.toInt())
}
}
@@ -9,9 +9,11 @@
package com.cobblemon.mod.common.battles
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
import com.cobblemon.mod.common.api.storage.party.PartyStore
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore
import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
@@ -31,7 +33,6 @@ import net.minecraft.network.chat.MutableComponent
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.Entity
import net.minecraft.world.phys.Vec3
import java.util.*
import kotlin.collections.HashMap
import kotlin.collections.Iterable
import kotlin.collections.MutableSet
@@ -60,8 +61,30 @@ object BattleBuilder {
healFirst: Boolean = false,
partyAccessor: (ServerPlayer) -> PartyStore = { it.party() }
): BattleStartResult {
val team1 = partyAccessor(player1).toBattleTeam(clone = cloneParties, healPokemon = healFirst, leadingPokemonPlayer1).sortedBy { it.health <= 0 }
val team2 = partyAccessor(player2).toBattleTeam(clone = cloneParties, healPokemon = healFirst, leadingPokemonPlayer2).sortedBy { it.health <= 0 }
val adjustLevel = battleFormat.adjustLevel
val team1 = partyAccessor(player1).toBattleTeam(clone = cloneParties || adjustLevel > 0, healPokemon = healFirst, leadingPokemonPlayer1).sortedBy { it.health <= 0 }
val team2 = partyAccessor(player2).toBattleTeam(clone = cloneParties || adjustLevel > 0, healPokemon = healFirst, leadingPokemonPlayer2).sortedBy { it.health <= 0 }
val battlePartyStores = mutableListOf<PlayerPartyStore>()
if (adjustLevel > 0) {
val tempStoreP1 = PlayerPartyStore(player1.uuid)
team1.forEachIndexed { index, it ->
it.effectedPokemon.level = adjustLevel
it.effectedPokemon.heal()
tempStoreP1.set(index, it.effectedPokemon)
}
battlePartyStores.add(tempStoreP1)
val tempStoreP2 = PlayerPartyStore(player2.uuid)
team2.forEachIndexed { index, it ->
it.effectedPokemon.level = adjustLevel
it.effectedPokemon.heal()
tempStoreP2.set(index, it.effectedPokemon)
}
battlePartyStores.add(tempStoreP2)
}
val player1Actor = PlayerBattleActor(player1.uuid, team1)
val player2Actor = PlayerBattleActor(player2.uuid, team2)
@@ -91,6 +114,7 @@ object BattleBuilder {
).ifSuccessful {
player1Actor.battleTheme = player2.getBattleTheme()
player2Actor.battleTheme = player1.getBattleTheme()
it.battlePartyStores.addAll(battlePartyStores)
result = SuccessfulBattleStart(it)
}
result
@@ -117,6 +141,20 @@ object BattleBuilder {
}
val playerActors = teams.mapIndexed { index, team -> PlayerBattleActor(players[index].uuid, team)}.toMutableList()
val adjustLevel = battleFormat.adjustLevel
val battlePartyStores = mutableListOf<PlayerPartyStore>()
if (adjustLevel > 0) {
teams.forEachIndexed { index, battleTeam ->
battleTeam.forEach { battlePokemon ->
battlePokemon.effectedPokemon.level = adjustLevel
battlePokemon.effectedPokemon.heal()
val tempStore = PlayerPartyStore(players[index].uuid)
battlePartyStores.add(tempStore)
}
}
}
val errors = ErroredBattleStart()
if (players.size != BattleRegistry.MAX_TEAM_MEMBER_COUNT * 2) {
@@ -169,6 +207,8 @@ object BattleBuilder {
playerActors[2].battleTheme = players[0].getBattleTheme()
playerActors[3].battleTheme = players[0].getBattleTheme()
it.battlePartyStores.addAll(battlePartyStores)
}
errors
} else {
@@ -272,7 +312,6 @@ object BattleBuilder {
): BattleStartResult {
val playerTeam = party.toBattleTeam(clone = cloneParties, healPokemon = healFirst, leadingPokemon = leadingPokemon)
val playerActor = PlayerBattleActor(player.uuid, playerTeam)
val npcParty = npcEntity.party?.getParty(player, npcEntity)
val errors = ErroredBattleStart()
@@ -313,8 +352,7 @@ object BattleBuilder {
side1 = BattleSide(playerActor),
side2 = BattleSide(npcActor)
).ifSuccessful { battle ->
// TODO NPC battle themes
// playerActor.battleTheme = pokemonEntity.getBattleTheme()
playerActor.battleTheme = npcEntity.getBattleTheme()
npcEntity.entityData.update(NPCEntity.BATTLE_IDS) { it + battle.battleId }
result = SuccessfulBattleStart(battle)
}
@@ -24,8 +24,9 @@ import net.minecraft.network.RegistryFriendlyByteBuf
data class BattleFormat(
val mod: String = "cobblemon",
val battleType: BattleType = BattleTypes.SINGLES,
val ruleSet: Set<String> = setOf(),
val gen: Int = 9
var ruleSet: Set<String> = setOf(),
val gen: Int = 9,
var adjustLevel: Int = -1, // Stop gap rule before a more general system for rules enforced by Cobblemon is implemented.
) {
companion object {
val GEN_9_SINGLES = BattleFormat(
@@ -49,8 +50,8 @@ data class BattleFormat(
)
val GEN_9_ROYAL = BattleFormat(
battleType = BattleTypes.ROYAL,
ruleSet = mutableSetOf(BattleRules.OBTAINABLE, BattleRules.PAST, BattleRules.UNOBTAINABLE)
battleType = BattleTypes.ROYAL,
ruleSet = mutableSetOf(BattleRules.OBTAINABLE, BattleRules.PAST, BattleRules.UNOBTAINABLE)
)
fun loadFromBuffer(buffer: RegistryFriendlyByteBuf): BattleFormat {
@@ -58,10 +59,12 @@ data class BattleFormat(
val battleType = BattleType.loadFromBuffer(buffer)
val ruleSet = mutableSetOf<String>()
repeat(times = buffer.readSizedInt(IntSize.U_BYTE)) { ruleSet.add(buffer.readString()) }
val adjustLevel = buffer.readSizedInt(IntSize.INT)
return BattleFormat(
mod = mod,
battleType = battleType,
ruleSet = ruleSet
ruleSet = ruleSet,
adjustLevel = adjustLevel
)
}
}
@@ -71,6 +74,7 @@ data class BattleFormat(
battleType.saveToBuffer(buffer)
buffer.writeSizedInt(IntSize.U_BYTE, ruleSet.size)
ruleSet.forEach(buffer::writeString)
buffer.writeSizedInt(IntSize.INT, adjustLevel)
return buffer
}
@@ -68,6 +68,7 @@ object ShowdownInterpreter {
updateInstructionParser["cant"] = { _, _, message, _ -> CantInstruction(message) }
updateInstructionParser["-clearallboost"] = { _, _, message, _ -> ClearAllBoostInstruction(message) }
updateInstructionParser["-clearnegativeboost"] = { _, _, message, _ -> ClearNegativeBoostInstruction(message) }
updateInstructionParser["-clearboost"] = { _, _, message, _ -> ClearBoostInstruction(message) }
updateInstructionParser["-copyboost"] = { _, _, message, _ -> CopyBoostInstruction(message) }
updateInstructionParser["-crit"] = { _, instructionSet, message, _ -> CritInstruction(message, instructionSet) }
updateInstructionParser["-curestatus"] = { _, _, message, _ -> CureStatusInstruction(message) }
@@ -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.battles.interpreter.instructions
import com.cobblemon.mod.common.api.battles.interpreter.BattleContext
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
import com.cobblemon.mod.common.util.battleLang
/**
* Format: |-clearboost|POKEMON
*
* Clear the boosts from the target POKEMON.
* @author Yaseen
* @since October 26th, 2024
*/
class ClearBoostInstruction(val message: BattleMessage): InterpreterInstruction {
override fun invoke(battle: PokemonBattle) {
val battlePokemon = message.battlePokemon(0, battle) ?: return
battle.dispatchWaiting(1.5F) {
val pokemonName = battlePokemon.getName()
val lang = battleLang("clearboost", pokemonName)
battle.broadcastChatMessage(lang)
battlePokemon.contextManager.clear(BattleContext.Type.BOOST, BattleContext.Type.UNBOOST)
battle.minorBattleActions[battlePokemon.uuid] = message
}
}
}
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
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.UsersProvider
import com.cobblemon.mod.common.api.pokemon.status.Statuses
import com.cobblemon.mod.common.api.text.red
@@ -28,6 +29,7 @@ import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacke
import com.cobblemon.mod.common.pokemon.evolution.progress.DamageTakenEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.progress.RecoilEvolutionProgress
import com.cobblemon.mod.common.pokemon.status.statuses.persistent.PoisonStatus
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.lang
@@ -100,7 +102,12 @@ class DamageInstruction(
if (status is PoisonStatus) {
status = pokemon.effectedPokemon.status?.status ?: status
}
val actionEffect = status?.getActionEffect() ?: return@dispatch GO
// Damage effects without a action effect receive the generic damage effect
val actionEffect = status?.getActionEffect() ?: effect?.let {
ActionEffects.actionEffects["generic_damage".asIdentifierDefaultingNamespace()]
} ?: return@dispatch GO
val providers = mutableListOf<Any>(battle)
battlePokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
@@ -137,16 +144,6 @@ class DamageInstruction(
distance = 50.0
)
}
//Play hit particle
if (pokemonEntity != null) {
RunPosableMoLangPacket(pokemonEntity.id, setOf("q.particle('cobblemon:hit', 'target')")).sendToPlayersAround(
x = pokemonEntity.x,
y = pokemonEntity.y,
z = pokemonEntity.z,
worldKey = pokemonEntity.level().dimension(),
distance = 50.0
)
}
val newHealthRatio: Float
val remainingHealth = newHealth.split("/")[0].toInt()
@@ -38,7 +38,7 @@ class InitializeInstruction(val instructionSet: InstructionSet, val message: Bat
pokemon.entity?.let {
// If a Pokémon entity is being recalled with an animation,
// wrap up the animation and recall the Pokémon immediately.
if (it.beamMode == 3) {
if (it.beamMode == 3 && battle.battlePartyStores.isEmpty()) {
pokemon.effectedPokemon.recall()
}
// If already on the field, initialize for the BattleInitializePacket
@@ -10,6 +10,8 @@ package com.cobblemon.mod.common.battles.interpreter.instructions
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.battles.instruction.MegaEvolutionEvent
import com.cobblemon.mod.common.api.text.yellow
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
import com.cobblemon.mod.common.util.battleLang
@@ -28,6 +30,7 @@ class MegaInstruction(val message: BattleMessage): InterpreterInstruction {
battle.dispatchWaiting {
val pokemonName = battlePokemon.getName()
battle.broadcastChatMessage(battleLang("mega", pokemonName).yellow())
CobblemonEvents.MEGA_EVOLUTON.post(MegaEvolutionEvent(battle, battlePokemon))
battle.minorBattleActions[battlePokemon.uuid] = message
}
}
@@ -9,11 +9,16 @@
package com.cobblemon.mod.common.battles.interpreter.instructions
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
import com.cobblemon.mod.common.api.battles.interpreter.Effect
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addEntityFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addPokemonEntityFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addPokemonFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.moves.Moves
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
@@ -26,9 +31,14 @@ import com.cobblemon.mod.common.battles.dispatch.InstructionSet
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
import com.cobblemon.mod.common.battles.dispatch.UntilDispatch
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.net.messages.client.battle.BattleAppendTargetedEntityPacket
import com.cobblemon.mod.common.pokemon.evolution.progress.UseMoveEvolutionProgress
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.ai.targeting.TargetingConditions
import net.minecraft.world.phys.AABB
import java.util.concurrent.CompletableFuture
/**
@@ -97,6 +107,13 @@ class MoveInstruction(
val runtime = MoLangRuntime().also {
battle.addQueryFunctions(it.environment.query).addStandardFunctions()
}
userPokemon.effectedPokemon.entity?.let {
val queryStruct = QueryStruct(hashMapOf())
queryStruct.addEntityFunctions(it)
queryStruct.addPokemonEntityFunctions(it)
queryStruct.addPokemonFunctions(it.pokemon)
runtime.environment.variable.setDirectly("user", queryStruct)
}
actionEffect ?: return@dispatch GO
val context = ActionEffectContext(
@@ -130,6 +147,17 @@ class MoveInstruction(
runtime.environment.query.addFunction("move") { move.struct }
runtime.environment.query.addFunction("instruction_id") { StringValue(cobblemonResource("move").toString()) }
if (userPokemon.entity != null && targetPokemon?.entity != null) {
//Not the most elegant solution, maybe we should just make the targeted entity a piece of SyncedData
val serverLevel = userPokemon.entity!!.level() as? ServerLevel
serverLevel?.getNearbyPlayers(
TargetingConditions.forNonCombat(),
userPokemon.entity!!,
AABB.ofSize(userPokemon.entity!!.position(), 128.0, 128.0, 128.0)
)?.mapNotNull { it as? ServerPlayer }?.forEach { it.sendPacket(BattleAppendTargetedEntityPacket(userPokemon.entity!!.id, targetPokemon.entity!!.id)) }
battle.sendUpdate(BattleAppendTargetedEntityPacket(userPokemon.entity!!.id, targetPokemon.entity!!.id))
}
this.future = actionEffect.run(context)
holds = context.holds // Reference so future things can check on this action effect's holds
future.thenApply { holds.clear() }
@@ -25,6 +25,8 @@ import com.cobblemon.mod.common.net.serverhandling.storage.SendOutPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.storage.SendOutPokemonHandler.SEND_OUT_STAGGER_BASE_DURATION
import com.cobblemon.mod.common.net.serverhandling.storage.SendOutPokemonHandler.SEND_OUT_STAGGER_RANDOM_MAX_DURATION
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.getPlayer
import com.cobblemon.mod.common.util.party
import com.cobblemon.mod.common.util.swap
import java.util.concurrent.CompletableFuture
import kotlin.random.Random
@@ -89,6 +91,28 @@ class SwitchInstruction(val instructionSet: InstructionSet, val battleActor: Bat
}
GO
}
val futureSwitches = instructionSet.getSubsequentInstructions(this).filterIsInstance<SwitchInstruction>()
if (futureSwitches.isEmpty()) {
if (battle.format.adjustLevel > 0) {
// means battle is using clone teams, recall the "real" pokemon before the sendouts occur
var waitOnRecall = false
battle.actors.forEach { it ->
val playerUUIDS = it.getPlayerUUIDs()
playerUUIDS.forEach { uuid ->
uuid.getPlayer()?.party()?.forEach { pokemon ->
if (pokemon.entity != null) {
waitOnRecall = true
pokemon.entity!!.recallWithAnimation()
}
}
}
}
if (waitOnRecall) {
battle.dispatchWaitingToFront(SEND_OUT_DURATION) { }
}
}
}
}
else {
battle.dispatchInsert {
@@ -10,8 +10,9 @@ package com.cobblemon.mod.common.battles.interpreter.instructions
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.battles.instruction.TerastallizationEvent
import com.cobblemon.mod.common.api.text.yellow
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.api.types.tera.TeraTypes
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
import com.cobblemon.mod.common.util.battleLang
@@ -31,6 +32,7 @@ class TerastallizeInstruction(val message: BattleMessage): InterpreterInstructio
battle.dispatchWaiting {
val pokemonName = battlePokemon.getName()
battle.broadcastChatMessage(battleLang("terastallize", pokemonName, type.displayName).yellow())
CobblemonEvents.TERASTALLIZATION.post(TerastallizationEvent(battle, battlePokemon, type))
battle.minorBattleActions[battlePokemon.uuid] = message
}
}

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