Compare commits

...
Author SHA1 Message Date
Waldleufer fde8a03c5f more cleanup [skip-ci] 2024-06-18 19:31:29 +02:00
Waldleufer df273a0075 cleanup [skip-ci] 2024-06-18 19:25:39 +02:00
Hiroku f6124d7474 Merge branch 'initiate_battle_while_recalling_bugfix' into 'main'
Fixes issue #872

Closes #872

See merge request cable-mc/cobblemon!1072
2024-06-16 08:07:16 +00:00
Notepadccino a0300ccd18 Update CHANGELOG.md 2024-06-16 08:05:22 +00:00
notepadccino 486056d7f0 Fixes issue #872 2024-06-14 16:52:12 +02:00
Hiroku 03ca6a4396 Merge branch 'tmetcalfe89/fix-energy-root-reviving' into 'main'
fixed energy root reviving

See merge request cable-mc/cobblemon!1065
2024-06-14 04:13:20 +00:00
Hiroku b2d26abc4b Merge branch 'Fixes901' into 'main'
Fix For 901

Closes #901

See merge request cable-mc/cobblemon!1069
2024-06-14 00:32:08 +00:00
JazzMcNade ebb677cc9c Don't read the current hp until you've fully calculated the max hp 2024-06-09 14:53:28 -05:00
Licious f181aabb3c Merge branch 'fix-898' into 'main'
Fix lack of side check when instancing Pokemon on PokemonEntity

Closes #898

See merge request cable-mc/cobblemon!1068
2024-06-09 17:43:34 +00:00
Licious 4df5e987c7 Fix lack of side check when instancing Pokemon on PokemonEntity 2024-06-09 17:43:33 +00:00
tmetcalfe89 3026e5c66f changelog 2024-06-09 10:39:43 -07:00
tmetcalfe89 f2310d8979 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into tmetcalfe89/fix-energy-root-reviving 2024-06-09 10:39:22 -07:00
Hiroku 65971386f2 Merge branch 'Myslippy-main-patch-82434' into 'main'
Update CHANGELOG.md

See merge request cable-mc/cobblemon!1062
2024-06-08 21:27:17 +00:00
tmetcalfe89 5b52fe5479 fixed energy root reviving 2024-06-07 08:08:19 -07:00
Hiroku 13ca5871cb Merge branch 'corals_restoration_tank_bugfix' into 'main'
Fix issue #892

Closes #892

See merge request cable-mc/cobblemon!1064
2024-06-05 21:48:10 +00:00
notepadccino 54ba99a002 Fix issue #892
The #minecraft:corals tag seems to apply to blocks, not to items. For items you'd either need to trace back the tags of whichever block is placed by the item, or just specify the items one by one. I went with the simpler option, but if needed the former solution can always be implemented.
2024-06-05 19:11:08 +02:00
Myslippy b40f47b00d Update CHANGELOG.md 2024-06-03 03:00:34 +00:00
Hiroku 800d348611 Merge branch 'mushroom_restoration_fabric_fix' into 'main'
Fix #890

Closes #890

See merge request cable-mc/cobblemon!1059
2024-06-03 00:04:49 +00:00
Hiroku d4dd48b3ff Merge branch 'implement_pokemon' into 'main'
5 new cries + bugfix

See merge request cable-mc/cobblemon!1061
2024-06-02 23:31:48 +00:00
Sterrezo 89d6bb2356 Merge branch 'main' into implement_pokemon 2024-06-02 21:48:03 +02:00
notepadccino 3a65425015 Fix mushroom tag issue
the #minecraft:mushrooms tag is a forge thing, it doesn't exist in fabric.
However I've tested out corals as well and they don't work either which is odd, since they should have a #minecraft:corals tag
2024-06-02 18:21:47 +02:00
Apion fad10da89f Merge branch 'forcespawn_cmd_fix' into 'main'
Fixes #877

Closes #877

See merge request cable-mc/cobblemon!1056
2024-06-01 15:19:06 +00:00
notepadccino 055ce8168c Fixes #877 2024-06-01 15:42:21 +02:00
Hiroku e4da05fd50 we are snapshotting thx 2024-06-01 00:24:30 +00:00
Paul 3a17a88ea2 Changelog stuff [skip-ci] 2024-06-01 09:38:50 +10:00
Hiroku 09abf30421 Merge branch 'no-middle-stage-ha-fix' into 'main'
Hidden Ability slot for cocoons.

See merge request cable-mc/cobblemon!1020
2024-05-31 23:38:18 +00:00
Hiroku 06ea4b4cec Merge branch 'berry-changes' into 'main'
Berry changes

See merge request cable-mc/cobblemon!1030
2024-05-31 23:35:59 +00:00
Hiroku 8799308800 Merge branch 'Frank's-Coding-Farm' into 'main'
Enabled Seafloor spawns & Disabled spawning in slabs

See merge request cable-mc/cobblemon!1040
2024-05-31 23:35:24 +00:00
Frank The FarmerandHiroku d727fde5b3 Enabled Seafloor spawns & Disabled spawning in slabs 2024-05-31 23:35:24 +00:00
Hiroku ce5e93b552 Merge branch 'main' into 'main'
Fixes #878

Closes #878

See merge request cable-mc/cobblemon!1052
2024-05-31 23:34:39 +00:00
Hiroku 77c0138c09 Merge branch 'get-sticked' into 'main'
Leeks are Sticks (visually)

See merge request cable-mc/cobblemon!1054
2024-05-31 23:34:25 +00:00
Sterrezo 0ded29dcad Added cries to Timburr and Golett lines. Updated the changelog with a recent Cubone sound fix. 2024-05-31 14:06:02 +02:00
Sterrezo 62fae979eb Merge branch 'main' into implement_pokemon 2024-05-31 13:40:42 +02:00
dhi_holo dc727fe56d Leeks are Sticks (visually)
Medicinal and Roasted Leeks now reference a new display setting, making them held like sticks/rods.

That's it, that's the entire change, it's a small parity thing, this is what I like doing, okay.
2024-05-31 10:19:06 +10:00
Apion 4db36ef6fa Merge branch 'tmetcalfe89/abstract-shedding' into 'main'
abstracted shedinja logic for datapackability

See merge request cable-mc/cobblemon!1014
2024-05-30 04:02:21 +00:00
Timothy MetcalfeandApion e350d920b5 abstracted shedinja logic for datapackability 2024-05-30 04:02:21 +00:00
Apion 2a0ae1a466 Merge branch 'tumbled-bricks' into 'main'
Tumbled Blocks and Bricks

See merge request cable-mc/cobblemon!1051
2024-05-30 02:58:57 +00:00
dhi_holoandApion 3b8f7f23a3 Tumbled Blocks and Bricks 2024-05-30 02:58:57 +00:00
apion 72cf161f0d Merge branch 'refs/heads/main' into berry-changes
# Conflicts:
#	CHANGELOG.md
2024-05-29 22:24:12 -04:00
apion fe3d8d3185 Changed CHANGELOG.md merge strategy 2024-05-29 22:06:53 -04:00
apion d04ed7a519 Add empty headers to CHANGELOG.md 2024-05-29 21:51:57 -04:00
Apion e6e9137cb5 Merge branch 'AmauraFetusClippingFix' into 'main'
Amaura fetus clipping fix

Closes #873

See merge request cable-mc/cobblemon!1053
2024-05-30 00:49:20 +00:00
JazzMcNade 78f25b3f8b Corrected typo in changelog 2024-05-28 17:25:08 -05:00
JazzMcNade 631293e0cd UpdatedChangelog 2024-05-28 17:10:20 -05:00
JazzMcNade 2865b8140a Scaled down Amaura's fetus model to avoid clipping through the tank while animating 2024-05-28 17:07:46 -05:00
notepadccino be34bc4c74 Fixes #878 2024-05-28 19:12:21 +02:00
Sterrezo bae26162dd Update cubone.animation.json 2024-05-28 12:09:35 +02:00
Paul df8f078d13 Fixed Wooloo Dubwool issues and fixed sync issues with Gimmighoul 2024-05-27 15:39:21 +10:00
Paul 309b223da9 Changelog update 4 [skip-ci] 2024-05-27 11:53:03 +10:00
Paul 75f688fa30 Changelog update 3 [skip-ci] 2024-05-27 11:48:22 +10:00
Paul d7fadd58ed Changelog update 2 [skip-ci] 2024-05-27 11:42:56 +10:00
Paul 996c7189b6 Changelog update [skip-ci] 2024-05-27 11:31:38 +10:00
Paul e1d5f07aed Fixed root part animations on JSON posers, clean up changelog, no snapshot, remove bubblebeam effect for now 2024-05-27 11:14:05 +10:00
Paul 6afe77ef0c Fixed confusion particle timing 2024-05-27 10:23:00 +10:00
Hiroku bf54f28b58 Merge branch 'move-effects' into 'main'
A bunch of particles, now with sound!

See merge request cable-mc/cobblemon!1049
2024-05-27 00:08:36 +00:00
Paul aac10e967f Reverted protect change to camera mode 2024-05-27 10:06:39 +10:00
Sterrezo 0cd9da80d7 Update sounds.json 2024-05-27 02:06:27 +02:00
Sterrezo d33f1150d2 Adjusted assets for powder moves, protect, swords dance and thunder wave. Rebalanced volumes of all moves. 2024-05-27 01:39:41 +02:00
Hiroku 216ed85da1 Merge branch 'IllusionThrownPokeballRevealFix' into 'main'
IllusionThrownPokeballRevealFix

See merge request cable-mc/cobblemon!1046
2024-05-26 23:35:07 +00:00
Paul 4b70b20ab7 Fixed using confusion breaking battles lol 2024-05-27 09:26:40 +10:00
Segfault Guy 125e193b81 Broadcast messages with CLIENT species on pokeball hit. 2024-05-26 19:17:16 -04:00
Paul 1ebd249351 Fixed sleeppowder effect, added redundancy to action effects in case they run into an exception 2024-05-27 09:08:22 +10:00
Segfault Guy 74727cda48 Merge branch 'main' into IllusionThrownPokeballRevealFix 2024-05-26 18:47:53 -04:00
Paul 6a8a2489d1 Fixed structure reference to cave_support not working 2024-05-27 08:27:59 +10:00
Paul 3524931596 Fixed dyeable Pokemon not being dyeable away from white unless spawned via command, fixed creative mode players still losing the dye 2024-05-27 07:06:57 +10:00
Paul 43d9347c9c Updated zh and es_es translations 2024-05-27 06:47:56 +10:00
Tyzillion 60303504cd Changelog update. 2024-05-26 11:52:30 -04:00
Tyzillion 63db0066d3 more sounds! 2024-05-26 11:49:50 -04:00
apion 6e0270ac80 Fully moved mulch into block entity 2024-05-26 11:31:21 -04:00
apion 30070d35f6 Fully moved mulch into block entity 2024-05-26 11:23:47 -04:00
apion 8e3435479a Start trying to move mulch into block entity 2024-05-26 09:39:57 -04:00
Tyzillion 333e1fe9ae Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into move-effects 2024-05-26 09:35:42 -04:00
Tyzillion c0c8c103f4 Updated changelog 2024-05-26 09:11:47 -04:00
Tyzillion a414784cca Added sounds to sand attack and the spore mushrooms, implemented confusion cuz I forgot to last night. 2024-05-26 09:10:41 -04:00
Apion b4b01ef0b6 Merge branch 'sound' into 'main'
Updated all generic impact assets

See merge request cable-mc/cobblemon!1048
2024-05-26 12:45:16 +00:00
SterrezoandApion 04f725d72e Updated all generic impact assets 2024-05-26 12:45:16 +00:00
Hiroku 0257f591de Merge branch 'implement_pokemon' into 'main'
Shedinja T Pose & Little guys sliding

See merge request cable-mc/cobblemon!1047
2024-05-26 11:40:35 +00:00
Frank The FarmerandHiroku dfeeed8796 Shedinja T Pose & Little guys sliding 2024-05-26 11:40:35 +00:00
Paul 0e304a81e8 Changelog, deleted unneeded caves template pool, licenses 2024-05-26 21:33:57 +10:00
Hiroku 03acc21af1 Merge branch 'move-effects' into 'main'
Implemented Action Effects

Closes #814, #773, #840, and #841

See merge request cable-mc/cobblemon!1045
2024-05-26 11:31:20 +00:00
Hiroku 2233e6903b Merge branch '1.5-structure-fixes' into 'main'
added loot to the trapped chest in unstable caves so you can't tell which one...

See merge request cable-mc/cobblemon!1042
2024-05-26 11:25:36 +00:00
Hiroku ac281faa3b Merge branch 'main' into 'move-effects'
# Conflicts:
#   CHANGELOG.md
2024-05-26 11:07:24 +00:00
FrankTheFarmer ad7a881fdc Changelog 2024-05-26 20:20:36 +10:00
FrankTheFarmer f9a2b5cc9c Fixed Budew and Lechonk sliding if they walked for too long 2024-05-26 20:17:47 +10:00
FrankTheFarmer e2cc006c7c Fixed Shedinja T posing in battle 2024-05-26 20:17:20 +10:00
FrankTheFarmer 13240d28ea Merge branch 'main' into implement_pokemon 2024-05-26 20:00:04 +10:00
JazzMcNade 6891272516 Throwing a ball at a player owned pokemon no longer reveals Illusion 2024-05-26 03:02:49 -05:00
Hiroku eba784071a Merge branch 'Primary-Quirks-for-JSON' into 'main'
Primary quirks for json

See merge request cable-mc/cobblemon!1044
2024-05-26 04:10:33 +00:00
Hiroku a4435af9c0 Merge branch 'GildedChestLockAnimFix' into 'main'
GildedChestLockAnimFix

Closes #811

See merge request cable-mc/cobblemon!1043
2024-05-26 04:08:22 +00:00
JazzMcNade 4b0b0f813e Merge branch 'main' into GildedChestLockAnimFix 2024-05-25 22:59:01 -05:00
JazzMcNade c32da0825c Updated Changelog 2024-05-25 22:47:39 -05:00
Tyzillion 803703b6a6 Updated changelog 2024-05-25 23:43:50 -04:00
Tyzillion 668914275e Added sounds to all the powder attacks. Tweaks and fixes. 2024-05-25 23:42:02 -04:00
FrankTheFarmer af90ff6733 Added excludedLabels 2024-05-26 13:07:16 +10:00
FrankTheFarmer c657c2ea68 CHANGELOG with example. 2024-05-26 11:27:58 +10:00
FrankTheFarmer 2f567830d4 Temporary function for bedrock quirks intended for 1.5.1 2024-05-26 11:07:14 +10:00
Tyzillion 569f3c624e Implemented Cotton guard. 2024-05-25 20:38:31 -04:00
Tyzillion f30be418f9 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into move-effects
# Conflicts:
#	CHANGELOG.md
2024-05-25 20:38:13 -04:00
Tyzillion 2c50dc2d0c Implemented Ember, Powder moves, and updated other particles. Implemented Infatuation 2024-05-25 20:34:07 -04:00
Hiroku dde2e9f52a Merge branch 'fix/form-sync' into 'main'
Form Sync on Form Change Fix

See merge request cable-mc/cobblemon!1041
2024-05-26 00:02:40 +00:00
NickandHiroku 50a21d91e8 Form Sync on Form Change Fix 2024-05-26 00:02:40 +00:00
Tyzillion 58f3de13fa Implemented Ember, Powder moves, and updated other particles. 2024-05-25 13:55:44 -04:00
Tyzillion 8d67a3a909 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into move-effects
# Conflicts:
#	CHANGELOG.md
2024-05-25 10:54:51 -04:00
JazzMcNade ad4cb8a290 Gilded Chest no longer animates to the open state on the client when the client fails to open a locked chest 2024-05-24 21:30:54 -05:00
Hiroku d9e5de5f97 Fixed pluralize usage for pose conditions 2024-05-24 22:35:48 +00:00
Hiroku e4a47af06d Merge branch 'sendout-bug' into 'main'
Fixed tiny bug, fixes #867

Closes #867

See merge request cable-mc/cobblemon!1037
2024-05-24 22:03:50 +00:00
Apion cc741c0478 Merge branch 'remulched' into 'main'
Cheap Mulch!

See merge request cable-mc/cobblemon!1039
2024-05-24 12:28:03 +00:00
dhi_holo 6887887d6b Cheap Mulch!
Made Mulch cheaper, as outlined by #866
2024-05-24 20:28:45 +10:00
Hiroku cf1100a20e Merge branch 'implement_pokemon' into 'main'
Wailord, Seedot line, and apostrophes in the changelog

See merge request cable-mc/cobblemon!1038
2024-05-24 09:46:27 +00:00
Frank The FarmerandHiroku ebc7b97e4f Wailord, Seedot line, and apostrophes in the changelog 2024-05-24 09:46:26 +00:00
FrankTheFarmer 5324b7b19e Merge branch 'main' into implement_pokemon
# Conflicts:
#	CHANGELOG.md
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen3/WailordModel.kt
2024-05-24 19:37:33 +10:00
FrankTheFarmer 5bddc31cbf Seedot line hitbox fixes 2024-05-24 19:30:11 +10:00
apion d65ce9222a Fixed tiny bug, fixes #867 2024-05-24 05:04:36 -04:00
FrankTheFarmer 72bc2221af Actually stopped Wailord in the chatbox for real this time 2024-05-24 18:56:27 +10:00
Apion 706221aead Merge branch 'LangFixes' into 'main'
A Couple of Lang Fixes

See merge request cable-mc/cobblemon!1035
2024-05-24 08:15:24 +00:00
Apion 26bfca893b Merge branch 'main' into 'LangFixes'
# Conflicts:
#   CHANGELOG.md
2024-05-24 07:01:46 +00:00
JazzMcNade 5f65f3c20c Updated Changelog 2024-05-24 01:47:23 -05:00
JazzMcNade 1e5239da10 Added English language keys for Rough Skin and Iron Barbs 2024-05-24 01:26:30 -05:00
JazzMcNade 7d8ec3470b Fix for Hyper Cutter / Big Pecks incorrectly stating they prevented accuracy from being lowered 2024-05-24 01:25:58 -05:00
Apion 389d2a0adc Merge branch '1.5-fixes-112313' into 'main'
1.5 fixes 112313

See merge request cable-mc/cobblemon!1034
2024-05-24 04:45:10 +00:00
apion 37433aa0c5 CHANGELOG.md 2024-05-24 00:34:04 -04:00
Paul 7fa0022095 Fixed species sync failing when madmen give pokemon more than 255 level up moves on the same level 2024-05-24 14:21:03 +10:00
Paul 9fde7a7618 Merge remote-tracking branch 'origin/main' into 1.5-fixes-112313 2024-05-24 14:18:04 +10:00
Paul 6c1f7ddd70 Putted the AttackDefenceRatioRequirement back for backcompat 2024-05-24 14:15:45 +10:00
apion 1a1cedb3aa Regenned berry data, added bone meal chance 2024-05-23 23:53:42 -04:00
Hiroku 241b83cec9 Merge branch 'implement_pokemon' into 'main'
Implementation Stuff

See merge request cable-mc/cobblemon!1027
2024-05-23 21:57:39 +00:00
Frank The FarmerandHiroku f0feb81a16 Implementation Stuff 2024-05-23 21:57:38 +00:00
apion b82287f258 Vera berry changes 2024-05-23 09:02:24 -04:00
FrankTheFarmer 9099cb4b5d Merge branch 'main' into implement_pokemon 2024-05-23 22:37:47 +10:00
FrankTheFarmer 99e0b7d995 Smeargle Mentioned 2024-05-23 22:34:58 +10:00
Hiroku 00f4052b75 Merge branch 'MoreFossilMachineFixes' into 'main'
Many Fossil Machine Fixes

See merge request cable-mc/cobblemon!1033
2024-05-23 11:02:07 +00:00
Hiroku 407c24b7c5 Merge branch 'asset-updates' into 'main'
Updated wooloo/dubwool textures and passho berry stuff

Closes #854

See merge request cable-mc/cobblemon!1031
2024-05-23 10:56:56 +00:00
FrankTheFarmer 372f44538b Smeagol 2024-05-23 15:47:13 +10:00
JazzMcNade c8904c3e38 Removed commented code, updated changelog 2024-05-23 00:24:22 -05:00
JazzMcNade 6bfc711129 Update FossilMultiblockStructure.kt 2024-05-22 23:25:46 -05:00
JazzMcNade 3d914f47ee Merge branch 'main' into MoreFossilMachineFixes 2024-05-22 23:25:26 -05:00
JazzMcNade 61891d8fe4 Refactored blockState check to for the blockstate property (credit to Charzard4261) , fixed typo 2024-05-22 21:26:49 -05:00
FrankTheFarmer 0bec3ac851 Merge branch 'main' into implement_pokemon 2024-05-23 07:21:49 +10:00
apion 1b66ee8ce3 Updated wooloo/dubwool textures and passho berry stuff 2024-05-22 03:57:34 -04:00
apion c884c556cb Remove binding soil 2024-05-22 03:37:04 -04:00
Apion 5e6091c782 Merge branch 'tmetcalfe89/revive-event' into 'main'
added fossil revived event

See merge request cable-mc/cobblemon!1029
2024-05-22 07:26:52 +00:00
Timothy MetcalfeandApion 5a2e5479e0 added fossil revived event 2024-05-22 07:26:52 +00:00
apion 9a8b481fa2 Changed berry grow timers per Vera request 2024-05-22 03:26:09 -04:00
apion e2fb31fad3 Merge branch 'refs/heads/main' into berry-changes 2024-05-22 02:39:51 -04:00
Tyzillion fc03682140 Implemented quick attack 2024-05-21 22:30:41 -04:00
JazzMcNade 07fbffaa71 Fixed refactor mistake in previous commit. 2024-05-21 20:45:54 -05:00
FrankTheFarmer 17b8dd3532 Wailord will now stop forcing its head into the chatbox 2024-05-22 09:53:31 +10:00
Tyzillion 5e2f5dadb4 Fixed some errors I ran into. 2024-05-21 19:36:11 -04:00
FrankTheFarmer 4cf8a19d43 Tyrantrum will now stop forcing its head into the chatbox 2024-05-22 09:34:12 +10:00
Tyzillion fc682d1cd1 Implemented action effects for Sand Attack, Protect, Minimize, and Swords Dance. 2024-05-21 19:13:06 -04:00
Tyzillion 7759c91f3b Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into move-effects
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/pokemon/evolution/Evolution.kt
2024-05-21 19:11:04 -04:00
JazzMcNade c13654f60c FossilMultiblockStructure no longer stores a created pokemon, instead the pokemon is created when the pokemon is retrieved from the machine 2024-05-21 02:36:39 -05:00
JazzMcNade 289e9df52b Fixed Restoration Tank over consuming items when interacting with Create blocks 2024-05-20 21:23:13 -05:00
FrankTheFarmer f205e7f29e CHANGELOG 2024-05-21 10:18:44 +10:00
FrankTheFarmer cec031595f Merge branch 'main' into implement_pokemon 2024-05-21 10:14:21 +10:00
FrankTheFarmer af007dad17 Added missing Chingling and Chimecho spawns near bells 2024-05-21 09:54:39 +10:00
Tyzillion 5dca5a1579 Merge remote-tracking branch 'origin/move-effects' into move-effects 2024-05-20 15:57:38 -04:00
JazzMcNade 3ebad9dc9d Fixed a Create crash when a chute attempts to access the inventory of the top half of the Restoration Tank when the bottom half has been destoryed 2024-05-19 21:27:03 -05:00
apion c93fa02616 Fixed dispatch timeline 2024-05-19 21:13:58 -04:00
Hiroku 4e1b82917b Merge branch 'Roaming-Gholdengo-Request' into 'main'
Lets Gholdengo maintain its roaming aspect

See merge request cable-mc/cobblemon!1025
2024-05-20 00:11:17 +00:00
Frank The FarmerandHiroku 3b1d257241 Lets Gholdengo maintain its roaming aspect 2024-05-20 00:11:16 +00:00
Hiroku 0b8f916648 Merge branch 'dimension-condition-uses-id-not-effects' into 'main'
Change dimension spawn condition to check with IDs not effects

See merge request cable-mc/cobblemon!1026
2024-05-20 00:11:02 +00:00
FrankTheFarmer 8490f3a923 Fixed Cyndaquil's flame clipping when it wasn't ignited 2024-05-20 08:17:02 +10:00
FrankTheFarmer 9bf6200163 Merge branch 'main' into implement_pokemon 2024-05-20 08:11:19 +10:00
apion 5897fff954 Added boost/unboost general particles, removed the particle from growl 2024-05-19 18:05:11 -04:00
apion 2fd2137d78 Added poison (this particle is BROKEN) 2024-05-19 17:22:09 -04:00
apion 42c4d6625e Added poison (this particle is BROKEN) 2024-05-19 17:21:52 -04:00
apion b0381d1685 We do a little refactoring 2024-05-19 16:23:41 -04:00
David Sadler 5ad7d5406a Change dimension spawn condition to check with IDs not effects 2024-05-19 18:45:34 +01:00
apion 3b00043b13 Got confusion kinda working, needs tweaks 2024-05-19 02:44:05 -04:00
JazzMcNade 2b403df6ef Removed client side mutations in FossilMultiblockStructure's onUse and enabled the client to enter the function 2024-05-19 01:37:04 -05:00
apion f0d5622bab Added volatile status stuff 2024-05-19 02:20:12 -04:00
apion ec28ca0c45 Added action effect for paralysis + action effect triggers for the cant command 2024-05-19 01:11:41 -04:00
Tyzillion 0d68eedc74 Merge remote-tracking branch 'origin/move-effects' into move-effects 2024-05-18 22:24:56 -04:00
Paul 6ec008ee83 Merge remote-tracking branch 'origin/main' into 1.5-fixy
# Conflicts:
#	CHANGELOG.md
2024-05-19 11:19:13 +10:00
Paul c969e1731b Merge remote-tracking branch 'origin/move-effects' into move-effects 2024-05-19 09:13:29 +10:00
Paul bb77c6d4a9 Fixed particle velocity not respecting drag as much as it should oops sorry 2024-05-19 09:13:17 +10:00
Tyzillion 5dfc90c0bd Merge remote-tracking branch 'origin/move-effects' into move-effects 2024-05-18 18:52:14 -04:00
apion 26a72fe6a9 I hope this works (pt. 2) 2024-05-18 18:46:58 -04:00
apion 4bb9547822 I hope this works 2024-05-18 17:08:09 -04:00
Tyzillion ffe88d75b5 Merge remote-tracking branch 'origin/move-effects' into move-effects 2024-05-18 16:08:32 -04:00
apion d8980fabbe Fix entity_scale var 2024-05-18 14:56:47 -04:00
apion 7598413e93 Merge branch 'refs/heads/particle-rave' into move-effects 2024-05-18 13:55:24 -04:00
apion b0cc4714fc Merge branch 'refs/heads/main' into move-effects
# Conflicts:
#	CHANGELOG.md
2024-05-18 13:53:45 -04:00
JazzMcNade 5aa3f34880 Added block type checks before attempting to update the blockstate from the fossilmultiblockstructure 2024-05-18 12:15:50 -05:00
Slippy 21363405fc console log spam fix for real this time 2024-05-18 12:00:11 -05:00
JazzMcNade 340be0b2a1 Fixed an issue where the lights on the restoration tank would not animate if it was facing east 2024-05-18 11:57:16 -05:00
JazzMcNade 933e29b134 Fix for TankEntityRenderer desync 2024-05-18 11:52:54 -05:00
Tyzillion 41b27e5d75 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into move-effects
# Conflicts:
#	CHANGELOG.md
2024-05-18 10:55:29 -04:00
Tyzillion e80bf0e331 Merge remote-tracking branch 'origin/move-effects' into move-effects 2024-05-18 10:54:32 -04:00
Hiroku f4d2226ec2 Merge branch '1.5.1' into 'main'
Moar 🐛🔫

Closes #847 and #799

See merge request cable-mc/cobblemon!1023
2024-05-18 01:50:12 +00:00
apion 0fc5d5e9d7 Fixed bad null handling 2024-05-17 21:41:58 -04:00
Hiroku 972c0f6430 Merge branch 'dubwool-dye' into 'main'
Make wooloos dyable

Closes #824

See merge request cable-mc/cobblemon!1021
2024-05-18 01:40:13 +00:00
ApionandHiroku 86db95a7dc Make wooloos dyable 2024-05-18 01:40:13 +00:00
apion be95b79e4d Removed unnecessary override 2024-05-17 21:20:20 -04:00
Paul 683aa354ed Fixed particle event triggers spawning particles on the emitter, fixes #814 2024-05-18 11:10:48 +10:00
apion aa19ff2c95 Added entity scale as a particle param 2024-05-17 20:57:10 -04:00
Paul 7d5e790f75 Fixed particle rotations being inverted 2024-05-18 10:55:28 +10:00
apion 5753443ab2 Optimized a player lookup 2024-05-17 20:39:27 -04:00
apion c6b7186032 Merge branch 'refs/heads/main' into 1.5.1
# Conflicts:
#	CHANGELOG.md
2024-05-17 20:35:50 -04:00
apion 32f3be2687 Changelog 2024-05-17 20:33:24 -04:00
apion 9012d78806 Apparently Kotlin uses .equals when using ==, === is Java == behavior 2024-05-17 20:30:18 -04:00
apion fffdfb7654 Fixes bug with InvMove, closes #847 2024-05-17 20:28:57 -04:00
Tyzillion 76f17c9760 Merge remote-tracking branch 'origin/move-effects' into move-effects 2024-05-17 18:33:17 -04:00
Hiroku b314733f0b Merge branch 'Frank's-Bug-Fixing-Farm' into 'main'
Frank's bug fixing farm

See merge request cable-mc/cobblemon!1019
2024-05-17 10:44:01 +00:00
Frank The FarmerandHiroku d5aa07fe91 Frank's bug fixing farm 2024-05-17 10:44:00 +00:00
Paul 3b0d2cd980 Added parametric particle support (motion and rotation), closes #773 2024-05-17 16:43:35 +10:00
Ludichat 7e43a7424e Updated CHANGELOG.md. 2024-05-17 08:26:51 +02:00
apion 27bedc2d2c Closes #799 2024-05-16 21:59:36 -04:00
Hiroku 86744c23a5 Merge branch '1.5.1' into 'main'
Fix recoil evo bug

Closes #844

See merge request cable-mc/cobblemon!1022
2024-05-17 01:41:41 +00:00
Tyzillion f5a3c93039 Merge remote-tracking branch 'origin/move-effects' into move-effects 2024-05-16 21:35:16 -04:00
Paul 00dc501df7 Fixed timed particle ages being a tick too long, fixes #840 2024-05-17 11:28:49 +10:00
apion 8d1a64136f Fix recoil evo bug 2024-05-16 20:33:19 -04:00
Paul 39fee0bcea Fixed particle effects generated from molang not having access to entity_radius and stuff. Fixes #841 2024-05-17 10:26:18 +10:00
Tyzillion 1162689172 Merge remote-tracking branch 'origin/move-effects' into move-effects 2024-05-16 20:08:03 -04:00
Paul bc550dd32c Fixed unlocked evolutions getting re-checked and eating held items, fixes #843 2024-05-17 10:04:54 +10:00
Paul b295644070 Cleaned imports 2024-05-17 09:37:29 +10:00
Paul 21df0085e2 Merge remote-tracking branch 'origin/main' into move-effects 2024-05-17 09:08:19 +10:00
Paul 3009af8c42 Fixed missing cant.nopp lang key, fixes #842 2024-05-17 08:52:23 +10:00
Hiroku bfd34eb621 Merge branch '1.5.1' into 'main'
Fixes a few issues

Closes #827, #828, #826, and #832

See merge request cable-mc/cobblemon!1012
2024-05-16 22:46:10 +00:00
Hiroku 2dc2c96176 Update CHANGELOG.md [skip-ci] 2024-05-16 22:44:00 +00:00
Hiroku df4db17cfd Removed println 2024-05-16 22:40:56 +00:00
Ludichat b718daf0f1 Gives a Hidden Ability slot to middle stage evolution and Ferroseed with a single ability. 2024-05-16 21:49:34 +02:00
Slippy 08c4f4a0ff added loot to the trapped chest in unstable caves so you can't tell which one is trapped if you're using lootr muwahahahaha 2024-05-16 01:57:41 -05:00
Slippy c4a1704a8b unstable cave loot table fixes 2024-05-15 20:35:24 -05:00
apion 45bec488f1 Fixed bug with pasture block 2024-05-15 20:41:32 -04:00
apion 9287374504 Merge branch 'refs/heads/main' into 1.5.1 2024-05-15 18:24:56 -04:00
apion 90c5180712 Revert "update Forge to current RB, update Fabric deps to latest"
This reverts commit 7139d4708b.
2024-05-15 18:17:29 -04:00
Tyzillion 51af37b37a Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into move-effects 2024-05-15 18:09:53 -04:00
apion f2a36cd74a Merge branch 'refs/heads/main' into 1.5.1
# Conflicts:
#	CHANGELOG.md
2024-05-15 14:51:45 -04:00
Nick 158aa05f24 Merge branch 'fix/downgrade-loom' into 'main'
fix: resolve mapping issues by downgrading loom

See merge request cable-mc/cobblemon!1015
2024-05-15 15:38:09 +00:00
Apion 8924d0fe0f Merge branch 'navneetset-main-patch-27693' into 'main'
Fix PC store downsizing not working with .resize()

See merge request cable-mc/cobblemon!1016
2024-05-15 12:12:04 +00:00
PebblesandApion d510eaa462 Fix PC store downsizing not working with .resize() 2024-05-15 12:12:04 +00:00
apion a3122812e4 Added color to all sprouts 2024-05-15 07:47:43 -04:00
Hiroku 8b63057d9d Merge branch 'we-ballin' into 'main'
Cherish, Dream, Beast, and Ancient Origin Send Out Particles

See merge request cable-mc/cobblemon!1018
2024-05-15 10:26:08 +00:00
Hiroku d572b3c505 Missed a bit [skip-ci] 2024-05-15 10:25:21 +00:00
Hiroku 8edc60224a Merge branch 'main' into 'we-ballin'
# Conflicts:
#   CHANGELOG.md
2024-05-15 10:24:54 +00:00
Hiroku a634c4f046 Merge branch 'update-libs' into 'main'
Update libs

See merge request cable-mc/cobblemon!1017
2024-05-15 10:23:14 +00:00
MoeBoy76 7139d4708b update Forge to current RB, update Fabric deps to latest 2024-05-15 11:11:02 +10:00
dhi_holo 50e99736a3 Partial Fix
Origin Ball now plays correctly in resource pack, but not in the mod itself, updated jsons to match, so all that's left is working out why the mod refuses to read the new jsons even though the new jsons are read in the files, in intellij, and in github desktop.
2024-05-15 10:43:09 +10:00
MoeBoy76 68c4acf0eb Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2024-05-15 09:21:22 +10:00
broccoli 5b5e7109f5 fix: resolve mapping issues by downgrading loom
fixes regression in fd7b82dbe3
2024-05-14 23:17:16 +01:00
Slippy 837aa5acf5 missing loot table in deserted tower 2024-05-14 16:58:55 -05:00
apion 19698fc0ff Merge branch 'refs/heads/main' into berry-changes 2024-05-14 16:36:34 -04:00
Hiroku 37596523db Merge branch 'tmetcalfe89/abstract-stat-ratio-requirement' into 'main'
abstracted stat ratio requirement

See merge request cable-mc/cobblemon!1011
2024-05-14 20:15:13 +00:00
tmetcalfe89 eb80c20dbf updated readme 2024-05-14 09:11:16 -07:00
apion 7ab3951613 Fix gilded chest item drops 2024-05-14 11:16:33 -04:00
apion e6d51c4d56 A little more fossil machine clean up 2024-05-14 10:26:25 -04:00
Apion 3813ec3c92 Merge branch 'sound' into 'main'
Renamed Relic Coin Sack sound assets. Added new sounds for Relic Coin Pouches.

See merge request cable-mc/cobblemon!1013
2024-05-14 14:12:24 +00:00
apion b9364304ca Changelog teehee 2024-05-14 09:47:35 -04:00
Sterrezo 9be212d2b8 Renamed Relic Coin Sack sound assets. Added new sounds for Relic Coin Pouches.
Renamed all sounds called "coin_pouch..." to "relic_coin_sack..." Added new sounds for breaking and placing Relic Coin Pouches with a new sound group for them.
2024-05-14 13:27:11 +02:00
tmetcalfe89 2559257b3a added licenses 2024-05-14 01:16:30 -07:00
apion 8236c6fb11 Merge branch 'refs/heads/main' into 1.5.1 2024-05-14 04:13:40 -04:00
apion 2041d43db4 Hopefully fixed some other bugs 2024-05-14 03:53:35 -04:00
Apion a1687e8304 Merge branch 'tmetcalfe89/ensure-defeat-count' into 'main'
Ensure update total defeat count on battle win

See merge request cable-mc/cobblemon!1010
2024-05-14 07:25:09 +00:00
JazzMcNade 94d92b6fc0 Fixes #827
Jade can now view the contents of the analyzer block
2024-05-14 01:53:56 -05:00
tmetcalfe89 3aa95b9339 abstracted stat ratio requirement 2024-05-13 23:39:01 -07:00
tmetcalfe89 4e97f70801 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into tmetcalfe89/ensure-defeat-count 2024-05-13 22:39:56 -07:00
dhi_holo 404ca565f5 4 balls maybe working
Send out particles for Cherish, Dream, Beast, and Ancient Origin balls

Needs testing on one issue before MR
2024-05-14 15:35:32 +10:00
MoeBoy76 93db0e1cda Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2024-05-14 08:57:15 +10:00
apion 4a4d292228 Fixes #828 2024-05-13 17:01:38 -04:00
apion 0fef9eec3d Fixes #826 2024-05-13 17:01:27 -04:00
apion 5f3dc395ec Fixes #832 2024-05-13 12:17:47 -04:00
Hiroku 1bf9d36dbd Merge branch 'wheres-the-tag-drake' into 'main'
Updated fossils.json Item Tag

Closes #834

See merge request cable-mc/cobblemon!1009
2024-05-13 09:45:38 +00:00
dhi_holo b19c5ed125 Updated fossils.json Item Tag
Sorted the fossils tag to match the order on Bulbapedia (just to make sure all other fossils were there, and because it looks a little nicer), and added Fossilized Drake to the tag
2024-05-13 17:51:19 +10:00
Paul e3cca0d9cf SpawnAction#complete returns R instead of Boolean 2024-05-13 15:08:55 +10:00
tmetcalfe89 1aa55f8199 replaced entity ref with originalPokemon 2024-05-12 21:49:58 -07:00
Paul 4c16b2ce2e Track friendship on client entities, tweaks to dataTracker initializing, MoLang in pose & quirk conditions 2024-05-13 12:47:53 +10:00
Slippy 969d6ac7fc console spam fix 2024-05-12 09:23:39 -05:00
Hiroku 920e314444 Merge branch '830-only-player-entity-can-send-out-pokemon' into 'main'
Remove unnecessary cast of phaseTarget to PlayerEntity in PokemonRenderer.renderTransition

Closes #830

See merge request cable-mc/cobblemon!1008
2024-05-12 10:23:34 +00:00
David Sadler 3e4fdc0f22 Remove unnecessary cast of phaseTarget to PlayerEntity in PokemonRenderer.renderTransition 2024-05-12 11:04:52 +01:00
Hiroku 209ac71e06 Merge branch 'FossilTankFixes' into 'main'
Fix for using incorrect item count when applying organic material with right click.

See merge request cable-mc/cobblemon!1007
2024-05-12 08:05:27 +00:00
JazzMcNade ecfc77f311 Updated Changelog 2024-05-12 02:49:19 -05:00
JazzMcNade e64de3aa7d Fixed a bug in which adding organic material was adding the full count of the stack currently in hand 2024-05-12 01:29:55 -05:00
Slippy 46bb9e1aec console fix 2024-05-11 21:58:50 -05:00
Slippy 9792ff3392 console spam fix 2024-05-11 21:36:29 -05:00
Nick fd7b82dbe3 Merge branch 'build/gradle-updates' into 'main'
gradle and build improvements

See merge request cable-mc/cobblemon!1006
2024-05-11 23:40:09 +00:00
broccolaiandNick 7ef48402fb gradle and build improvements 2024-05-11 23:40:09 +00:00
Nick 81ac6f3b44 Snapshot = true 2024-05-11 16:39:06 -07:00
Paul 347e10d7e4 Snapshot = false 2024-05-12 08:20:46 +10:00
Paul 32270b6176 Attempt at fixing data migration error in species features 2024-05-11 14:39:49 +10:00
Hiroku a0a26a98b5 Merge branch 'V-lpen-main-patch-49919' into 'main'
Update dragapult.json

See merge request cable-mc/cobblemon!996
2024-05-11 04:37:18 +00:00
Hiroku 85836f19b2 Merge branch 'held_item_back' into 'main'
Fixed held items without consumable tags from being consumed or swapped in battle.

See merge request cable-mc/cobblemon!1005
2024-05-11 04:36:47 +00:00
Hiroku 9f251b7070 Update CHANGELOG.md 2024-05-11 04:36:13 +00:00
Segfault Guy 86ddb6d743 Fixed held items without consumable tags from being consumed or swapped in battle. 2024-05-11 00:15:26 -04:00
Paul 9c8a00bbdc Fixed bad moveset JSON for Kyurem 2024-05-11 13:04:50 +10:00
Hiroku 04abf2bd25 Update CHANGELOG.md [skip-ci] 2024-05-11 00:27:36 +00:00
Paul e6553655a6 Changelog update heading [skip-ci] 2024-05-11 10:19:43 +10:00
Paul 5f33d16a75 More changelog cleanup 2024-05-11 09:53:00 +10:00
Hiroku 468f84862e Merge branch '1.5-structure-fixes' into 'main'
Deleted Duplicate Loot Table

See merge request cable-mc/cobblemon!1003
2024-05-10 22:27:50 +00:00
Slippy e863c6d094 Deleted Duplicate Loot Table 2024-05-10 16:19:15 -05:00
Nick 5b2d542fca Merge branch 'Myslippy-main-patch-94569' into 'main'
Update CHANGELOG.md

See merge request cable-mc/cobblemon!1002
2024-05-10 20:06:14 +00:00
Myslippy 95db34c55e Update CHANGELOG.md 2024-05-10 19:41:41 +00:00
Paul 15da48c5c0 Merge remote-tracking branch 'origin/main' 2024-05-10 18:42:29 +10:00
Paul ead62763c1 Changelog cleanup 2024-05-10 18:42:22 +10:00
apion 247c475c2d Fix oversight in incendium fix 2024-05-09 23:44:04 -04:00
Hiroku 44aab4f0e7 Merge branch 'spawn-fixes' into 'main'
Spawn fixes

See merge request cable-mc/cobblemon!1001
2024-05-10 03:02:48 +00:00
Frank The FarmerandHiroku 94edae591c Spawn fixes 2024-05-10 03:02:48 +00:00
Hiroku c83f045b4d Merge branch 'incendium-fix' into 'main'
Fixes #823

Closes #823

See merge request cable-mc/cobblemon!999
2024-05-10 00:16:23 +00:00
apion b5d7786ff7 Fixes #823 2024-05-09 20:05:03 -04:00
Paul 9283794e26 Merge remote-tracking branch 'origin/main' 2024-05-10 09:53:11 +10:00
Hiroku 55580fb564 Merge branch 'sound' into 'main'
Flamethrower sound fixes

See merge request cable-mc/cobblemon!998
2024-05-09 23:52:44 +00:00
Paul 472c9be634 Applied pt-pt translations 2024-05-10 09:49:07 +10:00
Sterrezo a247344ae4 Removed unused audio files 2024-05-10 01:41:03 +02:00
FrankTheFarmer 1fd0a9775c Flamethrower is flamethrowering now 2024-05-10 09:39:32 +10:00
Hiroku 9d9495f1f9 Merge branch 'fix-adorn-compat' into 'main'
Fixed adorn compat

See merge request cable-mc/cobblemon!997
2024-05-09 22:56:26 +00:00
apion 88e301d7c8 Fixed adorn compat 2024-05-09 18:53:44 -04:00
Hiroku b0e16a7f26 Merge branch 'FossilTankCreateFix' into 'main'
Fossil Tank Create Fix

See merge request cable-mc/cobblemon!993
2024-05-09 22:07:43 +00:00
Hiroku 54b5b3cbbc Merge branch 'implement_pokemon' into 'main'
Forgot to merge request

See merge request cable-mc/cobblemon!992
2024-05-09 22:07:14 +00:00
Frank The FarmerandHiroku 7850bc5263 Forgot to merge request 2024-05-09 22:07:14 +00:00
V-lpen 8ce5a927b9 Update dragapult.json 2024-05-09 19:19:22 +00:00
FrankTheFarmer 4482a4f072 Forgot to add Mismagius to model updates 2024-05-09 10:00:05 +10:00
FrankTheFarmer a92f37c740 Added Krabby's missing temporary-cry animation 2024-05-09 09:57:26 +10:00
FrankTheFarmer 4677dda922 Limited Mismagius' yaw range to prevent some clipping 2024-05-09 09:56:29 +10:00
FrankTheFarmer 81f7320e4a Mismagius asset updates 2024-05-09 09:56:01 +10:00
Test 24c34af8bf remove random color from ui text 2024-05-08 22:25:19 +00:00
Hiroku 7402426656 Merge branch 'tmetcalfe89/fletchinder-name-ru' into 'main'
in Russian translation the fletchinder was called fletchling

See merge request cable-mc/cobblemon!990
2024-05-08 20:47:41 +00:00
Hiroku c658e496cc Merge branch 'GildedChestHopperInteractionFix' into 'main'
Hoppers can now interact with all inventory slots in a Gilded Chest, Closes #822

Closes #822

See merge request cable-mc/cobblemon!994
2024-05-08 20:40:42 +00:00
JazzMcNade f3300806a3 Hoppers can now interact with all inventory slots in a Gilded Chest 2024-05-08 02:12:53 -05:00
JazzMcNade 8fee4de49b Graceful transition to new inventory, fixed item scatterer 2024-05-08 01:28:41 -05:00
JazzMcNade 5b951ef511 Added Anti-item clogging technology to the fossil tank 2024-05-07 23:43:40 -05:00
tmetcalfe89 6e0850331a held item too 2024-05-06 12:40:22 -07:00
tmetcalfe89 79b1771e7e quick fix 2024-05-06 10:00:50 -07:00
JazzMcNade c9b2c44083 Fixed create chute crash and item duping when chutes attempt to put items in a restoration tank. Refactored RestorationTankEntity to use SimpleInventory 2024-05-05 20:19:09 -05:00
FrankTheFarmer 3c9cf42da4 Fixed Flabebe's broken species name. Apparently its Flabébé and not Flabébé??? 2024-05-06 08:39:34 +10:00
FrankTheFarmer 620ed73fe9 Fixed Klefki t pose when sleeping 2024-05-06 08:38:23 +10:00
Hiroku c370076337 Merge branch 'bye-j16' into 'main'
Bye J16

See merge request cable-mc/cobblemon!988
2024-05-05 03:34:07 +00:00
Tyzillion 978d9e76a1 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into move-effects 2024-05-04 17:48:57 -04:00
FrankTheFarmer 7d09b7e2fe Fixed a broken texture on Elgyem 2024-05-04 18:48:08 +10:00
FrankTheFarmer 656cff2ab3 Made Galarian Zigzagoon use Hoenn Zigzagoon's shoulder animation 2024-05-04 18:16:59 +10:00
Tyzillion 1d8462fd63 Implemented better Krabby bubble blowing quirk animation. 2024-05-03 18:34:23 -04:00
Tyzillion e417db6a8d Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-05-03 16:39:08 -04:00
MoeBoy76 a0b263e392 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2024-05-03 10:45:11 +10:00
MoeBoy76 d05ae4d535 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into bye-j16 2024-05-03 10:19:18 +10:00
MoeBoy76 3cebfb38ef fix mixin compat level being set to Java 16 for no reason 2024-05-03 10:18:58 +10:00
Apion d69f1f17b6 Merge branch 'implement_pokemon' into 'main'
Daily Implementation Mission

See merge request cable-mc/cobblemon!987
2024-05-02 06:59:35 +00:00
Frank The FarmerandApion 3ba89472fa Daily Implementation Mission 2024-05-02 06:59:35 +00:00
MoeBoy76 573608b6fc Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2024-05-02 16:04:01 +10:00
MoeBoy76 f092584f83 changelog blank line at end [skip-ci] 2024-05-02 16:03:52 +10:00
Apion a76146f8e9 Merge branch 'JSON-Poser-Tweaks' into 'main'
Json poser tweaks

See merge request cable-mc/cobblemon!986
2024-05-02 05:53:59 +00:00
Frank The FarmerandApion 548daa84e4 Json poser tweaks 2024-05-02 05:53:59 +00:00
MoeBoy76 16d0d3b7e1 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
#	common/src/main/resources/data/cobblemon/species/generation1/exeggcute.json
#	common/src/main/resources/data/cobblemon/species/generation1/pikachu.json
#	common/src/main/resources/data/cobblemon/species/generation2/cyndaquil.json
#	common/src/main/resources/data/cobblemon/species/generation2/quilava.json
#	common/src/main/resources/data/cobblemon/species/generation5/dewott.json
#	common/src/main/resources/data/cobblemon/species/generation5/oshawott.json
#	common/src/main/resources/data/cobblemon/species/generation7/dartrix.json
#	common/src/main/resources/data/cobblemon/species/generation7/rowlet.json
2024-05-02 15:49:13 +10:00
Apion 7f1dd4546b Merge branch 'can-moe-scrape' into 'main'
Blueberry DLC

Closes #757, #649, and #758

See merge request cable-mc/cobblemon!953
2024-05-02 05:48:29 +00:00
MoeBoy76andApion a129c361df Blueberry DLC 2024-05-02 05:48:29 +00:00
MoeBoy76 dbedc58dd9 changelog conflict fix [skip-ci] 2024-05-02 15:43:54 +10:00
FrankTheFarmer c0ea565967 Updated Changelog with recent changes 2024-05-02 14:26:10 +10:00
FrankTheFarmer 7e92f5f314 Updated Spewpa evolution and Vivillon spawn biome tags 2024-05-02 14:25:21 +10:00
FrankTheFarmer df3ed93032 Added anticondition structure requirements to evolutions 2024-05-02 14:24:45 +10:00
FrankTheFarmer 2335fd388e Updated and added time ranges 2024-05-02 14:22:26 +10:00
FrankTheFarmer e152cc9fd0 Updated Changelog with recent work 2024-05-01 21:31:00 +10:00
FrankTheFarmer 3f7e2bef40 Updated Spewpa evolutions and made sure they work. I hate evolution™ 2024-05-01 21:30:16 +10:00
FrankTheFarmer 25927c6ebe Updated Vivillon biome tags to new format and added 2 more 2024-05-01 21:28:40 +10:00
FrankTheFarmer 2f18d6b05f Created new folder for all regional evolution biome tags and moved region bias ones there 2024-05-01 20:34:48 +10:00
FrankTheFarmer 2600e23233 Removed sliggoos cross region evolutions 2024-05-01 20:33:26 +10:00
FrankTheFarmer 5c5c72d800 Updated Goomy to use new evolution biome tags for evolution 2024-05-01 20:32:15 +10:00
FrankTheFarmer 2c812344f9 Updated Petilil evo biomes and added priority evos to save a sun stone hopefully 2024-05-01 20:24:33 +10:00
FrankTheFarmer 37b4577230 Updated Hisui Starter evos to use the updated evolution biome tags 2024-05-01 19:50:51 +10:00
FrankTheFarmer fcf64b00bf Updated Pikachu and Exeggcute evolutions to prioritize cross region evos if applicable 2024-05-01 19:40:48 +10:00
FrankTheFarmer 02b8cd81a0 Updated Conkeldurr with the correct animation files 2024-04-30 21:38:54 +10:00
FrankTheFarmer def1b44f08 Fixed Conkeldurr holding too much concrete during sleep animation 2024-04-30 17:02:01 +10:00
FrankTheFarmer b28f915af9 Selected Hisui starters will now come in ancient poke balls 2024-04-30 15:07:59 +10:00
Hiroku 5d5508a71e Merge branch '1.5-structure-fixes' into 'main'
1.5 structure fixes

See merge request cable-mc/cobblemon!984
2024-04-29 12:29:34 +00:00
Hiroku 5e5684d9fd Merge branch 'implement_pokemon' into 'main'
A couple fixes

See merge request cable-mc/cobblemon!985
2024-04-29 12:29:16 +00:00
Frank The FarmerandHiroku a1623c04b7 A couple fixes 2024-04-29 12:29:15 +00:00
FrankTheFarmer 29ce8b584a Stopped the zoroarks cry animations from looping 2024-04-29 19:22:18 +10:00
Slippy a070dc56bd Cleaning up unused files 2024-04-29 01:05:00 -05:00
Slippy 79f9e0f0f2 Gimmi Towers now have more junk it can generate at the top 2024-04-29 00:59:41 -05:00
Slippy 8500eb58ef Removed spam log issues and blended some structures into the world better 2024-04-29 00:49:48 -05:00
Hiroku 97e51eb7b5 Merge branch 'removing-items-is-hard' into 'main'
Update is_held_item.json

See merge request cable-mc/cobblemon!983
2024-04-29 05:44:20 +00:00
FrankTheFarmer 84f3a44109 Found Sudowoodo and Bonsly. Hiding since July 2023 2024-04-29 15:35:20 +10:00
dhi_holo ba75dcdf31 Update is_held_item.json
why is removing held items so damn annoying, can't we just get vera to fasttrack the sprites instead /j
2024-04-29 15:19:59 +10:00
Paul 9bf8c0e3ec Fixed MOVING data tracker field not using the new logic that drives the pose 2024-04-29 11:25:12 +10:00
Hiroku 0c62c247ec Merge branch '1.5-bug-fixes' into 'main'
(misleading branch name) Run config changes

See merge request cable-mc/cobblemon!980
2024-04-29 00:16:52 +00:00
Hiroku c70e8872ce Merge branch 'implement_pokemon' into 'main'
Implementation yet again

See merge request cable-mc/cobblemon!982
2024-04-29 00:10:19 +00:00
Frank The FarmerandHiroku ce323ddfbf Implementation yet again 2024-04-29 00:10:19 +00:00
FrankTheFarmer 08a58eee8a Prevented and preserved Cubone's evolution to Alolan Marowak 2024-04-29 08:55:05 +10:00
Hiroku ffe7978560 Merge branch 'no-more-heldies' into 'main'
Commented out the Held Items

See merge request cable-mc/cobblemon!981
2024-04-28 07:44:29 +00:00
dhi_holo a58632752a Commented out the Held Items
(just the ones without sprites, ofc, just trying to scare public git readers)
2024-04-28 17:21:23 +10:00
Tyzillion 1e067cb7e4 Implemented simple elemental punches. Implemented sweetscent effects, and stat increase and decrease particles. 2024-04-27 22:00:56 -04:00
FrankTheFarmer c10f48090c Added dried kelp blocks, melon, vines, and sea pickles to list of organic materials for the fossil machine 2024-04-28 11:07:16 +10:00
apion 0b93481dbf Remove unneeded imports 2024-04-27 13:10:21 -04:00
apion dda004a66c Change default run configs to generate with a uuid and username 2024-04-27 13:05:44 -04:00
Tyzillion 2f464f82b1 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into move-effects 2024-04-26 21:01:38 -04:00
apion 9648a91f4a Fixed fabric server run config, split client and server run folders 2024-04-26 20:35:50 -04:00
Hiroku e0c4bf7fb2 Merge branch 'implement_pokemon' into 'main'
Today's implementation fixes

See merge request cable-mc/cobblemon!977
2024-04-26 23:23:50 +00:00
Frank The FarmerandHiroku ed919f63f0 Today's implementation fixes 2024-04-26 23:23:49 +00:00
Apion 239acc0623 Merge branch '1.5-structure-fixes' into 'main'
One more try

See merge request cable-mc/cobblemon!978
2024-04-26 22:12:46 +00:00
Slippy e835b833b3 One more try 2024-04-26 16:48:04 -05:00
FrankTheFarmer 9c0e5e487a Reverted Snorlax's resize 2024-04-26 20:57:20 +10:00
FrankTheFarmer 95f2bbbf15 If for some reason you are above an Aurorus, it will no longer break its neck trying to look at you. 2024-04-26 20:37:53 +10:00
FrankTheFarmer 864d184cd9 Scaled drifloon down a bit 2024-04-26 17:53:56 +10:00
FrankTheFarmer a2256f6208 Lurantis animation file update 2024-04-26 16:44:14 +10:00
FrankTheFarmer 945d556b43 Fixed Cubone holding its bone humerusly 2024-04-26 16:18:14 +10:00
FrankTheFarmer f0def2e883 Fixed zubat's shoulder animations 2024-04-26 13:42:21 +10:00
FrankTheFarmer 79c644dad0 So the 10 and 11 bug can be fixed with underscores 👀 2024-04-26 13:37:39 +10:00
Hiroku 8f1127be46 Merge branch 'pve-fix' into 'main'
Fix BattleBuilder's Successful-ness

See merge request cable-mc/cobblemon!976
2024-04-26 00:44:27 +00:00
Hiroku 26a8bf1ca5 Merge branch 'idev-botarium-crash-fix' into 'main'
Fix for a very specific issue where Botarium and Cobblemon will have mapping...

See merge request cable-mc/cobblemon!975
2024-04-25 23:43:58 +00:00
Tyzillion 28c0e17a48 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into move-effects 2024-04-25 18:21:18 -04:00
Stampede d3da8c99a8 Simplify battle success fix and apply to 1v1s 2024-04-25 16:41:56 -05:00
Stampede d106deb7f6 Fix PvE battles not returning successful even it was 2024-04-25 14:32:57 -05:00
Waterpicker f1d1e87e47 Fix for a very specific issue where Botarium and Cobblemon will have mapping conflicts indev when the project uses mojang due to how kotlin syntax works. 2024-04-25 12:20:48 -05:00
FrankTheFarmer 87e41bdb89 Fixed Kabuto animation but on implementation branch 2024-04-25 22:22:18 +10:00
FrankTheFarmer 8a8505d816 3/4 of the Galar fossils can now look at the player. 2024-04-25 21:04:04 +10:00
Paul 2d9d6e172c Updated pt_pt 2024-04-25 19:19:07 +10:00
Paul 3c03b0e210 Updated many translations (de_de, en_pt, es_es, es_mx, fr_ca, fr_fr, ja_jp, ko_kr, pl_pl, ru_ru) 2024-04-25 19:03:35 +10:00
FrankTheFarmer 1a19c51748 Fixed Slowpoke spawning everywhere 2024-04-25 17:16:37 +10:00
FrankTheFarmer 8a66ab9235 Removed unimplemented cries from sounds json 2024-04-25 16:41:11 +10:00
Nick 724c674992 Fix packet/mixin issues related to forge, bump KFF version, and build details 2024-04-24 22:07:31 -07:00
Paul 99eb317a87 Fixed Kabuto animations 2024-04-25 13:32:06 +10:00
Hiroku 43a2c2f55d Merge branch 'implement_pokemon' into 'main'
Implementation stuff

See merge request cable-mc/cobblemon!973
2024-04-25 02:00:16 +00:00
Frank The FarmerandHiroku 4db9a35f2b Implementation stuff 2024-04-25 02:00:16 +00:00
Paul ee50361555 Merge remote-tracking branch 'origin/main' into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2024-04-25 11:47:23 +10:00
Paul d3631f1436 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-25 10:28:21 +10:00
Paul 31136435fe Fixed autogeneration of target and special_attack locators 2024-04-25 10:20:19 +10:00
Paul bdeb83c62c Fixed entity_particles parsing of the effect ID when it's a simple string 2024-04-25 10:20:01 +10:00
FrankTheFarmer 79e1f9143c Fixed Wooloo's blink and leg but in game 2024-04-25 10:07:09 +10:00
Paul 15bf726421 Merge remote-tracking branch 'origin/main' into move-effects 2024-04-24 15:13:23 +10:00
Hiroku 8228ac517b Merge branch 'interpreter_my_beloved' into 'main'
Misc interpreter refactor fixes

See merge request cable-mc/cobblemon!972
2024-04-24 02:48:02 +00:00
DoctorWafflePhD 7f1889db7b bubblebeam VFX uploaded for review by hiroku (thanks oomfie) 2024-04-23 21:42:16 -05:00
DoctorWafflePhD 548c18bea4 hit particle fix(?) 2024-04-23 21:41:46 -05:00
DoctorWafflePhD d9203bef2a hit particle fix(?) 2024-04-23 21:06:57 -05:00
FrankTheFarmer bef0b2fb87 Updated regional bias evolution data to hopefully work as intended. I hate evolution. 2024-04-23 20:49:22 +10:00
FrankTheFarmer d7bbc05af8 Created biome tags for the regional bias evolutions. They're specific to each form's spawn data 2024-04-23 20:47:27 +10:00
FrankTheFarmer 7ca3ab5e30 Updated portrait data for the Samurotts 2024-04-23 20:43:44 +10:00
FrankTheFarmer 1bbb1201c8 Chansey animation fixes. Cry implemented but no sound file yet 2024-04-23 18:20:26 +10:00
FrankTheFarmer 8ed4fee8af Added more visual distinction for Hisui Bias Quilava in the evolution menu. Plus Cyndaquil textures 2024-04-23 17:18:07 +10:00
FrankTheFarmer a3dacc2c3d Forgot about the changelog lol 2024-04-22 20:50:03 +10:00
FrankTheFarmer c265f73308 Fixed eyes on the faints of Hitmonlee and Phantump 2024-04-22 20:40:12 +10:00
FrankTheFarmer 670dedc0e2 Grovyle shiny texture fixes 2024-04-22 14:01:59 +10:00
Tyzillion 5e24799295 move effects are in the works now. :) 2024-04-21 23:05:41 -04:00
Tyzillion a7243102d5 Evolution particle tweaks and Pokemon now stop moving if evolution is started. 2024-04-21 21:06:47 -04:00
Tyzillion de6a84a75b Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into evolution-effect 2024-04-21 19:37:16 -04:00
FrankTheFarmer 6e19ee6059 Tricko remodel 2024-04-22 09:05:52 +10:00
Tyzillion be3c35eb43 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into evolution-effect 2024-04-21 11:21:57 -04:00
FrankTheFarmer a865d59b99 changelog update 2024-04-21 17:27:38 +10:00
FrankTheFarmer 8896440451 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-21 17:09:04 +10:00
FrankTheFarmer 39b27a8c17 Quick and dirty fixes for Pikachu and Exeggcute evolution data. Added new biome tag for their evolution requirements. 2024-04-21 16:41:50 +10:00
Sterrezo a0eb614f2a Kabuto now does the funny noise. Fixed Lucario's cry missing
I didn't know what to do with Kabuto's animation, ended up using a placeholder. Lucario had an incorrectly named keyframe.
2024-04-15 23:26:44 +02:00
FrankTheFarmer a6e4aeb321 The Doduo line will now bite less 2024-04-15 15:57:48 +10:00
FrankTheFarmer bb796921b5 Changelog updates. Removed duplicates and added list of new shoulder mounts 2024-04-15 10:30:11 +10:00
FrankTheFarmer 9f6f764aa1 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-15 07:59:57 +10:00
FrankTheFarmer f115a87b66 Roaming Gimmighoul can now evolve 2024-04-15 07:59:31 +10:00
Waldleufer 77c880ff2d fix: cry script - relaxing handling of all Forms, skipping non-regional forms [skip-ci] 2024-04-14 09:29:01 +02:00
FrankTheFarmer 16c64b9d8e Updated behaviour for Armaldo, Carracosta, Tirtouga, and Wimpod 2024-04-14 12:26:45 +10:00
FrankTheFarmer caeb45e9e1 Tyrantrum line kotlin poser placed in the proper generation. 2024-04-14 12:23:03 +10:00
FrankTheFarmer 6e341438e9 Goomy line updates and Steenee scale update 2024-04-14 11:38:17 +10:00
Tyzillion 7407483498 Updated Branch with latest main. Added Lucario aura in battle. 2024-04-13 16:34:44 -04:00
Tyzillion 020c728004 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-13 14:55:15 -04:00
Sterrezo 7125987c98 Fixed Hisuian Lilligant's cry missing
Asset was incorrectly named
2024-04-13 20:33:25 +02:00
Waldleufer 6448c4472e fix: cry script - handling all Forms, skipping non-regional forms [skip-ci] 2024-04-13 20:11:26 +02:00
Waldleufer eedac70d13 fix: cry script - sprinkling in some magic [skip-ci] 2024-04-13 19:07:48 +02:00
Sterrezo 025e09cd12 Couple cry fixes
Updated KrabbyModel.kt. Fixed missing or incorrect sound effect keyframes in animation.json files.
2024-04-13 18:54:55 +02:00
Waldleufer 4d2cfb63ea fix: cry script - warn about files not in the right locations [skip-ci] 2024-04-13 18:52:27 +02:00
Waldleufer 40794acdd5 fix: cry script - properly check elaborate cries [skip-ci] 2024-04-13 18:25:25 +02:00
Sterrezo 82f8855725 Fixed missing Grovyle and Sceptile cries missing 2024-04-13 17:57:21 +02:00
Waldleufer 5abcdbb837 fix: cry script - new way to implement cries does not require an import [skip-ci] 2024-04-13 17:48:01 +02:00
Waldleufer 2f817a7f9a fix: cry script - ignore commented out lines [skip-ci] 2024-04-13 17:33:35 +02:00
Waldleufer 67767fc53a fix: cry script - only log warnings for pokemon marked as "In-Game" [skip-ci] 2024-04-13 17:16:34 +02:00
Tyzillion 43cd4b8403 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-04-13 02:50:14 -04:00
Tyzillion 2660d73bb6 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-13 02:49:33 -04:00
FrankTheFarmerReal faa7ca5d19 Revoking Hisuian Visas 2024-04-13 11:48:17 +10:00
Tyzillion 0fcbe51d97 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-04-12 11:16:59 -04:00
Tyzillion b23ad62f99 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-12 11:16:44 -04:00
Sterrezo 3ca4ce8f80 Implemented 13 new cries, more changelog updates with previously undocumented cries 2024-04-12 16:47:25 +02:00
Sterrezo 446a994195 Fixed a typo in komala.animation.json 2024-04-12 16:14:12 +02:00
Sterrezo 60e7ac828d Implemented more cries, updated changelog
Added cries for Goomy, Sliggoo, Goodra, Hisui Bias Goomy, Hisuian Sliggoo, Hisuian Goodra, Klefki. Fixed Arcanine's cry misisng. Updated changelog with previously undocumented cries.
2024-04-12 13:10:18 +02:00
Sterrezo a870effd3b Added a keyframe with a cry for Lapras 2024-04-12 10:27:53 +02:00
FrankTheFarmerReal 236237a170 The simple blink of a Bouffalant shall no longer crash your game 2024-04-12 17:00:37 +10:00
FrankTheFarmerReal 0fc67ba042 Updated Goomy's hisui bias assets and added missing oinkologne cry files. 2024-04-12 13:32:48 +10:00
FrankTheFarmerReal 997ab29d91 Added a couple cries 2024-04-12 11:29:01 +10:00
FrankTheFarmerReal e74f54f1d0 Implemented Kotlin posers for Hisuian starters unique cries
Deleted Datrix
2024-04-12 00:05:12 +10:00
Sterrezo 081e368551 Merge branch 'implement_pokemon' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-04-11 14:04:44 +02:00
Sterrezo 1538f58a4a Added audio assets for previously added cries 2024-04-11 14:04:16 +02:00
FrankTheFarmerReal e5103e5d03 Separated Oinkologne models to allow for separate cries 2024-04-11 21:54:01 +10:00
FrankTheFarmerReal 1cea15c9e5 Fixed Milcery being unable to evolve properly 2024-04-11 21:49:58 +10:00
FrankTheFarmerReal 3395fe0140 Hisuian Samurott texture fixed 2024-04-11 21:49:58 +10:00
FrankTheFarmerReal 2eff8d14eb Fixed Happiny being unable to evolve 2024-04-11 21:49:58 +10:00
FrankTheFarmerReal ed3cdf9b75 Limited the Typhlosions and Cyndaquils ability to look up to prevent bone dislocation in certain scenarios 2024-04-11 21:49:58 +10:00
FrankTheFarmerReal 6e1ba0599f Corrected egg groups for Toedscool line 2024-04-11 21:49:58 +10:00
FrankTheFarmerReal 497d5ce39b Basculegion behaviour updated. Should stop drowning. 2024-04-11 21:49:58 +10:00
FrankTheFarmerReal 660de3ea03 Dusknoir animations updated 2024-04-11 21:49:58 +10:00
FrankTheFarmerReal 5ab3d7b493 Updated Ekans texture 2024-04-11 21:49:57 +10:00
FrankTheFarmerReal 2ce0069484 Closed Scyther's mouth after it cries 2024-04-11 21:49:57 +10:00
Sterrezo d87fa57c95 Implemented a bunch of cries
Woobat, Swoobat, Lilligant, Hisuian Lilligant, Basculin, Klink (Deleted a redundant animation file as well), Klang, Klinklang, Litwick, Lampent, Chandelure, Cubchoo, Bouffalant, Larvesta, Volcarona, Fomanting, Lurantis, Gossifleur, Eldegoss, Stonjourner, Basculegion, Sneasler, Overqwil, Oinkologne
2024-04-11 13:40:36 +02:00
FrankTheFarmerReal 69947b0b32 Fixed Flabebe line T pose when sleeping 2024-04-11 09:01:02 +10:00
Tyzillion f4c3f9ae04 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-04-10 09:34:02 -04:00
FrankTheFarmerReal 04e1a6b41c Removed duplicate entry from changelog 2024-04-10 18:13:26 +10:00
FrankTheFarmerReal 6ae2adb2d0 Stopped Pumpkaboo's cry from looping 2024-04-10 17:12:44 +10:00
FrankTheFarmerReal 0bf6932fe5 Dusknoir's animations are now about 20 degrees cooler™ 2024-04-10 09:59:27 +10:00
FrankTheFarmerReal 71382a3bd1 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-09 10:27:14 +10:00
FrankTheFarmerReal 0f4f29518b Placeholder Volcarona animations 2024-04-09 10:26:37 +10:00
Sterrezo 8aeeece0a3 Fixed missing cries, updated the changelog.
Fixed missing audio files, sound effect keyframes and model.kt files. Partially updated the changelog.
2024-04-08 18:55:58 +02:00
Paul 850b418c80 Improve surface-swimmers behaviour when submerged 2024-04-08 22:51:04 +10:00
FrankTheFarmerReal 42af2898b2 Hitbox fixes and Lapras placeholder swim animation 2024-04-08 18:23:01 +10:00
Tyzillion b4508bf87e More tweaks to evolution particles. 2024-03-10 06:29:27 -04:00
Tyzillion dcb4f52cdb Added sounds to evolution. 2024-03-10 00:32:08 -05:00
Tyzillion 1e9b390f38 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into evolution-effect 2024-03-09 23:34:36 -05:00
Tyzillion 7edd47f995 Evolution tweaks. 2024-03-08 19:12:46 -05:00
Tyzillion dd220c5c85 Merge remote-tracking branch 'origin/evolution-effect' into evolution-effect 2024-03-07 22:02:04 -05:00
Paul bea84a37d4 Fixed a bunch of evolution animation locator issues 2024-03-08 13:01:42 +10:00
Tyzillion ac30da3c15 Merge remote-tracking branch 'origin/evolution-effect' into evolution-effect 2024-03-07 20:58:08 -05:00
Paul 3861835d47 Test command spawns bedrock entity for evo 2024-03-06 21:06:38 +10:00
Tyzillion d62fb5c4c7 Merge remote-tracking branch 'origin/evolution-effect' into evolution-effect 2024-03-03 20:58:44 -05:00
Paul ca9dde92cd Merge remote-tracking branch 'origin/main' into evolution-effect 2024-03-04 11:32:33 +10:00
Tyzillion 6ba264ddcb Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into evolution-effect 2024-03-03 20:26:59 -05:00
Tyzillion ab6c088ddf Evolution particle edits. 2024-03-03 17:56:50 -05:00
Tyzillion 18105a8b3f Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into evolution-effect 2024-03-03 17:56:44 -05:00
Tyzillion acb5984a9e Evolution particles electric boogaloo. 2024-03-03 03:50:33 -05:00
Paul 0a3ba8d4fa Fixed generic bedrock animations not being loaded 2024-03-03 17:37:43 +10:00
Paul 15259f0a95 Merge remote-tracking branch 'origin/main' into evolution-effect 2024-03-03 17:32:04 +10:00
Tyzillion 9f66c053e1 Evolution Particles BB. 2024-03-03 02:25:10 -05:00
apion 743da2817b Added rooted soil 2024-02-27 06:07:24 -05:00
apion ebdf69f496 Rebuilt blockstate jsons 2024-02-27 05:57:41 -05:00
apion 995364c960 Texture updates 2024-02-23 19:53:27 -05:00
apion 289b2ddc7b Berries now stick out of the ground when initially planted 2024-02-23 19:08:03 -05:00
2966 changed files with 57759 additions and 12014 deletions
+1
View File
@@ -3,3 +3,4 @@
# are changed when only line endings change.
src/generated/**/.cache/cache text eol=lf
src/generated/**/*.json text eol=lf
CHANGELOG.md merge=union
+3
View File
@@ -21,6 +21,8 @@ build
# other
eclipse
run
runClient
runServer
# Files from Forge MDK
forge*changelog.txt
@@ -34,6 +36,7 @@ common/src/main/resources/assets/cobblemon/showdown
*/generated/resources/*
/fabric/src/generated/resources/cobblemon-common.accesswidener
/.ignored/
common/.fabric
# MacOS
.DS_Store
+285 -75
View File
@@ -1,43 +1,181 @@
# Changelog
## [1.5.0](#1-5-0)
## [1.5.3](#1-5-3)
### Fixes
- Scaled down Amaura's fetus model to avoid clipping through the tank while animating
- Added Polished Tumblestone and Tumblestone Brick block sets from Tumblestone, Black Tumblestone, and Sky Tumblestone.
- Fixed Cubone's cry not having a sound.
- 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.
- Fixed Pokémon losing their Hidden Ability through evolution if the middle stage did not have a Hidden Ability.
- Fixed Crumbling Arch not blending in with the world.
- Fixed Energy Root applying being usable on a fainted Pokemon.
- Fixed Pokémon entity not spawning when starting a battle while recalling said Pokémon
### Additions
- Added extra visuals to early berry growth stages
### Added cries to the following Pokémon
- Timburr, Gurdurr, Conkeldurr
- Golett, Golurk
### Changes
- Altered the item model for Medicinal Leeks and Roasted Leeks to be held like sticks and other rod items.
- Adjusted some berry balance values like yield and growth times
- Changes to mulch buffs/durations
### Developer
### Data Pack & Resource Pack Creators
- Added support for "shedders" similar to Shedinja's evolution logic.
## [1.5.2 (May 27th, 2024)](#1-5-2)
### Fixes
- Fixed Wooloo and Dubwool dyeing making your game start dying. Only if you do it on a server.
- Fixed Gimmighoul causing PCs and parties to look glitched out, also only in a server.
- Fixed players being able to dye other people's sheep Pokémon.
## [1.5.1 (May 27th, 2024)](#1-5-1)
### Additions
- Added unique send out particles for Cherish, Dream, Beast, and Ancient Origin balls.
- Made Wooloo and Dubwool dye-able like sheep. So cute!
- Added stat up and down particles.
- Most status effects now have particles! These include: Paralysis, Poison, Sleep, Confusion, Infatuation.
#### Move Particle Effects
- Confusion
- Cotton Guard
- Growl
- Ice Punch
- Fire Punch
- Thunder Punch
- Minimize
- Quick Attack
- Protect
- Swords Dance
- Sand Attack
- Poison Powder
- Sleep Powder
- Stun Spore
- Powder
- Rage Powder
- Spore
- Thunder Wave
### 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.
- Made Mulch cheaper to craft.
### Fixes
- Fixed a bug in which adding organic material to the restoration tank via right click was adding the full count of the stack currently in hand - but only taking 1 of the item.
- Fixed a niche issue where some properties of entities were not initialized correctly, causing Pokémon that appeared to be level 1 until you battle them.
- Fixed Fossilized Drake being missing from the Fossils item tag.
- Fixed Gilded Chest block entity not being cleared on block break, creating spooky ghost blocks. Old ones can be fixed by placing something like a furnace where it was, then breaking the furnace.
- Fixed sherd brokenness on Forge.
- 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 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 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 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.
- Fixed issue where the restoration tank's renderer was reading old data, making it appear wrong.
- Fixed issue where the lights on the restoration tank would not animate if it was facing east. Very specific.
- Fixed client crash with the fossil machine when updating block state on a chunk that is unloaded in the client. I don't understand this but the devs are sure that all of those are real words.
- Fixed Restoration Tank crash with Create upon the tank block's destruction.
- Fixed Restoration Tank over consuming items when interacting with Create blocks.
- Fixed addons that add very many moves to a learn-set causing disappearing Pokémon (visually) issues on servers.
- Fixed Hyper Cutter and Big Pecks incorrectly stating that it prevented accuracy from being lowered in battle.
- Fixed missing messages for Rough Skin and Iron Barbs in battle.
- Fixed a bug where sometimes Pokémon sendouts wouldn't create an entity, or the entity would spawn at 0 0 0 which is not a good place for a Pokémon to be. Or any of us, really.
- Fixed issue in which a locked gilded chest would animate to the open state when the client fails to open it, such as when it is locked.
- Fixed a bug where aspects of a form would not be properly reflected on form changes (eg. Normal -> Hisui).
- 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 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.
- Fixed root-part animations not working for JSON posed Pokémon. You didn't notice this but if we didn't fix this in this update then if you use Quick Attack a lot you'd have seen a whole lot of [this](https://cdn.discordapp.com/attachments/1076993968803434627/1242660506783715369/Minecraft__1.20.1_-_Singleplayer_2024-05-21_22-08-17.mp4?ex=66549408&is=66534288&hm=ff95ee293eb15634fd63e6546534ea279540a1c892605e8d561593ca2c5600c5&) which is damn funny but very unintended.
### Developer
- Changed SpawnAction#complete to return a nullable generic R (the spawn action result) instead of a boolean. Provides more information this way.
- Added an event that fires when a fossil is revived, with or without a player.
- Added IVS and EVS property extractors.
- Fixed PCStore#resize not allowing PC boxes size reduction.
### Data Pack & Resource Pack Creators
- Added support for MoLang conditions for quirks and poses.
- Changed the AttackDefenceRatio requirement to StatCompare and StatEqual. There is some backwards compatibility for AttackDefenceRatio, though.
- Changed "dimensions" spawn condition to check with dimension IDs instead of effects, so custom dimension IDs can be used.
- 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>'))"
]
}
```
### Localization
- Updated translations for:
- Simplified and Traditional Chinese.
- Spanish.
## [1.5.0 - The Ruins and Revival Update (May 12th, 2024)](#1-5-0)
#### "You're telling me that Mojang has added archaeology to the game? Hmm... that gives me an idea."
### Additions
- Added 17 ruin structures, where you can find Pokémon-themed Armor Trims and Pottery Sherds, Tumblestones, and more.
- Added 22 fossil structures, where you can brush Suspicious Sand/Gravel for Fossils.
- Added the Data Monitor, Fossil Compartment, and Restoration Tank. Placed in the correct formation, you can use these to create a Restoration Machine where you can bring fossils back to life.
- Added 3 variants of Tumblestones, which can be planted near Lava or Magma to grow harvestable Tumblestone Clusters.
- Added 23 fossil structures, where you can brush Suspicious Sand/Gravel for [Fossils](https://wiki.cobblemon.com/index.php/Fossil). You can add [custom fossils using datapacks](https://wiki.cobblemon.com/index.php/Fossils_File).
- Added the Data Monitor, Fossil Compartment, and Restoration Tank blocks. Placed in the correct formation, you can use these to create a [Restoration Machine](https://wiki.cobblemon.com/index.php/Resurrection_Machine) where you can bring fossils back to life. Use organic material to fill the tank first!
- Added 3 variants of [Tumblestone](https://wiki.cobblemon.com/index.php/Tumblestone), which can be planted near Lava or Magma to grow harvestable Tumblestone Clusters.
- Added Tumblestone Blocks, a storage block crafted from 9 Tumblestones.
- Added Ancient Poké Balls, which are aesthetic variants crafted from Tumblestones.
- Added the Ancient Feather, Wing, and Jet Balls, which fly further than regular Poké Balls.
- Added the Ancient Heavy, Leaden, and Gigaton Balls, which are heavier and don't fly as far as regular Poké Balls. These will receive more functionality in a future update.
- Added Original Trainer functionality. To edit the OT through commands, you must specify originaltrainertype=<Player/NPC>, and originaltrainer=<Username or UUID/NPC Name>
- Added visual effects for many Poké Balls when sending out or capturing Pokémon.
- Added a new send-out ball toss animation that showcases the ball used for the Pokémon.
- Added simple move animations for Pokémon in battle with a proof of concept (Flamethrower) for more complicated animations. More and more specific animations will come in future updates.
- Added Original Trainer to the summary menu. To edit the OT through commands, you must specify originaltrainertype=<Player/NPC>, and originaltrainer=<Username or UUID/NPC Name>
- Added support for planting Apricorn trees, berries, and mints in [Botany Pots](https://modrinth.com/mod/botany-pots)
- Added the hidden "True Vivillionaire" advancement.
- The "Poké Ball" Vivillon variant is now obtainable by evolving a Spewpa after obtaining the "Aspiring Vivillionaire" advancement.
- Added dynamic lighting support for any Species or Forms when using [LambDynamicLights](https://modrinth.com/mod/lambdynamiclights) or [Dynamic Lights Reforged](https://www.curseforge.com/minecraft/mc-mods/dynamiclights-reforged), at this time we don't ship with any defaults for this feature but addon creators can make use of this feature.
- Added a Display Case block! Use it to display your archaeological findings, or other items.
- Added 6 Pokémon-themed Pottery Sherds, obtained from ruin structures.
- Added the [Display Case](https://wiki.cobblemon.com/index.php/Display_Case) block. Use it to display your archaeological findings, Poké Balls, or other items.
- Added 6 Pokémon-themed Pottery Sherds, obtained from ruin structures. Sherds... sh-erds. Weird word.
- Added a Pokémon-themed armor trim, obtained from ruin structures.
- You can now find Nether Fire Stone Ore in, surprisingly, the Nether.
- You'll also find Terracotta Sun Stone Ore in Badlands biomes.
- Added effects for many Poké Balls when sending out Pokémon or capturing.
- Added a new send-out ball toss animation that showcases the ball used for the Pokémon.
- Added simple move animations for Pokémon in battle with a proof of concept for more complicated animations.
- Added Nether Fire Stone Ore to, surprisingly, the Nether.
- Added Terracotta Sun Stone Ore to Badlands biomes.
- Added the EV Boosting Feathers.
- Added Type Gems.
- Added various new tags for searchability and better compatibility.
- Added the [Ability Capsule](https://bulbapedia.bulbagarden.net/wiki/Ability_Capsule) and [Patch](https://bulbapedia.bulbagarden.net/wiki/Ability_Patch), these have no acquisition method for now and only work as intended with the traditional ability format of 1 to 2 common abilities and 1 hidden ability.
- Added Gilded Chests, available in all Apricorn colors.
- Added Relic Coins, Relic Coin Pouches, and Relic Coin Sacks.
- Added Type Gems. These items hold no functionality for now. Start collecting though...
- Added 6 custom Pottery Sherds, obtained from ruin structures.
- Added cries to Meowth, Alolan Meowth, Galaraian Meowth,
- Completed the advancement for placing a Tumblestone near Lava or Magma to make it grow.
- Added [Gilded Chests](https://wiki.cobblemon.com/index.php/Gilded_Chest), available in all Apricorn colors.
- Added Relic Coins, Relic Coin Pouches, and Relic Coin Sacks. Gimmighoul might be interested in these.
- Added Type Gems. These will have additional uses later, so you should start collecting them.
- Added new held items: Ability Shield, Absorb Bulb, Air Balloon, Binding Band, Blunder Policy, Cell Battery, Covert Cloak, Damp Rock, Eject Button, Eviolite, Expert Belt, Float Stone, Focus Sash, Heat Rock, Icy Rock, Iron Ball, Light Ball, Loaded Dice, Red Card, Shell Bell, Sticky Barb, Smooth Rock, Soothe Bell and Weakness Policy.
- Added Hisui starters to the starter selection menu.
- Added bubble quirk to Krabby that only play during clear sunset's.
- Added Hisui starters to the starter selection menu. They come inside of ancient Poké Balls.
- Added a bubble quirk to Krabby that only plays during clear sunsets. It looks familiar...
- Added forfeit option to PVP battles.
- Added visual changes for entities affected by Illusion, Imposter, or Transform in battle.
- Added shoulder mounting for Squirtle, Ralts, Roggenrola, Charcadet, Sizzlipede, Litwick, Cutiefly, Flabebe, Flittle, and Scatterbug
- Added species data for Hydrapple, Iron Boulder, Iron Crown, Pecharunt, Raging Bolt, and Terapagos
- Added various new tags for search-ability and better mod compatibility.
- Added the [Ability Capsule](https://bulbapedia.bulbagarden.net/wiki/Ability_Capsule) and [Patch](https://bulbapedia.bulbagarden.net/wiki/Ability_Patch). These have no way of getting them (for now) and only work as intended with the traditional ability format of 1 to 2 common abilities and 1 hidden ability.
### Pokémon Added
#### Gen 2
@@ -161,8 +299,6 @@
- Dreepy
- Drakloak
- Dragapult
- Hisuian Sliggoo
- Hisuian Goodra
- Impidimp
- Morgrem
- Grimmsnarl
@@ -170,10 +306,10 @@
#### Gen 9
- Gimmighoul
- Using Relic Coins, you can increase Gimmighoul's Coin Stash. Upon reaching 999, it can be evolved into Gholdengo.
- Additionally, if you give Gimmighoul a Netherite Scrap, you can increase its Netherite Stash. Who knows what might happen if it fills up?
- Additionally, if you give Gimmighoul a Netherite Scrap, you can increase its Netherite Stash. But what will that do to when you evolve it?
- Gholdengo
#### Cobblemon Exclusive's
#### Cobblemon Exclusives
- Hisui Bias Rowlet
- Hisui Bias Dartrix
- Hisui Bias Cyndaquil
@@ -183,82 +319,153 @@
- Hisui Bias Goomy
- Hisui Bias Petilil
These are our compromise for having both regular and Hisuian forms of these Pokémon in the game. Hisui Biased variations will evolve into the Hisuian evolutions under most conditions. They are otherwise purely cosmetic differences.
### Added cries to the following Pokémon
- Alolan Raticate
- Vulpix, Ninetales
- Zubat, Golbat, Crobat
- Meowth, Persian
- Psyduck, Golduck
- Growlithe, Arcanine
- Geodude, Graveler, Golem
- Doduo, Dodrio
- Seel, Dewgong
- Muk, Grimer
- Krabby, Kingler
- Voltorb, Electrode, Hisuian Voltorb, Hisuian Electrode
- Tangela, Tangrowth
- Snorlax
- Cubone, Marowak
- Koffing, Weezing
- Aerodactyl
- Elekid, Electabuzz, Electivire
- Omanyte, Omastar
- Kabuto, Kabutops
- Lapras
- Scyther
- Hisui Bias Cyndaquil, Hisui Bias Quilava
- Igglybuff
- Yanma, Yanmega
- Gligar, Gliscor
- Qwilfish, Hisuian Qwilfish, Overqwil
- Sneasel, Hisuian Sneasel, Weavile, Sneasler
- Larvitar, Pupitar, Tyranitar
- Swinub, Piloswine, Mamoswine
- Aron, Lairon, Aggron
- Trapinch, Vibrava, Flygon
- Cacnea, Cacturne
- Barboach, Whiscash
- Lileep, Cradily
- Anorith, Armaldo
- Tropius
- Chimecho
- Bidoof, Bibarel
- Buizel, Floatzel
- Gible, Gabite, Garchomp
- Hisui Bias Oshawott, Hisui Bias Dewott
- Petilil, Lilligant, Hisui Bias Petilil, Hisuian Lilligant
- Basculin, Basculegion
- Sandile, Krokolok, Krookodile
- Darumaka, Darmanitan
- Archen, Archeops
- Zorua, Zoroark, Hisuian Zorua, Hisuian Zoroark
- Tyrunt, Tyrantrum
- Amaura Aurorus
- Carbink
- Goomy, Sliggoo, Goodra, Hisui Bias Goomy, Hisuian Sliggoo, Hisuian Goodra
- Klefki
- Hisui Bias Rowlet, Hisui Bias Dartrix
- Komala
- Impidimp, Morgrem, Grimmsnarl
- Cufant, Copperajah
- Dreepy, Drakloak, Dragapult
- Dracozolt, Arctozolt, Dracovish, Arctovish
- Lechonk, Oinkologne
- Maushold family of three and four
### Changes
- Alolan Pikachu and Exeggcute changed to Alola bias.
- Alolan Pikachu and Exeggcute changed to Alola Bias.
- Pokémon now transition more smoothly between different poses.
- Updated models for Mimikyu, Alcremie, Squirtle, Wartortle, Blastoise, Pidgey, Pidgeotto, Pidgeot, Omanyte, Omastar, Growlithe, Arcanine, Nidoran Male, Nidoran Female, Lapras, Swinub, Piloswine, Basculin, Rowlet, Dartrix, Decidueye, Kabuto, Kabutops, Piplup, Prinplup, Elekid, Electabuzz, Cubone, Marowak, Paras, Mawile, Drifloon, Drifblim, Venonat, Venomoth, Yanma, Yanmega, Psyduck, Dusknoir, Diglett, Dugtrio, Natu, Xatu, Oshawott, Samurott, Torchic, Grovyle, Sceptile, Sizzlipede, and Raboot.
- Updated models for Mimikyu, Alcremie, Squirtle, Wartortle, Blastoise, Pidgey, Pidgeotto, Pidgeot, Omanyte, Omastar, Growlithe, Arcanine, Nidoran Male, Nidoran Female, Lapras, Swinub, Piloswine, Basculin, Rowlet, Dartrix, Decidueye, Kabuto, Kabutops, Piplup, Prinplup, Elekid, Electabuzz, Cubone, Marowak, Paras, Mawile, Drifloon, Drifblim, Venonat, Venomoth, Yanma, Yanmega, Psyduck, Dusknoir, Diglett, Dugtrio, Natu, Xatu, Oshawott, Samurott, Torchic, Grovyle, Sceptile, Sizzlipede, Mismagius, and Raboot.
- Updated animations for Squirtle, Wartortle, Blastoise, Pidgey, Pidgeotto, Diglett, Dugtrio, Magikarp, Dragonite, Omanyte, Omastar, Kabuto, Pinsir, Chinchou, Lanturn, Ralts, Kirlia, Gardevoir, Gallade, Buizel, Garchomp, Pumpkaboo, Falinks, Lechonk, Litwick, Lampent, Chandelure, Carnivine, Galarian Meowth, Galarian Rapidash, Venonat, Venomoth, Phanphy, Donphan, Dratini, Dragonair, Happiny, Chansey, Blissey, Volbeat, Illumise, Numel, Sizzlipede, Centiskorch, Obstagoon, Timburr, Gurdurr, Conkeldurr, Drifloon, and Drifblim.
- Resized Drifloon.
- Added more held items to the held item tag, and Metal Coat to the held item tab.
- Added all ores to the modloader ore tags, and added tags for each ore type to the mod (both blocks and items).
- Changed the Destiny Knot to be crafted with a Ghast Tear, rather than a diamond.
- You can now punch grown apricorns to harvest them.
- Changed the Destiny Knot to be crafted with a Ghast Tear rather than a diamond. We have big plans for the Destiny Knot...
- You can now punch grown apricorns to harvest them. We saw so many content creators breaking apricorns with their fists that it was making us die inside.
- The "Poké Ball" Vivillon variant is now obtainable by evolving a Spewpa after obtaining the "Aspiring Vivillionaire" advancement.
- Renamed the "Vivillionaire" advancement to "Aspiring Vivillionaire"
- Removed the Inferno, Forsaken, Poké Ball, and Void patterns from the Aspiring Vivillionaire advancement.
- Updated movesets to add Gen 9 DLC moves.
- Updated the biome tags for Spewpa's evolutions into the various Vivillon patterns. You should mostly be getting one evolution option at a time now.
- Apricorn Sprouts can now be planted directly on Apricorn leaves to create a new Apricorn of the same color.
- Added tooltips to interaction GUIs to make it clearer what they do.
- Poké Ball recipes now use tags for their center ingredient, rather than specificied Copper Ingot, Iron Ingot, Gold Ingot, and Diamond, allowing for further datapack customisation.
- Starter Toast now closes once corresponding button is pressed once.
- Moved some items in the vanilla Food & Drinks category.
- Poké Ball recipes now use tags for their center ingredient, rather than specifically Copper Ingots, Iron Ingots, Gold Ingots, and Diamonds, allowing for further datapack customisation and mod compatibility.
- Starter Toast now closes once the corresponding button is pressed once.
- Moved some items into the vanilla Food & Drinks category.
- Stacked Cobblemon Potion Bases can now be quick moved into Brewing Stands.
- Changed Healer recipe to swap the Max Revive for a Revive.
- Upped the rate that Gastly drop Ghast Tears from 2.5% to 5%.
- Changed the Healing Machine recipe to swap the Max Revive for a Revive so that it is a bit easier to craft.
- Upped the rate that Gastly drop Ghast Tears from 2.5% to 5%, further helping the crafting of a Healing Machine.
- Pokémon with a low Blaze Powder drop chance now drop it more frequently in the Nether.
- Reorganised a few advancements.
- Pokémon entity shadows now scale when the Pokémon is being sent out or recalled.
- Remade Torkoal particles, now they only appear when in battle.
- Updated shiny icon within summary and PC interfaces.
- Changed the Poison Barb sprite so that it doesn't look like a sword when held.
- Moon Stone ore generates more frequently in Taigas and has been added to Magical and Spooky biomes.
- Improved the shiny icon within summary and PC interfaces.
- Changed the Poison Barb sprite so that it doesn't look like a sword when held. It's a Poison Barb, not a Poison Sword. Wait, that gives me an idea.
- Moon Stone ore generates more frequently in Taigas and has been added to Magical and Spooky biomes. Ooo... Sorry.
- Density, Season, and Nether biome tags have been moved and renamed within the biome tags directory.
- Added particles to Lucario when in battle. Lucario is special.
- Movesets updated for Blueberry DLC.
### Fixes
- Resized Snorlax
- Re-added the recipe for the Iron Vitamin.
- Cleaned up empty evolutions declaration in species files (no, I'm not listing all 169 by name).
- Fixed Exeggcute not being able to evolve.
- Fixed battle lang for Poison Touch Ability
- Fixed Cubone not being able to evolve into Alolan Marowak.
- Re-added the recipe for the Iron vitamin. Well, technically it's a mineral.
- Fixed Exeggcute and Pikachu not being able to evolve.
- Fixed evolution priority for Exeggcute and Pikachu regional evolutions. Using a thunder stone on Kantonian Pikachu on the beach will give Alolan Raichu. A second thunder stone would then give Kantonian Raichu.
- Fixed battle text for the Poison Touch Ability.
- Finally found Sudowoodo and Bonsly. They were missing spawn data. Same with Drifloon and Litwick. Uh... sorry about that.
- Fixed Squawkabilly forms not being recognized.
- Fixed the bounce animation for Poké Balls being delayed by like, a full second.
- Note blocks now play the correct sound on the Apricorn Plank based blocks.
- Fixed the bounce animation for Poké Balls being delayed by like, a full second. It's enough to drive you mad.
- Note blocks now play the correct sound on the Apricorn Plank-based blocks.
- Fixed an issue with transformed parts in posers causing whacky positional issues.
- Fixed Poké Balls freezing in an open state if you look away when it's meant to close.
- Adds a translation string name to the Empty Pokeball entity.
- Fixed very many issues with Bedrock particle effects.
- Fixed Arbok patterns not being as specific in spawning as they were intended.
- Fixed Poké Balls freezing in an open state if you're looking away at the moment that it's meant to close. This actually fixes some other things but it's hard to explain.
- 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 pathing over snow layers and carpets.
- Fixed Sobble line not being able to swim or breathe underwater.
- Fixed incompatibility with [Just Enough Resources](https://modrinth.com/mod/just-enough-resources-jer).
- Fixed incompatibility with [Visual Overhaul](https://modrinth.com/mod/visual-overhaul).
- Fixed an issue that allowed Pokemon to spawn on rails.
- 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).
- Fixed mod incompatibility with [Visual Overhaul](https://modrinth.com/mod/visual-overhaul).
- Fixed an issue that allowed Pokémon to spawn on rails.
- Fixed the data set on Pokémon when abilities are given via properties such as in ``/spawnpokemon``.
- Fixed sometimes Pokémon losing hidden abilities when evolving, this fix will only take effect to newly created Pokémon.
- Fixed capture messages not displaying.
- Fixed illusion ability causing the wrong Pokémon to be targeted in battle.
- Battles starting with fainted party members no longer cause a softlock on defeat.
- 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 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.
- Cleaned up empty evolutions declaration in species data (And no, I'm not listing all 169. No I don't care what you pay me, I'm not doing it).
- Fixed non-consumable held items being consumed or swapped in battle permanently.
### Developer
- Significantly changed the way properties in PokemonEntity work. This could break some plugins (not in a big way, but changes will be needed).
- Rebuilt the scheduling API to more clearly force side choices and temporal frames of reference for tasks.
- Added dialogue API and data registry.
- Significantly changed the way the properties in PokemonEntity work. This could break some plugins (not in a big way, but changes will be needed for some things).
- Rebuilt the scheduling API to more clearly force side choices and temporal frames of reference for tasks. The developers say that how it works is cool but I stopped listening.
- Added dialogue API and data registry. This is powerful, and there is a full example in the Cobblemon mod you can trigger using /opendialogue \<username\> cobblemon:example. The example JSON is inside the data folder of the mod.
- Opened up the ItemDropEntry class to allow for it to be extended.
- Added a new "advancement" evolution variant that takes an advancement identifier and succeeds if the player has the advancement.
- Made spawning API capable of non-entity spawning
- Made PokemonProperties.parse more interoperable with Java.
- 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``.
- API to support dynamic lighting in any mod that implements this feature has been added to all Species & Forms, see LightingData class for details.
- Added a Mixin for the BrewingStandScreenHandler to fix the incorrect handling of quickMove in Fabric.
- 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.
- ``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.
- ``AbilityChanger`` has been added to API alongside some implementations, this is subject to change as the ability capsule and patch currently only expect the traditional behaviour in the Pokémon games of 1 to 2 regular abilities and 1 hidden.
- ``Pokemon#rollAbility`` has been added, this rerolls a legal ability for the Pokémon.
- `docs/cobblemon-tags` tags and spawn-presets can now be auto-generated from the current tags in the cobblemon mod with the `generateSpawnPresetList.py` and `generateTagList.py` scripts.
- ``AbilityChanger`` has been added to API alongside some implementations, this is subject to change as the ability capsule and patch currently only expect the traditional behaviour in the Pokémon games of 1 or 2 regular abilities and 1 hidden ability.
- ``Pokemon#rollAbility`` has been added which rerolls for a legal ability for the Pokémon.
- `docs/cobblemon-tags` tags and spawn-presets can now be auto-generated from the current tags in the Cobblemon mod with the `generateSpawnPresetList.py` and `generateTagList.py` scripts.
- `public_spawns_to_json.py` script has been added to give the powerful spawn.json generator a simplistic UI.
- Updated Showdown with Gen 9 DLC.
- Updated Showdown with Gen 9 DLC.
- Changed mixins to be Java 17 for compatibility level instead of 16, removing a warning from startup logs.
### Datapack & Resourcepack Creators
- The maximum amount of fossils that can fit in the Fossil Analyzer can be adjusted in the config.
@@ -428,6 +635,7 @@
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)
#### "No, we don't provide the friends."
### Additions
- Added pasture blocks, used to let your PC Pokémon roam around an area.
- Added nicknaming from the summary menu of a Pokémon (click their name).
@@ -968,6 +1176,7 @@ Thank you so much to all of our community translators that bring the mod to the
- All the translators that contributed are amazing.
## [1.3.0 - The Foundation Update (March 17th, 2023)](#1-3-0)
#### "Now we can start doing the really cool stuff."
### Dependencies
- Upgraded Fabric API dependence to 0.75.1+1.19.2
@@ -1117,6 +1326,7 @@ Thank you so much to all of our community translators that bring the mod to the
- Thank you to all of the fantastic volunteer translators for taking the time to help with this!
## [1.2.0 - The Customization Update (January 1st, 2023)](#1-2-0)
#### "There are going to be so many fakemon..."
### Additions
- Added models for Natu and Xatu, Murkrow and Honchkrow, Wailmer and Wailord.
- Added new PC interface and it is beautiful.
@@ -1230,4 +1440,4 @@ Thank you so much to all of our community translators that bring the mod to the
- Added species, ability, and move translations for `ko_ko`, `jp_jp`, `fr_fr`, `es_es`, `it_it`, and `zh_cn`.
## [1.0.0 (November 12th, 2022)](#1-0-0)
- Initial release.
- Initial release.
-10
View File
@@ -1,10 +0,0 @@
import ca.stellardrift.build.configurate.ConfigFormats
import ca.stellardrift.build.configurate.catalog.PolyglotVersionCatalogExtension
plugins {
id("ca.stellardrift.polyglot-version-catalogs") version "5.0.1"
}
extensions.configure<PolyglotVersionCatalogExtension> {
from(ConfigFormats.YAML, file("../gradle/libs.versions.yml"))
}
@@ -1,32 +0,0 @@
plugins {
id("cobblemon.base-conventions")
id("com.github.johnrengelman.shadow")
}
val bundle: Configuration by configurations.creating {
isCanBeConsumed = false
isCanBeResolved = true
}
tasks {
jar {
archiveBaseName.set("Cobblemon-${project.name}")
archiveClassifier.set("dev-slim")
}
shadowJar {
archiveClassifier.set("dev-shadow")
archiveBaseName.set("Cobblemon-${project.name}")
configurations = listOf(bundle)
mergeServiceFiles()
}
remapJar {
dependsOn(shadowJar)
inputFile.set(shadowJar.flatMap { it.archiveFile })
archiveBaseName.set("Cobblemon-${project.name}")
archiveVersion.set("${rootProject.version}")
}
}
@@ -1,21 +0,0 @@
plugins {
`java-library`
}
tasks {
val collectJars by registering(Copy::class) {
val tasks = subprojects.filter { it.path != ":common" }.map { it.tasks.named("remapJar") }
dependsOn(tasks)
from(tasks)
into(buildDir.resolve("libs"))
}
assemble {
dependsOn(collectJars)
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
+2 -3
View File
@@ -1,13 +1,12 @@
plugins {
base
id("cobblemon.root-conventions")
id ("net.nemerosa.versioning") version "2.8.2"
}
group = "com.cobblemon.mod"
version = "${project.property("mod_version")}+${project.property("mc_version")}"
val isSnapshot = project.property("snapshot")?.equals("true") ?: false
if (isSnapshot) {
version = "$version-${versioning.info.branch}-${versioning.info.build}"
val fixedBranchName = versioning.info.branch.substringAfter("/")
version = "$version-${fixedBranchName}-${versioning.info.build}"
}
+18 -24
View File
@@ -1,5 +1,5 @@
import extensions.isSnapshot
import extensions.version
import utilities.isSnapshot
import utilities.version
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
@@ -20,7 +20,7 @@ plugins {
id("net.kyori.blossom")
id("org.jetbrains.gradle.plugin.idea-ext")
id ("net.nemerosa.versioning") version "2.8.2"
id("net.nemerosa.versioning") version "2.8.2"
}
architectury {
@@ -34,31 +34,26 @@ repositories {
}
dependencies {
implementation(libs.stdlib)
implementation(libs.reflect)
modImplementation(libs.fabricLoader)
//Flywheel has no common dep so just pick one and don't use any platform specific code in common
// modCompileOnly(libs.flywheelFabric)
implementation(libs.bundles.kotlin)
modImplementation(libs.fabric.loader)
modApi(libs.molang)
compileOnlyApi(libs.jeiApi)
modCompileOnly(libs.adornFabric)
modCompileOnly(libs.lambDynamicLights) { isTransitive = false }
// For Showdown
// Integrations
compileOnlyApi(libs.jei.api)
modCompileOnly(libs.bundles.fabric.integrations.compileOnly) {
isTransitive = false
}
// Flywheel has no common dep so just pick one and don't use any platform specific code in common
// modCompileOnly(libs.flywheelFabric)
// Showdown
modCompileOnly(libs.graal)
//shadowCommon group: 'commons-io', name: 'commons-io', version: '2.6'
// Data Storage
modCompileOnly(libs.bundles.mongo)
// For datastore
modCompileOnly(libs.mongoDriverCore)
modCompileOnly(libs.mongoDriverSync)
testImplementation(libs.fabricJunit)
testImplementation(libs.junitParams)
testImplementation(libs.mockito)
testImplementation(libs.mockk)
testImplementation(libs.classgraph)
// Unit Testing
testImplementation(libs.bundles.unitTesting)
}
tasks.withType<Test> {
@@ -94,7 +89,6 @@ sourceSets {
property("gitCommit", versioning.info.commit)
property("branch", versioning.info.branch)
System.getProperty("buildNumber")?.let { property("buildNumber", it) }
property("timestamp", OffsetDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss")) + " UTC")
}
}
}
@@ -26,7 +26,6 @@ public final class CrashReportMixin {
cobblemon.add("Is Snapshot", CobblemonBuildDetails.SNAPSHOT);
cobblemon.add("Git Commit", CobblemonBuildDetails.INSTANCE.smallCommitHash() + " (" + "https://gitlab.com/cable-mc/cobblemon/-/commit/" + CobblemonBuildDetails.GIT_COMMIT + ")");
cobblemon.add("Branch", CobblemonBuildDetails.BRANCH);
cobblemon.add("Timestamp", CobblemonBuildDetails.TIMESTAMP);
cobblemon.addStackTrace(builder);
builder.append("\n\n");
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.invoker;
import com.cobblemon.mod.common.integration.adorn.AdornCompatibility;
import java.util.List;
import juuxel.adorn.block.variant.BlockVariantSet;
import juuxel.adorn.block.variant.BlockVariantSets;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
//This is a yucky hack but better than what we were doing before
@Mixin(BlockVariantSets.class)
public abstract class AdornRegisterInvoker {
@Final
@Shadow(remap = false)
private static List<BlockVariantSet> variantSets;
@Inject(method = "register()V", at = @At("HEAD"), remap = false)
void register(CallbackInfo ci) {
variantSets.add(AdornCompatibility.INSTANCE);
}
}
@@ -10,7 +10,6 @@ object CobblemonBuildDetails {
const val GIT_COMMIT = "{{ gitCommit | default("Not Specified") }}"
const val BRANCH = "{{ branch | default("Not Specified") }}"
const val TIMESTAMP = "{{ timestamp }}"
fun smallCommitHash(): String {
return this.GIT_COMMIT.substring(0, 7)
@@ -102,7 +102,6 @@ import com.cobblemon.mod.common.pokemon.properties.HiddenAbilityPropertyType
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
import com.cobblemon.mod.common.pokemon.properties.tags.PokemonFlagProperty
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
import com.cobblemon.mod.common.sherds.CobblemonSherds
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
import com.cobblemon.mod.common.trade.TradeManager
import com.cobblemon.mod.common.util.DataKeys
@@ -141,8 +140,8 @@ import kotlin.reflect.jvm.javaField
import kotlin.math.roundToInt
object Cobblemon {
const val MODID = "cobblemon"
const val VERSION = "1.4.0"
const val MODID = CobblemonBuildDetails.MOD_ID
const val VERSION = CobblemonBuildDetails.VERSION
const val CONFIG_PATH = "config/$MODID/main.json"
val LOGGER: Logger = LogManager.getLogger()
@@ -179,7 +178,6 @@ object Cobblemon {
if(CobblemonBuildDetails.SNAPSHOT) {
this.LOGGER.info(" - Git Commit: ${smallCommitHash()} (https://gitlab.com/cable-mc/cobblemon/-/commit/${CobblemonBuildDetails.GIT_COMMIT})")
this.LOGGER.info(" - Branch: ${CobblemonBuildDetails.BRANCH}")
this.LOGGER.info(" - Timestamp: ${CobblemonBuildDetails.TIMESTAMP}")
}
implementation.registerPermissionValidator()
@@ -236,7 +234,7 @@ object Cobblemon {
val player = event.player
val block = player.world.getBlockState(event.pos).block
player.party().forEach { pokemon ->
pokemon.evolutions
pokemon.lockedEvolutions
.filterIsInstance<BlockClickEvolution>()
.forEach { evolution ->
evolution.attemptEvolution(pokemon, BlockClickEvolution.BlockInteractionContext(block, player.world))
@@ -373,36 +371,6 @@ object Cobblemon {
BATTLE_VICTORY.subscribe { AdvancementHandler.onWinBattle(it) }
EVOLUTION_COMPLETE.subscribe(Priority.LOWEST) { event ->
AdvancementHandler.onEvolve(event)
val pokemon = event.pokemon
val ninjaskIdentifier = cobblemonResource("ninjask")
// Ensure the config option is enabled and that the result was a ninjask and that shedinja exists
if (this.config.ninjaskCreatesShedinja && pokemon.species.resourceIdentifier == ninjaskIdentifier && PokemonSpecies.getByIdentifier(Pokemon.SHEDINJA) != null) {
val player = pokemon.getOwnerPlayer() ?: return@subscribe
if (player.isCreative || player.inventory.containsAny { it.item is PokeBallItem }) {
var pokeball = Items.AIR
player.inventory.combinedInventory.forEach {
it.forEach {
itemStack -> if (itemStack.item is PokeBallItem && pokeball == Items.AIR) {
pokeball = itemStack.item as PokeBallItem
}
}
}
if (!player.isCreative) {
player.inventory.removeAmountIf(1) { it.item is PokeBallItem }
}
if (pokeball == Items.AIR) {
pokeball = CobblemonItems.POKE_BALL
}
val properties = event.evolution.result.copy()
properties.species = Pokemon.SHEDINJA.toString()
val product = pokemon.clone()
product.removeHeldItem()
properties.apply(product)
product.caughtBall = (pokeball as PokeBallItem).pokeBall
pokemon.storeCoordinates.get()?.store?.add(product)
CobblemonCriteria.EVOLVE_POKEMON.trigger(player, EvolvePokemonContext(event.pokemon.preEvolution!!.species.resourceIdentifier, product.species.resourceIdentifier, playerData.get(player).advancementData.totalEvolvedCount))
}
}
}
LEVEL_UP_EVENT.subscribe { AdvancementHandler.onLevelUp(it) }
TRADE_COMPLETED.subscribe { AdvancementHandler.onTradeCompleted(it) }
@@ -417,7 +385,6 @@ object Cobblemon {
).ifSuccessful { it.mute = true }
}
CobblemonSherds.registerSherds()
}
fun getLevel(dimension: RegistryKey<World>): World? {
@@ -214,6 +214,213 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
.instrument(Instrument.BASEDRUM)
))
@JvmField
val POLISHED_TUMBLESTONE = this.create("polished_tumblestone", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val POLISHED_TUMBLESTONE_STAIRS = this.create("polished_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(POLISHED_TUMBLESTONE.defaultState, AbstractBlock.Settings.copy(POLISHED_TUMBLESTONE)))
@JvmField
val POLISHED_TUMBLESTONE_SLAB = this.create("polished_tumblestone_slab", SlabBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val POLISHED_TUMBLESTONE_WALL = this.create("polished_tumblestone_wall", WallBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val CHISELED_POLISHED_TUMBLESTONE = this.create("chiseled_polished_tumblestone", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val TUMBLESTONE_BRICKS = this.create("tumblestone_bricks", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val TUMBLESTONE_BRICK_STAIRS = this.create("tumblestone_brick_stairs", StairsBlockInvoker.`cobblemon$create`(TUMBLESTONE_BRICKS.defaultState, AbstractBlock.Settings.copy(TUMBLESTONE_BRICKS)))
@JvmField
val TUMBLESTONE_BRICK_SLAB = this.create("tumblestone_brick_slab", SlabBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val TUMBLESTONE_BRICK_WALL = this.create("tumblestone_brick_wall", WallBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val CHISELED_TUMBLESTONE_BRICKS = this.create("chiseled_tumblestone_bricks", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val POLISHED_SKY_TUMBLESTONE = this.create("polished_sky_tumblestone", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.LIGHT_BLUE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val POLISHED_SKY_TUMBLESTONE_STAIRS = this.create("polished_sky_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(POLISHED_SKY_TUMBLESTONE.defaultState, AbstractBlock.Settings.copy(POLISHED_SKY_TUMBLESTONE)))
@JvmField
val POLISHED_SKY_TUMBLESTONE_SLAB = this.create("polished_sky_tumblestone_slab", SlabBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.LIGHT_BLUE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val POLISHED_SKY_TUMBLESTONE_WALL = this.create("polished_sky_tumblestone_wall", WallBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.LIGHT_BLUE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val CHISELED_POLISHED_SKY_TUMBLESTONE = this.create("chiseled_polished_sky_tumblestone", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.LIGHT_BLUE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val SKY_TUMBLESTONE_BRICKS = this.create("sky_tumblestone_bricks", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.LIGHT_BLUE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val SKY_TUMBLESTONE_BRICK_STAIRS = this.create("sky_tumblestone_brick_stairs", StairsBlockInvoker.`cobblemon$create`(
SKY_TUMBLESTONE_BRICKS.defaultState, AbstractBlock.Settings.copy(SKY_TUMBLESTONE_BRICKS)))
@JvmField
val SKY_TUMBLESTONE_BRICK_SLAB = this.create("sky_tumblestone_brick_slab", SlabBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.LIGHT_BLUE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val SKY_TUMBLESTONE_BRICK_WALL = this.create("sky_tumblestone_brick_wall", WallBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.LIGHT_BLUE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val CHISELED_SKY_TUMBLESTONE_BRICKS = this.create("chiseled_sky_tumblestone_bricks", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.LIGHT_BLUE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val POLISHED_BLACK_TUMBLESTONE = this.create("polished_black_tumblestone", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val POLISHED_BLACK_TUMBLESTONE_STAIRS = this.create("polished_black_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(POLISHED_BLACK_TUMBLESTONE.defaultState, AbstractBlock.Settings.copy(POLISHED_BLACK_TUMBLESTONE)))
@JvmField
val POLISHED_BLACK_TUMBLESTONE_SLAB = this.create("polished_black_tumblestone_slab", SlabBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val POLISHED_BLACK_TUMBLESTONE_WALL = this.create("polished_black_tumblestone_wall", WallBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val CHISELED_POLISHED_BLACK_TUMBLESTONE = this.create("chiseled_polished_black_tumblestone", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val BLACK_TUMBLESTONE_BRICKS = this.create("black_tumblestone_bricks", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val BLACK_TUMBLESTONE_BRICK_STAIRS = this.create("black_tumblestone_brick_stairs", StairsBlockInvoker.`cobblemon$create`(
BLACK_TUMBLESTONE_BRICKS.defaultState, AbstractBlock.Settings.copy(BLACK_TUMBLESTONE_BRICKS)))
@JvmField
val BLACK_TUMBLESTONE_BRICK_SLAB = this.create("black_tumblestone_brick_slab", SlabBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val BLACK_TUMBLESTONE_BRICK_WALL = this.create("black_tumblestone_brick_wall", WallBlock(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val CHISELED_BLACK_TUMBLESTONE_BRICKS = this.create("chiseled_black_tumblestone_bricks", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val BLACK_APRICORN = apricornBlock("black_apricorn", Apricorn.BLACK)
@JvmField
@@ -234,7 +441,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
"relic_coin_pouch",
CoinPouchBlock(
AbstractBlock.Settings.create()
.sounds(CobblemonSounds.COIN_POUCH_SOUNDS)
.sounds(CobblemonSounds.RELIC_COIN_POUCH_SOUNDS)
.pistonBehavior(PistonBehavior.DESTROY)
.strength(0.4f)
.nonOpaque(), true
@@ -245,7 +452,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
"relic_coin_sack",
CoinPouchBlock(
AbstractBlock.Settings.create()
.sounds(CobblemonSounds.COIN_POUCH_SOUNDS)
.sounds(CobblemonSounds.RELIC_COIN_SACK_SOUNDS)
.pistonBehavior(PistonBehavior.DESTROY)
.strength(0.4f), false
))
@@ -528,6 +735,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
val WEPEAR_BERRY = this.berryBlock("wepear")
val WIKI_BERRY = this.berryBlock("wiki")
val YACHE_BERRY = this.berryBlock("yache")
//val BINDING_SOIL = this.create("binding_soil", BindingSoilBlock(AbstractBlock.Settings.create()))
init {
/**
@@ -23,6 +23,7 @@ import com.cobblemon.mod.common.item.armor.CobblemonArmorTrims
import com.cobblemon.mod.common.item.battle.DireHitItem
import com.cobblemon.mod.common.item.battle.GuardSpecItem
import com.cobblemon.mod.common.item.battle.XStatItem
import com.cobblemon.mod.common.item.berry.BerryItem
import com.cobblemon.mod.common.item.berry.FriendshipRaisingBerryItem
import com.cobblemon.mod.common.item.berry.HealingBerryItem
import com.cobblemon.mod.common.item.berry.PPRestoringBerryItem
@@ -667,8 +668,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val CHOICE_SPECS = heldItem("choice_specs")
@JvmField
val CLEANSE_TAG = heldItem("cleanse_tag")
@JvmField
val CLEAR_AMULET = heldItem("clear_amulet")
// @JvmField
// val CLEAR_AMULET = heldItem("clear_amulet")
@JvmField
val COVERT_CLOAK = heldItem("covert_cloak")
@JvmField
@@ -697,16 +698,16 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val FOCUS_BAND = heldItem("focus_band")
@JvmField
val FOCUS_SASH = heldItem("focus_sash")
@JvmField
val GRIP_CLAW = heldItem("grip_claw")
// @JvmField
// val GRIP_CLAW = heldItem("grip_claw")
@JvmField
val HARD_STONE = heldItem("hard_stone")
@JvmField
val HEAVY_DUTY_BOOTS = heldItem("heavy_duty_boots")
@JvmField
val IRON_BALL = heldItem("iron_ball")
@JvmField
val LAGGING_TAIL = heldItem("lagging_tail")
// @JvmField
// val LAGGING_TAIL = heldItem("lagging_tail")
@JvmField
val LEFTOVERS = heldItem("leftovers")
@JvmField
@@ -719,12 +720,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val LOADED_DICE = heldItem("loaded_dice")
@JvmField
val LUCKY_EGG = heldItem("lucky_egg")
@JvmField
val LUMINOUS_MOSS = heldItem("luminous_moss")
// @JvmField
// val LUMINOUS_MOSS = heldItem("luminous_moss")
@JvmField
val MAGNET = heldItem("magnet")
@JvmField
val METRONOME = heldItem("metronome")
// @JvmField
// val METRONOME = heldItem("metronome")
@JvmField
val MIRACLE_SEED = heldItem("miracle_seed")
@JvmField
@@ -747,10 +748,10 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val POWER_LENS = heldItem("power_lens")
@JvmField
val POWER_WEIGHT = heldItem("power_weight")
@JvmField
val PROTECTIVE_PADS = heldItem("protective_pads")
@JvmField
val PUNCHING_GLOVE = heldItem("punching_glove")
// @JvmField
// val PROTECTIVE_PADS = heldItem("protective_pads")
// @JvmField
// val PUNCHING_GLOVE = heldItem("punching_glove")
@JvmField
val QUICK_CLAW = heldItem("quick_claw")
@JvmField
@@ -759,16 +760,16 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val RING_TARGET = heldItem("ring_target")
@JvmField
val ROCKY_HELMET = heldItem("rocky_helmet")
@JvmField
val ROOM_SERVICE = heldItem("room_service")
// @JvmField
// val ROOM_SERVICE = heldItem("room_service")
@JvmField
val SAFETY_GOGGLES = heldItem("safety_goggles")
@JvmField
val SCOPE_LENS = heldItem("scope_lens")
// @JvmField
// val SCOPE_LENS = heldItem("scope_lens")
@JvmField
val SHARP_BEAK = heldItem("sharp_beak")
@JvmField
val SHED_SHELL = heldItem("shed_shell")
// @JvmField
// val SHED_SHELL = heldItem("shed_shell")
@JvmField
val SHELL_BELL = heldItem("shell_bell")
@JvmField
@@ -785,24 +786,24 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val SOOTHE_BELL = heldItem("soothe_bell")
@JvmField
val STICKY_BARB = heldItem("sticky_barb")
@JvmField
val TERRAIN_EXTENDER = heldItem("terrain_extender")
@JvmField
val THROAT_SPRAY = heldItem("throat_spray")
// @JvmField
// val TERRAIN_EXTENDER = heldItem("terrain_extender")
// @JvmField
// val THROAT_SPRAY = heldItem("throat_spray")
@JvmField
val TOXIC_ORB = heldItem("toxic_orb")
@JvmField
val TWISTED_SPOON = heldItem("twisted_spoon")
@JvmField
val UTILITY_UMBRELLA = heldItem("utility_umbrella")
// @JvmField
// val UTILITY_UMBRELLA = heldItem("utility_umbrella")
@JvmField
val WEAKNESS_POLICY = heldItem("weakness_policy")
@JvmField
val WIDE_LENS = heldItem("wide_lens")
// @JvmField
// val WIDE_LENS = heldItem("wide_lens")
@JvmField
val WISE_GLASSES = heldItem("wise_glasses")
@JvmField
val ZOOM_LENS = heldItem("zoom_lens")
// @JvmField
// val ZOOM_LENS = heldItem("zoom_lens")
@JvmField
val MENTAL_HERB = compostableHeldItem("mental_herb", null, 1F)
@JvmField
@@ -932,6 +933,67 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField
val BLACK_TUMBLESTONE_BLOCK = blockItem("black_tumblestone_block", CobblemonBlocks.BLACK_TUMBLESTONE_BLOCK)
@JvmField
val POLISHED_TUMBLESTONE = blockItem("polished_tumblestone", CobblemonBlocks.POLISHED_TUMBLESTONE)
@JvmField
val POLISHED_TUMBLESTONE_STAIRS = blockItem("polished_tumblestone_stairs", CobblemonBlocks.POLISHED_TUMBLESTONE_STAIRS)
@JvmField
val POLISHED_TUMBLESTONE_SLAB = blockItem("polished_tumblestone_slab", CobblemonBlocks.POLISHED_TUMBLESTONE_SLAB)
@JvmField
val POLISHED_TUMBLESTONE_WALL = blockItem("polished_tumblestone_wall", CobblemonBlocks.POLISHED_TUMBLESTONE_WALL)
@JvmField
val CHISELED_POLISHED_TUMBLESTONE = blockItem("chiseled_polished_tumblestone", CobblemonBlocks.CHISELED_POLISHED_TUMBLESTONE)
@JvmField
val TUMBLESTONE_BRICKS = blockItem("tumblestone_bricks", CobblemonBlocks.TUMBLESTONE_BRICKS)
@JvmField
val TUMBLESTONE_BRICK_STAIRS = blockItem("tumblestone_brick_stairs", CobblemonBlocks.TUMBLESTONE_BRICK_STAIRS)
@JvmField
val TUMBLESTONE_BRICK_SLAB = blockItem("tumblestone_brick_slab", CobblemonBlocks.TUMBLESTONE_BRICK_SLAB)
@JvmField
val TUMBLESTONE_BRICK_WALL = blockItem("tumblestone_brick_wall", CobblemonBlocks.TUMBLESTONE_BRICK_WALL)
@JvmField
val CHISELED_TUMBLESTONE_BRICKS = blockItem("chiseled_tumblestone_bricks", CobblemonBlocks.CHISELED_TUMBLESTONE_BRICKS)
@JvmField
val POLISHED_SKY_TUMBLESTONE = blockItem("polished_sky_tumblestone", CobblemonBlocks.POLISHED_SKY_TUMBLESTONE)
@JvmField
val POLISHED_SKY_TUMBLESTONE_STAIRS = blockItem("polished_sky_tumblestone_stairs", CobblemonBlocks.POLISHED_SKY_TUMBLESTONE_STAIRS)
@JvmField
val POLISHED_SKY_TUMBLESTONE_SLAB = blockItem("polished_sky_tumblestone_slab", CobblemonBlocks.POLISHED_SKY_TUMBLESTONE_SLAB)
@JvmField
val POLISHED_SKY_TUMBLESTONE_WALL = blockItem("polished_sky_tumblestone_wall", CobblemonBlocks.POLISHED_SKY_TUMBLESTONE_WALL)
@JvmField
val CHISELED_POLISHED_SKY_TUMBLESTONE = blockItem("chiseled_polished_sky_tumblestone", CobblemonBlocks.CHISELED_POLISHED_SKY_TUMBLESTONE)
@JvmField
val SKY_TUMBLESTONE_BRICKS = blockItem("sky_tumblestone_bricks", CobblemonBlocks.SKY_TUMBLESTONE_BRICKS)
@JvmField
val SKY_TUMBLESTONE_BRICK_STAIRS = blockItem("sky_tumblestone_brick_stairs", CobblemonBlocks.SKY_TUMBLESTONE_BRICK_STAIRS)
@JvmField
val SKY_TUMBLESTONE_BRICK_SLAB = blockItem("sky_tumblestone_brick_slab", CobblemonBlocks.SKY_TUMBLESTONE_BRICK_SLAB)
@JvmField
val SKY_TUMBLESTONE_BRICK_WALL = blockItem("sky_tumblestone_brick_wall", CobblemonBlocks.SKY_TUMBLESTONE_BRICK_WALL)
@JvmField
val CHISELED_SKY_TUMBLESTONE_BRICKS = blockItem("chiseled_sky_tumblestone_bricks", CobblemonBlocks.CHISELED_SKY_TUMBLESTONE_BRICKS)
@JvmField
val POLISHED_BLACK_TUMBLESTONE = blockItem("polished_black_tumblestone", CobblemonBlocks.POLISHED_BLACK_TUMBLESTONE)
@JvmField
val POLISHED_BLACK_TUMBLESTONE_STAIRS = blockItem("polished_black_tumblestone_stairs", CobblemonBlocks.POLISHED_BLACK_TUMBLESTONE_STAIRS)
@JvmField
val POLISHED_BLACK_TUMBLESTONE_SLAB = blockItem("polished_black_tumblestone_slab", CobblemonBlocks.POLISHED_BLACK_TUMBLESTONE_SLAB)
@JvmField
val POLISHED_BLACK_TUMBLESTONE_WALL = blockItem("polished_black_tumblestone_wall", CobblemonBlocks.POLISHED_BLACK_TUMBLESTONE_WALL)
@JvmField
val CHISELED_POLISHED_BLACK_TUMBLESTONE = blockItem("chiseled_polished_black_tumblestone", CobblemonBlocks.CHISELED_POLISHED_BLACK_TUMBLESTONE)
@JvmField
val BLACK_TUMBLESTONE_BRICKS = blockItem("black_tumblestone_bricks", CobblemonBlocks.BLACK_TUMBLESTONE_BRICKS)
@JvmField
val BLACK_TUMBLESTONE_BRICK_STAIRS = blockItem("black_tumblestone_brick_stairs", CobblemonBlocks.BLACK_TUMBLESTONE_BRICK_STAIRS)
@JvmField
val BLACK_TUMBLESTONE_BRICK_SLAB = blockItem("black_tumblestone_brick_slab", CobblemonBlocks.BLACK_TUMBLESTONE_BRICK_SLAB)
@JvmField
val BLACK_TUMBLESTONE_BRICK_WALL = blockItem("black_tumblestone_brick_wall", CobblemonBlocks.BLACK_TUMBLESTONE_BRICK_WALL)
@JvmField
val CHISELED_BLACK_TUMBLESTONE_BRICKS = blockItem("chiseled_black_tumblestone_bricks", CobblemonBlocks.CHISELED_BLACK_TUMBLESTONE_BRICKS)
@JvmField
val AUTOMATON_ARMOR_TRIM_SMITHING_TEMPLATE: SmithingTemplateItem = this.create(
"automaton_armor_trim_smithing_template",
@@ -985,6 +1047,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val STEEL_GEM = noSettingsItem("steel_gem")
@JvmField
val FAIRY_GEM = noSettingsItem("fairy_gem")
//@JvmField
//val BINDING_SOIL = blockItem("binding_soil", CobblemonBlocks.BINDING_SOIL)
private fun blockItem(name: String, block: Block): BlockItem = this.create(name, BlockItem(block, Item.Settings()))
@@ -235,6 +235,7 @@ object CobblemonNetwork : NetworkManager {
this.createClientBound(TradeableUpdatePacket.ID, TradeableUpdatePacket::decode, PokemonUpdatePacketHandler())
this.createClientBound(SpeciesFeatureUpdatePacket.ID, SpeciesFeatureUpdatePacket::decode, PokemonUpdatePacketHandler())
this.createClientBound(OriginalTrainerUpdatePacket.ID, OriginalTrainerUpdatePacket::decode, PokemonUpdatePacketHandler())
this.createClientBound(FormUpdatePacket.ID, FormUpdatePacket::decode, PokemonUpdatePacketHandler())
// Evolution start
this.createClientBound(AddEvolutionPacket.ID, AddEvolutionPacket::decode, PokemonUpdatePacketHandler())
@@ -122,13 +122,18 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
val FOSSIL_MACHINE_UNPROTECTED = this.create("fossil_machine.unprotected")
@JvmField
val COIN_POUCH_BREAK = this.create("coin_pouch.break")
val RELIC_COIN_SACK_BREAK = this.create("relic_coin_sack.break")
@JvmField
val COIN_POUCH_HIT = this.create("coin_pouch.hit")
val RELIC_COIN_SACK_HIT = this.create("relic_coin_sack.hit")
@JvmField
val COIN_POUCH_STEP = this.create("coin_pouch.step")
val RELIC_COIN_SACK_STEP = this.create("relic_coin_sack.step")
@JvmField
val COIN_POUCH_PLACE = this.create("coin_pouch.place")
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")
@JvmField
val TUMBLESTONE_BREAK = this.create("tumblestone.break")
@JvmField
@@ -189,13 +194,22 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
val GILDED_CHEST_PLACE = this.create("gilded_chest.place")
@JvmField
val COIN_POUCH_SOUNDS = BlockSoundGroup(1f, 1f,
COIN_POUCH_BREAK,
COIN_POUCH_STEP,
COIN_POUCH_PLACE,
COIN_POUCH_HIT,
COIN_POUCH_STEP
val RELIC_COIN_SACK_SOUNDS = BlockSoundGroup(1f, 1f,
RELIC_COIN_SACK_BREAK,
RELIC_COIN_SACK_STEP,
RELIC_COIN_SACK_PLACE,
RELIC_COIN_SACK_HIT,
RELIC_COIN_SACK_STEP
)
@JvmField
val RELIC_COIN_POUCH_SOUNDS = BlockSoundGroup(1f, 1f,
RELIC_COIN_POUCH_BREAK,
RELIC_COIN_SACK_STEP,
RELIC_COIN_POUCH_PLACE,
RELIC_COIN_SACK_HIT,
RELIC_COIN_SACK_STEP
)
@JvmField
val IMPACT_NORMAL = this.create("impact.normal")
@JvmField
@@ -226,7 +226,7 @@ open class PokemonBattle(
val facedFainted = opponentPokemon.facedOpponents.contains(faintedPokemon)
val pokemon = opponentPokemon.effectedPokemon
if (facedFainted) {
pokemon.evolutions.forEach { evolution ->
pokemon.lockedEvolutions.forEach { evolution ->
evolution.requirements.filterIsInstance<DefeatRequirement>().forEach { defeatRequirement ->
if (defeatRequirement.target.matches(faintedPokemon.effectedPokemon)) {
val progress = pokemon.evolutionProxy.current().progressFirstOrCreate({ it is DefeatEvolutionProgress && it.currentProgress().target == defeatRequirement.target }) { DefeatEvolutionProgress() }
@@ -16,7 +16,7 @@ import com.cobblemon.mod.common.api.events.berry.BerryYieldCalculationEvent
import com.cobblemon.mod.common.api.mulch.MulchVariant
import com.cobblemon.mod.common.block.BerryBlock
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
import com.cobblemon.mod.common.item.BerryItem
import com.cobblemon.mod.common.item.berry.BerryItem
import com.cobblemon.mod.common.pokemon.Nature
import com.cobblemon.mod.common.util.readBox
import com.cobblemon.mod.common.util.writeBox
@@ -45,9 +45,8 @@ import net.minecraft.world.biome.Biome
* @property identifier The [Identifier] of this berry.
* @property baseYield The [IntRange] possible for the berry tree before [bonusYield] is calculated.
* @property preferredBiomeTags The [TagKey]s of the berries preffered biomes. Determines spawning and yield
* @property growthTime The [IntRange] possible in minutes for how long the berry tree takes to grow.
* @property refreshRate The [IntRange] possible in minutes for how long the berry tree takes to regrow its berries once it has been harvested.
* @depreciated @property lifeCycles The [IntRange] possible for the berry to live for between harvests.
* @property growthTime The [IntRange] possible in minutes for how long the berry tree takes to grow frome age 0 to age 3
* @property refreshRate The [IntRange] possible in minutes for how long the berry tree takes to grow from age 3 to age 5
* @property favoriteMulches The types of mulches that benefit this berries yield
* @property growthFactors An array of [GrowthFactor]s that will affect this berry. The client is not aware of these.
* @property mutations A map of the partner berry as the key and the value as the resulting mutation with this berry.
@@ -60,6 +59,7 @@ import net.minecraft.world.biome.Biome
* @property flowerTexture The [Identifier] for the texture of the berry in flower form. This is resolved into a [ModelPart] on the client.
* @property fruitModelIdentifier The [Identifier] for the model of the berry in flower form. This is resolved into a [ModelPart] on the client.
* @property fruitTexture The [Identifier] for the texture of the berry in flower form.
* @property stageOnePositioning Transformation of the berry model for age 0
*
* @throws IllegalArgumentException if the any yield range argument is not a positive range.
*/
@@ -69,7 +69,6 @@ class Berry(
val preferredBiomeTags: List<TagKey<Biome>>,
val growthTime: IntRange,
val refreshRate: IntRange,
//val lifeCycles: IntRange,
val favoriteMulches: EnumSet<MulchVariant>,
val growthFactors: Collection<GrowthFactor>,
val spawnConditions: List<BerrySpawnCondition>,
@@ -88,7 +87,9 @@ class Berry(
@SerializedName("fruitModel")
val fruitModelIdentifier: Identifier,
val fruitTexture: Identifier,
val weight: Float
val stageOnePositioning: GrowthPoint,
val weight: Float,
val boneMealChance: Float
) {
@Transient
@@ -161,8 +162,9 @@ class Berry(
val bonus = this.bonusYield(world, state, pos)
var yield = base + bonus.first
val treeEntity = world.getBlockEntity(pos) as BerryBlockEntity
if (BerryBlock.getMulch(state) == MulchVariant.RICH) {
yield = min(yield + 1, maxYield())
if (BerryBlock.getMulch(treeEntity) == MulchVariant.RICH) {
//I hope the upper bound isnt exclusive, especially when there's a method called nextBetweenExclusive
yield += world.random.nextBetween(1, 3)
treeEntity.decrementMulchDuration(world, pos, state)
}
val event = BerryYieldCalculationEvent(this, world, state, pos, placer, yield, bonus.second)
@@ -279,6 +281,13 @@ class Berry(
buffer.writeIdentifier(this.flowerTexture)
buffer.writeIdentifier(this.fruitModelIdentifier)
buffer.writeIdentifier(this.fruitTexture)
buffer.writeDouble(stageOnePositioning.position.x)
buffer.writeDouble(stageOnePositioning.position.y)
buffer.writeDouble(stageOnePositioning.position.z)
buffer.writeDouble(stageOnePositioning.rotation.x)
buffer.writeDouble(stageOnePositioning.rotation.y)
buffer.writeDouble(stageOnePositioning.rotation.z)
buffer.writeFloat(boneMealChance)
}
/**
@@ -292,7 +301,8 @@ class Berry(
private fun bonusYield(world: World, state: BlockState, pos: BlockPos): Pair<Int, Collection<GrowthFactor>> {
var bonus = 0
val passed = arrayListOf<GrowthFactor>()
val mulchVariant = BerryBlock.getMulch(state)
val treeEntity = world.getBlockEntity(pos) as? BerryBlockEntity ?: return 0 to passed
val mulchVariant = BerryBlock.getMulch(treeEntity)
val hasBiomeMulch = mulchVariant in favoriteMulches
this.growthFactors.forEach { factor ->
if (factor.isValid(world, state, pos)) {
@@ -339,7 +349,9 @@ class Berry(
val flowerTexture = buffer.readIdentifier()
val fruitModelIdentifier = buffer.readIdentifier()
val fruitTexture = buffer.readIdentifier()
return Berry(identifier, baseYield, emptyList(), growthTime, refreshRate, favMulchs, emptySet(), emptyList(), growthPoints, randomizedGrowthPoints, mutations, sproutShapeBoxes, matureShapeBoxes, flavors, tintIndexes, flowerModelIdentifier, flowerTexture, fruitModelIdentifier, fruitTexture, 0F)
val stageOneYPos = GrowthPoint(Vec3d(buffer.readDouble(), buffer.readDouble(), buffer.readDouble()), Vec3d(buffer.readDouble(), buffer.readDouble(), buffer.readDouble()))
val boneMealChance = buffer.readFloat()
return Berry(identifier, baseYield, emptyList(), growthTime, refreshRate, favMulchs, emptySet(), emptyList(), growthPoints, randomizedGrowthPoints, mutations, sproutShapeBoxes, matureShapeBoxes, flavors, tintIndexes, flowerModelIdentifier, flowerTexture, fruitModelIdentifier, fruitTexture, stageOneYPos, 0F, boneMealChance)
}
}
@@ -78,6 +78,8 @@ object CobblemonEvents {
val POKE_BALL_CAPTURE_CALCULATED = EventObservable<PokeBallCaptureCalculatedEvent>()
@JvmField
val POKEMON_CAPTURED = EventObservable<PokemonCapturedEvent>()
@JvmField
val FOSSIL_REVIVED = EventObservable<FossilRevivedEvent>()
// @JvmField
// val EGG_HATCH = EventObservable<HatchEggEvent>()
@JvmField
@@ -0,0 +1,17 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.events.pokemon
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.server.network.ServerPlayerEntity
data class FossilRevivedEvent (
val pokemon: Pokemon,
val player: ServerPlayerEntity?
)
@@ -10,9 +10,7 @@ package com.cobblemon.mod.common.api.moves.animations
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.VariableStruct
import com.cobblemon.mod.common.api.moves.animations.keyframes.ActionEffectKeyframe
import com.cobblemon.mod.common.api.scheduling.ScheduledTask
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.resolveBoolean
import java.util.concurrent.CompletableFuture
@@ -43,6 +41,9 @@ class ActionEffectTimeline(
// .toList copy because I'm paranoid about iterators being trying to share between identical effects playing
chainKeyframes(context, timeline.toList().iterator(), finalFuture)
finalFuture
}.exceptionallyCompose {
it.printStackTrace()
CompletableFuture.completedFuture(Unit)
}
}
@@ -55,6 +56,7 @@ class ActionEffectTimeline(
keyframe.play(context)
.thenRun { context.currentKeyframes.remove(keyframe) }
.thenApply { chainKeyframes(context, iterator, finalFuture) }
.exceptionally { finalFuture.completeExceptionally(it) }
}
}
}
@@ -8,7 +8,6 @@
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.EntityProvider
@@ -40,7 +39,7 @@ class EntityParticlesActionEffectKeyframe : ConditionalActionEffectKeyframe(), E
.flatMap { prov -> prov.entities.filter { test(context, it, isUser = prov is UsersProvider) } }
val effectIdentifier = try {
effect?.asExpressionLike()?.resolveString(context.runtime)
effect?.asExpressionLike()?.resolveString(context.runtime)?.takeIf { it != "0.0" } ?: effect
} catch (e: Exception) {
effect
}?.asIdentifierDefaultingNamespace() ?: return skip()
@@ -8,24 +8,30 @@
package com.cobblemon.mod.common.api.mulch
import com.cobblemon.mod.common.BakingOverride
import com.cobblemon.mod.common.client.CobblemonBakingOverrides
import net.minecraft.util.StringIdentifiable
/**
* Represents the different types of Mulch implemented in the mod.
*
*/
enum class MulchVariant(val duration: Int = -1) : StringIdentifiable {
COARSE,
GROWTH(3),
HUMID,
LOAMY,
PEAT,
RICH(3),
SANDY,
SURPRISE(3),
NONE;
enum class MulchVariant(val model: BakingOverride?, val duration: Int = -1) : StringIdentifiable {
COARSE(CobblemonBakingOverrides.COARSE_MULCH),
GROWTH(CobblemonBakingOverrides.GROWTH_MULCH, 5),
HUMID(CobblemonBakingOverrides.HUMID_MULCH),
LOAMY(CobblemonBakingOverrides.LOAMY_MULCH),
PEAT(CobblemonBakingOverrides.PEAT_MULCH),
RICH(CobblemonBakingOverrides.RICH_MULCH, 5),
SANDY(CobblemonBakingOverrides.SANDY_MULCH),
SURPRISE(CobblemonBakingOverrides.SURPRISE_MULCH, 3),
NONE(null);
override fun asString(): String {
return name.lowercase()
}
companion object {
const val GROWTH_TIME_MULTIPLIER = 0.5
}
}
@@ -60,13 +60,14 @@ abstract class MultiblockBlock(properties: Settings) : BlockWithEntity(propertie
}
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
super.onBreak(world, pos, state, player)
if (!world.isClient) {
val entity = world.getBlockEntity(pos)
if (entity is MultiblockEntity && entity.multiblockStructure != null) {
entity.multiblockStructure!!.onBreak(world, pos, state, player)
}
entity?.markRemoved()
}
super.onBreak(world, pos, state, player)
}
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity? {
@@ -78,6 +79,7 @@ abstract class MultiblockBlock(properties: Settings) : BlockWithEntity(propertie
return BlockRenderType.MODEL
}
//This is done so a block picked with NBT doesnt absolutely DESTROY multiblocks
override fun getPickStack(world: BlockView, pos: BlockPos, state: BlockState): ItemStack {
val blockEntity = world.getBlockEntity(pos) as? MultiblockEntity ?: return ItemStack.EMPTY
return if (blockEntity.multiblockStructure == null) super.getPickStack(world, pos, state) else ItemStack.EMPTY
@@ -47,6 +47,10 @@ fun interface PokemonPropertyExtractor {
val NICKNAME = add { pokemon, properties -> properties.nickname = pokemon.nickname }
@JvmField
val STATUS = add { pokemon, properties -> properties.status = pokemon.status?.status?.showdownName }
@JvmField
val IVS = add { pokemon, properties -> properties.ivs = pokemon.ivs }
@JvmField
val EVS = add { pokemon, properties -> properties.evs = pokemon.evs }
@JvmField
val ILLUSION = mutableListOf(SPECIES, FORM, ASPECTS, GENDER, NICKNAME, SHINY)
@@ -8,7 +8,11 @@
package com.cobblemon.mod.common.api.pokemon.evolution
import com.cobblemon.mod.common.Cobblemon.playerData
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.advancement.CobblemonCriteria
import com.cobblemon.mod.common.advancement.criterion.EvolvePokemonContext
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionCompleteEvent
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionTestedEvent
@@ -17,7 +21,9 @@ import com.cobblemon.mod.common.api.moves.MoveTemplate
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.evolution.requirement.EvolutionRequirement
import com.cobblemon.mod.common.api.scheduling.afterOnServer
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.entity.generic.GenericBedrockEntity
import com.cobblemon.mod.common.item.PokeBallItem
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.activestate.ShoulderedState
import com.cobblemon.mod.common.pokemon.evolution.variants.ItemInteractionEvolution
@@ -25,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.cobblemonResource
import com.cobblemon.mod.common.util.lang
import com.cobblemon.mod.common.util.party
import net.minecraft.item.ItemStack
import net.minecraft.sound.SoundCategory
@@ -44,6 +51,11 @@ interface Evolution : EvolutionLike {
*/
val result: PokemonProperties
/**
* The shed result of this evolution.
*/
val shedder: PokemonProperties?
/**
* If this evolution allows the user to choose when to start it or not.
*/
@@ -95,6 +107,36 @@ interface Evolution : EvolutionLike {
return true
}
fun shed(pokemon: Pokemon): Boolean {
val innerShedder = shedder ?: return false
val owner = pokemon.getOwnerPlayer() ?: return false
// If the player has at least one Pokeball in their inventory.
var pokeballStack: ItemStack? = null
if (!owner.isCreative) {
for (i in 0 until owner.inventory.size()) {
val stackI = owner.inventory.getStack(i)
if (stackI.isIn(CobblemonItemTags.POKE_BALLS)) {
pokeballStack = stackI
}
}
if (pokeballStack == null) return false
}
// If the player has at least one empty spot in their party.
val emptySlot = owner.party().getFirstAvailablePosition() ?: return false
// Add shed Pokemon to player's party
val shedPokemon = pokemon.clone()
shedPokemon.removeHeldItem()
innerShedder.apply(shedPokemon)
shedPokemon.caughtBall = ((pokeballStack?.item ?: CobblemonItems.POKE_BALL) as PokeBallItem).pokeBall
pokemon.storeCoordinates.get()?.store?.add(shedPokemon)
CobblemonCriteria.EVOLVE_POKEMON.trigger(owner, EvolvePokemonContext(pokemon.preEvolution!!.species.resourceIdentifier, shedPokemon.species.resourceIdentifier, playerData.get(owner).advancementData.totalEvolvedCount))
// Consume one of the balls
pokeballStack?.decrement(1)
return true
}
/**
* Starts this evolution as soon as possible.
@@ -153,8 +195,9 @@ interface Evolution : EvolutionLike {
pokemon.getOwnerPlayer()?.sendMessage(lang("experience.learned_move", pokemon.getDisplayName(), move.displayName))
}
// we want to instantly tick for example you might only evolve your Bulbasaur at level 34 so Venusaur should be immediately available
pokemon.evolutions.filterIsInstance<PassiveEvolution>().forEach { evolution -> evolution.attemptEvolution(pokemon) }
pokemon.lockedEvolutions.filterIsInstance<PassiveEvolution>().forEach { evolution -> evolution.attemptEvolution(pokemon) }
pokemon.getOwnerPlayer()?.playSound(CobblemonSounds.EVOLVING, SoundCategory.NEUTRAL, 1F, 1F)
this.shed(pokemon)
CobblemonEvents.EVOLUTION_COMPLETE.post(EvolutionCompleteEvent(pokemon, this))
}
@@ -101,7 +101,7 @@ open class Learnset : ClientDataSynchronizer<Learnset> {
repeat(times = buffer.readSizedInt(IntSize.U_BYTE)) {
val level = buffer.readSizedInt(IntSize.U_SHORT)
val moves = mutableListOf<MoveTemplate>()
repeat(times = buffer.readSizedInt(IntSize.U_BYTE)) {
repeat(times = buffer.readSizedInt(IntSize.U_SHORT)) {
Moves.getByNumericalId(buffer.readInt())?.let(moves::add)
}
levelUpMoves[level] = moves
@@ -112,7 +112,7 @@ open class Learnset : ClientDataSynchronizer<Learnset> {
buffer.writeSizedInt(IntSize.U_BYTE, levelUpMoves.size)
for ((level, moves) in levelUpMoves) {
buffer.writeSizedInt(IntSize.U_SHORT, level)
buffer.writeSizedInt(IntSize.U_BYTE, moves.size)
buffer.writeSizedInt(IntSize.U_SHORT, moves.size)
for (move in moves) {
buffer.writeInt(move.num)
}
@@ -51,8 +51,8 @@ enum class Stats(override val identifier: Identifier, override val displayName:
/** Gets the [Stat] from the respective Showdown id. */
fun getStat(statKey: String) = when(statKey) {
"atk" -> ATTACK
"def" -> DEFENCE
"atk", "Attack" -> ATTACK // Hyper Cutter states the full stat name "Attack"
"def", "Defense" -> DEFENCE // Big Pecks states the full stat name "Defense"
"spa" -> SPECIAL_ATTACK
"spd" -> SPECIAL_DEFENCE
"spe" -> SPEED
@@ -8,6 +8,9 @@
package com.cobblemon.mod.common.api.pokemon.status
import com.cobblemon.mod.common.api.moves.animations.ActionEffectTimeline
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import net.minecraft.util.Identifier
/**
@@ -20,4 +23,6 @@ open class Status(
val showdownName: String = "",
val applyMessage: String,
val removeMessage: String
)
) {
fun getActionEffect() = ActionEffects.actionEffects[name]
}
@@ -9,21 +9,29 @@
package com.cobblemon.mod.common.api.pokemon.status
import com.cobblemon.mod.common.pokemon.status.PersistentStatus
import com.cobblemon.mod.common.pokemon.status.statuses.BurnStatus
import com.cobblemon.mod.common.pokemon.status.statuses.FrozenStatus
import com.cobblemon.mod.common.pokemon.status.statuses.ParalysisStatus
import com.cobblemon.mod.common.pokemon.status.statuses.PoisonBadlyStatus
import com.cobblemon.mod.common.pokemon.status.statuses.PoisonStatus
import com.cobblemon.mod.common.pokemon.status.statuses.SleepStatus
import com.cobblemon.mod.common.pokemon.status.VolatileStatus
import com.cobblemon.mod.common.pokemon.status.statuses.persistent.BurnStatus
import com.cobblemon.mod.common.pokemon.status.statuses.persistent.FrozenStatus
import com.cobblemon.mod.common.pokemon.status.statuses.persistent.ParalysisStatus
import com.cobblemon.mod.common.pokemon.status.statuses.persistent.PoisonBadlyStatus
import com.cobblemon.mod.common.pokemon.status.statuses.persistent.PoisonStatus
import com.cobblemon.mod.common.pokemon.status.statuses.persistent.SleepStatus
import com.cobblemon.mod.common.pokemon.status.statuses.nonpersistent.ConfuseStatus
import com.cobblemon.mod.common.pokemon.status.statuses.nonpersistent.AttractStatus
import net.minecraft.util.Identifier
/**
* Main API point for Statuses
* Get or register Statuses
*
* NOTE: May seem weird to have so many things called volatile statuses but the package is called nonpersistent.
* Its because volatile is a reserved keyword in Java. Cant use it in a package name
*
* @author Deltric
*/
object Statuses {
private val persistentStatuses = mutableListOf<Status>()
private val volatileStatuses = mutableListOf<Status>()
private val allStatuses = mutableListOf<Status>()
val POISON = registerStatus(PoisonStatus())
@@ -32,13 +40,23 @@ object Statuses {
val SLEEP = registerStatus(SleepStatus())
val FROZEN = registerStatus(FrozenStatus())
val BURN = registerStatus(BurnStatus())
val ATTRACT = registerStatus(AttractStatus())
val CONFUSE = registerStatus(ConfuseStatus())
fun <T: Status> registerStatus(status: T) : T {
if (status is PersistentStatus) {
persistentStatuses.add(status)
}
else if (status is VolatileStatus) {
volatileStatuses.add(status)
}
allStatuses.add(status)
return status
}
fun getStatus(name: Identifier) = allStatuses.find { status -> status.name == name }
fun getStatus(showdownName: String) = allStatuses.find { it.showdownName == showdownName }
fun getPersistentStatuses() = allStatuses.filterIsInstance<PersistentStatus>()
fun getPersistentStatuses() = persistentStatuses
}
@@ -79,15 +79,15 @@ class ParticleEvent(
particleEffect?.let { effect ->
val bedrockParticleEffect = BedrockParticleEffectRepository.getEffect(effect.effect) ?: return@let
val rootMatrix = when (effect.type) {
EventParticleEffect.EventParticleType.EMITTER -> MatrixWrapper().updatePosition(storm.matrixWrapper.getOrigin())
EventParticleEffect.EventParticleType.EMITTER_BOUND -> storm.matrixWrapper
EventParticleEffect.EventParticleType.EMITTER,// -> MatrixWrapper().updatePosition(storm.matrixWrapper.getOrigin())
EventParticleEffect.EventParticleType.EMITTER_BOUND,// -> storm.matrixWrapper
EventParticleEffect.EventParticleType.PARTICLE,
EventParticleEffect.EventParticleType.PARTICLE_WITH_VELOCITY -> (particle?.let { Vec3d(it.getX(), it.getY(), it.getZ()) } ?: Vec3d(storm.getX(), storm.getY(), storm.getZ())).let { MatrixWrapper().updatePosition(it) }
}
val sourceVelocity = when (effect.type) {
EventParticleEffect.EventParticleType.EMITTER -> storm.sourceVelocity().let { { it } }
EventParticleEffect.EventParticleType.EMITTER_BOUND -> storm.sourceVelocity
EventParticleEffect.EventParticleType.EMITTER,// -> storm.sourceVelocity().let { { it } }
EventParticleEffect.EventParticleType.EMITTER_BOUND,// -> storm.sourceVelocity
EventParticleEffect.EventParticleType.PARTICLE -> { { Vec3d.ZERO } }
EventParticleEffect.EventParticleType.PARTICLE_WITH_VELOCITY -> (particle?.let { Vec3d(it.getVelocityX(), it.getVelocityY(), it.getVelocityZ()) } ?: Vec3d.ZERO).let { { it } }
}
@@ -15,10 +15,12 @@ import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.codec.CodecMapped
import com.cobblemon.mod.common.api.data.ArbitrarilyMappedSerializableCompanion
import com.cobblemon.mod.common.client.particle.ParticleStorm
import com.cobblemon.mod.common.client.render.SnowstormParticle
import com.cobblemon.mod.common.util.codec.EXPRESSION_CODEC
import com.cobblemon.mod.common.util.getString
import com.cobblemon.mod.common.util.math.geometry.transformDirection
import com.cobblemon.mod.common.util.resolveDouble
import com.cobblemon.mod.common.util.resolveVec3d
import com.mojang.serialization.Codec
import com.mojang.serialization.DynamicOps
import com.mojang.serialization.codecs.PrimitiveCodec
@@ -35,20 +37,79 @@ interface ParticleMotion : CodecMapped {
init {
registerSubtype(ParticleMotionType.DYNAMIC, DynamicParticleMotion::class.java, DynamicParticleMotion.CODEC)
registerSubtype(ParticleMotionType.STATIC, StaticParticleMotion::class.java, StaticParticleMotion.CODEC)
registerSubtype(ParticleMotionType.PARAMETRIC, ParametricParticleMotion::class.java, ParametricParticleMotion.CODEC)
}
}
val type: ParticleMotionType
fun getInitialVelocity(runtime: MoLangRuntime, storm: ParticleStorm, particlePos: Vec3d, emitterPos: Vec3d): Vec3d
fun getAcceleration(runtime: MoLangRuntime, velocity: Vec3d): Vec3d
fun getVelocity(runtime: MoLangRuntime, particle: SnowstormParticle, velocity: Vec3d): Vec3d
fun getParticleDirection(runtime: MoLangRuntime, storm: ParticleStorm, velocity: Vec3d, minSpeed: Float): Vec3d
}
enum class ParticleMotionType {
DYNAMIC,
PARAMETRIC, // TODO figure out how that even works
PARAMETRIC,
STATIC
}
class ParametricParticleMotion(
var offset: Triple<Expression, Expression, Expression> = Triple(
NumberExpression(0.0),
NumberExpression(0.0),
NumberExpression(0.0)
),
var direction: Triple<Expression, Expression, Expression> = Triple(
NumberExpression(0.0),
NumberExpression(0.0),
NumberExpression(0.0)
)
) : ParticleMotion {
companion object {
val CODEC: Codec<ParametricParticleMotion> = RecordCodecBuilder.create { instance ->
instance.group(
PrimitiveCodec.STRING.fieldOf("type").forGetter { it.type.name },
EXPRESSION_CODEC.listOf().fieldOf("offset").forGetter { listOf(it.offset.first, it.offset.second, it.offset.third) },
EXPRESSION_CODEC.listOf().fieldOf("direction").forGetter { listOf(it.direction.first, it.direction.second, it.direction.third) }
).apply(instance) { _, offset, direction -> ParametricParticleMotion(Triple(offset[0], offset[1], offset[2]), Triple(direction[0], direction[1], direction[2])) }
}
}
override val type = ParticleMotionType.PARAMETRIC
override fun getInitialVelocity(runtime: MoLangRuntime, storm: ParticleStorm, particlePos: Vec3d, emitterPos: Vec3d) = Vec3d.ZERO
override fun getVelocity(runtime: MoLangRuntime, particle: SnowstormParticle, velocity: Vec3d): Vec3d {
val stormPosition = Vec3d(particle.storm.getX(), particle.storm.getY(), particle.storm.getZ())
val offset = runtime.resolveVec3d(this.offset)
val particlePosition = Vec3d(particle.getX(), particle.getY(), particle.getZ())
val desiredPosition = stormPosition.add(offset)
return desiredPosition.subtract(particlePosition)
}
override fun getParticleDirection(runtime: MoLangRuntime, storm: ParticleStorm, velocity: Vec3d, minSpeed: Float) = runtime.resolveVec3d(direction).normalize()
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
override fun readFromBuffer(buffer: PacketByteBuf) {
offset = Triple(
MoLang.createParser(buffer.readString()).parseExpression(),
MoLang.createParser(buffer.readString()).parseExpression(),
MoLang.createParser(buffer.readString()).parseExpression()
)
direction = Triple(
MoLang.createParser(buffer.readString()).parseExpression(),
MoLang.createParser(buffer.readString()).parseExpression(),
MoLang.createParser(buffer.readString()).parseExpression()
)
}
override fun writeToBuffer(buffer: PacketByteBuf) {
buffer.writeString(offset.first.getString())
buffer.writeString(offset.second.getString())
buffer.writeString(offset.third.getString())
buffer.writeString(direction.first.getString())
buffer.writeString(direction.second.getString())
buffer.writeString(direction.third.getString())
}
}
class DynamicParticleMotion(
var direction: ParticleMotionDirection = InwardsMotionDirection(),
var speed: Expression = NumberExpression(0.0),
@@ -79,14 +140,23 @@ class DynamicParticleMotion(
return direction.getDirectionVector(runtime, storm, emitterPos, particlePos).normalize().multiply(runtime.resolveDouble(speed))
}
override fun getAcceleration(runtime: MoLangRuntime, velocity: Vec3d): Vec3d {
return Vec3d(
override fun getVelocity(runtime: MoLangRuntime, particle: SnowstormParticle, velocity: Vec3d): Vec3d {
val acceleration = Vec3d(
runtime.resolveDouble(acceleration.first),
runtime.resolveDouble(acceleration.second),
runtime.resolveDouble(acceleration.third)
).subtract(velocity.multiply(runtime.resolveDouble(drag)))
)
.subtract(velocity.multiply(20 * runtime.resolveDouble(drag)))
.multiply(1 / 20.0).multiply(1 / 20.0) // blocks per second per second -> blocks per tick per tick
return Vec3d(
velocity.x + acceleration.x,
velocity.y + acceleration.y,
velocity.z + acceleration.z
)
}
override fun getParticleDirection(runtime: MoLangRuntime, storm: ParticleStorm, velocity: Vec3d, minSpeed: Float) = velocity.normalize()
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
override fun readFromBuffer(buffer: PacketByteBuf) {
@@ -234,7 +304,8 @@ class StaticParticleMotion : ParticleMotion {
override val type = ParticleMotionType.STATIC
override fun getInitialVelocity(runtime: MoLangRuntime, storm: ParticleStorm, particlePos: Vec3d, emitterPos: Vec3d) = Vec3d.ZERO
override fun getAcceleration(runtime: MoLangRuntime, velocity: Vec3d) = Vec3d.ZERO
override fun getVelocity(runtime: MoLangRuntime, particle: SnowstormParticle, velocity: Vec3d) = velocity
override fun getParticleDirection(runtime: MoLangRuntime, storm: ParticleStorm, velocity: Vec3d, minSpeed: Float) = velocity.normalize()
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
override fun readFromBuffer(buffer: PacketByteBuf) {}
override fun writeToBuffer(buffer: PacketByteBuf) {}
@@ -32,6 +32,7 @@ interface ParticleRotation : CodecMapped {
) {
init {
registerSubtype(ParticleRotationType.DYNAMIC, DynamicParticleRotation::class.java, DynamicParticleRotation.CODEC)
registerSubtype(ParticleRotationType.PARAMETRIC, ParametricParticleRotation::class.java, ParametricParticleRotation.CODEC)
}
}
@@ -39,7 +40,34 @@ interface ParticleRotation : CodecMapped {
fun getInitialRotation(runtime: MoLangRuntime): Double
fun getInitialAngularVelocity(runtime: MoLangRuntime): Double
fun getAngularAcceleration(runtime: MoLangRuntime, angularVelocity: Double): Double
fun getAngularVelocity(runtime: MoLangRuntime, angle: Double, angularVelocity: Double): Double
}
class ParametricParticleRotation(var expression: Expression = NumberExpression(0.0)): ParticleRotation {
companion object {
val CODEC: Codec<ParametricParticleRotation> = RecordCodecBuilder.create { instance ->
instance.group(
PrimitiveCodec.STRING.fieldOf("type").forGetter { it.type.name },
EXPRESSION_CODEC.fieldOf("expression").forGetter { it.expression }
).apply(instance) { _, expression ->
ParametricParticleRotation(expression)
}
}
}
override val type = ParticleRotationType.PARAMETRIC
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
override fun getInitialRotation(runtime: MoLangRuntime) = runtime.resolveDouble(expression)
override fun getInitialAngularVelocity(runtime: MoLangRuntime) = 0.0
override fun getAngularVelocity(runtime: MoLangRuntime, angle: Double, angularVelocity: Double) = runtime.resolveDouble(expression) - angle
override fun readFromBuffer(buffer: PacketByteBuf) {
expression = MoLang.createParser(buffer.readString()).parseExpression()
}
override fun writeToBuffer(buffer: PacketByteBuf) {
buffer.writeString(expression.getString())
}
}
class DynamicParticleRotation(
@@ -66,15 +94,15 @@ class DynamicParticleRotation(
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
override fun getInitialRotation(runtime: MoLangRuntime) = runtime.resolveDouble(startRotation)
override fun getInitialAngularVelocity(runtime: MoLangRuntime) = runtime.resolveDouble(speed) / 20
override fun getAngularAcceleration(runtime: MoLangRuntime, angularVelocity: Double): Double {
override fun getAngularVelocity(runtime: MoLangRuntime, angle: Double, angularVelocity: Double): Double {
val acceleration = runtime.resolveDouble(acceleration)
val nextVelocity = angularVelocity + acceleration
val nextVelocity = angularVelocity * 20 + acceleration
val drag = nextVelocity * runtime.resolveDouble(drag)
return if (abs(drag) > abs(nextVelocity)) {
return angularVelocity + (if (abs(drag) > abs(nextVelocity)) {
0.0
} else {
nextVelocity - drag - angularVelocity
}
nextVelocity - drag - angularVelocity * 20
})
}
override fun readFromBuffer(buffer: PacketByteBuf) {
@@ -10,12 +10,7 @@ package com.cobblemon.mod.common.api.spawning
import com.cobblemon.mod.common.Cobblemon.LOGGER
import com.cobblemon.mod.common.api.entity.Despawner
import com.cobblemon.mod.common.api.spawning.condition.AreaSpawningCondition
import com.cobblemon.mod.common.api.spawning.condition.BasicSpawningCondition
import com.cobblemon.mod.common.api.spawning.condition.GroundedSpawningCondition
import com.cobblemon.mod.common.api.spawning.condition.SpawningCondition
import com.cobblemon.mod.common.api.spawning.condition.SubmergedSpawningCondition
import com.cobblemon.mod.common.api.spawning.condition.SurfaceSpawningCondition
import com.cobblemon.mod.common.api.spawning.condition.*
import com.cobblemon.mod.common.api.spawning.context.AreaContextResolver
import com.cobblemon.mod.common.api.spawning.context.GroundedSpawningContext
import com.cobblemon.mod.common.api.spawning.context.LavafloorSpawningContext
@@ -91,6 +86,7 @@ object BestSpawner {
SpawningCondition.register(SubmergedSpawningCondition.NAME, SubmergedSpawningCondition::class.java)
SpawningCondition.register(GroundedSpawningCondition.NAME, GroundedSpawningCondition::class.java)
SpawningCondition.register(SurfaceSpawningCondition.NAME, SurfaceSpawningCondition::class.java)
SpawningCondition.register(SeafloorSpawningCondition.NAME, SeafloorSpawningCondition::class.java)
LOGGER.info("Loaded ${SpawningCondition.conditionTypes.size} spawning condition types.")
SpawningContextCalculator.register(GroundedSpawningContextCalculator)
@@ -100,7 +96,7 @@ object BestSpawner {
SpawningContextCalculator.register(SurfaceSpawningContextCalculator)
SpawningContext.register(name = "grounded", clazz = GroundedSpawningContext::class.java, defaultCondition = GroundedSpawningCondition.NAME)
SpawningContext.register(name = "seafloor", clazz = SeafloorSpawningContext::class.java, defaultCondition = GroundedSpawningCondition.NAME)
SpawningContext.register(name = "seafloor", clazz = SeafloorSpawningContext::class.java, defaultCondition = SeafloorSpawningCondition.NAME)
SpawningContext.register(name = "lavafloor", clazz = LavafloorSpawningContext::class.java, defaultCondition = GroundedSpawningCondition.NAME)
SpawningContext.register(name = "submerged", clazz = SubmergedSpawningContext::class.java, defaultCondition = SubmergedSpawningCondition.NAME)
SpawningContext.register(name = "surface", clazz = SurfaceSpawningContext::class.java, defaultCondition = SurfaceSpawningCondition.NAME)
@@ -35,11 +35,13 @@ class TimeRange : IntRanges {
"night" to TimeRange(12542..23459),
"noon" to TimeRange(5000..6999),
"midnight" to TimeRange(17000..18999),
"dawn" to TimeRange(22300..23999, 0..166),
"dawn" to TimeRange(22300..23999, 0..999),
"dusk" to TimeRange(11834..13701),
"twilight" to TimeRange(11834..13701, 22300..23999, 0..166),
"morning" to TimeRange(0..4999),
"afternoon" to TimeRange(7000..12039)
"morning" to TimeRange(23000..23999, 0..4999),
"afternoon" to TimeRange(7000..12999),
"predawn" to TimeRange(19000..22999),
"evening" to TimeRange(13000..16999)
)
}
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.spawning.condition
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
import com.cobblemon.mod.common.api.spawning.context.SeafloorSpawningContext
import com.cobblemon.mod.common.util.Merger
import net.minecraft.block.Block
/**
* Base type for a spawning condition that applies to some kind of [SeafloorSpawningContext]. This
* can be extended for subclasses of [SeafloorSpawningContext].
*
* Borrowed the Grounded context code since it was unintentionally spawning Pokémon on the sea floor
* already. Seems to be working fine /shrug
*
* @author FrankTheFarmer
* @since May 22nd, 2024
*/
abstract class SeafloorTypeSpawningCondition<T : SeafloorSpawningContext> : AreaTypeSpawningCondition<T>() {
var neededBaseBlocks: MutableList<RegistryLikeCondition<Block>>? = null
override fun fits(ctx: T): Boolean {
return if (!super.fits(ctx)) {
false
} else if (minHeight != null && ctx.height < minHeight!!) {
return false
} else if (maxHeight != null && ctx.height > maxHeight!!) {
return false
} else !(neededBaseBlocks != null && neededBaseBlocks!!.none { it.fits(ctx.baseBlock.block, ctx.blockRegistry) })
}
override fun copyFrom(other: SpawningCondition<*>, merger: Merger) {
super.copyFrom(other, merger)
if (other is SeafloorTypeSpawningCondition) {
neededBaseBlocks = merger.merge(neededBaseBlocks, other.neededBaseBlocks)?.toMutableList()
}
}
}
/**
* A spawning condition for a [SeafloorSpawningContext].
*
* @author FrankTheFarmer
* @since May 22nd, 2024
*/
open class SeafloorSpawningCondition : SeafloorTypeSpawningCondition<SeafloorSpawningContext>() {
override fun contextClass() = SeafloorSpawningContext::class.java
companion object {
const val NAME = "seafloor"
}
}
@@ -78,7 +78,7 @@ abstract class SpawningCondition<T : SpawningContext> {
return false
} else if (ctx.position.z < minZ.orMin() || ctx.position.z > maxZ.orMax()) {
return false
} else if (dimensions != null && dimensions!!.isNotEmpty() && ctx.world.dimension.effects !in dimensions!!) {
} else if (dimensions != null && dimensions!!.isNotEmpty() && ctx.world.dimensionKey.value !in dimensions!!) {
return false
} else if (moonPhase != null && ctx.moonPhase !in moonPhase!!) {
return false
@@ -49,7 +49,7 @@ open class AreaSpawningContext(
* This is not considering the provided state as what the entity would be on top of,
* but rather the space its hitbox would fill.
*/
open fun isSafeSpace(world: ServerWorld, pos: BlockPos, state: BlockState): Boolean = !state.isFullCube(world, pos)
open fun isSafeSpace(world: ServerWorld, pos: BlockPos, state: BlockState): Boolean = !state.isSolid
override fun postFilter(detail: SpawnDetail): Boolean {
if (!super.postFilter(detail)) {
@@ -30,8 +30,8 @@ import net.minecraft.server.world.ServerWorld
*/
interface SpawningContextCalculator<I : SpawningContextInput, O : SpawningContext> {
companion object {
val isAirCondition: (BlockState) -> Boolean = { it.isAir || (!it.isSolid && !it.isLiquid) }
val isSolidCondition: (BlockState) -> Boolean = { it.isSolid && !it.isIn(BlockTags.LEAVES) }
val isAirCondition: (BlockState) -> Boolean = { it.isAir || (!it.isSolid && !it.fluidState.isIn(FluidTags.WATER)) }
val isSolidCondition: (BlockState) -> Boolean = { it.isSolid }
val isWaterCondition: (BlockState) -> Boolean = { it.fluidState.isIn(FluidTags.WATER) && it.fluidState.isStill }
val isLavaCondition: (BlockState) -> Boolean = { it.fluidState.isIn(FluidTags.LAVA) && it.fluidState.isStill }
@@ -34,15 +34,19 @@ abstract class SpawnAction<R>(
/**
* Runs the spawn action and processes any non-null result.
*/
open fun complete(): Boolean {
open fun complete(): R? {
if (future.isDone) {
return null
}
ctx.influences.forEach { it.affectAction(this) }
val result = run()
return if (result != null) {
if (result != null) {
future.complete(result)
true
} else {
future.completeExceptionally(Exception("Nothing was spawned."))
false
}
return result
}
}
@@ -34,7 +34,8 @@ class BestSpawnerConfig {
val contextWeights = mutableMapOf(
"grounded" to 1F,
"submerged" to 0.99F,
"surface" to 0.01F
"surface" to 0.01F,
"seafloor" to 1F
)
val buckets = mutableListOf(
SpawnBucket("common", 93.8F),
@@ -48,7 +48,7 @@ abstract class SpawnDetailPreset {
var weightMultipliers: MutableList<WeightMultiplier>? = null
var weight: Float? = null
var percentage: Float? = null
var mergeMode = MergeMode.KEEP
var mergeMode = MergeMode.INSERT
open fun apply(spawnDetail: SpawnDetail) {
bucket?.let { spawnDetail.bucket = it }
@@ -124,7 +124,7 @@ open class PlayerPartyStore(
}
// Passive evolutions
pokemon.evolutions.filterIsInstance<PassiveEvolution>().forEach { it.attemptEvolution(pokemon) }
pokemon.lockedEvolutions.filterIsInstance<PassiveEvolution>().forEach { it.attemptEvolution(pokemon) }
val removeList = mutableListOf<Evolution>()
pokemon.evolutionProxy.server().forEach {
if (!it.test(pokemon) && it is LevelUpEvolution && !it.permanent)
@@ -99,7 +99,7 @@ open class PCStore(
this.lockedSize = lockNewSize
if (boxes.size > newSize) {
// reduce
val slicedBoxes = boxes.slice(boxes.size until newSize)
val slicedBoxes = boxes.slice(newSize until boxes.size)
boxes.removeAll(slicedBoxes)
slicedBoxes.flatMap { it.asIterable() }.forEach(overflowHandler)
} else {
@@ -71,7 +71,6 @@ object BattleBuilder {
player1Actor.battleTheme = player2.getBattleTheme()
player2Actor.battleTheme = player1.getBattleTheme()
}
errors
} else {
errors
}
@@ -140,7 +139,6 @@ object BattleBuilder {
}
playerActor.battleTheme = pokemonEntity.getBattleTheme()
}
errors
} else {
errors
}
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.battles.dispatch
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.getQueryStruct
import net.minecraft.util.Identifier
import java.util.concurrent.CompletableFuture
/**
* An [InterpreterInstruction] that triggers an [ActionEffectTimeline]
* I think it might be better to have this as an abstract class so we can default the fields
*
* @author Apion
* @since May 19, 2024
*/
interface ActionEffectInstruction : InterpreterInstruction {
var future: CompletableFuture<*>
var holds: MutableSet<String>
//To expose via molang, so action effects can do different stuff in different instructions
//e.g. "x is confused" vs "x hit itself in confusion"
val id: Identifier
override fun invoke(battle: PokemonBattle) {
preActionEffect(battle)
val runtime = MoLangRuntime()
battle.addQueryFunctions(runtime.environment.getQueryStruct())
runtime.environment.getQueryStruct().addStandardFunctions()
addMolangQueries(runtime)
runActionEffect(battle, runtime)
postActionEffect(battle)
}
fun preActionEffect(battle: PokemonBattle)
fun runActionEffect(battle: PokemonBattle, runtime: MoLangRuntime)
fun postActionEffect(battle: PokemonBattle)
fun addMolangQueries(runtime: MoLangRuntime) {
runtime.environment.getQueryStruct()
.addFunction("instruction_id") { StringValue(id.toString()) }
}
}
@@ -8,16 +8,28 @@
package com.cobblemon.mod.common.battles.interpreter.instructions
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.getQueryStruct
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
import com.cobblemon.mod.common.api.pokemon.status.Statuses
import com.cobblemon.mod.common.battles.ShowdownInterpreter
import com.cobblemon.mod.common.battles.dispatch.ActionEffectInstruction
import com.cobblemon.mod.common.battles.dispatch.CauserInstruction
import com.cobblemon.mod.common.battles.dispatch.GO
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.dispatch.WaitDispatch
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.text.Text
import net.minecraft.util.Identifier
import java.util.concurrent.CompletableFuture
/**
* Format: |-activate|POKEMON|EFFECT
@@ -28,19 +40,50 @@ import net.minecraft.text.Text
* @author Hunter
* @since September 25th, 2022
*/
class ActivateInstruction(val instructionSet: InstructionSet, val message: BattleMessage) : InterpreterInstruction, CauserInstruction {
override fun invoke(battle: PokemonBattle) {
class ActivateInstruction(val instructionSet: InstructionSet, val message: BattleMessage) : ActionEffectInstruction, CauserInstruction {
override var future: CompletableFuture<*> = CompletableFuture.completedFuture(Unit)
override var holds = mutableSetOf<String>()
override val id = cobblemonResource("activate")
override fun preActionEffect(battle: PokemonBattle) {
val pokemon = message.battlePokemon(0, battle) ?: return
val effect = message.effectAt(1) ?: return
val extraEffect = message.effectAt(2)?.typelessData ?: Text.literal("UNKNOWN")
ShowdownInterpreter.broadcastOptionalAbility(battle, effect, pokemon)
battle.dispatch{
val pokemonName = pokemon.getName()
val sourceName = message.battlePokemonFromOptional(battle)?.getName() ?: Text.literal("UNKNOWN")
ShowdownInterpreter.lastCauser[battle.battleId] = message
battle.minorBattleActions[pokemon.uuid] = message
GO
}
}
override fun runActionEffect(battle: PokemonBattle, runtime: MoLangRuntime) {
battle.dispatch {
val effect = message.effectAt(1) ?: return@dispatch GO
val status = Statuses.getStatus(effect.id)
val actionEffect = status?.getActionEffect() ?: return@dispatch GO
val providers = mutableListOf<Any>(battle)
val pokemon = message.battlePokemon(0, battle) ?: return@dispatch GO
pokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
val context = ActionEffectContext(
actionEffect = actionEffect,
runtime = runtime,
providers = providers
)
this.future = actionEffect.run(context)
holds = context.holds // Reference so future things can check on this action effect's holds
future.thenApply { holds.clear() }
return@dispatch GO
}
}
override fun postActionEffect(battle: PokemonBattle) {
battle.dispatch {
val pokemon = message.battlePokemon(0, battle) ?: return@dispatch GO
val extraEffect = message.effectAt(2)?.typelessData ?: Text.literal("UNKNOWN")
val effect = message.effectAt(1) ?: return@dispatch GO
val pokemonName = pokemon.getName()
val sourceName = message.battlePokemonFromOptional(battle)?.getName() ?: Text.literal("UNKNOWN")
val lang = when (effect.id) {
// Includes a 3rd argument being the magnitude level as a number
"magnitude" -> battleLang("activate.magnitude", message.argumentAt(2)?.toIntOrNull() ?: 1)
@@ -59,7 +102,8 @@ class ActivateInstruction(val instructionSet: InstructionSet, val message: Battl
else -> battleLang("activate.${effect.id}", pokemonName, sourceName, extraEffect)
}
battle.broadcastChatMessage(lang)
WaitDispatch(1F)
//We check holds here so the chat msg + particle effect happen more concurrently, instead of sequentially
UntilDispatch { "effects" !in holds}
}
}
}
@@ -8,14 +8,25 @@
package com.cobblemon.mod.common.battles.interpreter.instructions
import com.bedrockk.molang.runtime.MoLangRuntime
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.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.stats.Stats
import com.cobblemon.mod.common.api.pokemon.status.Statuses
import com.cobblemon.mod.common.battles.ShowdownInterpreter
import com.cobblemon.mod.common.battles.dispatch.ActionEffectInstruction
import com.cobblemon.mod.common.battles.dispatch.GO
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.util.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.util.Identifier
import java.util.concurrent.CompletableFuture
/**
* Format: |-boost|POKEMON|STAT|AMOUNT or |-unboost|POKEMON|STAT|AMOUNT
@@ -25,9 +36,33 @@ import com.cobblemon.mod.common.util.battleLang
* @author Hiroku
* @since August 20th, 2022
*/
class BoostInstruction(val instructionSet: InstructionSet, val message: BattleMessage, val remainingLines: Iterator<BattleMessage>, val isBoost: Boolean = true): InterpreterInstruction {
class BoostInstruction(val instructionSet: InstructionSet, val message: BattleMessage, val remainingLines: Iterator<BattleMessage>, val isBoost: Boolean = true): ActionEffectInstruction {
override var future: CompletableFuture<*> = CompletableFuture.completedFuture(Unit)
override var holds = mutableSetOf<String>()
override val id = cobblemonResource("boost")
override fun preActionEffect(battle: PokemonBattle) {
override fun invoke(battle: PokemonBattle) {
}
override fun runActionEffect(battle: PokemonBattle, runtime: MoLangRuntime) {
battle.dispatch {
val actionEffect = if (isBoost) BOOST_EFFECT else UNBOOST_EFFECT
val providers = mutableListOf<Any>(battle)
val pokemon = message.battlePokemon(0, battle) ?: return@dispatch GO
pokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
val context = ActionEffectContext(
actionEffect = actionEffect,
runtime = runtime,
providers = providers
)
this.future = actionEffect.run(context)
holds = context.holds // Reference so future things can check on this action effect's holds
future.thenApply { holds.clear() }
return@dispatch GO
}
}
override fun postActionEffect(battle: PokemonBattle) {
val pokemon = message.battlePokemon(0, battle) ?: return
val statKey = message.argumentAt(1) ?: return
val stages = message.argumentAt(2)?.toInt() ?: return
@@ -35,7 +70,7 @@ class BoostInstruction(val instructionSet: InstructionSet, val message: BattleMe
val severity = Stats.getSeverity(stages)
val rootKey = if (isBoost) "boost" else "unboost"
battle.dispatchWaiting(1.5F) {
battle.dispatch {
val lang = when {
message.hasOptionalArgument("zeffect") -> battleLang("$rootKey.$severity.zeffect", pokemon.getName(), stat)
else -> battleLang("$rootKey.$severity", pokemon.getName(), stat)
@@ -47,6 +82,13 @@ class BoostInstruction(val instructionSet: InstructionSet, val message: BattleMe
// TODO: replace with context that tracks detailed information such as # of stages
repeat(stages) { pokemon.contextManager.add(context) }
battle.minorBattleActions[pokemon.uuid] = message
return@dispatch UntilDispatch { "effects" !in holds }
}
}
companion object {
val BOOST_EFFECT = ActionEffects.actionEffects[cobblemonResource("boost")]!!
val UNBOOST_EFFECT = ActionEffects.actionEffects[cobblemonResource("unboost")]!!
}
}
@@ -8,14 +8,27 @@
package com.cobblemon.mod.common.battles.interpreter.instructions
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.getQueryStruct
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.TargetsProvider
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
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.battles.dispatch.ActionEffectInstruction
import com.cobblemon.mod.common.battles.dispatch.GO
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
import com.cobblemon.mod.common.battles.dispatch.UntilDispatch
import com.cobblemon.mod.common.battles.dispatch.WaitDispatch
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.lang
import net.minecraft.util.Identifier
import java.util.concurrent.CompletableFuture
/**
* Formats: |cant|POKEMON|REASON and |cant|POKEMON|REASON|MOVE
@@ -24,12 +37,40 @@ import com.cobblemon.mod.common.util.lang
* @author Deltric
* @since January 22nd, 2022
*/
class CantInstruction(val message: BattleMessage): InterpreterInstruction {
class CantInstruction(val message: BattleMessage): ActionEffectInstruction {
override var future: CompletableFuture<*> = CompletableFuture.completedFuture(Unit)
override var holds = mutableSetOf<String>()
override val id = cobblemonResource("cant")
override fun preActionEffect(battle: PokemonBattle) {
override fun invoke(battle: PokemonBattle) {
battle.dispatchWaiting {
val pokemon = message.battlePokemon(0, battle) ?: return@dispatchWaiting
val effectID = message.effectAt(1)?.id ?: return@dispatchWaiting
}
override fun runActionEffect(battle: PokemonBattle, runtime: MoLangRuntime) {
battle.dispatch {
val pokemon = message.battlePokemon(0, battle) ?: return@dispatch GO
val effectID = message.effectAt(1)?.id ?: return@dispatch GO
val name = pokemon.getName()
val status = Statuses.getStatus(effectID)
val actionEffect = status?.getActionEffect() ?: return@dispatch GO
val providers = mutableListOf<Any>(battle)
pokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
val context = ActionEffectContext(
actionEffect = actionEffect,
runtime = runtime,
providers = providers
)
this.future = actionEffect.run(context)
holds = context.holds // Reference so future things can check on this action effect's holds
future.thenApply { holds.clear() }
GO
}
}
override fun postActionEffect(battle: PokemonBattle) {
battle.dispatch {
val pokemon = message.battlePokemon(0, battle) ?: return@dispatch GO
val effectID = message.effectAt(1)?.id ?: return@dispatch GO
val name = pokemon.getName()
// Move may be null as it's not always given
val moveName = message.moveAt(2)?.displayName ?: run { "(Unrecognized: ${message.argumentAt(2)})".text() }
@@ -38,7 +79,7 @@ class CantInstruction(val message: BattleMessage): InterpreterInstruction {
// TODO: in the games they use a generic image because there is a popup of the ability and the sprite of the mon, it may be good to have a similar system here
"armortail", "damp", "dazzling", "queenlymajesty" -> battleLang("cant.generic", name, moveName)
"par", "slp", "frz" -> {
val status = Statuses.getStatus(effectID)?.name?.path ?: return@dispatchWaiting
val status = Statuses.getStatus(effectID)?.name?.path ?: return@dispatch GO
lang("status.$status.is", name)
}
else -> battleLang("cant.$effectID", name, moveName)
@@ -46,6 +87,10 @@ class CantInstruction(val message: BattleMessage): InterpreterInstruction {
battle.broadcastChatMessage(lang.red())
battle.minorBattleActions[pokemon.uuid] = message
UntilDispatch { "effects" !in holds }
}
}
}
@@ -8,15 +8,21 @@
package com.cobblemon.mod.common.battles.interpreter.instructions
import com.bedrockk.molang.runtime.MoLangRuntime
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.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.getQueryStruct
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
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
import com.cobblemon.mod.common.battles.ShowdownInterpreter
import com.cobblemon.mod.common.battles.ShowdownInterpreter.lastCauser
import com.cobblemon.mod.common.battles.dispatch.ActionEffectInstruction
import com.cobblemon.mod.common.battles.dispatch.GO
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.dispatch.WaitDispatch
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
@@ -25,11 +31,13 @@ import com.cobblemon.mod.common.net.messages.client.battle.BattleHealthChangePac
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
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.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.lang
import java.util.concurrent.CompletableFuture
import kotlin.math.roundToInt
import net.minecraft.text.Text
import net.minecraft.util.Identifier
/**
* Format: |-damage|POKEMON|HP STATUS
@@ -43,45 +51,87 @@ class DamageInstruction(
val actor: BattleActor,
val publicMessage: BattleMessage,
val privateMessage: BattleMessage
) : InterpreterInstruction {
var future = CompletableFuture.completedFuture(Unit)
) : ActionEffectInstruction {
val expectedTarget = publicMessage.battlePokemon(0, actor.battle)
override var future: CompletableFuture<*> = CompletableFuture.completedFuture(Unit)
override var holds = mutableSetOf<String>()
override val id = cobblemonResource("damage")
override fun invoke(battle: PokemonBattle) {
override fun preActionEffect(battle: PokemonBattle) {
val battlePokemon = publicMessage.battlePokemon(0, actor.battle) ?: return
val recoiling = privateMessage.optionalArgument("from")?.equals("recoil", true) == true
val lastCauser = instructionSet.getMostRecentCauser(comparedTo = this)
if (recoiling) {
battlePokemon.effectedPokemon.let { pokemon ->
if (RecoilEvolutionProgress.supports(pokemon)) {
val newPercentage = privateMessage.argumentAt(1)?.split("/")?.getOrNull(0)?.toIntOrNull() ?: 0
val newHealth = (pokemon.hp * (newPercentage / 100.0)).roundToInt()
val difference = pokemon.currentHealth - newHealth
if (difference > 0) {
val progress = pokemon.evolutionProxy.current().progressFirstOrCreate({ it is RecoilEvolutionProgress }) { RecoilEvolutionProgress() }
progress.updateProgress(RecoilEvolutionProgress.Progress(progress.currentProgress().recoil + difference))
}
doRecoilEvoChecks(battlePokemon)
if (lastCauser is MoveInstruction) {
battle.dispatch {
//Is the recoil hold currently used anywhere?
UntilDispatch { "recoil" !in lastCauser.holds }
}
}
}
val newHealth = privateMessage.argumentAt(1)?.split(" ")?.get(0) ?: return
val effect = privateMessage.effect()
val source = privateMessage.battlePokemonFromOptional(battle)
var causedFaint = newHealth == "0"
source?.let { ShowdownInterpreter.broadcastOptionalAbility(battle, effect, it) }
}
battle.dispatch {
if (lastCauser is MoveInstruction && recoiling) {
UntilDispatch { "recoil" !in lastCauser.holds }
} else {
GO
private fun doRecoilEvoChecks(battlePokemon: BattlePokemon) {
battlePokemon.effectedPokemon.let { pokemon ->
if (RecoilEvolutionProgress.supports(pokemon)) {
val healthStr = privateMessage.argumentAt(1) ?: throw UnsupportedOperationException(
"Cant get recoil string"
)
val newHealth =
"([0-9]+).*".toRegex().find(healthStr)?.groups?.get(1)?.value?.toIntOrNull()
?: throw UnsupportedOperationException("Cant get recoil string")
val difference = pokemon.currentHealth - newHealth
if (difference > 0) {
val progress = pokemon.evolutionProxy.current()
.progressFirstOrCreate({ it is RecoilEvolutionProgress }) { RecoilEvolutionProgress() }
progress.updateProgress(RecoilEvolutionProgress.Progress(progress.currentProgress().recoil + difference))
}
}
}
}
source?.let { ShowdownInterpreter.broadcastOptionalAbility(battle, effect, it) }
override fun runActionEffect(battle: PokemonBattle, runtime: MoLangRuntime) {
val effect = privateMessage.effect()
val battlePokemon = publicMessage.battlePokemon(0, actor.battle) ?: return
var status = effect?.id?.let { Statuses.getStatus(it) }
battle.dispatch {
val pokemon = privateMessage.battlePokemon(0, battle) ?: return@dispatch GO
//Showdown doesnt tell us on damage if its poison or toxic so we gotta consult the entity
if (status is PoisonStatus) {
status = pokemon.effectedPokemon.status?.status ?: status
}
val actionEffect = status?.getActionEffect() ?: return@dispatch GO
val providers = mutableListOf<Any>(battle)
battlePokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
val context = ActionEffectContext(
actionEffect = actionEffect,
runtime = runtime,
providers = providers
)
this.future = actionEffect.run(context)
holds = context.holds // Reference so future things can check on this action effect's holds
future.thenApply { holds.clear() }
return@dispatch GO
}
}
override fun postActionEffect(battle: PokemonBattle) {
val newHealth = privateMessage.argumentAt(1)?.split(" ")?.get(0) ?: return
val battlePokemon = publicMessage.battlePokemon(0, actor.battle) ?: return
var causedFaint = newHealth == "0"
val effect = privateMessage.effect()
val source = privateMessage.battlePokemonFromOptional(battle)
val lastCauser = instructionSet.getMostRecentCauser(comparedTo = this)
battle.dispatch {
val pokemonName = battlePokemon.getName()
val pokemonEntity = battlePokemon.entity
//Play recoil animation if the pokemon recoiling isnt dead
if (!causedFaint && pokemonEntity != null) {
val pkt = PlayPoseableAnimationPacket(pokemonEntity.id, setOf("recoil"), emptySet())
pkt.sendToPlayersAround(
@@ -92,7 +142,7 @@ class DamageInstruction(
distance = 50.0
)
}
//Play hit particle
if (pokemonEntity != null) {
RunPosableMoLangPacket(pokemonEntity.id, setOf("q.particle('cobblemon:hit', 'target')")).sendToPlayersAround(
x = pokemonEntity.x,
@@ -157,8 +207,9 @@ class DamageInstruction(
} else if (causedFaint) {
GO
} else {
WaitDispatch(1F)
UntilDispatch {"effects" !in holds}
}
}
}
}
@@ -10,10 +10,10 @@ package com.cobblemon.mod.common.battles.interpreter.instructions
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.StringValue
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.addFunction
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.getQueryStruct
import com.cobblemon.mod.common.api.moves.Moves
@@ -29,6 +29,7 @@ import com.cobblemon.mod.common.battles.dispatch.UntilDispatch
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.pokemon.evolution.progress.UseMoveEvolutionProgress
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import java.util.concurrent.CompletableFuture
/**
@@ -121,6 +122,7 @@ class MoveInstruction(
}
runtime.environment.getQueryStruct().addFunction("move") { move.struct }
runtime.environment.getQueryStruct().addFunction("instruction_id") { StringValue(cobblemonResource("move").toString()) }
this.future = actionEffect.run(context)
holds = context.holds // Reference so future things can check on this action effect's holds
@@ -47,7 +47,16 @@ class SwitchInstruction(val instructionSet: InstructionSet, val battleActor: Bat
if (!battle.started) {
activePokemon.battlePokemon = pokemon
activePokemon.illusion = illusion
val pokemonEntity = pokemon.entity
val pokemonEntity = 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) {
pokemon.effectedPokemon.recall()
return@let null
}
pokemon.entity
}
if (pokemonEntity == null && entity != null) {
val targetPos = battleActor.getSide().getOppositeSide().actors.filterIsInstance<EntityBackedBattleActor<*>>().firstOrNull()?.entity?.pos?.let { pos ->
val offset = pos.subtract(entity.pos)
@@ -19,6 +19,7 @@ import com.cobblemon.mod.common.api.mulch.MulchVariant
import com.cobblemon.mod.common.api.mulch.Mulchable
import com.cobblemon.mod.common.api.tags.CobblemonBlockTags
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
import dev.lambdaurora.lambdynlights.util.SodiumDynamicLightHandler.pos
import net.minecraft.block.Block
import net.minecraft.block.BlockRenderType
import net.minecraft.block.BlockState
@@ -87,22 +88,31 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
init {
defaultState = this.stateManager.defaultState
.with(WAS_GENERATED, false)
.with(AGE, 0)
.with(MULCH, MulchVariant.NONE)
.with(AGE, 0)
.with(IS_ROOTED, false)
}
override fun grow(world: ServerWorld, random: Random, pos: BlockPos, state: BlockState) {
growHelper(world, random, pos, state, true)
}
//grow, but cooler
fun growHelper(world: ServerWorld, random: Random, pos: BlockPos, state: BlockState, boneMealed: Boolean = false) {
val berry = berry() ?: return
if (boneMealed && random.nextFloat() > berry.boneMealChance) return
val curAge = state.get(AGE)
val newAge = curAge + 1
if (newAge > FRUIT_AGE) return
val newState = state.with(AGE, newAge)
val treeEntity = world.getBlockEntity(pos) as BerryBlockEntity
if (curAge == MATURE_AGE) {
treeEntity.generateGrowthPoints(world, state, pos, null)
determineMutation(world, random, pos, state)
treeEntity.generateGrowthPoints(world, newState, pos, null)
determineMutation(world, random, pos, newState)
}
world.setBlockState(pos, newState, Block.NOTIFY_LISTENERS)
convertMulchToEntity(world, newState, pos)
treeEntity.goToNextStageTimer(FRUIT_AGE - curAge)
treeEntity.markDirty()
}
@@ -122,7 +132,7 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
CobblemonEvents.BERRY_MUTATION_OFFER.post(BerryMutationOfferEvent(berry, world, state, pos, mutations)) { berryMutationOffer ->
if (berryMutationOffer.mutations.isNotEmpty()) {
var mutateChance = 125
if (getMulch(state) == MulchVariant.SURPRISE) {
if (getMulch(treeEntity) == MulchVariant.SURPRISE) {
mutateChance *= 4
treeEntity.decrementMulchDuration(world, pos, state)
}
@@ -143,7 +153,10 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
state: BlockState,
variant: MulchVariant
): Boolean {
return getMulch(state) == MulchVariant.NONE && state.get(AGE) < FLOWER_AGE && world.getBlockState(pos.down()).isOf(Blocks.FARMLAND)
val underBlockState = world.getBlockState(pos.down())
val validSoil = state.get(IS_ROOTED) || underBlockState.isIn(CobblemonBlockTags.BERRY_SOIL)
val treeEntity = world.getBlockEntity(pos) as? BerryBlockEntity ?: return false
return getMulch(treeEntity) == MulchVariant.NONE && state.get(AGE) < FLOWER_AGE && validSoil
}
override fun applyMulch(
@@ -154,18 +167,15 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
variant: MulchVariant
) {
val treeEntity = world.getBlockEntity(pos) as BerryBlockEntity
setMulch(world, pos, state, variant)
treeEntity.mulchDuration = variant.duration
treeEntity.setMulch(variant, world, state, pos)
world.playSound(null, pos, CobblemonSounds.MULCH_PLACE, SoundCategory.BLOCKS, 0.6F, 1F)
treeEntity.refreshTimers(pos)
}
@Deprecated("Deprecated in Java")
override fun onUse(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockHitResult): ActionResult {
val treeEntity = world.getBlockEntity(pos) as BerryBlockEntity
if (player.getStackInHand(hand).item is ShovelItem && getMulch(state) != MulchVariant.NONE) {
setMulch(world, pos, state, MulchVariant.NONE)
treeEntity.markDirty()
if (player.getStackInHand(hand).item is ShovelItem && getMulch(treeEntity) != MulchVariant.NONE) {
treeEntity.setMulch(MulchVariant.NONE, world, state, pos)
world.playSound(null, pos, CobblemonSounds.MULCH_REMOVE, SoundCategory.BLOCKS, 0.6F, 1F)
this.spawnBreakParticles(world, player, pos, state.with(AGE, 0))
return ActionResult.SUCCESS
@@ -189,7 +199,7 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
val below = world.getBlockState(pos.down())
return (state.get(WAS_GENERATED) && below.isIn(CobblemonBlockTags.BERRY_WILD_SOIL))
|| below.isIn(CobblemonBlockTags.BERRY_SOIL)
|| below.block is FarmlandBlock
|| state.get(IS_ROOTED)
}
@Deprecated("Deprecated in Java")
@@ -208,6 +218,7 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
builder.add(AGE)
builder.add(WAS_GENERATED)
builder.add(MULCH)
builder.add(IS_ROOTED)
}
override fun getPickStack(world: BlockView?, pos: BlockPos?, state: BlockState?): ItemStack {
@@ -239,6 +250,7 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
val AGE: IntProperty = IntProperty.of("age", 0, FRUIT_AGE)
val MULCH: EnumProperty<MulchVariant> = EnumProperty.of("mulch", MulchVariant::class.java)
val WAS_GENERATED: BooleanProperty = BooleanProperty.of("generated")
val IS_ROOTED: BooleanProperty = BooleanProperty.of("rooted")
// val PLANTED_SHAPE = VoxelShapes.union(
// VoxelShapes.cuboid(0.3125, -0.0625, 0.3125, 0.6875, 0.0, 0.6875),
// VoxelShapes.cuboid(0.375, 0.0, 0.375, 0.625, 0.0625, 0.625)
@@ -301,15 +313,14 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
val TALL_MATURE = listOf(Box(0.0, -1.0, 0.0, 16.0, 24.0, 16.0))
fun getMulch(state: BlockState): MulchVariant {
if (!state.contains(MULCH)) {
return MulchVariant.NONE
}
return state.get(MULCH)
}
fun getMulch(entity: BerryBlockEntity) = entity.mulchVariant
fun setMulch(world: World, pos: BlockPos, state: BlockState, mulch: MulchVariant) {
world.setBlockState(pos, state.with(MULCH, mulch))
fun convertMulchToEntity(world: ServerWorld, state: BlockState, pos: BlockPos) {
val entity = world.getBlockEntity(pos) as? BerryBlockEntity ?: return
if (state.get(MULCH) != MulchVariant.NONE && state.get(MULCH) != entity.mulchVariant) {
entity.mulchVariant = state.get(MULCH)
world.setBlockState(pos, state.with(MULCH, MulchVariant.NONE))
}
}
}
}
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
import com.cobblemon.mod.common.item.berry.BerryItem
import net.minecraft.block.AbstractBlock
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.util.ActionResult
import net.minecraft.util.Hand
import net.minecraft.util.hit.BlockHitResult
import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
/**
* @author Apion
* @since February 27, 2024
*/
class BindingSoilBlock(settings: Settings) : Block(settings) {
@Deprecated("Deprecated in Java")
override fun onUse(
state: BlockState,
world: World,
pos: BlockPos,
player: PlayerEntity,
hand: Hand,
hit: BlockHitResult
): ActionResult {
if (!world.isClient) {
val itemStack = player.getStackInHand(hand)
val item = itemStack.item
if (item is BerryItem) {
world.setBlockState(pos, item.block.defaultState.with(BerryBlock.IS_ROOTED, true))
if (!player.isCreative) {
itemStack.decrement(1)
}
}
}
return ActionResult.SUCCESS
}
}
@@ -19,6 +19,7 @@ import net.minecraft.entity.LivingEntity
import net.minecraft.entity.ai.pathing.NavigationType
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.inventory.SidedInventory
import net.minecraft.inventory.SimpleInventory
import net.minecraft.item.ItemPlacementContext
import net.minecraft.item.ItemStack
import net.minecraft.server.world.ServerWorld
@@ -38,6 +39,7 @@ import net.minecraft.util.shape.VoxelShapes
import net.minecraft.world.BlockView
import net.minecraft.world.World
import net.minecraft.world.WorldAccess
import net.minecraft.world.WorldEvents
import net.minecraft.world.WorldView
@@ -72,10 +74,12 @@ class RestorationTankBlock(properties: Settings) : MultiblockBlock(properties),
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
super.onBreak(world, pos, state, player)
val otherPart = world.getBlockState(getPositionOfOtherPart(state, pos))
if (otherPart.block is RestorationTankBlock) {
world.setBlockState(getPositionOfOtherPart(state, pos), Blocks.AIR.defaultState, 35)
world.syncWorldEvent(player, 2001, getPositionOfOtherPart(state, pos), getRawIdFromState(otherPart))
if (!world.isClient) {
val otherPart = world.getBlockState(getPositionOfOtherPart(state, pos))
if (otherPart.block is RestorationTankBlock) {
world.setBlockState(getPositionOfOtherPart(state, pos), Blocks.AIR.defaultState, Block.NOTIFY_ALL)
world.syncWorldEvent(player, WorldEvents.BLOCK_BROKEN, getPositionOfOtherPart(state, pos), getRawIdFromState(otherPart))
}
}
}
@@ -87,9 +91,9 @@ class RestorationTankBlock(properties: Settings) : MultiblockBlock(properties),
itemStack: ItemStack?
) {
//Place the full block before we call to super to validate the multiblock
world.setBlockState(pos.up(), state.with(PART, TankPart.TOP) as BlockState, 3)
world.setBlockState(pos.up(), state.with(PART, TankPart.TOP) as BlockState, Block.NOTIFY_ALL)
world.updateNeighbors(pos, Blocks.AIR)
state.updateNeighbors(world, pos, 3)
state.updateNeighbors(world, pos, Block.NOTIFY_ALL)
super.onPlaced(world, pos, state, placer, itemStack)
}
@@ -100,7 +104,7 @@ class RestorationTankBlock(properties: Settings) : MultiblockBlock(properties),
val tankBottomPos = pos.down()
val tankBottomState = world.getBlockState(tankBottomPos)
if(tankBottomState.block.equals(CobblemonBlocks.RESTORATION_TANK.asBlock()) && tankBottomState.get(PART) == TankPart.BOTTOM) {
return super.onUse(tankBottomState, world, tankBottomPos, player, hand, hit)
return onUse(tankBottomState, world, tankBottomPos, player, hand, hit)
}
}
return super.onUse(state, world, pos, player, hand, hit)
@@ -206,9 +210,8 @@ class RestorationTankBlock(properties: Settings) : MultiblockBlock(properties),
): SidedInventory {
val tankEntity =
(if (state.get(PART) == TankPart.TOP) world.getBlockEntity(pos.down())
else world.getBlockEntity(pos)) as RestorationTankBlockEntity
return tankEntity.inv
else world.getBlockEntity(pos))
return if(tankEntity != null && tankEntity is RestorationTankBlockEntity) tankEntity.inv else DummyInventory()
}
enum class TankPart(private val label: String) : StringIdentifiable {
@@ -226,5 +229,18 @@ class RestorationTankBlock(properties: Settings) : MultiblockBlock(properties),
val PART = EnumProperty.of("part", TankPart::class.java)
val TRIGGERED = Properties.TRIGGERED
val ON = BooleanProperty.of("on")
class DummyInventory : SimpleInventory(0), SidedInventory {
override fun getAvailableSlots(side: Direction): IntArray {
return IntArray(0)
}
override fun canInsert(slot: Int, stack: ItemStack, dir: Direction?): Boolean {
return false
}
override fun canExtract(slot: Int, stack: ItemStack, dir: Direction): Boolean {
return false
}
}
}
}
@@ -27,6 +27,7 @@ import net.minecraft.item.ItemPlacementContext
import net.minecraft.item.ItemStack
import net.minecraft.screen.ScreenHandler
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.server.world.ServerWorld
import net.minecraft.sound.SoundCategory
import net.minecraft.state.StateManager
import net.minecraft.state.property.BooleanProperty
@@ -37,6 +38,7 @@ import net.minecraft.util.*
import net.minecraft.util.hit.BlockHitResult
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.util.math.random.Random
import net.minecraft.util.shape.VoxelShape
import net.minecraft.util.shape.VoxelShapes
import net.minecraft.world.BlockView
@@ -125,11 +127,12 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
fun isFake() = (type == Type.FAKE)
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) {
if (isFake()) {
if (player is ServerPlayerEntity) {
if (!world.isClient) {
if (isFake() && (player is ServerPlayerEntity)) {
spawnPokemon(world, pos, state, player)
}
world.setBlockState(pos, if (state.fluidState.isOf(Fluids.WATER)) Blocks.WATER.defaultState else Blocks.AIR.defaultState)
val bEntity = world.getBlockEntity(pos) as? GildedChestBlockEntity
bEntity?.markRemoved()
} else super.onBreak(world, pos, state, player)
}
@@ -183,10 +186,6 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
if (!player.world.isClient) {
PiglinBrain.onGuardedBlockInteracted(player, true)
}
val state = entity.poseableState
state.currentModel?.let {
it.moveToPose(null, state, it.getPose("OPEN")!!)
}
return ActionResult.SUCCESS
}
@@ -197,9 +196,11 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
newState: BlockState,
moved: Boolean
) {
if (!state.isOf(newState.block)) {
val chest = world.getBlockEntity(pos) as GildedChestBlockEntity
ItemScatterer.spawn(world, pos, chest.inventoryContents)
if (!state.isOf(newState.block) && !world.isClient) {
val chest = world.getBlockEntity(pos) as? GildedChestBlockEntity
chest?.let {
ItemScatterer.spawn(world, pos, chest.inventoryContents)
}
}
}
@@ -261,4 +262,14 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
}
}
override fun scheduledTick(
state: BlockState?,
world: ServerWorld?,
pos: BlockPos?,
random: Random?
) {
val blockEntity = world?.getBlockEntity(pos) as? GildedChestBlockEntity ?: return
blockEntity.onScheduledTick()
}
}
@@ -17,7 +17,6 @@ import com.cobblemon.mod.common.api.events.berry.BerryHarvestEvent
import com.cobblemon.mod.common.api.mulch.MulchVariant
import com.cobblemon.mod.common.block.BerryBlock
import com.cobblemon.mod.common.block.BerryBlock.Companion.getMulch
import com.cobblemon.mod.common.block.BerryBlock.Companion.setMulch
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.entity.BlockEntity
@@ -43,8 +42,8 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
lateinit var berryIdentifier: Identifier
private val ticksPerMinute = 1200
var renderState: RenderState? = null
//The time left for the tree to grow to stage 5
var growthTimer: Int = 72000
//The time left for the tree until its either age 3 or age 5 (check block state, if we are at age 0<x<3 unti 3 otherwise until 5)
var growthTimer: Int = 0
set(value) {
if (value < 0) {
throw IllegalArgumentException("You cannot set the growth time to less than zero")
@@ -55,7 +54,7 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
field = value
}
//The time left for the tree to grow to the next stage
var stageTimer: Int = growthTimer / BerryBlock.MATURE_AGE
var stageTimer: Int = 0
set(value) {
if (field != value) {
this.markDirty()
@@ -63,6 +62,7 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
field = value
}
private val growthPoints = arrayListOf<Identifier>()
var mulchVariant = MulchVariant.NONE
/**
* The idea behind the growth point sequence is it's a 16-long string of
@@ -85,20 +85,6 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
markDirty()
}
fun decrementMulchDuration(world: World, pos: BlockPos, state: BlockState) {
val currentMulch = getMulch(state)
if (currentMulch == MulchVariant.NONE || currentMulch.duration == -1) {
return
}
val newDuration = mulchDuration - 1
mulchDuration = if (newDuration <= 0) {
setMulch(world, pos, state, MulchVariant.NONE)
0
} else {
newDuration
}
}
constructor(pos: BlockPos, state: BlockState, berryIdentifier: Identifier): this(pos, state) {
this.berryIdentifier = berryIdentifier
resetGrowTimers(pos, state)
@@ -107,6 +93,31 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
}
}
fun decrementMulchDuration(world: World, pos: BlockPos, state: BlockState) {
if (mulchVariant == MulchVariant.NONE || mulchVariant.duration == -1) {
return
}
val newDuration = mulchDuration - 1
mulchDuration = if (newDuration <= 0) {
mulchVariant = MulchVariant.NONE
this.markDirty()
world.updateListeners(pos, state, state, Block.NOTIFY_LISTENERS)
0
} else {
newDuration
}
}
fun setMulch(mulch: MulchVariant, world: World, state: BlockState, pos: BlockPos) {
this.mulchVariant = mulch
this.mulchDuration = mulch.duration
refreshTimers(pos)
world.updateListeners(pos, state, state, Block.NOTIFY_LISTENERS)
this.markDirty()
}
//This function basically runs twice when the berry tree is growing, once when it starts, once when it hits age 3
//Why dont we just go 0-5? Design thinks its annoying to balance the numbers using 0-5 and 3-5
fun resetGrowTimers(pos: BlockPos, state: BlockState) {
val curAge = state.get(BerryBlock.AGE)
if (curAge == 5) {
@@ -119,12 +130,15 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
val upperGrowthLimit = (if (curAge == 0) berry.growthTime.last else berry.refreshRate.last) * multiplier / 10
val growthRange = lowerGrowthLimit..upperGrowthLimit
this.growthTimer = this.applyMulchModifier(pos, growthRange.random() * ticksPerMinute)
this.goToNextStageTimer(BerryBlock.FRUIT_AGE - curAge)
this.growthTimer = this.applyMulchModifier(pos, growthRange.random() * ticksPerMinute, true)
val stagesLeft = if (curAge < 3) BerryBlock.MATURE_AGE - curAge else BerryBlock.FRUIT_AGE - curAge
this.goToNextStageTimer(stagesLeft)
}
fun goToNextStageTimer(stagesLeft: Int) {
val avgStageTime = growthTimer / stagesLeft
//A number between 80% and 100% the average stage time
//So stages have some variance
stageTimer = this.world?.random?.nextBetween((avgStageTime * 8) / 10, avgStageTime) ?:
(((Math.random() * 0.2) + 0.8) * avgStageTime).toInt()
growthTimer -= stageTimer
@@ -137,7 +151,7 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
* @param timer Timer to be modified
* @return The modified timer
*/
private fun applyMulchModifier(pos: BlockPos, timer: Int): Int {
private fun applyMulchModifier(pos: BlockPos, timer: Int, decrementMulch: Boolean = false): Int {
val state = world?.getBlockState(pos) ?: return timer
val curAge = state.get(BerryBlock.AGE)
@@ -145,11 +159,15 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
return timer
}
if (getMulch(state) != MulchVariant.GROWTH) {
if (mulchVariant != MulchVariant.GROWTH) {
return timer
}
return (timer * 0.66).toInt()
if (decrementMulch) {
world?.let {
decrementMulchDuration(it, pos, state)
}
}
return (timer * MulchVariant.GROWTH_TIME_MULTIPLIER).toInt()
}
/**
@@ -157,8 +175,8 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
* @param pos The position of the block
*/
fun refreshTimers(pos: BlockPos) {
this.growthTimer = this.applyMulchModifier(pos, growthTimer)
this.stageTimer = this.applyMulchModifier(pos, stageTimer)
this.growthTimer = this.applyMulchModifier(pos, growthTimer, false)
this.stageTimer = this.applyMulchModifier(pos, stageTimer, false)
}
/**
@@ -248,6 +266,9 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
if (nbt.contains(GROWTH_POINTS_SEQUENCE)) {
growthPointSequence = nbt.getString(GROWTH_POINTS_SEQUENCE)
}
if (nbt.contains(MULCH_VARIANT)) {
mulchVariant = MulchVariant.valueOf(nbt.getString(MULCH_VARIANT))
}
this.renderState?.needsRebuild = true
}
@@ -260,6 +281,7 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
nbt.putString(BERRY, berryIdentifier.toString())
nbt.putInt(MULCH_DURATION, mulchDuration)
nbt.putString(GROWTH_POINTS_SEQUENCE, growthPointSequence)
nbt.putString(MULCH_VARIANT, mulchVariant.toString())
}
override fun markDirty() {
@@ -323,11 +345,12 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
companion object {
internal val TICKER = BlockEntityTicker<BerryBlockEntity> { world, pos, state, blockEntity ->
if (world.isClient) return@BlockEntityTicker
if (state.get(BerryBlock.IS_ROOTED)) return@BlockEntityTicker
if (blockEntity.stageTimer >= 0) {
blockEntity.stageTimer--
}
if (blockEntity.stageTimer == 0) {
(state.block as BerryBlock).grow(world as ServerWorld, world.random, pos, state)
(state.block as BerryBlock).growHelper(world as ServerWorld, world.random, pos, state)
}
}
//private const val LIFE_CYCLES = "life_cycles"
@@ -337,6 +360,7 @@ class BerryBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobblemon
private const val STAGE_TIMER = "StageTimer"
private const val BERRY = "Berry"
private const val MULCH_DURATION = "MulchDuration"
private const val MULCH_VARIANT = "MulchVariant"
}
}
@@ -29,11 +29,17 @@ class FossilAnalyzerBlockEntity(
class FossilAnalyzerInventory(val analyzerEntity: FossilAnalyzerBlockEntity) : SidedInventory {
override fun clear() {
TODO("Not yet implemented")
if(analyzerEntity.multiblockStructure != null && analyzerEntity.multiblockStructure is FossilMultiblockStructure) {
val fossilMultiblockStructure = analyzerEntity.multiblockStructure as FossilMultiblockStructure
fossilMultiblockStructure.fossilInventory.clear()
}
}
override fun size(): Int {
TODO("Not yet implemented")
if (analyzerEntity.multiblockStructure != null) {
return 3
}
return 0
}
override fun isEmpty(): Boolean {
@@ -41,11 +47,18 @@ class FossilAnalyzerBlockEntity(
}
override fun getStack(slot: Int): ItemStack {
if (analyzerEntity.multiblockStructure != null && analyzerEntity.multiblockStructure is FossilMultiblockStructure) {
val fossilMultiblockStructure = analyzerEntity.multiblockStructure as FossilMultiblockStructure
if (fossilMultiblockStructure.fossilInventory.size > slot) {
return fossilMultiblockStructure.fossilInventory[slot]
}
}
return ItemStack.EMPTY
}
//Unimplemented since no extract
override fun removeStack(slot: Int, amount: Int): ItemStack {
return ItemStack.EMPTY
return removeStack(slot)
}
override fun removeStack(slot: Int): ItemStack {
@@ -53,7 +66,7 @@ class FossilAnalyzerBlockEntity(
}
override fun setStack(slot: Int, stack: ItemStack) {
if (analyzerEntity.multiblockStructure != null) {
if (analyzerEntity.multiblockStructure != null && analyzerEntity.multiblockStructure is FossilMultiblockStructure) {
val struct = analyzerEntity.multiblockStructure as FossilMultiblockStructure
analyzerEntity.world?.let {
struct.insertFossil(stack, it)
@@ -72,7 +85,10 @@ class FossilAnalyzerBlockEntity(
}
override fun getAvailableSlots(side: Direction?): IntArray {
return IntArray(1)
if(analyzerEntity.multiblockStructure != null && analyzerEntity.multiblockStructure is FossilMultiblockStructure) {
return intArrayOf(0,1,2)
}
return IntArray(0)
}
override fun canInsert(slot: Int, stack: ItemStack?, dir: Direction?): Boolean {
@@ -89,6 +105,5 @@ class FossilAnalyzerBlockEntity(
override fun canExtract(slot: Int, stack: ItemStack?, dir: Direction?): Boolean {
return false
}
}
}
@@ -38,18 +38,14 @@ open class FossilMultiblockEntity(
}
}
get() {
return if (field != null) {
field
} else if (masterBlockPos != null && masterBlockPos != pos) {
if(masterBlockPos != null && masterBlockPos != pos) {
val chunkPos = ChunkPos(masterBlockPos)
if (world?.chunkManager?.isChunkLoaded(chunkPos.x, chunkPos.z) == true) {
val entity: FossilMultiblockEntity? = world?.getBlockEntity(masterBlockPos) as FossilMultiblockEntity?
field = entity?.multiblockStructure
}
field
} else {
null
}
return field
}
override fun markRemoved() {
@@ -20,6 +20,7 @@ import net.minecraft.entity.player.PlayerEntity
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.inventory.DoubleInventory
import net.minecraft.inventory.Inventories
import net.minecraft.inventory.Inventory
import net.minecraft.inventory.SidedInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtCompound
@@ -58,9 +59,7 @@ class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type =
override fun isPlayerViewing(player: PlayerEntity): Boolean {
if (player.currentScreenHandler is GenericContainerScreenHandler) {
val inventory = (player.currentScreenHandler as GenericContainerScreenHandler).inventory
return inventory === this@GildedChestBlockEntity || inventory is DoubleInventory && inventory.isPart(
this@GildedChestBlockEntity
)
return inventory === this@GildedChestBlockEntity
}
return false
}
@@ -86,7 +85,7 @@ class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type =
}
override fun getAvailableSlots(side: Direction): IntArray {
return if (type == Type.FAKE) IntArray(0) else IntArray(NUM_SLOTS)
return if (type == Type.FAKE) IntArray(0) else IntArray(NUM_SLOTS) { it }
}
override fun canInsert(slot: Int, stack: ItemStack?, dir: Direction?): Boolean {
@@ -99,8 +98,6 @@ class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type =
return dir == Direction.DOWN
}
override fun canPlayerUse(player: PlayerEntity) = !player.isSpectator
override fun getInvStackList(): DefaultedList<ItemStack> = inventoryContents
override fun setInvStackList(list: DefaultedList<ItemStack>) {
@@ -164,4 +161,10 @@ class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type =
Inventories.readNbt(nbt, inventoryContents)
}
}
fun onScheduledTick() {
if (!this.removed) {
stateManager.updateViewerCount(this.getWorld(), this.getPos(), this.cachedState)
}
}
}
@@ -36,8 +36,8 @@ import net.minecraft.util.math.BlockPos
@Suppress("MemberVisibilityCanBePrivate", "unused")
class HealingMachineBlockEntity(
val blockPos: BlockPos,
val blockState: BlockState
blockPos: BlockPos,
blockState: BlockState
) : BlockEntity(CobblemonBlockEntities.HEALING_MACHINE, blockPos, blockState) {
var currentUser: UUID? = null
private set
@@ -114,7 +114,7 @@ class HealingMachineBlockEntity(
this.setUser(player.uuid)
alreadyHealing.add(player.uuid)
updateBlockChargeLevel(HealingMachineBlock.MAX_CHARGE_LEVEL + 1)
if (world != null && !world!!.isClient) world!!.playSoundServer(position = blockPos.toVec3d(), sound = CobblemonSounds.HEALING_MACHINE_ACTIVE, volume = 1F, pitch = 1F)
if (world != null && !world!!.isClient) world!!.playSoundServer(position = pos.toVec3d(), sound = CobblemonSounds.HEALING_MACHINE_ACTIVE, volume = 1F, pitch = 1F)
}
fun completeHealing() {
@@ -217,10 +217,10 @@ class HealingMachineBlockEntity(
else floor((healingCharge / maxCharge) * HealingMachineBlock.MAX_CHARGE_LEVEL).toInt()
).coerceIn(0..HealingMachineBlock.MAX_CHARGE_LEVEL + 1)
val state = world!!.getBlockState(blockPos)
val state = world!!.getBlockState(pos)
if (state != null && state.block is HealingMachineBlock) {
val currentCharge = state.get(HealingMachineBlock.CHARGE_LEVEL).toInt()
if (chargeLevel != currentCharge) world!!.setBlockState(blockPos, state.with(HealingMachineBlock.CHARGE_LEVEL, chargeLevel))
if (chargeLevel != currentCharge) world!!.setBlockState(pos, state.with(HealingMachineBlock.CHARGE_LEVEL, chargeLevel))
}
}
}
@@ -26,24 +26,24 @@ import net.minecraft.util.math.Box
import net.minecraft.world.World
class PCBlockEntity(
val blockPos: BlockPos,
val blockState: BlockState
blockPos: BlockPos,
blockState: BlockState
) : BlockEntity(CobblemonBlockEntities.PC, blockPos, blockState) {
companion object {
internal val TICKER = BlockEntityTicker<PCBlockEntity> { world, _, _, blockEntity ->
if (world.isClient) return@BlockEntityTicker
blockEntity.togglePCOn(blockEntity.getInRangeViewerCount(world, blockEntity.blockPos) > 0)
blockEntity.togglePCOn(blockEntity.getInRangeViewerCount(world, blockEntity.pos) > 0)
}
}
private fun togglePCOn(on: Boolean) {
val pcBlock = blockState.block as PCBlock
val pcBlock = cachedState.block as PCBlock
if (world != null && !world!!.isClient) {
val world = world!!
val posBottom = pcBlock.getBasePosition(blockState, blockPos)
val posBottom = pcBlock.getBasePosition(cachedState, pos)
val stateBottom = world.getBlockState(posBottom)
val posTop = pcBlock.getPositionOfOtherPart(stateBottom, posBottom)
@@ -71,7 +71,7 @@ class PCBlockEntity(
val pcLink = PCLinkManager.getLink(player.uuid)
return pcLink != null
&& pcLink is ProximityPCLink
&& pcLink.pos == blockPos
&& pcLink.pos == pos
&& pcLink.world!!.dimension == player.world.dimension
}
@@ -48,7 +48,7 @@ import net.minecraft.world.World
import java.util.*
import kotlin.math.ceil
class PokemonPastureBlockEntity(pos: BlockPos, val state: BlockState) : BlockEntity(CobblemonBlockEntities.PASTURE, pos, state) {
class PokemonPastureBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(CobblemonBlockEntities.PASTURE, pos, state) {
open class Tethering(
val minRoamPos: BlockPos,
val maxRoamPos: BlockPos,
@@ -173,11 +173,11 @@ class PokemonPastureBlockEntity(pos: BlockPos, val state: BlockState) : BlockEnt
}
private fun togglePastureOn(on: Boolean) {
val pastureBlock = state.block as PastureBlock
val pastureBlock = cachedState.block as PastureBlock
if (world != null && !world!!.isClient) {
val world = world!!
val posBottom = pastureBlock.getBasePosition(state, pos)
val posBottom = pastureBlock.getBasePosition(cachedState, pos)
val stateBottom = world.getBlockState(posBottom)
val posTop = pastureBlock.getPositionOfOtherPart(stateBottom, posBottom)
@@ -16,9 +16,10 @@ import net.minecraft.block.BlockState
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.inventory.Inventories
import net.minecraft.inventory.SidedInventory
import net.minecraft.item.Item
import net.minecraft.inventory.SimpleInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtList
import net.minecraft.registry.Registries
import net.minecraft.util.collection.DefaultedList
import net.minecraft.util.math.BlockPos
@@ -27,88 +28,71 @@ import net.minecraft.util.math.Direction
class RestorationTankBlockEntity(
pos: BlockPos, state: BlockState,
multiblockBuilder: MultiblockStructureBuilder
) : FossilMultiblockEntity(pos, state, multiblockBuilder, CobblemonBlockEntities.RESTORATION_TANK) {
) : FossilMultiblockEntity(pos, state, multiblockBuilder, CobblemonBlockEntities.RESTORATION_TANK) {
val inv = RestorationTankInventory(this)
override fun writeNbt(nbt: NbtCompound) {
super.writeNbt(nbt)
Inventories.writeNbt(nbt, inv.items)
nbt.put("inventory", inv.toNbtList())
}
override fun readNbt(nbt: NbtCompound) {
super.readNbt(nbt)
Inventories.readNbt(nbt, inv.items)
if (nbt.contains("Items")) {
// Old format
val items = DefaultedList.ofSize(inv.size(), ItemStack.EMPTY)
Inventories.readNbt(nbt, items)
RestorationTankInventory(this, *items.toTypedArray())
} else if (nbt.contains("inventory")) {
// New format
inv.readNbtList(nbt.get("inventory") as NbtList)
}
}
class RestorationTankInventory(val tankEntity: RestorationTankBlockEntity) : SidedInventory {
class RestorationTankInventory(val tankEntity: RestorationTankBlockEntity, vararg items: ItemStack) : SimpleInventory(*items), SidedInventory {
val items: DefaultedList<ItemStack> = DefaultedList.ofSize(8, ItemStack.EMPTY)
constructor(tankEntity: RestorationTankBlockEntity) : this(tankEntity, *Array(8) { ItemStack.EMPTY })
override fun clear() {
for (i in items.indices) {
items[i] = ItemStack.EMPTY
}
}
override fun size(): Int {
return 8
}
override fun isEmpty(): Boolean {
return items.all { it == ItemStack.EMPTY }
}
override fun getStack(slot: Int): ItemStack {
if(slot == -1 || slot >= size()) {
return ItemStack.EMPTY
}
return items[slot]
}
override fun removeStack(slot: Int, amount: Int): ItemStack {
if(slot < 0 || slot >= size()) {
return ItemStack.EMPTY
}
val result = items[slot].split(amount)
if(items[slot].count == 0) {
items[slot] = ItemStack.EMPTY
}
return result
}
override fun removeStack(slot: Int): ItemStack {
return removeStack(slot, 1)
}
override fun setStack(slot: Int, stack: ItemStack) {
val struct = tankEntity.multiblockStructure as? FossilMultiblockStructure
tankEntity.world?.let {
struct?.insertOrganicMaterial(stack, it)
val returnIdentifier = NaturalMaterials.getReturnItem((stack))
if(returnIdentifier != null ) {
// Store the return item
val returnItem = Registries.ITEM.get(returnIdentifier)
storeReturnItem(returnItem, stack.count)
}
}
}
private fun storeReturnItem(returnItem: Item, count: Int) {
val destStack = items.withIndex().firstOrNull {
it.value == ItemStack.EMPTY || (it.value.count < it.value.maxCount && it.value.item == returnItem)
}
if (destStack != null) {
if(destStack.value == ItemStack.EMPTY) {
items[destStack.index] = ItemStack(returnItem, 1)
} else {
destStack.value.increment(count)
}
}
override fun getMaxCountPerStack(): Int {
return 1
}
override fun markDirty() {
super.markDirty()
for(i in 0 until size()) { // iterate over inventory, consume items, generate and place return items
val itemStack : ItemStack = this.getStack(i)
if(!itemStack.isEmpty) {
val struct = tankEntity.multiblockStructure as? FossilMultiblockStructure
val returnIdentifier = NaturalMaterials.getReturnItem(itemStack)
if(tankEntity.world != null) {
if(struct?.insertOrganicMaterial(itemStack, tankEntity.world!!) == true) {
removeStack(i)
if (returnIdentifier != null) {
val returnItem = Registries.ITEM.get(returnIdentifier)
val returnStack = ItemStack(returnItem, itemStack.count)
var done = false
for(j in 1 until size()) {
// Look for a inventory slot to merge with
val existingStack : ItemStack = getStack(j)
if (existingStack.isEmpty
|| (Registries.ITEM.getId(existingStack.item) == returnIdentifier && existingStack.count + returnStack.count < existingStack.maxCount)) {
setStack(j, ItemStack(returnItem, existingStack.count + returnStack.count))
done = true
}
}
if (!done) {
setStack(i, ItemStack(returnItem, itemStack.count))
}
}
}
}
}
}
tankEntity.world?.let {
// tankEntity.world!!.updateListeners(tankEntity.pos, tankEntity.cachedState, tankEntity.cachedState, Block.NOTIFY_ALL)
// tankEntity.world!!.updateComparators(tankEntity.pos, tankEntity.world!!.getBlockState(tankEntity.pos).block)
tankEntity.markDirty()
tankEntity.multiblockStructure?.markDirty(it)
}
}
@@ -118,7 +102,7 @@ class RestorationTankBlockEntity(
}
override fun getAvailableSlots(side: Direction?): IntArray {
return if(side == Direction.DOWN) intArrayOf(0,1,2,3,4,5,6,7) else intArrayOf(-1)
return if (side == Direction.DOWN) intArrayOf(0,1,2,3,4,5,6,7) else intArrayOf(0)
}
override fun canInsert(slot: Int, stack: ItemStack?, dir: Direction?): Boolean {
@@ -127,17 +111,25 @@ class RestorationTankBlockEntity(
val structure = tankEntity.multiblockStructure as FossilMultiblockStructure
val canUtilize = stack?.let { NaturalMaterials.isNaturalMaterial(it) } == true
&& structure.organicMaterialInside < FossilMultiblockStructure.MATERIAL_TO_START
&& structure.createdPokemon == null
&& !structure.hasCreatedPokemon
val returnItem = NaturalMaterials.getReturnItem(stack!!) ?: return canUtilize
if(canUtilize) {
// See if there's room
for (i in items.indices ) {
if(items[i] == ItemStack.EMPTY || (items[i].count < items[i].maxCount
&& items[i].item == Registries.ITEM.get(returnItem))) {
return true
val returnStack = ItemStack(Registries.ITEM.get(returnItem), stack.count)
if(canUtilize && super.canInsert(returnStack)) {
if(returnStack == ItemStack.EMPTY && getStack(0) == ItemStack.EMPTY) {
return true
}
// See if there's room for the return item
var emptyCount = 0
for(i in 1 until size()) {
val existingStack : ItemStack = getStack(i)
if(existingStack == ItemStack.EMPTY) {
emptyCount += 1
if(emptyCount > 1) {
// 2 empty slots, safe to insert
return true
}
}
}
return false
}
}
}
@@ -10,7 +10,8 @@ package com.cobblemon.mod.common.block.multiblock
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.advancement.CobblemonCriteria
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.pokemon.FossilRevivedEvent
import com.cobblemon.mod.common.api.fossil.Fossil
import com.cobblemon.mod.common.api.fossil.Fossils
import com.cobblemon.mod.common.api.fossil.NaturalMaterials
@@ -72,7 +73,7 @@ class FossilMultiblockStructure (
var organicMaterialInside = 0
private set
var createdPokemon: Pokemon? = null
var hasCreatedPokemon: Boolean = false
private set
var timeRemaining = -1
private set
@@ -102,8 +103,7 @@ class FossilMultiblockStructure (
if (player !is ServerPlayerEntity) {
return ActionResult.SUCCESS
}
if (this.createdPokemon != null) {
if (this.hasCreatedPokemon) {
if (this.fossilOwnerUUID != null && player.uuid != this.fossilOwnerUUID) {
var ownerName : String = "UNKNOWN_USER" // TODO: lang agnostic fallback
server()?.userCache?.getByUuid(this.fossilOwnerUUID)?.orElse(null)?.name?.let {
@@ -114,25 +114,28 @@ class FossilMultiblockStructure (
}
val ballType = (stack.item as PokeBallItem).pokeBall
if (!player.isCreative) {
stack?.decrement(1)
}
this.createdPokemon!!.caughtBall = ballType
player.party().add(this.createdPokemon!!)
this.fossilState.growthState = "Taken"
player.playSound(CobblemonSounds.FOSSIL_MACHINE_RETRIEVE_POKEMON, SoundCategory.BLOCKS, 1.0F, 1.0F)
CobblemonCriteria.RESURRECT_POKEMON.trigger(player, createdPokemon!!)
val pokemon = this.resultingFossil?.result?.create()
if(pokemon != null) {
pokemon.caughtBall = ballType
player.party().add(pokemon)
this.fossilState.growthState = "Taken"
player.playSound(CobblemonSounds.FOSSIL_MACHINE_RETRIEVE_POKEMON, SoundCategory.BLOCKS, 1.0F, 1.0F)
CobblemonEvents.FOSSIL_REVIVED.post(FossilRevivedEvent(pokemon, player))
}
// Turn the monitor off
val monitorState = world.getBlockState(monitorPos)
if(!monitorState.equals(MonitorBlock.MonitorScreen.OFF)) {
if(monitorState.contains(MonitorBlock.SCREEN) && !monitorState.equals(MonitorBlock.MonitorScreen.OFF)) {
world.setBlockState(monitorPos, monitorState.with(MonitorBlock.SCREEN, MonitorBlock.MonitorScreen.OFF))
}
this.createdPokemon = null
this.hasCreatedPokemon = false
this.fossilOwnerUUID = null
this.protectionTime = -1
this.updateFossilType(world)
@@ -144,15 +147,14 @@ class FossilMultiblockStructure (
// Reclaim the last fossil from the machine if their hand is empty
if (player.getStackInHand(interactionHand).isEmpty) {
if(!this.isRunning() && this.createdPokemon == null) {
if(!this.isRunning() && !this.hasCreatedPokemon) {
if (fossilInventory.isEmpty()) {
return ActionResult.CONSUME
}
player.setStackInHand(interactionHand, fossilInventory.last())
// remove last fossil in the fossil machine stack when grabbed out of the machine
this.fossilInventory.removeAt(fossilInventory.size - 1)
if(!world.isClient) {
if(player is ServerPlayerEntity) {
player.setStackInHand(interactionHand, fossilInventory.last())
// remove last fossil in the fossil machine stack when grabbed out of the machine
this.fossilInventory.removeAt(fossilInventory.size - 1)
world.playSound(null, analyzerPos, CobblemonSounds.FOSSIL_MACHINE_RETRIEVE_FOSSIL, SoundCategory.BLOCKS)
this.updateFossilType(world)
this.syncToClient(world)
@@ -164,19 +166,17 @@ class FossilMultiblockStructure (
// Check if the player is holding a fossil and if so insert it into the machine.
if (Fossils.isFossilIngredient(stack)) {
if(!this.isRunning() && this.createdPokemon == null) {
if (!this.isRunning() && !this.hasCreatedPokemon) {
if (fossilInventory.size > Cobblemon.config.maxInsertedFossilItems) {
return ActionResult.FAIL
}
val copyFossilStack = stack.copyWithCount(1)
if (!player.isCreative) {
stack?.decrement(1)
}
fossilOwnerUUID = player.uuid
fossilInventory.add(copyFossilStack)
if(!world.isClient) {
if (player is ServerPlayerEntity) {
val copyFossilStack = stack.copyWithCount(1)
if (!player.isCreative) {
stack?.decrement(1)
}
fossilOwnerUUID = player.uuid
fossilInventory.add(copyFossilStack)
this.updateFossilType(world)
world.playSound(null, analyzerPos, CobblemonSounds.FOSSIL_MACHINE_INSERT_FOSSIL, SoundCategory.BLOCKS)
this.syncToClient(world)
@@ -188,7 +188,11 @@ class FossilMultiblockStructure (
// Check if the player is holding a natural material and if so, feed it to the machine.
if (NaturalMaterials.isNaturalMaterial(stack)) {
if (!this.isRunning() && this.createdPokemon == null && this.organicMaterialInside < MATERIAL_TO_START && insertOrganicMaterial(stack, world)) {
if (player is ServerPlayerEntity
&& !this.isRunning()
&& !this.hasCreatedPokemon
&& this.organicMaterialInside < MATERIAL_TO_START
&& insertOrganicMaterial(ItemStack(stack.item, 1), world)) {
this.lastInteraction = world.time
if (!player.isCreative) {
val returnItem = NaturalMaterials.getReturnItem(stack)
@@ -220,6 +224,7 @@ class FossilMultiblockStructure (
entity.setPosition(fixedPosition.toCenterPos().subtract(0.0, 0.5, 0.0))
// TODO: Find a correct way to set the new entity's Yaw rotation. (Face away from the machine)
if (world.spawnEntity(entity)) {
CobblemonEvents.FOSSIL_REVIVED.post(FossilRevivedEvent(pokemon, null))
return true
} else {
Cobblemon.LOGGER.warn("Couldn't spawn resurrected Pokémon for some reason")
@@ -271,7 +276,7 @@ class FossilMultiblockStructure (
return 0
}
if(monitorPos == pos) {
if(createdPokemon != null) {
if(hasCreatedPokemon) {
return 15
}
if(!isRunning()) {
@@ -287,13 +292,13 @@ class FossilMultiblockStructure (
override fun onTriggerEvent(state: BlockState?, world: ServerWorld?, pos: BlockPos?, random: Random?) {
// instantiate the pokemon as a new entity and spawn it at the location of the machine
if(this.protectionTime <= 0) {
val wildPokemon: Pokemon = this.createdPokemon ?: return
val wildPokemon: Pokemon = if (hasCreatedPokemon) resultingFossil?.result?.create() ?: return else return
val direction = state?.get(HorizontalFacingBlock.FACING)?.opposite
if(pos != null && direction != null && world != null) {
val success = this.spawn(world, pos, direction, wildPokemon)
if(success) {
this.fossilState.growthState = "Taken"
this.createdPokemon = null
this.hasCreatedPokemon = false
this.fossilOwnerUUID = null
this.protectionTime = -1
world.playSound(null, tankBasePos, CobblemonSounds.FOSSIL_MACHINE_RETRIEVE_POKEMON, SoundCategory.BLOCKS)
@@ -310,9 +315,9 @@ class FossilMultiblockStructure (
val analyzerEntity = world.getBlockEntity(analyzerPos) as? MultiblockEntity
val tankBaseEntity = world.getBlockEntity(tankBasePos) as? MultiblockEntity
val tankTopEntity = world.getBlockEntity(tankBasePos.up()) as? MultiblockEntity
val state = world.getBlockState(tankBaseEntity?.pos)
val direction = state.get(HorizontalFacingBlock.FACING).getOpposite()
val wildPokemon: Pokemon? = this.createdPokemon
val tankBaseBlockState = world.getBlockState(tankBaseEntity?.pos)
val direction = tankBaseBlockState.get(HorizontalFacingBlock.FACING).opposite
val wildPokemon: Pokemon? = if(hasCreatedPokemon) resultingFossil?.result?.create() else null
monitorEntity?.multiblockStructure = null
analyzerEntity?.multiblockStructure = null
@@ -331,11 +336,9 @@ class FossilMultiblockStructure (
}
}
if(tankBaseEntity is RestorationTankBlockEntity) {
tankBaseEntity.inv.items.forEach {
val stack = ItemStack(it.item, 1)
ItemScatterer.spawn(world, pos.x.toDouble(), pos.y.toDouble(), pos.z.toDouble(), stack)
tankBaseEntity.inv.clearToList().forEach {
ItemScatterer.spawn(world, pos.x.toDouble(), pos.y.toDouble(), pos.z.toDouble(), it)
}
tankBaseEntity.inv.clear()
}
@@ -374,7 +377,7 @@ class FossilMultiblockStructure (
world.playSound(null, tankBasePos, CobblemonSounds.FOSSIL_MACHINE_UNPROTECTED, SoundCategory.BLOCKS)
}
if (this.createdPokemon != null) {
if (this.hasCreatedPokemon) {
return
}
@@ -403,10 +406,7 @@ class FossilMultiblockStructure (
if (this.timeRemaining == 0) {
world.playSound(null, tankBasePos, CobblemonSounds.FOSSIL_MACHINE_FINISHED, SoundCategory.BLOCKS)
fossilInventory.clear()
this.resultingFossil?.let {
this.createdPokemon = it.result.create()
}
this.hasCreatedPokemon = true
if(this.fossilOwnerUUID != null) {
protectionTime = PROTECTION_TIME
}
@@ -477,20 +477,26 @@ class FossilMultiblockStructure (
val upperTankPos = tankBasePos.up()
val analyzerState = world.getBlockState(analyzerPos)
val tankState = world.getBlockState(tankBasePos.up())
world.setBlockState(analyzerPos, analyzerState.with(FossilAnalyzerBlock.ON, timeRemaining >= 0))
world.setBlockState(upperTankPos, tankState.with(RestorationTankBlock.ON, timeRemaining >= 0))
if (analyzerState.contains(FossilAnalyzerBlock.ON)) {
world.setBlockState(analyzerPos, analyzerState.with(FossilAnalyzerBlock.ON, timeRemaining >= 0))
}
if (tankState.contains(RestorationTankBlock.ON)) {
world.setBlockState(upperTankPos, tankState.with(RestorationTankBlock.ON, timeRemaining >= 0))
}
}
fun updateProgress(world: World) {
val screenID = if(protectionTime > 0F ) {
MonitorBlock.MonitorScreen.GREEN_PROGRESS_9
} else if (timeRemaining <= 0) {
MonitorBlock.MonitorScreen.OFF
} else {
getProgressScreen((TIME_TO_TAKE - timeRemaining) / TIME_PER_STAGE)
}
val monitorState = world.getBlockState(monitorPos)
world.setBlockState(monitorPos, monitorState.with(MonitorBlock.SCREEN, screenID))
if (monitorState.contains(MonitorBlock.SCREEN)) {
val screenID = if (protectionTime > 0F) {
MonitorBlock.MonitorScreen.GREEN_PROGRESS_9
} else if (timeRemaining <= 0) {
MonitorBlock.MonitorScreen.OFF
} else {
getProgressScreen((TIME_TO_TAKE - timeRemaining) / TIME_PER_STAGE)
}
world.setBlockState(monitorPos, monitorState.with(MonitorBlock.SCREEN, screenID))
}
}
fun getProgressScreen(progress:Int) : MonitorBlock.MonitorScreen {
@@ -533,12 +539,13 @@ class FossilMultiblockStructure (
//Returns false if material wasnt inserted
fun insertOrganicMaterial(stack: ItemStack, world: World): Boolean {
val natureValue = NaturalMaterials.getContent(stack)
var natureValue = NaturalMaterials.getContent(stack)
if (timeRemaining > 0 || this.organicMaterialInside >= MATERIAL_TO_START || natureValue == null) {
return false
}
natureValue *= stack.count
if (natureValue < 0 && organicMaterialInside == 0) return false
if (natureValue <= 0 && organicMaterialInside == 0) return false
val oldFillStage = organicMaterialInside * 8 / MATERIAL_TO_START
// to prevent over/under filling the tank causing a crash
@@ -604,9 +611,7 @@ class FossilMultiblockStructure (
result.putString(DataKeys.INSERTED_FOSSIL, this.resultingFossil!!.asString())
}
if (this.createdPokemon != null) {
result.put(DataKeys.CREATED_POKEMON, createdPokemon!!.saveToNBT(NbtCompound()))
}
result.putBoolean(DataKeys.HAS_CREATED_POKEMON, hasCreatedPokemon)
return result
}
@@ -655,7 +660,10 @@ class FossilMultiblockStructure (
}
if (nbt.contains(DataKeys.CREATED_POKEMON)) {
result.createdPokemon = Pokemon.loadFromNBT(nbt.getCompound(DataKeys.CREATED_POKEMON))
// migration of instances that saved the created pokeon in the nbt
result.hasCreatedPokemon = true
} else if (nbt.contains(DataKeys.HAS_CREATED_POKEMON)){
result.hasCreatedPokemon = nbt.getBoolean(DataKeys.HAS_CREATED_POKEMON)
}
result.fillLevel = result.organicMaterialInside * 8 / MATERIAL_TO_START
return result
@@ -14,6 +14,7 @@ import com.bedrockk.molang.runtime.value.MoValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.getQueryStruct
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import net.minecraft.client.MinecraftClient
import net.minecraft.client.sound.PositionedSoundInstance
@@ -31,6 +32,13 @@ object ClientMoLangFunctions {
MinecraftClient.getInstance().soundManager.play(PositionedSoundInstance.master(soundEvent, pitch))
}
},
"is_time" to java.util.function.Function { params ->
val time = (MinecraftClient.getInstance().world?.timeOfDay ?: 0) % 24000
val min = params.getInt(0)
val max = params.getInt(1)
time in min..max
},
"say" to java.util.function.Function { params -> MinecraftClient.getInstance().player?.sendMessage(params.getString(0).text()) ?: Unit },
)
fun MoLangRuntime.setupClient(): MoLangRuntime {
@@ -62,6 +62,46 @@ object CobblemonBakingOverrides {
cobblemonModel("restoration_tank_connector", "none")
)
val COARSE_MULCH = registerOverride(
cobblemonResource("block/coarse_mulch"),
cobblemonModel("coarse_mulch", "none")
)
val GROWTH_MULCH = registerOverride(
cobblemonResource("block/growth_mulch"),
cobblemonModel("growth_mulch", "none")
)
val HUMID_MULCH = registerOverride(
cobblemonResource("block/humid_mulch"),
cobblemonModel("humid_mulch", "none")
)
val LOAMY_MULCH = registerOverride(
cobblemonResource("block/loamy_mulch"),
cobblemonModel("loamy_mulch", "none")
)
val PEAT_MULCH = registerOverride(
cobblemonResource("block/peat_mulch"),
cobblemonModel("peat_mulch", "none")
)
val RICH_MULCH = registerOverride(
cobblemonResource("block/rich_mulch"),
cobblemonModel("rich_mulch", "none")
)
val SANDY_MULCH = registerOverride(
cobblemonResource("block/sandy_mulch"),
cobblemonModel("sandy_mulch", "none")
)
val SURPRISE_MULCH = registerOverride(
cobblemonResource("block/surprise_mulch"),
cobblemonModel("surprise_mulch", "none")
)
fun registerOverride(modelLocation: Identifier, modelIdentifier: ModelIdentifier): BakingOverride {
val result = BakingOverride(modelLocation, modelIdentifier)
models.add(result)
@@ -272,6 +272,9 @@ class PokemonClientDelegate : PoseableEntityState<PokemonEntity>(), PokemonSideD
},
"weight" to java.util.function.Function {
return@Function DoubleValue(currentEntity.pokemon.species.weight.toDouble())
},
"friendship" to java.util.function.Function {
return@Function DoubleValue(currentEntity.pokemon.friendship.toDouble())
}
))
}
@@ -318,7 +318,6 @@ class PCGUI(
centered = true,
shadow = true,
scale = SCALE,
colour = 0x32CBFF,
pMouseX = mouseX,
pMouseY = mouseY
)
@@ -18,7 +18,8 @@ import net.minecraft.client.MinecraftClient
object PlayPoseableAnimationHandler : ClientNetworkPacketHandler<PlayPoseableAnimationPacket> {
override fun handle(packet: PlayPoseableAnimationPacket, client: MinecraftClient) {
val entity = client.world?.getEntityById(packet.entityId) ?: return
val world = client.world ?: return
val entity = world.getEntityById(packet.entityId) ?: return
if (entity is Poseable) {
val delegate = entity.delegate
if (delegate is PoseableEntityState<*>) {
@@ -18,7 +18,8 @@ import net.minecraft.client.MinecraftClient
object RunPosableMoLangHandler : ClientNetworkPacketHandler<RunPosableMoLangPacket> {
override fun handle(packet: RunPosableMoLangPacket, client: MinecraftClient) {
val entity = client.world?.getEntityById(packet.entityId) ?: return
val world = client.world ?: return
val entity = world.getEntityById(packet.entityId) ?: return
if (entity is Poseable) {
val state = entity.delegate as? PoseableEntityState<*> ?: return
for (expression in packet.expressions.map { it.asExpression() }) {
@@ -15,9 +15,6 @@ import com.cobblemon.mod.common.client.render.MatrixWrapper
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
import net.minecraft.client.MinecraftClient
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.util.math.RotationAxis.NEGATIVE_X
import net.minecraft.util.math.RotationAxis.POSITIVE_X
import net.minecraft.util.math.RotationAxis.POSITIVE_Y
object SpawnSnowstormParticleHandler : ClientNetworkPacketHandler<SpawnSnowstormParticlePacket> {
override fun handle(packet: SpawnSnowstormParticlePacket, client: MinecraftClient) {
@@ -10,16 +10,20 @@ package com.cobblemon.mod.common.client.particle
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addFunction
import com.cobblemon.mod.common.api.molang.MoLangFunctions.getQueryStruct
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies.species
import com.cobblemon.mod.common.api.snowstorm.BedrockParticleEffect
import com.cobblemon.mod.common.api.snowstorm.ParticleEmitterAction
import com.cobblemon.mod.common.client.render.MatrixWrapper
import com.cobblemon.mod.common.client.render.SnowstormParticle
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.particle.SnowstormParticleEffect
import com.cobblemon.mod.common.util.math.geometry.transformDirection
import kotlin.random.Random
import net.minecraft.client.MinecraftClient
import net.minecraft.client.particle.NoRenderParticle
import net.minecraft.client.util.ParticleUtil.spawnParticle
import net.minecraft.client.world.ClientWorld
import net.minecraft.entity.Entity
import net.minecraft.util.math.Vec3d
@@ -48,12 +52,22 @@ class ParticleStorm(
.addFunction("entity_height") { DoubleValue(entity.boundingBox.yLength) }
.addFunction("entity_size") { DoubleValue(entity.boundingBox.run { if (xLength > yLength) xLength else yLength }) }
.addFunction("entity_radius") { DoubleValue(entity.boundingBox.run { if (xLength > yLength) xLength else yLength } / 2) }
.addFunction("entity_scale") {
val pokeEntity = entity as? PokemonEntity
val pokemon = pokeEntity?.pokemon
//Use form data if available, species as fall back
val baseScale = pokemon?.form?.baseScale ?: pokemon?.species?.baseScale ?: 1.0F
val pokemonScale = pokemon?.scaleModifier ?: 1.0F
val entityScale = pokeEntity?.scaleFactor ?: 1.0F
DoubleValue(baseScale * pokemonScale * entityScale)
}
// TODO replace with a generified call to if (entity is MoLangEntity) entity.applyVariables(env) or w/e
runtime.environment.setSimpleVariable("entity_width", DoubleValue(entity.boundingBox.xLength))
runtime.environment.setSimpleVariable("entity_height", DoubleValue(entity.boundingBox.yLength))
val longerDiameter = entity.boundingBox.run { if (xLength > yLength) xLength else yLength }
runtime.environment.setSimpleVariable("entity_size", DoubleValue(longerDiameter))
runtime.environment.setSimpleVariable("entity_radius", DoubleValue(longerDiameter / 2))
runtime.environment.setSimpleVariable("entity_scale", DoubleValue((entity as? PokemonEntity)?.scaleFactor ?: 1.0))
}
MinecraftClient.getInstance().particleManager.addParticle(this)
}
@@ -118,7 +118,7 @@ class SnowstormParticle(
init {
setVelocity(initialVelocity.x, initialVelocity.y, initialVelocity.z)
angle = storm.effect.particle.rotation.getInitialRotation(storm.runtime).toFloat()
angle = -storm.effect.particle.rotation.getInitialRotation(storm.runtime).toFloat()
prevAngle = angle
angularVelocity = storm.effect.particle.rotation.getInitialAngularVelocity(storm.runtime)
velocityMultiplier = 1F
@@ -256,24 +256,20 @@ class SnowstormParticle(
setParticleAgeInRuntime()
storm.effect.curves.forEach { it.apply(storm.runtime) }
storm.runtime.execute(storm.effect.particle.updateExpressions)
angularVelocity += storm.effect.particle.rotation.getAngularAcceleration(storm.runtime, angularVelocity) / 20
angularVelocity = storm.effect.particle.rotation.getAngularVelocity(storm.runtime, -angle.toDouble(), angularVelocity) / 20
if (age > maxAge || storm.runtime.resolveBoolean(storm.effect.particle.killExpression)) {
if (age >= maxAge || storm.runtime.resolveBoolean(storm.effect.particle.killExpression)) {
runExpirationEvents()
markDead()
return
} else {
val acceleration = storm.effect.particle.motion.getAcceleration(
storm.runtime,
Vec3d(velocityX, velocityY, velocityZ).multiply(20.0) // Uses blocks per second, not blocks per tick
).multiply(1 / 20.0).multiply(1 / 20.0) // blocks per second per second -> blocks per tick per tick
velocityX += acceleration.x
velocityY += acceleration.y
velocityZ += acceleration.z
val velocity = storm.effect.particle.motion.getVelocity(storm.runtime, this, Vec3d(velocityX, velocityY, velocityZ))
velocityX = velocity.x
velocityY = velocity.y
velocityZ = velocity.z
prevAngle = angle
angle = prevAngle + angularVelocity.toFloat()
// Subtract because Bedrock particles are counter-clockwise and Java Edition is clockwise.
angle = prevAngle - angularVelocity.toFloat()
}
viewDirection = storm.effect.particle.viewDirection.getDirection(
@@ -16,6 +16,7 @@ class BerryBlockEntityRenderState : BerryBlockEntity.RenderState {
override var needsRebuild = true
val vbo: VertexBuffer = VertexBuffer(VertexBuffer.Usage.STATIC)
var vboLightLevel: Int = 0
var drawVbo: Boolean = false
override fun close() {
vbo.close()
@@ -23,6 +23,7 @@ import net.minecraft.client.gl.ShaderProgram
import net.minecraft.client.gl.VertexBuffer
import net.minecraft.client.render.GameRenderer
import net.minecraft.client.render.LightmapTextureManager
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.Tessellator
import net.minecraft.client.render.VertexConsumerProvider
import net.minecraft.client.render.VertexFormat
@@ -33,6 +34,7 @@ import net.minecraft.client.util.math.MatrixStack
import net.minecraft.util.math.Box
import net.minecraft.util.math.Vec3d
import org.joml.Matrix4f
import org.joml.Vector3f
class BerryBlockRenderer(private val context: BlockEntityRendererFactory.Context) : BlockEntityRenderer<BerryBlockEntity> {
@@ -45,33 +47,88 @@ class BerryBlockRenderer(private val context: BlockEntityRendererFactory.Context
override fun render(entity: BerryBlockEntity, tickDelta: Float, matrices: MatrixStack, vertexConsumers: VertexConsumerProvider, light: Int, overlay: Int) {
if (!isInRenderDistance(entity, entity.pos.toVec3d())) return
val blockState = entity.cachedState
val age = blockState.get(BerryBlock.AGE)
if (age <= BerryBlock.MATURE_AGE) {
return
}
if (entity.renderState == null) {
entity.renderState = BerryBlockEntityRenderState()
}
val renderState = entity.renderState as BerryBlockEntityRenderState
if (renderState.needsRebuild || renderState.vboLightLevel != light) {
renderToBuffer(entity, light, overlay, renderState.vbo)
renderToBuffer(entity, light, overlay, renderState)
renderState.vboLightLevel = light
(entity.renderState as BerryBlockEntityRenderState).needsRebuild = false
}
if (renderState.drawVbo) {
matrices.push()
CobblemonRenderLayers.BERRY_LAYER.startDrawing()
renderState.vbo.bind()
renderState.vbo.draw(
matrices.peek().positionMatrix.mul(RenderSystem.getModelViewMatrix()),
RenderSystem.getProjectionMatrix(),
GameRenderer.getRenderTypeCutoutProgram()
)
VertexBuffer.unbind()
CobblemonRenderLayers.BERRY_LAYER.endDrawing()
matrices.pop()
}
drawMulch(matrices, vertexConsumers, entity, light, overlay)
}
private fun drawMulch(
matrices: MatrixStack,
vertexConsumers: VertexConsumerProvider,
entity: BerryBlockEntity,
light: Int,
overlay: Int
) {
matrices.push()
CobblemonRenderLayers.BERRY_LAYER.startDrawing()
renderState.vbo.bind()
renderState.vbo.draw(
matrices.peek().positionMatrix.mul(RenderSystem.getModelViewMatrix()),
RenderSystem.getProjectionMatrix(),
GameRenderer.getRenderTypeCutoutProgram()
)
VertexBuffer.unbind()
CobblemonRenderLayers.BERRY_LAYER.endDrawing()
//Mulch is rendered on a different layer than the actual berries so
val mulchBuf = vertexConsumers.getBuffer(RenderLayer.getCutout())
val model = entity.mulchVariant.model
model?.let {
it.getModel().getQuads(entity.cachedState, null, entity.world?.random).forEach { quad ->
mulchBuf.quad(matrices.peek(), quad, 1F, 1F, 1F, light, overlay)
}
}
matrices.pop()
}
fun renderToBuffer(entity: BerryBlockEntity, light: Int, overlay: Int, buffer: VertexBuffer) {
fun renderToBuffer(entity: BerryBlockEntity, light: Int, overlay: Int, renderState: BerryBlockEntityRenderState) {
if (entity.cachedState.get(BerryBlock.AGE) == 0) {
renderBabyToBuffer(entity, light, overlay, renderState.vbo)
renderState.drawVbo = true
}
else if (entity.cachedState.get(BerryBlock.AGE) > BerryBlock.MATURE_AGE){
renderAdultToBuffer(entity, light, overlay, renderState.vbo)
renderState.drawVbo = true
}
else {
renderState.drawVbo = false
}
}
fun renderBabyToBuffer(entity: BerryBlockEntity, light: Int, overlay: Int, buffer: VertexBuffer) {
val bufferBuilder = Tessellator.getInstance().buffer
bufferBuilder.begin(CobblemonRenderLayers.BERRY_LAYER.drawMode, CobblemonRenderLayers.BERRY_LAYER.vertexFormat)
val berry = entity.berry() ?: return
val model = BerryModelRepository.modelOf(berry.fruitModelIdentifier) ?: return
val pos = berry.stageOnePositioning.position
model.setPosition(Axis.X_AXIS.ordinal, pos.x.toFloat())
model.setPosition(Axis.Y_AXIS.ordinal, pos.y.toFloat())
model.setPosition(Axis.Z_AXIS.ordinal, pos.z.toFloat())
val rot = berry.stageOnePositioning.rotation
model.setAngles(
Math.toRadians(180 - rot.x).toFloat(),
Math.toRadians(180 + rot.y).toFloat(),
Math.toRadians(rot.z).toFloat()
)
model.render(MatrixStack(), bufferBuilder, light, overlay)
val bufferBuilderFinal = bufferBuilder.end()
buffer.bind()
buffer.upload(bufferBuilderFinal)
VertexBuffer.unbind()
}
fun renderAdultToBuffer(entity: BerryBlockEntity, light: Int, overlay: Int, buffer: VertexBuffer) {
val blockState = entity.cachedState
val age = blockState.get(BerryBlock.AGE)
if (age <= BerryBlock.MATURE_AGE) {
@@ -61,17 +61,17 @@ class RestorationTankRenderer(ctx: BlockEntityRendererFactory.Context) : BlockEn
matrices.pop()
}
val fillLevel = struct.fillLevel
if (fillLevel == 0 && struct.createdPokemon == null) {
if (fillLevel == 0 && !struct.hasCreatedPokemon) {
return
}
if (struct.isRunning() or (struct.createdPokemon != null)) renderFetus(entity, tickDelta, matrices, vertexConsumers, light, overlay)
if (struct.isRunning() or (struct.hasCreatedPokemon)) renderFetus(entity, tickDelta, matrices, vertexConsumers, light, overlay)
matrices.push()
val transparentBuffer = vertexConsumers.getBuffer(RenderLayer.getTranslucent())
val fluidModel = if (struct.isRunning()) FLUID_MODELS[8]
else if (struct.createdPokemon != null) FLUID_MODELS[7]
else if (struct.hasCreatedPokemon) FLUID_MODELS[7]
else FLUID_MODELS[fillLevel.coerceAtMost(FLUID_MODELS.size - 1) - 1]
fluidModel.getQuads(entity.cachedState, null, entity.world?.random).forEach { quad ->
transparentBuffer?.quad(matrices.peek(), quad, 0.75f, 0.75f, 0.75f, light, OverlayTexture.DEFAULT_UV)
@@ -20,7 +20,10 @@ import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFram
import com.cobblemon.mod.common.client.render.models.blockbench.quirk.SimpleQuirk
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.normalizeToArray
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.resolveObject
import com.cobblemon.mod.common.util.singularToPluralList
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
@@ -34,6 +37,8 @@ class JsonPose<T : Entity>(model: PoseableEntityModel<T>, json: JsonObject) {
it.environment.getQueryStruct().addFunctions(model.functions.functions)
}
val condition: ExpressionLike = json.singularToPluralList("condition").get("conditions")?.normalizeToArray()?.map { it.asString }?.asExpressionLike() ?: "true".asExpressionLike()
val poseName = json.get("poseName")?.asString ?: "pose"
val poseTypes = (json.get("poseTypes")?.asJsonArray?.map { name ->
PoseType.values().find { it.name.lowercase() == name.asString.lowercase() }
@@ -81,8 +86,9 @@ class JsonPose<T : Entity>(model: PoseableEntityModel<T>, json: JsonObject) {
}
json as JsonObject
json.singularToPluralList("animation")
val animations: (state: PoseableEntityState<T>) -> List<StatefulAnimation<T, *>> = { _ ->
(json.get("animations")?.asJsonArray ?: JsonArray()).map { animJson ->
(json.get("animations")?.normalizeToArray()?.asJsonArray ?: JsonArray()).map { animJson ->
try {
val expr = animJson.asString.asExpressionLike()
runtime.resolveObject(expr).obj as StatefulAnimation<T, *>
@@ -97,10 +103,11 @@ class JsonPose<T : Entity>(model: PoseableEntityModel<T>, json: JsonObject) {
val loopTimes = json.get("loopTimes")?.asInt ?: 1
val minSeconds = json.get("minSecondsBetweenOccurrences")?.asFloat ?: 8F
val maxSeconds = json.get("maxSecondsBetweenOccurrences")?.asFloat ?: 30F
val condition = json.get("condition")?.asString?.asExpressionLike() ?: "true".asExpressionLike()
model.quirkMultiple(
secondsBetweenOccurrences = minSeconds to maxSeconds,
condition = { true },
condition = { it.runtime.resolveBoolean(condition) },
loopTimes = 1..loopTimes,
animations = animations
)
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.client.render.models.blockbench
import com.cobblemon.mod.common.client.render.MatrixWrapper
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Bone
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.entity.Entity
/**
* A storage of locator information for a model, attached to its [joint].
@@ -68,20 +69,45 @@ class LocatorAccess(
* Updates all of the locator states with the position at this current frame.
* This is the same logic as ModelPart uses, that's why we reuse ModelPart#rotate.
*/
fun update(matrixStack: MatrixStack, state: MutableMap<String, MatrixWrapper>) {
fun update(matrixStack: MatrixStack, entity: Entity, scale: Float, state: MutableMap<String, MatrixWrapper>, isRoot: Boolean = false) {
matrixStack.push()
joint.transform(matrixStack)
if (isRoot) {
matrixStack.push()
matrixStack.scale(-1F, -1F, 1F)
state.getOrPut("root") { MatrixWrapper() }.updateMatrix(matrixStack.peek().positionMatrix)
matrixStack.pop()
// Put in an approximation of the target locator. If the model has one defined,
// this will be overridden.
matrixStack.push()
matrixStack.translate(0.0, -entity.boundingBox.yLength / 2.0 / scale, -entity.width * 0.6 / scale)
matrixStack.scale(-1F, -1F, 1F)
state.getOrPut("target") { MatrixWrapper() }.updateMatrix(matrixStack.peek().positionMatrix)
state.getOrPut("special_attack") { MatrixWrapper() }.updateMatrix(matrixStack.peek().positionMatrix)
matrixStack.pop()
// If we have the entity, put in a "middle" locator for center of mass
// this will be overridden.
matrixStack.push()
matrixStack.translate(0.0, -entity.boundingBox.yLength / 2.0 / scale, 0.0)
matrixStack.scale(-1F, -1F, 1F)
state.getOrPut("middle") { MatrixWrapper() }.updateMatrix(matrixStack.peek().positionMatrix)
matrixStack.pop()
}
for ((name, locator) in locators) {
matrixStack.push()
locator.transform(matrixStack)
matrixStack.scale(1F, -1F, 1F)
matrixStack.scale(-1F, -1F, 1F)
state.getOrPut(name) { MatrixWrapper() }.updateMatrix(matrixStack.peek().positionMatrix)
matrixStack.pop()
}
children.forEach {
it.update(matrixStack, state)
it.update(matrixStack, entity, scale, state, isRoot = false)
}
matrixStack.pop()
@@ -46,6 +46,7 @@ import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.getDoubleOrNull
import com.cobblemon.mod.common.util.getStringOrNull
import com.cobblemon.mod.common.util.plus
import com.cobblemon.mod.common.util.resolveBoolean
import net.minecraft.client.model.ModelPart
import net.minecraft.client.render.OverlayTexture
import net.minecraft.client.render.RenderLayer
@@ -154,6 +155,7 @@ abstract class PoseableEntityModel<T : Entity>(
val maxPitch = params.getDoubleOrNull(3) ?: 70F
val minPitch = params.getDoubleOrNull(4) ?: -45F
val maxYaw = params.getDoubleOrNull(5) ?: 45F
val minYaw = params.getDoubleOrNull(6) ?: -45F
ObjectValue(
SingleBoneLookAnimation<T>(
frame = this,
@@ -162,7 +164,8 @@ abstract class PoseableEntityModel<T : Entity>(
yawMultiplier = yawMultiplier.toFloat(),
maxPitch = maxPitch.toFloat(),
minPitch = minPitch.toFloat(),
maxYaw = maxYaw.toFloat()
maxYaw = maxYaw.toFloat(),
minYaw = minYaw.toFloat()
)
)
}
@@ -258,6 +261,41 @@ abstract class PoseableEntityModel<T : Entity>(
)
)
}
.addFunction("bedrock_primary_quirk") { params ->
val animationGroup = params.getString(0)
val animationNames = params.get<MoValue>(1)?.let { if (it is ArrayStruct) it.map.values.map { it.asString() } else listOf(it.asString()) } ?: listOf()
val minSeconds = params.getDoubleOrNull(2) ?: 8F
val maxSeconds = params.getDoubleOrNull(3) ?: 30F
val loopTimes = params.getDoubleOrNull(4)?.toInt() ?: 1
val excludedLabels = mutableSetOf<String>()
var curve: WaveFunction = { t ->
if (t < 0.1) {
t * 10
} else if (t < 0.9) {
1F
} else {
1F
}
}
for (index in 5 until params.params.size) {
val param = params.get<MoValue>(index)
if (param is ObjectValue<*>) {
curve = param.obj as WaveFunction
continue
}
val label = params.getString(index) ?: continue
excludedLabels.add(label)
}
ObjectValue(
quirk(
secondsBetweenOccurrences = minSeconds.toFloat() to maxSeconds.toFloat(),
condition = { true },
loopTimes = 1..loopTimes,
animation = { PrimaryAnimation(bedrockStateful(animationGroup, animationNames.random()), excludedLabels = excludedLabels, curve = curve) }
)
)
}
@Transient
val runtime = MoLangRuntime().setup().setupClient().also { it.environment.getQueryStruct().addFunctions(functions.functions) }
@@ -785,7 +823,6 @@ abstract class PoseableEntityModel<T : Entity>(
matrixStack.push()
matrixStack.scale(-1F, -1F, 1F)
scale = entity.pokemon.form.baseScale * entity.pokemon.scaleModifier * (entity.delegate as PokemonClientDelegate).entityScaleModifier
matrixStack.scale(scale, scale, scale)
} else if (entity is EmptyPokeBallEntity) {
matrixStack.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(entity.yaw))
@@ -800,27 +837,14 @@ abstract class PoseableEntityModel<T : Entity>(
matrixStack.scale(1F, -1F, 1F)
}
matrixStack.push()
matrixStack.scale(1F, -1F, 1F)
val states = state.locatorStates
states.getOrPut("root") { MatrixWrapper() }.updateMatrix(matrixStack.peek().positionMatrix)
matrixStack.pop()
if (isForLivingEntityRenderer) {
// Standard living entity offset, only God knows why Mojang did this.
matrixStack.translate(0.0, -1.5, 0.0)
}
// If we have the entity, put in an approximation of the target locator. If the model has one defined,
// this will be overridden.
matrixStack.push()
matrixStack.translate(0.0, -entity.boundingBox.yLength / 2.0 / scale + 1.5F, -entity.width * 0.6 / scale)
matrixStack.scale(1F, -1F, 1F)
states.getOrPut("target") { MatrixWrapper() }.updateMatrix(matrixStack.peek().positionMatrix)
states.getOrPut("special_attack") { MatrixWrapper() }.updateMatrix(matrixStack.peek().positionMatrix)
matrixStack.pop()
locatorAccess.update(matrixStack, states)
locatorAccess.update(matrixStack, entity, scale, states, isRoot = true)
}
fun ModelPart.translation(
@@ -876,6 +900,18 @@ abstract class PoseableEntityModel<T : Entity>(
animations = { listOf(animation(it)) }
)
fun quirkMoLangCondition(
secondsBetweenOccurrences: Pair<Float, Float> = 8F to 30F,
loopTimes: IntRange = 1..1,
conditionExpression: ExpressionLike = "true".asExpressionLike(),
animation: (state: PoseableEntityState<T>) -> StatefulAnimation<T, *>
) = SimpleQuirk<T>(
secondsBetweenOccurrences = secondsBetweenOccurrences,
loopTimes = loopTimes,
condition = { it.runtime.resolveBoolean(conditionExpression) },
animations = { listOf(animation(it)) }
)
fun quirkMultiple(
secondsBetweenOccurrences: Pair<Float, Float> = 8F to 30F,
loopTimes: IntRange = 1..1,
@@ -78,7 +78,7 @@ abstract class PoseableEntityState<T : Entity> : Schedulable {
"anim_time" to java.util.function.Function { return@Function reusableAnimTime.also { it.value = animationSeconds.toDouble() } },
"pose_type" to java.util.function.Function { return@Function StringValue((getEntity() as Poseable).getCurrentPoseType().name) },
"pose" to java.util.function.Function { _ -> return@Function StringValue(currentPose ?: "") },
"say" to java.util.function.Function { params -> MinecraftClient.getInstance().player?.sendMessage(params.getString(0).text()) ?: Unit },
"has_entity" to java.util.function.Function { _ -> return@Function DoubleValue(getEntity() != null) },
"sound" to java.util.function.Function { params ->
val entity = getEntity() ?: return@Function Unit
if (params.get<MoValue>(0) !is StringValue) {
@@ -135,6 +135,7 @@ abstract class PoseableEntityState<T : Entity> : Schedulable {
val storm = ParticleStorm(
effect = effect,
entity = entity,
matrixWrapper = matrixWrapper,
world = world,
runtime = particleRuntime,
@@ -33,7 +33,7 @@ class SingleBoneLookAnimation<T : Entity>(
val pitchMultiplier: Float = 1F,
val yawMultiplier: Float = 1F,
val maxPitch: Float = 70F,
val minPitch: Float = 45F,
val minPitch: Float = -45F,
val maxYaw: Float = 45F,
val minYaw: Float = -45F,
) : StatelessAnimation<T, ModelFrame>(frame) {
@@ -54,8 +54,8 @@ class SingleBoneLookAnimation<T : Entity>(
bone = frame.head,
pitchMultiplier = pitchMultiplier ?: if (disableX) 0F else if (invertX) -1F else 1F,
yawMultiplier = yawMultiplier ?: if (disableY) 0F else if (invertY) -1F else 1F,
maxPitch = maxPitch ?: 45F,
minPitch = minPitch ?: -70F,
maxPitch = maxPitch ?: 70F,
minPitch = minPitch ?: -45F,
maxYaw = maxYaw ?: 45F,
minYaw = minYaw ?: -45F,
)
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.models.blockbench.JsonPose
import com.cobblemon.mod.common.client.render.models.blockbench.JsonPoseableEntityModel
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityState
@@ -20,6 +21,11 @@ import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
import com.cobblemon.mod.common.util.adapters.Vec3dAdapter
import com.cobblemon.mod.common.util.isDusk
import com.cobblemon.mod.common.util.isStandingOnRedSand
import com.cobblemon.mod.common.util.isStandingOnSand
import com.cobblemon.mod.common.util.isStandingOnSandOrRedSand
import com.cobblemon.mod.common.util.resolveBoolean
import com.google.gson.ExclusionStrategy
import com.google.gson.FieldAttributes
import com.google.gson.GsonBuilder
@@ -33,6 +39,7 @@ import com.google.gson.annotations.SerializedName
import com.google.gson.reflect.TypeToken
import java.lang.reflect.Type
import java.util.function.Supplier
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
/**
@@ -43,7 +50,8 @@ import net.minecraft.util.math.Vec3d
* @author Hiroku
* @since August 7th, 2022
*/
class JsonPokemonPoseableModel(override val rootPart: Bone) : PokemonPoseableModel(), HeadedFrame {
class JsonPokemonPoseableModel(rootPart: Bone) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = (rootPart as ModelPart).children.entries.first().let { rootPart.registerChildWithAllChildren(it.key) }
companion object {
val gson = GsonBuilder()
.setPrettyPrinting()
@@ -80,30 +88,12 @@ class JsonPokemonPoseableModel(override val rootPart: Bone) : PokemonPoseableMod
override val head: Bone by lazy { headJoint?.let { getPart(it) } ?: rootPart }
@SerializedName("portraitScale")
private val _portraitScale: Float? = null
@SerializedName("portraitTranslation")
private val _portraitTranslation: Vec3d? = null
@SerializedName("profileScale")
private val _profileScale: Float? = null
@SerializedName("profileTranslation")
private val _profileTranslation: Vec3d? = null
//Some weirdness going on here, vars have to be initialized, gson doesn't like multiple fields with the same name
@Transient
//Idk, works fine with Blastoise
override var portraitScale = 1F
get() = _portraitScale ?: 1F
@Transient
override var portraitTranslation = Vec3d.ZERO
get() = _portraitTranslation ?: Vec3d(0.0, 0.0, 0.0)
@Transient
override var profileScale = 1F
get() = _profileScale ?: 1F
@Transient
override var profileTranslation = Vec3d.ZERO
get() = _profileTranslation ?: Vec3d(0.0, 0.0, 0.0)
val faint: Supplier<StatefulAnimation<PokemonEntity, ModelFrame>>? = null
@@ -142,6 +132,7 @@ class JsonPokemonPoseableModel(override val rootPart: Bone) : PokemonPoseableMod
override fun createInstance(type: Type): JsonPokemonPoseableModel {
return JsonPokemonPoseableModel(modelPart!!).also {
model = it
modelPart as ModelPart
it.loadAllNamedChildren(modelPart!!)
}
}
@@ -163,6 +154,32 @@ class JsonPokemonPoseableModel(override val rootPart: Bone) : PokemonPoseableMod
if (mustBeTouchingWater != null) {
conditionsList.add { mustBeTouchingWater == it.isTouchingWater }
}
val mustBeTouchingWaterOrRain = json.get("isTouchingWaterOrRain")?.asBoolean
if (mustBeTouchingWaterOrRain != null) {
conditionsList.add { mustBeTouchingWaterOrRain == it.isTouchingWaterOrRain }
}
val mustBeSubmergedInWater = json.get("isSubmergedInWater")?.asBoolean
if (mustBeSubmergedInWater != null) {
conditionsList.add { mustBeSubmergedInWater == it.isSubmergedInWater }
}
val mustBeStandingOnRedSand = json.get("isStandingOnRedSand")?.asBoolean
if (mustBeStandingOnRedSand != null) {
conditionsList.add { mustBeStandingOnRedSand == it.isStandingOnRedSand() }
}
val mustBeStandingOnSand = json.get("isStandingOnSand")?.asBoolean
if (mustBeStandingOnSand != null) {
conditionsList.add { mustBeStandingOnSand == it.isStandingOnSand() }
}
val mustBeStandingOnSandOrRedSand = json.get("isStandingOnSandOrRedSand")?.asBoolean
if (mustBeStandingOnSandOrRedSand != null) {
conditionsList.add { mustBeStandingOnSandOrRedSand == it.isStandingOnSandOrRedSand() }
}
val mustBeDusk = json.get("isDusk")?.asBoolean
if (mustBeDusk != null) {
conditionsList.add { mustBeDusk == it.isDusk() }
}
conditionsList.add { (it.delegate as PokemonClientDelegate).runtime.resolveBoolean(pose.condition) }
val poseCondition: ((PokemonEntity) -> Boolean)? = if (conditionsList.isEmpty()) null else conditionsList.reduce { acc, function -> { acc(it) && function(it) } }
@@ -19,6 +19,7 @@ import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
class ArcanineModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, QuadrupedFrame {
override val rootPart = root.registerChildWithAllChildren("arcanine")
override val head = getPart("head")
@@ -37,7 +38,7 @@ class ArcanineModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Quad
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
//override val cryAnimation = CryProvider { _, _ -> bedrockStateful("arcanine", "cry") }
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("arcanine", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("arcanine", "blink") }
@@ -9,8 +9,8 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityState
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
@@ -37,6 +37,8 @@ class ChanseyModel(root: ModelPart) : PokemonPoseableModel(), BipedFrame {
lateinit var sleep: PokemonPose
lateinit var battleIdle: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("chansey", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("chansey", "blink") }
@@ -50,6 +50,11 @@ class DodrioModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
val blink1 = quirk { bedrockStateful("dodrio", "blink1") }
val blink2 = quirk { bedrockStateful("dodrio", "blink2") }
val blink3 = quirk { bedrockStateful("dodrio", "blink3") }
val bite1 = quirk(secondsBetweenOccurrences = 5F to 20F) { bedrockStateful("dodrio", "bite_quirk1") }
val bite2 = quirk(secondsBetweenOccurrences = 5F to 20F) { bedrockStateful("dodrio", "bite_quirk2") }
val bite3 = quirk(secondsBetweenOccurrences = 5F to 20F) { bedrockStateful("dodrio", "bite_quirk3") }
sleep = registerPose(
poseType = PoseType.SLEEP,
idleAnimations = arrayOf(bedrock("dodrio", "sleep"))
@@ -83,7 +88,7 @@ class DodrioModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink1, blink2, blink3),
quirks = arrayOf(blink1, blink2, blink3, bite1, bite2, bite3),
condition = { it.isBattling },
idleAnimations = arrayOf(
bedrock("dodrio", "battle_idle")
@@ -37,8 +37,8 @@ class DoduoModel (root: ModelPart) : PokemonPoseableModel() {
override fun registerPoses() {
val blink = quirk { bedrockStateful("doduo", "blink1") }
val blink2 = quirk { bedrockStateful("doduo", "blink2") }
val bite = quirk { bedrockStateful("doduo", "bite_quirk1") }
val bite2 = quirk { bedrockStateful("doduo", "bite_quirk2") }
val bite = quirk(secondsBetweenOccurrences = 5F to 20F) { bedrockStateful("doduo", "bite_quirk1") }
val bite2 = quirk(secondsBetweenOccurrences = 5F to 20F) { bedrockStateful("doduo", "bite_quirk2") }
sleep = registerPose(
poseType = PoseType.SLEEP,
@@ -50,7 +50,7 @@ class DoduoModel (root: ModelPart) : PokemonPoseableModel() {
poseTypes = STATIONARY_POSES + UI_POSES,
transformTicks = 10,
condition = { !it.isBattling },
quirks = arrayOf(blink, blink2, bite, bite2),
quirks = arrayOf(blink, blink2),
idleAnimations = arrayOf(
bedrock("doduo", "ground_idle")
)
@@ -60,7 +60,7 @@ class DoduoModel (root: ModelPart) : PokemonPoseableModel() {
poseName = "walking",
poseTypes = MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink, blink2, bite, bite2),
quirks = arrayOf(blink, blink2),
idleAnimations = arrayOf(
bedrock("doduo", "ground_walk")
)
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
@@ -26,6 +27,8 @@ class ElectrodeHisuianModel (root: ModelPart) : PokemonPoseableModel() {
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("electrode_hisuian", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("electrode_hisuian", "blink") }
standing = registerPose(
@@ -29,7 +29,7 @@ class KabutoModel(root: ModelPart) : PokemonPoseableModel() {
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
// override val cryAnimation = CryProvider { _, _ -> bedrockStateful("kabuto", "cry") }
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("kabuto", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("kabuto", "blink") }
@@ -8,13 +8,14 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
@@ -56,7 +57,7 @@ class KabutopsModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Bipe
standing = registerPose(
poseName = "standing",
poseTypes = UI_POSES + PoseType.STAND,
poseTypes = UI_POSES + STATIONARY_POSES,
condition = { !it.isBattling },
quirks = arrayOf(blink),
idleAnimations = arrayOf(
@@ -67,7 +68,7 @@ class KabutopsModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Bipe
walk = registerPose(
poseName = "walk",
poseType = PoseType.WALK,
poseTypes = MOVING_POSES,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
singleBoneLook(),
@@ -34,7 +34,7 @@ class KrabbyModel(root: ModelPart) : PokemonPoseableModel() {
lateinit var standingBubbles: PokemonPose
lateinit var standingRain: PokemonPose
// override val cryAnimation = CryProvider { _, _ -> bedrockStateful("krabby", "cry") }
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("krabby", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("krabby", "blink")}
@@ -41,7 +41,7 @@ class LaprasModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Quadru
lateinit var underwaterIdle: PokemonPose
lateinit var underwaterMove: PokemonPose
//override val cryAnimation = CryProvider { _, _ -> bedrockStateful("lapras", "cry") }
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("lapras", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("lapras", "blink") }
@@ -86,7 +86,7 @@ class LaprasModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Quadru
quirks = arrayOf(blink),
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("lapras", "surfacewater_idle")
bedrock("lapras", "surfacewater_swim")
)
)
@@ -106,7 +106,7 @@ class LaprasModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Quadru
quirks = arrayOf(blink),
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("lapras", "surfacewater_idle")
bedrock("lapras", "surfacewater_swim")
)
)
}
@@ -8,21 +8,14 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WingFlapIdleAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.parabolaFunction
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.SHOULDER_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
@@ -66,7 +59,7 @@ class PidgeyModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
stand = registerPose(
poseName = "standing",
poseTypes = SHOULDER_POSES + UI_POSES + PoseType.STANDING_POSES,
poseTypes = SHOULDER_POSES + UI_POSES + PoseType.STATIONARY_POSES - PoseType.HOVER,
transformTicks = 10,
transformedParts = arrayOf(
wingClosedLeft.createTransformation().withVisibility(visibility = true),
@@ -58,7 +58,6 @@ class RattataAlolanModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame,
poseTypes = setOf(PoseType.NONE, PoseType.PROFILE, PoseType.STAND, PoseType.FLOAT, PoseType.PORTRAIT, PoseType.SHOULDER_LEFT, PoseType.SHOULDER_RIGHT),
transformTicks = 10,
quirks = arrayOf(blink),
condition = { !it.dataTracker.get(PokemonEntity.MOVING) },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("rattata_alolan", "ground_idle")
@@ -69,7 +68,6 @@ class RattataAlolanModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame,
poseType = PoseType.WALK,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.dataTracker.get(PokemonEntity.MOVING) },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("rattata_alolan", "ground_walk")
@@ -57,7 +57,6 @@ class RattataModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Quadr
poseTypes = setOf(PoseType.NONE, PoseType.PROFILE, PoseType.STAND, PoseType.FLOAT, PoseType.PORTRAIT, PoseType.SHOULDER_LEFT, PoseType.SHOULDER_RIGHT),
transformTicks = 10,
quirks = arrayOf(blink),
condition = { !it.dataTracker.get(PokemonEntity.MOVING) },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("rattata", "ground_idle")
@@ -68,7 +67,6 @@ class RattataModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Quadr
poseType = PoseType.WALK,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.dataTracker.get(PokemonEntity.MOVING) },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("rattata", "ground_walk")
@@ -45,7 +45,7 @@ class ScytherModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Biped
lateinit var hover: PokemonPose
lateinit var fly: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("voltorb", "cry") }
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("scyther", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("scyther", "blink")}
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
@@ -30,6 +31,8 @@ class SnorlaxModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("snorlax", "cry") }
override fun registerPoses() {
standing = registerPose(
poseName = "standing",
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
@@ -33,6 +34,9 @@ class TangelaModel(root: ModelPart) : PokemonPoseableModel(), BipedFrame {
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("tangela", "cry") }
// Animating illegally rn. Created a new file for this cry. hope it works
override fun registerPoses() {
standing = registerPose(
poseName = "standing",
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
@@ -26,6 +27,8 @@ class VoltorbHisuianModel (root: ModelPart) : PokemonPoseableModel() {
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("voltorb_hisuian", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("voltorb_hisuian", "blink") }
@@ -0,0 +1,83 @@
/*
* 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.client.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
class CyndaquilHisuiBiasModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("cyndaquil_hisui_bias")
override val head = getPart("head")
override var portraitScale = 1.4F
override var portraitTranslation = Vec3d(-0.26, 0.0, 0.0)
override var profileScale = 0.65F
override var profileTranslation = Vec3d(0.0, 0.8, 0.0)
lateinit var standing: PokemonPose
lateinit var walking: PokemonPose
lateinit var sleep: PokemonPose
lateinit var battleidle: PokemonPose
override val cryAnimation = CryProvider { entity, _ -> if (entity.isBattling) bedrockStateful("cyndaquil_hisui_bias", "battle_cry") else bedrockStateful("cyndaquil_hisui_bias", "cry") }
override fun registerPoses() {
// val sneeze = quirk { bedrockStateful("cyndaquil_hisui_bias", "sneeze_quirk") }
sleep = registerPose(
poseType = PoseType.SLEEP,
idleAnimations = arrayOf(bedrock("cyndaquil_hisui_bias", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
condition = { !it.isBattling },
// quirks = arrayOf(sneeze),
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("cyndaquil_hisui_bias", "ground_idle")
)
)
walking = registerPose(
poseName = "walking",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
// quirks = arrayOf(sneeze),
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("cyndaquil_hisui_bias", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
// quirks = arrayOf(sneeze),
condition = { it.isBattling },
idleAnimations = arrayOf(
singleBoneLook(minPitch = 0F),
bedrock("cyndaquil_hisui_bias", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PoseableEntityState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walking, battleidle, sleep)) bedrockStateful("cyndaquil_hisui_bias", "faint") else null
}

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