Compare commits

...
Author SHA1 Message Date
JazzMcNade 6ba2804a46 Added type checking 2024-05-14 00:46:40 -05:00
JazzMcNade d13d5183c8 Implemented missing functions. 2024-05-14 00:24:09 -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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Segfault Guy c7ae41bf7b Merge branch 'main' into interpreter_my_beloved 2024-04-23 22:43:06 -04:00
Segfault Guy 1653be5fa8 Misc refactor fixes. 2024-04-23 22:42:00 -04:00
Hiroku b0497065f4 Merge branch '1.5-spawns-and-fixes' into 'main'
1.5 spawns and fixes

See merge request cable-mc/cobblemon!968
2024-04-24 02:34:03 +00:00
Paul dfc1a39f58 Merge branch 'refs/heads/main' into 1.5-spawns-and-fixes
# Conflicts:
#	CHANGELOG.md
2024-04-24 12:30:17 +10:00
Paul 9a92e074a2 Fixed instant particle emitter not defaulting the number of particles the way it does in Snowstorm 2024-04-24 11:38:59 +10:00
Hiroku 44b195f0a6 Updated changelog with exact counts for structures [skip-ci] 2024-04-22 23:34:40 +00:00
Hiroku 7c21e6feb5 Merge branch '1.5-Structures' into 'main'
1.5 structures

See merge request cable-mc/cobblemon!971
2024-04-22 22:33:21 +00:00
Slippy 3b653b745e suspicious mound shoved further into the ground 2024-04-22 17:20:46 -05:00
Paul f246d90e4c Merge remote-tracking branch 'origin/main' 2024-04-22 09:11:59 +10:00
Hiroku df22cc5b3e Merge branch 'advancement-description-inconsistencies-fixes' into 'main'
Update en_us.json

Closes #809

See merge request cable-mc/cobblemon!969
2024-04-21 23:11:49 +00:00
Paul 3fbe2102a0 Fixed curves not working properly at the particle level if they weren't always on screen, closes #806 2024-04-22 09:11:39 +10:00
dhi_holo 21b667f5d8 Update en_us.json
Corrects two advancement descriptions to be accurate and match formatting of all other advancements.

I think I made the branch name longer than the changes, looking at it in githubdesktop I'm not so sure now xD
2024-04-21 16:35:29 +10:00
Paul eb88a43769 Fixed bedrock particle rotation velocity being treated as blocks per tick instead of blocks per second, closes #807 2024-04-21 15:32:07 +10:00
Paul c41a6766ef Fixed lookat_y camera mode 2024-04-21 15:31:19 +10:00
Paul 842de0e92c Fixed woopsy with automaton armor trim advancement 2024-04-21 15:30:50 +10:00
Veraxiel 04b516765d Edited Moon Stone Ore gen. Updated changelog. 2024-04-21 00:44:28 -04:00
Paul 3faad69484 Oops remove that TODO 2024-04-21 12:36:13 +10:00
Paul 74e2f8429c Fixed expiration events not running for particles when they expire on collision. Closes #805 2024-04-21 12:35:53 +10:00
Paul 10219fbf38 Made vivillon advancement description consistent on punctuation. Closes #809 2024-04-21 12:33:15 +10:00
Hiroku cf68ccc29e Merge branch 'sound' into 'main'
Removed an unused sound file

See merge request cable-mc/cobblemon!966
2024-04-21 02:29:58 +00:00
Hiroku f78847f917 Merge branch 'mistrim' into 'main'
Trim Recipe Fixes

See merge request cable-mc/cobblemon!967
2024-04-21 02:29:17 +00:00
Village 8768c4c541 differentiate badly poisoned in ui 2024-04-17 21:50:03 -04:00
Veraxiel 2bf0fd625b Tweaked some spawns, flipped the Poison Barb sprite for looking too much like a sword when held. 2024-04-17 19:49:53 -04:00
dhi_holo 65e3052e69 Removed Missing Textures
Automaton Trims now work when trimming same material (Iron Armour, Iron Trim Material, same for diamond, gold, and netherite)
2024-04-16 17:00:28 +10:00
dhi_holo be7192ae2c Trim Recipe Fixes
+ Adds duplication recipe
+ Adds advancement to unlock duplication recipe
- Renamed smithing recipe to match Vanilla
+ Adds advancement to unlock smithing recipe
2024-04-16 16:14:45 +10:00
Sterrezo 1c921a372b Removed an unused sound file
My guess is it was put there when battle effects or particles were being worked on. As far as I can tell it's not used anywhere.
2024-04-15 23:14:01 +02:00
Nick cf3587557d Merge branch 'ui-icon' into 'main'
Update shiny icon

See merge request cable-mc/cobblemon!963
2024-04-15 19:14:48 +00:00
TestandNick bbd44c0010 Update shiny icon 2024-04-15 19:14:48 +00:00
Nick bb05177985 Merge branch 'imposter_fix' into 'main'
Imposter fixes

See merge request cable-mc/cobblemon!965
2024-04-15 19:14:18 +00:00
Segfault GuyandNick 31143359ee Imposter fixes 2024-04-15 19:14:18 +00:00
Nick c8f0140870 Merge branch '1.5-Structures' into 'main'
found a spelling error smh

See merge request cable-mc/cobblemon!964
2024-04-15 19:13:00 +00:00
MyslippyandNick 0b9ca3a97c found a spelling error smh 2024-04-15 19:12:59 +00:00
Slippy d03541ff6f iron bar fix 2024-04-15 00:56:31 -05:00
Slippy 0d7aff0349 Please work 2024-04-15 00:24:54 -05:00
Slippy c904888c6a found a spelling error smh 2024-04-13 09:12:21 -05:00
Hiroku 450ebfc44e Merge branch 'scripts/public-spawn-writer-script' into 'main'
public spawn writer script open beta

See merge request cable-mc/cobblemon!961
2024-04-13 01:26:36 +00:00
Hiroku 253bde945f Merge branch 'gilded-chest-crash-fix' into 'main'
Fixes gilded chest encounter from crashing when party is empty.

See merge request cable-mc/cobblemon!962
2024-04-13 01:06:14 +00:00
Islana 3622946974 Fixes gilded chest encounter from crashing when party is empty. 2024-04-12 19:52:33 -04:00
Hiroku 4077feca35 Merge branch '1.5-Structures' into 'main'
It wasnt the last D:

See merge request cable-mc/cobblemon!960
2024-04-11 02:37:44 +00:00
Waldleufer bf330c112b Allowing any combination of Folder and File Name [skip-ci] 2024-04-10 21:47:26 +02:00
Slippy c07d7d304e It wasnt the last D: 2024-04-09 19:19:02 -05:00
Hiroku 5797a2e568 Merge branch '1.5-Structures' into 'main'
1.5 structures

See merge request cable-mc/cobblemon!959
2024-04-10 00:16:49 +00:00
Slippy 5f94999b4f Is this the last push? 2024-04-09 19:15:02 -05:00
Hiroku 8b8fa06472 Update 0999_gimmighoul.json 2024-04-09 01:24:18 +00:00
Hiroku 0459780171 Update 0442_spiritomb.json 2024-04-09 00:22:21 +00:00
Hiroku e27bf7fc4b Merge branch 'ys/forfeit' into 'main'
PVP Forfeit Option

Closes #142

See merge request cable-mc/cobblemon!957
2024-04-08 14:28:57 +00:00
Paul 36007caf16 Merge remote-tracking branch 'origin/main' into ys/forfeit
# Conflicts:
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2024-04-08 22:55:49 +10:00
Hiroku f00b16ab1a Merge branch 'better_victory_msg' into 'main'
Fix capture messages and improve win/defeat messages.

See merge request cable-mc/cobblemon!958
2024-04-08 12:25:37 +00:00
Hiroku ac93c89d2c Merge branch '1.5-more-spawn-and-drops' into 'main'
1.5 more spawn and drops

See merge request cable-mc/cobblemon!954
2024-04-08 12:22:00 +00:00
Hiroku 1c5f6a8f54 Merge branch 'implement_pokemon' into 'main'
Hisui Starters, some model, animation, & texture fixes, and more!

See merge request cable-mc/cobblemon!956
2024-04-08 04:09:18 +00:00
Segfault Guy f66358e358 Fix capture messages and improve win/defeat messages. 2024-04-07 22:53:50 -04:00
Tyzillion 446706e6cd Moved my conditions from PokemonEntity to EntityExtensions. 2024-04-07 22:50:42 -04:00
Segfault Guy 967fd2e0ec Force Showdown loss on forfeit. 2024-04-07 22:48:38 -04:00
Tyzillion 57d2b51264 Sorry, found another error in the changelog. 2024-04-07 22:29:21 -04:00
Tyzillion 4baa43ccb4 Quick changelog amend. 2024-04-07 22:26:28 -04:00
Tyzillion c9be0104dd Updated Changelog. 2024-04-07 22:14:04 -04:00
Tyzillion 55a179f548 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-04-07 22:11:23 -04:00
Tyzillion beaea0e88c Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-07 22:11:05 -04:00
Tyzillion fb54ff8054 Revamped Torkoal's particles. Made the particles only appear in battle. Hoping in the future when it gets more animations to add quirks that have it spew smoke. 2024-04-07 22:10:52 -04:00
Hiroku c273192ba2 Merge branch 'tumbleshatter' into 'main'
Reduces Tumblestone blocks to a 2x2 recipe, makes Tumblestone blocks drop the tumblestones on break

See merge request cable-mc/cobblemon!955
2024-04-08 02:06:33 +00:00
dhi_holo acfc3b1acc Tumbleshatter
Tumblestone Blocks now shatter back into tumblestones on breaking, unless using silk touch
2024-04-08 09:44:38 +10:00
dhi_holo e45e7a589b Reduces Tumblestone blocks to a 2x2 recipe
(this is for future content)
2024-04-08 09:09:31 +10:00
FrankTheFarmerReal 0fc3bf9de7 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-08 07:15:42 +10:00
FrankTheFarmerReal b6af9381f0 Ferroseed line is not from gen 2 🤔 2024-04-08 07:14:59 +10:00
Sterrezo ee64810970 Cry checker script fix 2024-04-07 23:05:51 +02:00
Tyzillion a7152f3e35 Added ambient Bubble particles to Krabby that play during sunset with no rain. 2024-04-07 14:09:11 -04:00
Tyzillion 46290554c5 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-04-07 14:08:38 -04:00
Tyzillion 771a2c0727 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-07 14:08:03 -04:00
Segfault Guy 4e456e030d Merge branch 'main' into ys/forfeit
Conflicts:
	common/src/main/kotlin/com/cobblemon/mod/common/api/battles/model/PokemonBattle.kt
	common/src/main/kotlin/com/cobblemon/mod/common/battles/ShowdownActionRequest.kt
	common/src/main/resources/assets/cobblemon/lang/en_us.json
2024-04-07 13:33:34 -04:00
FrankTheFarmerReal 9d69c593b8 Hitbox and Look animation fixes. Stopped Ferroseed and Whirlipede turbo spins. 2024-04-08 00:05:29 +10:00
Hiroku 6e58f4be59 Merge branch 'illusion' into 'main'
Illusion and Transform Entity Effects

Closes #769, #744, #741, #297, and #123

See merge request cable-mc/cobblemon!929
2024-04-07 01:33:47 +00:00
FrankTheFarmerReal f1807dc27c Many many fix 2024-04-06 22:13:33 +10:00
Tyzillion cb8e96230e Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-04-06 04:48:37 -04:00
Paul dc6b3ada9b Fixed F3-T crash on Fabric. Closes #780 2024-04-06 13:28:39 +10:00
Paul ccdb8803b2 Merge remote-tracking branch 'origin/main' into implement_pokemon 2024-04-06 12:00:24 +10:00
Paul fd917438a1 Fixed Pokémon pathing over snow layers and carpets. Closes #783 2024-04-06 11:44:39 +10:00
Tyzillion 4a0e567554 Fixed starterconfig to use right features 2024-04-05 16:18:46 -04:00
Tyzillion bb6b67e4aa Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-05 16:16:23 -04:00
Slippy 6515bfa108 Decaying Crypt no longer has a random floating granite block 2024-04-05 12:14:57 -05:00
FrankTheFarmerReal 8bf5492409 10 Fixes + Retextures implemented 2024-04-05 23:46:02 +10:00
FrankTheFarmerReal e6573f3c3b Sneasel hitbox fixes 2024-04-05 15:28:53 +10:00
Tyzillion 86d8fa1806 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-04-05 00:10:56 -04:00
Hiroku de65320610 Merge branch 'SortFaintedToBottom_Fix' into 'main'
Sort fainted to bottom fix

See merge request cable-mc/cobblemon!932
2024-04-05 02:57:21 +00:00
Hiroku 3828991a71 Update BattleActor.kt 2024-04-05 01:32:00 +00:00
Paul 129ea86829 Licenses 2024-04-05 11:10:51 +10:00
Hiroku 216270b798 Merge branch 'bugs_and_tweaks' into 'main'
Bugs and tweaks

Closes #782

See merge request cable-mc/cobblemon!931
2024-04-05 01:03:00 +00:00
Hiroku ad1674a1bc Merge branch 'main' into 'illusion'
# Conflicts:
#   common/src/main/kotlin/com/cobblemon/mod/common/pokemon/Pokemon.kt
2024-04-05 00:46:37 +00:00
FrankTheFarmerReal 2b80d99614 Commented out some faint poses for pokemon that don't have faint animations currently. 2024-04-04 22:56:26 +10:00
FrankTheFarmerReal 723302ed39 Fixed Shieldon animation crash 2024-04-04 22:42:15 +10:00
FrankTheFarmerReal 79bec94f55 Restored missing Hippowdon sound 2024-04-04 22:41:39 +10:00
FrankTheFarmerReal d7a7d421a0 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-04 21:52:50 +10:00
FrankTheFarmerReal 49632b6f85 Revised SingleBoneLookAnimation. Can properly invert X and Y axis and define range limits. 2024-04-04 21:50:13 +10:00
Tyzillion 308a41a5fc Gave Lapras funny placeholder Quadruped walk. hehe 2024-04-04 07:20:16 -04:00
Paul a5486be16f Removed a test log message 2024-04-04 20:40:33 +10:00
Paul 94c9f865e7 Fixed poser issues for gen8 fossils, Omanyte line, Wingull line, Hippowdown, Chespin line 2024-04-04 20:06:28 +10:00
Paul 3385b9c8bf Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-04-04 19:38:39 +10:00
Veraxiel cdfc894d49 Removed spawns not supposed to be there. 2024-04-03 16:55:13 -04:00
Veraxiel 784e2c0fb8 Updates to spawns and some tags. 2024-04-03 16:52:18 -04:00
Waldleufer e6a487dc52 Handling custom file name groupings and custom output folders in the public spawn writer [skip-ci] 2024-04-03 22:28:37 +02:00
Waldleufer bdb79a32cc Generated a bunch of drops. 2024-04-03 20:51:57 +02:00
Waldleufer 5d6a227c49 Merge branch 'main' into 1.5-more-spawn-and-drops 2024-04-03 19:37:40 +02:00
FrankTheFarmerReal 2bca651f75 PLEASE REVIEW: SingleBoneLookAnimation changes to support min and max ranges for yaw. Dugtrio and Dodrio examples. 2024-04-03 23:22:59 +10:00
FrankTheFarmerReal cbde864cc1 diglett and dugtrio hitbox fixes 2024-04-03 23:17:55 +10:00
FrankTheFarmerReal 4b3a5d7ca9 Flaaffy head bone correction 2024-04-03 20:04:30 +10:00
FrankTheFarmerReal e55c08648f Expanded constructor for SingleBoneLook and added Grimmsnarl sight cone restrictions. 2024-04-03 13:15:38 +10:00
FrankTheFarmerReal 052f8fd94a Some placeholder animations 2024-04-03 08:50:57 +10:00
Tyzillion cd4f7fc7aa Forgot to merge main into branch. 2024-04-02 17:19:33 -04:00
Tyzillion c90400bba6 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
2024-04-02 17:17:32 -04:00
Tyzillion d390764717 changed pattern aspect to region_bias. Updated all that needed to be updated with the new aspect name. Made the region bias pokemon share animations with their normal variants. 2024-04-02 17:15:51 -04:00
Lily 0880d127a7 Merge branch 'main' into bugs_and_tweaks
# Conflicts:
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2024-04-02 16:13:39 -04:00
Nick 30466a6063 Merge branch 'shifting-shadows' into 'main'
Scale shadows on sendout/recall

See merge request cable-mc/cobblemon!949
2024-04-02 18:50:13 +00:00
MiaandNick fd59b81bff Scale shadows on sendout/recall 2024-04-02 18:50:13 +00:00
FrankTheFarmerReal ba82a6bc56 Some placeholder animations 2024-04-02 16:16:28 +10:00
Lily abf64e6047 Merge branch 'main' into bugs_and_tweaks 2024-04-01 22:06:23 -04:00
Lily c463278498 Fix outdated advancement name 2024-04-01 22:04:42 -04:00
Paul a37fdf709a Fixed Inkay evo method. Fixes #787 2024-04-01 18:51:55 +10:00
Paul 5023f28d04 Fixed underwalking the target position leading to walking in place. Fixes #790 2024-04-01 18:40:57 +10:00
Slippy c502fec709 more bug fixes and balancing 2024-04-01 02:48:33 -05:00
FrankTheFarmerReal 49444eea50 Updated walk animations for Armaldo and Hoothoot 2024-04-01 15:36:56 +10:00
FrankTheFarmerReal 470fb80e08 Cutiefly, Flabebe, Flittle, and Scatterbug are now shoulder mountable 2024-04-01 15:22:29 +10:00
FrankTheFarmerReal a2aa6deddb Fixed Roselia battle idle not playing 2024-04-01 14:26:12 +10:00
Paul 0d4ef20b4a Merge remote-tracking branch 'origin/main' into implement_pokemon
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
2024-04-01 11:55:37 +10:00
Hiroku 67de28386a Merge branch 'ball-animation-changes' into 'main'
Breakout Animation, Overhauled Sendout Logic

See merge request cable-mc/cobblemon!943
2024-04-01 01:03:16 +00:00
Hiroku cd37d3538e Formatting 2024-04-01 00:39:38 +00:00
Tyzillion 137fed9152 Removed cry sound effect from Gimmighoul surprise animation so that it doesn't play the cry twice when encountering a closed Gimmighoul. Fixed Archen quirk sound being on wrong quirk. 2024-03-31 15:29:01 -04:00
Tyzillion 42ea462937 Hopefully fixed Xatu's t-posing while flying. 2024-03-31 11:14:19 -04:00
Tyzillion f32852db9d Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-03-31 11:08:30 -04:00
Tyzillion 4294360cb9 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-03-31 11:08:15 -04:00
FrankTheFarmerReal d54565dbb5 Fixed Rookidee and Corvisquire T posing underwater 2024-03-31 23:12:08 +10:00
FrankTheFarmerReal 0e005ea1ba Galarian Rapidash will now stop T posing when asleep, but will have to sleep with its eyes open :( 2024-03-31 22:58:16 +10:00
FrankTheFarmerReal d2e32bc26a Gave temporary walk animation to Salazzle 2024-03-31 22:47:16 +10:00
FrankTheFarmerReal 92d5005a62 Restored Lechonk's cry 2024-03-31 22:34:43 +10:00
Hiroku 3d03ee5eb3 Merge branch 'gilded_chest_names' into 'main'
Preserve and display custom names for gilded chests

Closes #792

See merge request cable-mc/cobblemon!945
2024-03-31 12:11:57 +00:00
Paul 0b685ed453 Actually that one field is nullable 2024-03-31 21:47:10 +10:00
Hiroku 115e990df6 Update GildedChestBlock.kt 2024-03-31 10:19:16 +00:00
Hiroku 2ee38f0a29 Merge branch '1.5-Structures' into 'main'
fixed spelling error in gilded chest loot table

See merge request cable-mc/cobblemon!948
2024-03-31 10:18:03 +00:00
Slippy 756ef48ba2 coins are more common in sus blocks 2024-03-31 04:52:02 -05:00
Slippy 2c4df6622a fixed spelling error in gilded chest loot table 2024-03-31 04:30:48 -05:00
FrankTheFarmerReal 99dc9930b8 Fixed Timburr and Gurdurr quirks 2024-03-31 18:52:28 +10:00
Hiroku 425c41bc4b Merge branch 'waterloggable-tumblestones' into 'main'
Make tumblestones waterloggable

Closes #793

See merge request cable-mc/cobblemon!946
2024-03-31 07:22:48 +00:00
Hiroku 9f7a99b583 Merge branch '1.5-Structures' into 'main'
1.5 structures

See merge request cable-mc/cobblemon!947
2024-03-31 07:22:22 +00:00
Slippy f1213abdf4 candy adjustment 2024-03-31 01:04:02 -05:00
Slippy 9b1d847f59 added absorb bulb to some fossil loot tables 2024-03-31 00:09:28 -05:00
Slippy bf900a0167 Just an enormous amount of changes to loot tables and structures 2024-03-30 23:57:54 -05:00
FrankTheFarmerReal 7b008fe0ec Fixed broken animations for Chinchou, Lanturn, Gallade, and Magikarp 2024-03-31 14:09:12 +10:00
FrankTheFarmerReal ffa9ae4e86 Updated animations for Unovan and Hisuian Petilil 2024-03-31 13:37:07 +10:00
miasmus d60d828e93 make tumblestones waterloggable 2024-03-30 23:00:08 -04:00
FrankTheFarmerReal fcbc7ee72b Updated more walk speeds 2024-03-31 12:13:50 +10:00
Tyzillion 7319fdf29b Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-03-30 21:53:27 -04:00
Slippy 703282eca1 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into 1.5-Structures 2024-03-30 19:39:12 -05:00
miasmus 5d7e6f6487 Preserve and display custom names for gilded chests 2024-03-30 19:38:38 -04:00
Hiroku 4e3e6405d0 Merge branch 'FossilMachineBalancing01' into 'main'
Fossil machine balancing01

See merge request cable-mc/cobblemon!944
2024-03-30 23:01:44 +00:00
Segfault Guy d8ad55506d Update Showdown w/ illusion and party bug fixes. 2024-03-30 16:00:18 -04:00
Segfault Guy adef71c23f Merge branch 'main' into illusion 2024-03-30 15:52:10 -04:00
Segfault Guy 9b49f5e01f Add licenses. 2024-03-30 15:37:37 -04:00
Segfault Guy 23c52fd106 Fix transform with shiny aspect. 2024-03-30 15:22:33 -04:00
Segfault Guy d118fe4ee8 Fix interpreter instructions pulling real BattlePokemon name before illusion is dispatched. 2024-03-30 15:09:17 -04:00
Segfault Guy 7b2b860e52 Fix ClientBattlePokemon syncing for transform and illusion. 2024-03-30 14:35:30 -04:00
FrankTheFarmerReal d733eaae2f Updated behaviours for Dreepy line and Flabebe line. 2024-03-31 00:25:40 +10:00
FrankTheFarmerReal 0c8fe42087 Fixed portraits for Lunatone, Solrock, and Salazzle 2024-03-30 23:38:26 +10:00
FrankTheFarmerReal 5e88116e08 Adjusted movement speed of Anorith and Armaldo. Fixed Hisuian Goodra crash 2024-03-30 23:30:45 +10:00
JazzMcNade 1e161a52ee Fixed an index out of bounds issue related to having a extreme excess of material in the tank 2024-03-30 02:27:04 -05:00
JazzMcNade 65b2204783 Decreased required material to 128 (from 256). Decreased restoration time to 12min (from 15min). 2024-03-30 02:14:06 -05:00
Flarkinater 76d9137ae4 Merge branch 'main' into ball-animation-changes 2024-03-29 22:09:21 -04:00
Flarkinater 9f6c44fd75 Sendout location is only shifted vertically when necessary 2024-03-29 22:08:40 -04:00
Flarkinater 6c086f5555 Fixed merge conflict goofs 2024-03-29 21:58:26 -04:00
FrankTheFarmerReal ef96814900 Restored cries for Gardevoir and Rowlet 2024-03-30 11:37:52 +10:00
Tyzillion f6161d8687 Misc fixes and implemented region pattern evolution methods. 2024-03-29 17:31:08 -04:00
Tyzillion 8aa5d3a72c Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-03-29 11:27:37 -04:00
Waldleufer 353de8b8a3 ✨ Polishing ✨ [skip-ci] 2024-03-29 16:23:21 +01:00
Waldleufer 0423dd4939 hint at potential partial implementations that are not checked of in the spreadsheet. [skip-ci] 2024-03-29 16:19:38 +01:00
Waldleufer fe02ea6fa9 Polished Cry Checker Skript to help verify implemented cries [skip-ci] 2024-03-29 16:08:18 +01:00
Tyzillion 90f7454ffb Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-03-29 08:52:39 -04:00
FrankTheFarmerReal 04f53040a3 Many long pokemon are no longer partly rendered in the PC 2024-03-29 22:50:16 +10:00
Tyzillion 69e21672eb Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2024-03-29 08:36:41 -04:00
FrankTheFarmerReal 4f2e3ecb0f Fixed Conkeldurr using Gurdurr's animations. Also updated the whole line's animations. 2024-03-29 22:27:30 +10:00
FrankTheFarmerReal 1acc41da8c Gimmighoul, Pupitar, and Tyranitar will now appear using the spawnallpokemon command 2024-03-29 20:50:56 +10:00
FrankTheFarmerReal a6917162a7 Updated animations on Quaxwell and Quaquaval 2024-03-29 17:47:53 +10:00
Slippy a9115bfb15 XL RCs are less common 2024-03-29 01:27:30 -05:00
FrankTheFarmerReal 111cb3a2f3 Fixed cries and T poses for Unovan and Hisuian Oshawott 2024-03-29 16:21:03 +10:00
Hiroku f2c5113f0b Merge branch 'json-addict' into 'main'
Advancement and Tag Updates

See merge request cable-mc/cobblemon!942
2024-03-29 05:31:33 +00:00
Hiroku e29a2402e9 Merge branch 'spawning-gamerule-change' into 'main'
Move doPokemonSpawning gamerule logic

See merge request cable-mc/cobblemon!941
2024-03-29 05:30:53 +00:00
Hiroku aa4857abbb Merge branch 'Quick-Move-Stacked-PokePotion-Bases' into 'main'
Add the ability to quick move stacked PokePotion bases into Brewing Stands.

See merge request cable-mc/cobblemon!935
2024-03-29 05:29:13 +00:00
Hiroku d29653233d Merge branch 'main' into 'Quick-Move-Stacked-PokePotion-Bases'
# Conflicts:
#   CHANGELOG.md
2024-03-29 05:28:22 +00:00
Hiroku 1b51a128d7 Merge branch 'OldAmberSpriteUpdate' into 'main'
Corrected Old Amber Sprite

See merge request cable-mc/cobblemon!939
2024-03-29 05:27:10 +00:00
Hiroku 245011cf5e Merge branch '1.5-Structures' into 'main'
Oh boy that's a lot of changes and fixes to structures

See merge request cable-mc/cobblemon!940
2024-03-29 05:26:30 +00:00
FrankTheFarmerReal 8ac9f38b06 Petilil pivot changes and Stonjourner walk speed adjusted 2024-03-29 15:12:47 +10:00
FrankTheFarmerReal 48193160b9 Texture updates for Forretress, Sizzlipede, and Centiskorch 2024-03-29 14:31:14 +10:00
FrankTheFarmerReal 83100dec11 Tweaked Anorith and Armaldo again 2024-03-29 14:14:52 +10:00
Flarkinater 100bf7fee4 Merge remote-tracking branch 'origin/main' into ball-animation-changes
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/pokemon/PokemonRenderer.kt
2024-03-29 00:05:58 -04:00
Flarkinater be043a0ea1 Fixed minor issue with shifting Pokemon vertically during suffocation sendout check 2024-03-28 23:41:24 -04:00
Flarkinater a902f4a8a3 Fixed suffocation avoidance when sending out Pokemon adjacent to a wall, other related fixes 2024-03-28 23:05:30 -04:00
Flarkinater 442f54839f Improved spacing when targeting walls and above blocks 2024-03-28 22:09:41 -04:00
FrankTheFarmerReal a87b5090b0 Added Anorith and Armaldo animations 2024-03-29 11:48:05 +10:00
dhi_holo 20a97984a2 Misc Structures
Just a couple tags containing all structures not represented in a sub-tag, if someone wants to go in and make more tags to reduce the ones in here feel free, just make sure it adds up.
2024-03-29 10:54:10 +10:00
dhi_holo d1517548bd Update en_us.json
Gamerule Translation so it's not just a shitty string anymore
2024-03-29 10:09:22 +10:00
dhi_holo 3e1f9dc9b0 2 Shiny
Updated shiny icon for summary and advancement
2024-03-29 09:54:52 +10:00
FrankTheFarmerReal f0c8d08a04 Pivot fixes for Kirlia and Obstagoon 2024-03-29 09:22:20 +10:00
FrankTheFarmerReal 4fdc738b9e Updated many Pokemon walk speeds 2024-03-29 08:55:53 +10:00
miasmus fd19e65f79 move doPokemonSpawing gamerule logic 2024-03-28 16:42:42 -04:00
dhi_holo 6b10d81bc8 Update en_us.json
Capital fixes because it wasn't right
2024-03-28 23:53:56 +10:00
FrankTheFarmerReal 920c5fd01a Rowlet, Dartrix, and Parasect retextures 2024-03-28 21:46:16 +10:00
dhi_holo f3b9c03fc2 Advancement Updates
Reorgainised the advancements Healing Power, Consult the Fossil, and Free Roam: Enabled, renamed Tumbling Down to be correct, and changed the Shiny advancement to use Shiny icon.
2024-03-28 21:39:56 +10:00
FrankTheFarmerReal 7d8c8a724f Fixed some aquatic pokemon drowning 2024-03-28 19:45:28 +10:00
Veraxiel 0f5f5d4eed Changed fossil machine recipes. Updated some tags. 2024-03-28 05:37:35 -04:00
FrankTheFarmerReal 30744c42a4 Changelog: Changelog changed 2024-03-28 18:14:39 +10:00
FrankTheFarmerReal 821bb79c14 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-03-28 16:19:51 +10:00
FrankTheFarmerReal f5171a4a8a PNG fixes for Flygon and Archen 2024-03-28 16:19:16 +10:00
Tyzillion 061c9a1c52 Fixed Darmanitan zen crash 2024-03-28 01:15:45 -04:00
FrankTheFarmerReal da45f7d040 Fixes that just keep happening 2024-03-28 14:41:37 +10:00
Flarkinater 92653c1307 When targeting a wall, Pokemon are sent out far enough away to avoid suffocation, based on their size. Wailord rejoice! 2024-03-27 23:42:24 -04:00
Flarkinater c372114da5 Improved avoidance of unsafe locations when sending out Pokemon 2024-03-27 23:26:07 -04:00
FrankTheFarmerReal 230ab53369 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2024-03-28 11:38:38 +10:00
FrankTheFarmerReal ac43853baa Changelog updates 2024-03-28 11:36:09 +10:00
Tyzillion 0de5f82971 More fixes 2024-03-27 21:24:46 -04:00
Slippy 2b95138c46 Oh boy that's a lot of changes and fixes to structures 2024-03-27 20:02:02 -05:00
JazzMcNade 864e6be461 Corrected Old Amber Sprite 2024-03-27 19:53:10 -05:00
Tyzillion ec084cffbc AHHHHHHHHHHHHHHHH 2024-03-27 17:41:44 -04:00
Tyzillion f8ae312c0a Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-03-27 17:28:34 -04:00
Tyzillion abce88fab6 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-03-27 17:28:21 -04:00
Apion c02fa1f85e Merge branch '1.5-Drops-and-Fixes' into 'main'
New drops and some tag/script fixes.

See merge request cable-mc/cobblemon!938
2024-03-27 20:29:11 +00:00
Apion 503b1069fd Merge branch 'MultiBlockEntityClientCrashFix' into 'main'
MultiBlockEntity Safer Casting

See merge request cable-mc/cobblemon!937
2024-03-27 20:27:01 +00:00
JazzMcNadeandApion f1d593d53c MultiBlockEntity Safer Casting 2024-03-27 20:27:01 +00:00
FrankTheFarmerReal 69fb39f148 Hisuian Typhlosion's flames are now hidden outside of battle 2024-03-27 20:44:23 +10:00
FrankTheFarmerReal 70838464d5 Litwick also wants to be shouldermountable 2024-03-27 20:14:28 +10:00
FrankTheFarmerReal 3cdb6e05c3 Kommo-o pose and model updates 2024-03-27 17:23:00 +10:00
FrankTheFarmerReal 87822bc2f7 Ralts, Roggenrola, Charcadet, and Sizzlepede are now shoulderable 2024-03-27 16:37:36 +10:00
Veraxiel 55dd486044 Updated Changelog. 2024-03-27 01:10:26 -04:00
FrankTheFarmerReal dffb944f3e Squirtle can now ride on your shoulder 2024-03-27 13:02:47 +10:00
FrankTheFarmerReal 613f3044bc Zorua and Zoroark hitbox fixes 2024-03-27 11:38:44 +10:00
FrankTheFarmerReal 342b9cb31e Fixed Dragapult height and Sliggoo's evolution not requiring rain 2024-03-27 11:23:39 +10:00
FrankTheFarmerReal 4679cfb07f -Updated UI positions and model scale of the Goomy line 2024-03-27 10:32:04 +10:00
FrankTheFarmerReal 9bb701abc8 -Updated scale values and regional data for many pokemon 2024-03-27 08:15:19 +10:00
FrankTheFarmerReal d070a7b75a -Fixed floating dragonair and T-posing sleeping Mawile 2024-03-26 20:40:24 +10:00
FrankTheFarmerReal 00a4b88437 -Model & Texture fixes for Gimmighoul, Lurantis, and Jangmo-o line
-Hisuian Samurott animation fix to prevent floating
2024-03-26 20:16:57 +10:00
FrankTheFarmerReal 005a98742e -Updated UI poses and data for several pokemon 2024-03-26 18:56:55 +10:00
FrankTheFarmerReal 94168a65f0 -Updated Walk Speed for some Pokemon 2024-03-26 16:26:20 +10:00
FrankTheFarmerReal 39d626b349 -Texture fixes for Aggron, Copperajah, Dracozolt, Gimmighoul and Lilligant 2024-03-26 14:06:45 +10:00
Hiroku 3263837137 Merge branch '1.5-Structures' into 'main'
Structure fixes and generation rate adjustments

See merge request cable-mc/cobblemon!936
2024-03-25 21:14:19 +00:00
Tyzillion db6852134c Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-03-25 17:03:22 -04:00
Slippy a471fcd948 Increased rates for underground ruin structures, forest ruin structures and gimmi towers 2024-03-25 12:29:03 -05:00
Slippy a14bfd55d1 Jungle Fossil rates were increased 2024-03-25 12:22:25 -05:00
Slippy 725e819e89 Snow Forest structures rates were increased 2024-03-25 12:21:23 -05:00
Slippy b52b843206 Ocean fossils structures rates were increased 2024-03-25 12:20:13 -05:00
Slippy 74c65e22cb Decaying Crypt generation rates increased 2024-03-25 12:19:20 -05:00
Slippy c348520a9b Increased the generation rate for Mossy Oubliette 2024-03-25 12:15:42 -05:00
Slippy 78dd5f334a Decrease how common desert ruins are and adjusted the weights at which each will generate 2024-03-25 12:12:54 -05:00
Slippy 67318c9307 Sandy Den's were way too common. Adjusted their rates of generation 2024-03-25 12:05:17 -05:00
Slippy 31c48407df Slightly lowered the amount of sus sand in the sandy den structure 2024-03-25 11:43:45 -05:00
FrankTheFarmerReal 7170825848 -Darmanitan revamp and Krokorok texture fixes 2024-03-25 16:32:52 +10:00
Flarkinater 43da7ecece First attempt at canceling sendouts into unsafe locations (cactus, fire if the Pokemon isn't immune) 2024-03-24 23:41:22 -04:00
FrankTheFarmerReal 5b1531b894 -License Changes 2024-03-25 11:14:59 +10:00
Charzard4261 0957de86c7 Add the ability to quick move stacked PokePotion bases into Brewing Stands. 2024-03-25 00:05:19 +00:00
Slippy daae444fa9 Prehistoric Rooted Pits are more common 2024-03-23 22:51:39 -05:00
Slippy 79423ef5ee Prehistoric_Birch_Tree Fix 2024-03-23 22:13:07 -05:00
Veraxiel 6255f7dc31 Removed spawn that shouldn't be in. 2024-03-23 22:29:43 -04:00
Segfault Guy af9f1accf8 Fix Cant and Damage instructions. 2024-03-23 20:41:36 -04:00
Hiroku ff10306372 Merge branch 'GiveGimmighoulRightClick' into 'main'
Easier Gimmighoul Giving

See merge request cable-mc/cobblemon!930
2024-03-23 22:07:16 +00:00
Hiroku aaf7daa45b Merge branch 'sound' into 'main'
A lot of audio asset updates

See merge request cable-mc/cobblemon!933
2024-03-23 22:06:29 +00:00
Tyzillion 3b87846562 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-03-23 16:09:42 -04:00
Tyzillion dfd4450e11 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-03-23 15:18:08 -04:00
Waldleufer 7c42f8e37f Added check for minimum audio length to cry checker script [skip-ci] 2024-03-23 18:45:18 +01:00
Waldleufer ae550f78c4 Now the order of selection of input and output does not matter anymore. [skip-ci] 2024-03-23 16:19:40 +01:00
Waldleufer 66e4194a3e Made public spawn writer read Dex No. as int for consistency [skip-ci] 2024-03-23 16:04:53 +01:00
Waldleufer 12e6b76504 chore: added spawn specific drops to a bunch of cobblemon - mainly nether spawns. 2024-03-23 15:54:52 +01:00
Waldleufer 93861af71f dropping drops helps. [skip-ci] 2024-03-23 15:51:34 +01:00
Waldleufer 0c80748012 perf: script speed is over 9000! [skip-ci] 2024-03-23 15:18:30 +01:00
FrankTheFarmerReal 4060dbd596 - Fixed Wartortle, Blissey, and Hisuian Sliggo crashes
- Implemented a bunch of pokemon
- Specifically added darumaka changes
2024-03-23 23:26:53 +10:00
Waldleufer fcf832c22c more sensible script default values [skip-ci] 2024-03-23 13:17:48 +01:00
Sterrezo a065aff744 Added audio assets for fossil Pokemon cries 2024-03-23 13:04:19 +01:00
Sterrezo d77f424a83 Updated battle SFX 2024-03-23 12:49:47 +01:00
Waldleufer d5d2a2cec3 fix: improved hint for rare spreadsheet parsing bug. [skip-ci] 2024-03-23 11:55:02 +01:00
Sterrezo 036e150191 Merge branch 'main' into sound 2024-03-23 11:52:52 +01:00
Waldleufer 0bf1d84675 fix: added hint for rare spreadsheet parsing bug. [skip-ci] 2024-03-23 11:52:52 +01:00
Waldleufer b1b8e658b2 chore: updated drops data and fixed some missing form specific drops. 2024-03-23 11:42:20 +01:00
Waldleufer f984b21929 fix: Drops script now robustly handles form drops and hints at missing data in both spreadsheet and .json files [skip-ci] 2024-03-23 11:34:42 +01:00
Waldleufer 0a5193b209 perf: Increase preformance of drops script to be linear function, added dex_range option [skip-ci] 2024-03-23 10:46:59 +01:00
Veraxiel 43f1f1c30d Update to spawns to use SkyLight. 2024-03-23 04:05:56 -04:00
Waldleufer c16597ae41 chore: CHANGELOG [skip-ci] 2024-03-22 23:31:39 +01:00
Waldleufer f76e7582d2 Reworked our spawn writer script to be compatible with new UI [skip-ci] 2024-03-22 23:28:41 +01:00
Waldleufer 40761d87db Adding DexRange as input [skip-ci] 2024-03-22 20:45:19 +01:00
Waldleufer 89a9ad0bfb Refactoring the hell out of it [skip-ci] 2024-03-22 19:41:36 +01:00
Waldleufer 20291c54a5 First Version of public spawn writer script [skip-ci] 2024-03-22 19:12:13 +01:00
Islana 04b7500887 Fixes battlebuilder from sending out fainted pokemon, causing a softlock. 2024-03-22 00:45:39 -04:00
Hiroku d6fdfe6ebc Merge branch 'FetusResizing' into 'main'
Fossil Fetus Rescaling

See merge request cable-mc/cobblemon!927
2024-03-22 01:06:17 +00:00
Islana fe3d2a29b9 Fixes battlebuilder from sending out fainted pokemon, causing a softlock. 2024-03-21 20:07:41 -04:00
Lily ad81202d49 Updated the display case to allow cleaner rotations 2024-03-21 15:54:06 -04:00
Lily acbacfa8cf Fixed certain evolutions not working 2024-03-21 15:30:15 -04:00
Lily 9740267f91 Fixed a bug causing items to disappear from display cases 2024-03-21 14:28:34 -04:00
Lily fcca3b1d68 Fix armor trim name inconsistency. Closes #782 2024-03-21 14:11:32 -04:00
Nick 9f63b62651 Merge branch '1.5-Structures' into 'main'
Hi Hiro

See merge request cable-mc/cobblemon!928
2024-03-21 16:42:25 +00:00
JazzMcNade 392632b7d4 Added the ability for a player to add to Gimighoul's treasure horde by right clicking directly on a gimmighoul that they own. 2024-03-21 00:48:59 -05:00
Segfault Guy 767e279cf1 Merge branch 'main' into illusion 2024-03-21 00:25:45 -04:00
Segfault Guy 6ace08aaa6 Fix illusion battle interactions. 2024-03-21 00:19:28 -04:00
Slippy 0d377dcbe0 Changes, fixes, and balancing of 1.5 structures 2024-03-20 22:17:13 -05:00
JazzMcNade 88c31bcb7b Scaled Archen to0.55 (from 0.8). Scaled Kabuto to 0.85 (from 0.75) 2024-03-20 19:36:27 -05:00
Waldleufer 8efea17ae6 added structure: prefix for anticonditions and conditions and refactored script [skip-ci] 2024-03-20 21:03:37 +01:00
Waldleufer cdbf569bbc feat: made spawnwriter handle new preset: tag for spawn specific drops [skip-ci] 2024-03-20 16:26:28 +01:00
Hiroku 8b81b13d01 Merge branch 'archaeology_fixup' into 'main'
Archaeology Fixup

See merge request cable-mc/cobblemon!925
2024-03-20 12:34:33 +00:00
Hiroku f19d9410c0 Merge branch 'GildedChestComparatorOutput' into 'main'
Add comparator output for the Gilded Chest

See merge request cable-mc/cobblemon!926
2024-03-20 11:36:52 +00:00
JazzMcNade 9ac3a9249d Added comparator output for the Gilded Chest 2024-03-20 00:49:56 -05:00
Lily 4f340b2eee - Fixed a bug involving hoppers and Gimmighoul chests
- Fixed certain structures not generating
- Fixed certain loot tables failing to load
2024-03-19 17:15:32 -04:00
Tyzillion 7dc00c3e88 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-03-19 13:19:11 -04:00
Sterrezo d000790996 Uhh some cries
Implemented cries for Scyther, Electabuzz, Lapras, Omastar, Aerodactyl.
I have to wait for the next animation push.
2024-03-19 14:12:32 +01:00
Veraxiel 0415cf8a69 Added Carnivine spawn files. 2024-03-19 04:09:58 -04:00
Sterrezo 663624c434 Implemented most Gen 1 cries for 1.5
Omitted Tangela because it's missing animation.json. Don't know how to work around that.
Script update is from a different branch, used it for implementation.
2024-03-18 16:18:02 +01:00
Sterrezo 79af092888 Merge branch 'main' into sound 2024-03-18 11:52:30 +01:00
Hiroku 5cff52df5f Merge branch 'archaeology' into 'main'
Merging Structure Tweaks for Playtesting

See merge request cable-mc/cobblemon!924
2024-03-18 06:38:20 +00:00
Hiroku ca311fa97c Merge branch 'Waldleufer/automatingTagListCreation' into 'main'
tooling: automating tag list creation

See merge request cable-mc/cobblemon!908
2024-03-18 06:34:42 +00:00
Slippy 27020d3068 Loot table changes for structures 2024-03-18 01:14:55 -05:00
Paul 3ac4b8622f Merge remote-tracking branch 'origin/main' into 1.5-Spawns 2024-03-18 15:41:22 +10:00
Paul acd7a0583c Fixed Ekans line spawns, fixed season tag references for new locations 2024-03-18 15:35:28 +10:00
Nick e341948bd4 Merge branch 'tooling-fixes' into 'main'
tooling: mark gradlew as executable & fix logs being created during unit tests

See merge request cable-mc/cobblemon!921
2024-03-18 04:24:22 +00:00
broccolaiandNick 1a465abf9d tooling: mark gradlew as executable & fix logs being created during unit tests 2024-03-18 04:24:22 +00:00
Paul e56a6e5b1a Updated qwilfish and overqwil spawns 2024-03-18 14:03:53 +10:00
Paul 33d707a73b Spawn fixes 2024-03-18 14:02:17 +10:00
Segfault Guy ba8e40d5a7 Implement illusion and transform entity effects. No pokemon can be trusted. 2024-03-18 00:00:43 -04:00
Paul e3c3cd380c Merge remote-tracking branch 'origin/main' into 1.5-Spawns
# Conflicts:
#	utilityscripts/cobblemon_drops_csv_to_json.py
2024-03-18 13:42:02 +10:00
Hiroku 578ce789b1 Merge branch 'implement_pokemon' into 'main'
Many Pokémon implemented and some animation transition fixes.

See merge request cable-mc/cobblemon!923
2024-03-18 03:19:20 +00:00
Paul 460e8f7501 Fixed various Pokemon not being marked as implemented when they are, fixed Golem and Lairon legs moving in a hurry 2024-03-18 11:37:24 +10:00
Tyzillion 2fee86e7bc Updated branch and forgot to add diglett line updates to changelog. 2024-03-17 19:35:04 -04:00
Tyzillion f73e631f81 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-03-17 19:28:46 -04:00
Tyzillion 0ca0c1a552 hitboxes adjusted. 2024-03-17 19:26:34 -04:00
Hiroku b3bf2c5ded Merge branch 'test-improvements' into 'main'
tooling: improve tests by properly bootstrapping minecraft

See merge request cable-mc/cobblemon!922
2024-03-17 22:31:17 +00:00
broccoli 7875006c8e tooling: improve tests by properly bootstrapping minecraft
- uses the fabric-loader-junit build
- rewrites the SpawnValidator to use #getResource instead of code file paths
- create a junit extension to bootstrap easier
2024-03-17 21:13:45 +00:00
Slippy 67bb63b638 Well that didn't work at all... 2024-03-17 14:34:42 -05:00
Slippy 511f97b963 Fixed structures unintentionally generating in the oceans. Fixed structures unintentionally generating on the surface. 2024-03-17 13:15:31 -05:00
Waldleufer 54c426f5ff feat: spawn writer now handles skyLight [skip-ci] 2024-03-17 16:01:07 +01:00
Waldleufer f89902ece8 feat: spawn_csv_to_json script improvements [skip-ci]
* only verify biome tags if tag directories are available.
* Missing cobblemon items in the natural names to tags spreadsheet are now printed out as an error.
2024-03-17 15:45:32 +01:00
Waldleufer 52c6bbd842 chore: update Changelog [skip-ci] 2024-03-17 14:24:26 +01:00
Waldleufer 8246a822cf feat: added "ready for implementation" list to cry_checker script. [skip-ci] 2024-03-17 14:17:01 +01:00
Hiroku 54202bed98 Merge branch 'BalancedFossils' into 'main'
Play test values for fossil machine

See merge request cable-mc/cobblemon!920
2024-03-17 08:55:46 +00:00
Paul e6313cf4c5 Reverted partial run change 2024-03-17 16:44:56 +10:00
JazzMcNade 7debc6e047 Increased timings, increased required natural material, updated material values, increased quirk cooldown. Fixed bugs revealed upon changing these values 2024-03-16 22:37:16 -05:00
Tyzillion bf9b69a143 Updated Dragonite, Omanyte, Omastar, and Pinsir animations. 2024-03-16 21:44:02 -04:00
Hiroku d7f34972c1 Merge branch 'MoreHoldItems' into 'main'
more held items woah

See merge request cable-mc/cobblemon!918
2024-03-17 00:58:35 +00:00
Veraxiel fa7356d2ed Update to Ocean tag. 2024-03-16 18:10:07 -04:00
Sterrezo 812d42a42f Merge branch 'main' into sound 2024-03-16 22:22:26 +01:00
Sterrezo 3f114706fa Implemented sounds for Revival Herb and Vivichoke. Volume adjustments.
Implemented sounds for Revival Herb and Vivichoke. Tweaked assets for Fossil Machine insert dna sounds. Adjusted volumes to Fossil Machine, Tumblestone and Coin Pouch sounds.
2024-03-16 22:21:05 +01:00
Lily 8d1f41919d nvm eject button can go back in 👍😄 2024-03-16 16:11:48 -04:00
Lily b40c21d99e pull eject pack and eject button since they brick battles 2024-03-16 16:07:35 -04:00
Lily 461d8bd282 more held items woah 2024-03-16 14:37:32 -04:00
Tyzillion 84d34709a3 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-03-16 13:44:49 -04:00
Tyzillion b6c04e8746 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon
# Conflicts:
#	common/src/main/resources/data/cobblemon/species/generation2/heracross.json
#	common/src/main/resources/data/cobblemon/species/generation5/darmanitan.json
#	common/src/main/resources/data/cobblemon/species/generation5/lilligant.json
#	common/src/main/resources/data/cobblemon/species/generation5/zoroark.json
#	common/src/main/resources/data/cobblemon/species/generation6/floette.json
#	common/src/main/resources/data/cobblemon/species/generation6/goodra.json
#	common/src/main/resources/data/cobblemon/species/generation7/kommoo.json
#	common/src/main/resources/data/cobblemon/species/generation7/lurantis.json
#	common/src/main/resources/data/cobblemon/species/generation7/salazzle.json
#	common/src/main/resources/data/cobblemon/species/generation8/copperajah.json
2024-03-16 13:43:31 -04:00
Hiroku 81a96afaa6 Merge branch 'tag-god' into 'main'
Added structure tags (for /locate command)

See merge request cable-mc/cobblemon!917
2024-03-16 11:19:40 +00:00
dhi_holo 724332dd34 Added structure tags (for /locate command)
The reason for these is primarily the /locate command, combining biome variants together so if you're just looking for a structure of a specific kind, but the biome doesn't matter, you don't have to deal with deciding which to search for.
2024-03-16 18:23:02 +10:00
Veraxiel f5bfd64495 Added some more spawns. 2024-03-16 01:32:55 -04:00
Hiroku bf8f7f628f Merge branch 'quick-ficks' into 'main'
Puffing Bells

See merge request cable-mc/cobblemon!916
2024-03-16 05:24:14 +00:00
dhi_holo 898fdf983f Puffing Bells
Hisui Puff hopefully fixed, and soothe bell recipe cleaned up (so many errors)

Also added the newer tags to the lang
2024-03-16 14:32:20 +10:00
Hiroku a547e0f535 Merge branch 'fix/adjust-node-type' into 'main'
fix: don't access entity in adjustNodeType

See merge request cable-mc/cobblemon!915
2024-03-16 02:34:46 +00:00
broccoli 564ced926c fix: don't access entity in adjustNodeType
Mojang has disposed of the entity by this point, leading to a crash that's
especially noticed in the Wander goal.
2024-03-16 02:16:28 +00:00
Paul a93dd14fd8 Fixed soothe bell recipe 2024-03-16 12:08:44 +10:00
Paul f0535901cb Fixed prepared transition animations not playing (lol) 2024-03-16 11:47:16 +10:00
Paul 7a42df591f Merge remote-tracking branch 'origin/main' into implement_pokemon
# Conflicts:
#	common/src/main/resources/assets/cobblemon/particles/snowstorm.json
#	common/src/main/resources/data/cobblemon/species/generation2/heracross.json
#	common/src/main/resources/data/cobblemon/species/generation5/darmanitan.json
#	common/src/main/resources/data/cobblemon/species/generation5/lilligant.json
#	common/src/main/resources/data/cobblemon/species/generation5/zoroark.json
#	common/src/main/resources/data/cobblemon/species/generation6/floette.json
#	common/src/main/resources/data/cobblemon/species/generation6/goodra.json
#	common/src/main/resources/data/cobblemon/species/generation7/kommoo.json
#	common/src/main/resources/data/cobblemon/species/generation7/lurantis.json
#	common/src/main/resources/data/cobblemon/species/generation7/salazzle.json
#	common/src/main/resources/data/cobblemon/species/generation8/copperajah.json
2024-03-16 11:21:54 +10:00
Veraxiel 616419880f Updated spawn files. 2024-03-15 16:45:09 -04:00
Slippy 9fa38430c0 Deleted old structure file 2024-03-15 13:42:25 -05:00
Slippy 26012278e7 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into archaeology 2024-03-15 13:35:42 -05:00
Slippy 2c0967d293 1.5 structures for real??? 2024-03-15 13:04:00 -05:00
Nick 885fc72d93 Revert "1.5 Structures final changes before Playtesting"
This reverts commit 8130cd0998
2024-03-15 17:56:22 +00:00
Slippy 8130cd0998 1.5 Structures final changes before Playtesting 2024-03-15 12:52:32 -05:00
Veraxiel 447d35f28b Updated tags. Added presets. 2024-03-15 05:47:07 -04:00
Hiroku bf82def925 Merge branch 'MoreHoldItems' into 'main'
Implement more held items

See merge request cable-mc/cobblemon!905
2024-03-15 02:57:05 +00:00
Hiroku dace364701 Merge branch 'FossilMachineHandWaggling' into 'main'
When using a pokeball, fossil, or natural material on the fossil machine the...

See merge request cable-mc/cobblemon!911
2024-03-15 02:49:31 +00:00
Lily d737444ac9 Merge branch 'main' into MoreHoldItems
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/Cobblemon.kt
2024-03-14 21:43:54 -04:00
Hiroku 95f58ba557 Merge branch 'panning_for_gilded_chests' into 'main'
make gilded chests waterloggable

See merge request cable-mc/cobblemon!910
2024-03-15 01:28:56 +00:00
Hiroku 8993b007a5 Merge branch 'FossilMachineChunkLoadFix' into 'main'
Fossil machine chunk load fix

See merge request cable-mc/cobblemon!912
2024-03-15 01:28:04 +00:00
Hiroku c84f9dd112 Merge branch 'anychangeobservable-public' into 'main'
Make anyChangeObservable public

See merge request cable-mc/cobblemon!909
2024-03-15 01:25:46 +00:00
apionandJazzMcNade eea7477f7f More changes to how things work in unloaded chunks 2024-03-14 01:19:10 -05:00
JazzMcNade 241abd79d7 FossilMultiblock multiblock getter performance improvement for chunkloading issues 2024-03-14 01:19:10 -05:00
Veraxiel 35618cea46 Merge branch '1.5-Spawns' of https://gitlab.com/cable-mc/pokemon-cobbled into 1.5-Spawns 2024-03-14 02:10:34 -04:00
Veraxiel 31b97d391d Updated tags. Reorganized tags. Added tags for blocks in biomes. 2024-03-14 02:10:00 -04:00
Lily 7769a73246 make gilded chests waterloggable 2024-03-13 23:28:00 -04:00
Nick 65bf9507d3 Fix invalid JSON 2024-03-13 04:48:50 +00:00
miasmus 6d336fc27b make anyChangeObservable public 2024-03-12 17:25:54 -04:00
Sterrezo 9514a1d470 Fossil Machine sound updates
Updated audio assets. Moved and renamed the files for consistency. Adjusted volumes.
2024-03-12 13:31:02 +01:00
Waldleufer 16df7695c4 feat: made speciesJsonReader more robust. 2024-03-10 21:32:11 +01:00
Waldleufer 8fd63912a3 feat: always sort tables alphabetically 2024-03-09 09:07:53 +01:00
Waldleufer 04941a9a38 feat: adding header and TOC 2024-03-09 09:06:24 +01:00
Waldleufer 1853a1677a feat: adding header and TOC 2024-03-09 09:06:18 +01:00
Waldleufer 94f8de8ddc feat: three column representation 2024-03-09 08:52:51 +01:00
Waldleufer 7ea866d82a feat: 2 column version 2024-03-09 08:46:34 +01:00
Waldleufer ea529a52c2 feat: initial version of SpawnPresetListWriter script 2024-03-09 08:34:47 +01:00
Waldleufer 1f6dd03064 refactor: separating code into functions. 2024-03-09 07:42:49 +01:00
Waldleufer d62ea394ee feat: added place for descriptive text for the detailed tag files. 2024-03-09 07:36:33 +01:00
Waldleufer d0b8a3368c feat: moved full tag lists to their own folder 2024-03-09 07:25:32 +01:00
Tyzillion 6d23e762d6 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2024-03-08 19:41:19 -05:00
Tyzillion 6edb0c19c4 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	common/src/main/resources/assets/cobblemon/particles/snowstorm.json
#	common/src/main/resources/data/cobblemon/species/generation2/heracross.json
#	common/src/main/resources/data/cobblemon/species/generation5/darmanitan.json
#	common/src/main/resources/data/cobblemon/species/generation5/lilligant.json
#	common/src/main/resources/data/cobblemon/species/generation5/zoroark.json
#	common/src/main/resources/data/cobblemon/species/generation6/floette.json
#	common/src/main/resources/data/cobblemon/species/generation6/goodra.json
#	common/src/main/resources/data/cobblemon/species/generation7/kommoo.json
#	common/src/main/resources/data/cobblemon/species/generation7/lurantis.json
#	common/src/main/resources/data/cobblemon/species/generation7/salazzle.json
#	common/src/main/resources/data/cobblemon/species/generation8/copperajah.json
2024-03-08 19:27:53 -05:00
Veraxiel 71e9adae1f Merge branch '1.5-Spawns' of https://gitlab.com/cable-mc/pokemon-cobbled into 1.5-Spawns 2024-03-08 19:16:02 -05:00
Veraxiel 35b53daa09 Added tags. 2024-03-08 19:12:59 -05:00
Waldleufer 937c30fca5 feat: initial version of output mds. 2024-03-08 23:54:34 +01:00
Waldleufer 141249e6c7 feat: remove redundant "Tags ↓" 2024-03-08 23:50:52 +01:00
Waldleufer 94f9bf9f50 feat: splitting output in multiple md files. 2024-03-08 23:43:20 +01:00
Waldleufer 4638b01279 feat: first version of markdown writer. 2024-03-08 23:35:10 +01:00
Nick e39d59c37a Merge branch 'gen10-will-wash-this-away' into 'main'
Support Stellar tera type & fix tera type selection.

See merge request cable-mc/cobblemon!907
2024-03-08 20:31:44 +00:00
LiciousandNick 072071d679 Support Stellar tera type & fix tera type selection. 2024-03-08 20:31:44 +00:00
Licious aa4400395b Support for soothe bell mechanic. 2024-03-08 10:50:07 +00:00
Licious 09ad3d0a4d Merge branch 'consolidated-versioning' into 'main'
Quick Fix for Crash Report Details to Actually be Written

See merge request cable-mc/cobblemon!906
2024-03-08 10:30:22 +00:00
NickandLicious de7df10f36 Quick Fix for Crash Report Details to Actually be Written 2024-03-08 10:30:22 +00:00
Lily 897bcf6fc0 Merge branch 'main' into MoreHoldItems
# Conflicts:
#	CHANGELOG.md
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonItems.kt
2024-03-07 17:21:43 -05:00
Lily 1e14042455 removed recipes for cut held items 2024-03-07 17:14:47 -05:00
Nick 8583c9af4d Merge branch 'ores_galore' into 'main'
terracotta sun stone ore

See merge request cable-mc/cobblemon!904
2024-03-07 19:50:08 +00:00
LilyandNick ce756997d6 terracotta sun stone ore 2024-03-07 19:50:08 +00:00
Licious 4efc5b6748 Merge branch 'consolidated-versioning' into 'main'
Change Version Publication for Better Maven Support

See merge request cable-mc/cobblemon!901
2024-03-07 18:23:07 +00:00
NickandLicious 7ed6075410 Change Version Publication for Better Maven Support 2024-03-07 18:23:06 +00:00
Lily 320d995672 add new held item sprites 2024-03-07 12:19:23 -05:00
Nick 8ae91587aa Merge branch 'feat/rework-starter-toast' into 'main'
Removing Starter Toast when it is nice and crispy.

Closes #579, #656, #771, and #655

See merge request cable-mc/cobblemon!898
2024-03-06 23:12:49 +00:00
WaldleuferandNick 61362fa1b1 Removing Starter Toast when it is nice and crispy. 2024-03-06 23:12:49 +00:00
Nick d010129864 Merge branch 'food_reorganization' into 'main'
moved the items in the food category around to make more sense (previously...

See merge request cable-mc/cobblemon!903
2024-03-06 21:24:18 +00:00
Nick 282f002895 Merge branch 'amo/sendout-upgrade' into 'main'
Ancient Send Outs

See merge request cable-mc/cobblemon!902
2024-03-06 21:22:48 +00:00
Lily 863f6de059 moved the items in the food category around to make more sense (previously were all at the very bottom) 2024-03-06 14:43:03 -05:00
JazzMcNade 8ddf628f19 When using a pokeball, fossil, or natural material on the fossil machine the client will always play ActionResult.CONSUME. 2024-03-05 01:25:43 -06:00
dhi_holo 8762d518c1 Merge branch 'main' into amo/sendout-upgrade 2024-03-05 13:56:10 +10:00
Paul 46798d694e Fixed generic entities not rendering, fixed Torkoal particles going upside down, fixed idle animation particles not playing, fixed loop particles not looping 2024-03-04 11:26:20 +10:00
Hiroku 056dd0fd4b Merge branch 'JsonScriptFixes' into 'main'
tiny Json script fixes

See merge request cable-mc/cobblemon!853
2024-03-03 07:54:12 +00:00
WaldleuferandHiroku 3ac00d976b tiny Json script fixes 2024-03-03 07:54:11 +00:00
Paul b30a76855b Fixed cancelling spawn events not actually cancelling the action, closes #612 2024-03-03 17:18:08 +10:00
Paul e976556ae3 (Probably) fixed edge case with pose transitions 2024-03-03 16:10:02 +10:00
Paul 9f16eca621 Merge branch 'main' into implement_pokemon 2024-03-03 15:49:20 +10:00
dhi_holo f4a94bd732 Merge branch 'main' into amo/sendout-upgrade
does this really fix forge?
2024-03-03 15:14:10 +10:00
Paul b6c964e03b Fixed Forge runs, again 2024-03-03 14:40:18 +10:00
dhi_holo aed2204483 Merge branch 'main' into amo/sendout-upgrade 2024-03-03 13:39:35 +10:00
Paul 3ed46cb7af Removed unused option in config (maxHorizontalSpace) 2024-03-03 13:38:59 +10:00
Paul cf9efe9b8c Fixed Snowstorm particles sometimes not appearing 2024-03-03 13:28:40 +10:00
Paul 02b9431731 Attach the entity from the entity particle packet to the storm (oops) 2024-03-03 13:14:13 +10:00
Paul a30ae0ccef Added query functions for entity_width, height, size, and radius to entity tracked particle storms 2024-03-03 12:46:28 +10:00
Hiroku a2905f4d37 Merge branch 'particle-events' into 'main'
Added "event" support to bedrock particles, locator support in the command,...

Closes #767

See merge request cable-mc/cobblemon!900
2024-03-03 02:00:36 +00:00
Paul b3aba1532c Added "event" support to bedrock particles, locator support in the command, and fixed inwards motion direction 2024-03-03 11:28:54 +10:00
Hiroku 6369bdb612 Merge branch '1.5_Structures' into 'main'
Added most of the 1.5 Structures

See merge request cable-mc/cobblemon!877
2024-03-03 00:20:02 +00:00
Hiroku b5db5605ef Merge branch 'FossilAnalyzerDirRenderFix' into 'main'
Fossils are now positioned correctly in all possible block facing directions

See merge request cable-mc/cobblemon!899
2024-03-02 23:48:29 +00:00
JazzMcNade 0207459a0f Fossils are now positioned correctly in all possible block facing directions 2024-03-02 16:37:44 -06:00
Hiroku 0e2fdfbce8 Merge branch 'ability-fix' into 'main'
Abilities fix

See merge request cable-mc/cobblemon!891
2024-03-02 05:20:10 +00:00
Hiroku 8c9da885c7 Merge branch 'main' into 'ability-fix'
# Conflicts:
#   CHANGELOG.md
2024-03-02 04:16:11 +00:00
Hiroku a5b6529f3c Merge branch 'display_case' into 'main'
Display case

See merge request cable-mc/cobblemon!879
2024-03-02 04:10:44 +00:00
Tyzillion 6e9bdb6019 Many hitboxes adjusted. Updated Squirtle and Wartortle animations. 2024-03-01 21:27:34 -05:00
Paul b430b7db76 Corrected Gimmighoul chest battle behaviour on server environments 2024-03-02 12:02:35 +10:00
Hiroku 8015ff0e20 Merge branch 'fix-grow-tumblestone-advancement' into 'main'
Grow Tumblestone Advancement triggers when placed near Lava or Magma

See merge request cable-mc/cobblemon!893
2024-03-02 01:21:55 +00:00
Dhyan PatelandHiroku ee78657e3d Grow Tumblestone Advancement triggers when placed near Lava or Magma 2024-03-02 01:21:55 +00:00
Hiroku 6cc84cd38c Merge branch 'tooltip-fix-fix' into 'main'
fix a small issue with appending tooltips

See merge request cable-mc/cobblemon!897
2024-03-02 00:28:30 +00:00
miasmus 31d6ff541e fix a small issue with appending tooltips 2024-03-01 16:36:31 -05:00
Veraxiel 841a40c973 Added and updated spawns. 2024-03-01 01:42:54 -05:00
jeffw773 e1a4086f24 - push new changes for Slippy 2024-02-29 20:11:09 -08:00
Tyzillion df049a315c Finished adjusting portraits and profiles on all newly implemented Pokemon. Started adjusting hitboxes. 2024-02-29 22:19:38 -05:00
Tyzillion 9ce5486189 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-02-29 22:18:54 -05:00
Paul b1992a94d3 Fixed piglin entity mixin on Forge 2024-03-01 11:10:47 +10:00
Veraxiel 167a1ea8eb Added some new tags. Updated spawn writer. 2024-02-29 10:19:57 -05:00
dhi_holo f95beaa7a1 Delete LICENSE
Gonna hope this wasn't important, it's giving a log error though and feels randomly placed in this folder, if we're meant to have it in here, probably shouldn't randomly be in the fossil items folder?
2024-02-29 20:08:36 +10:00
dhi_holo 1c0f7bbf8f Update restoration_tank.json
was erroring, so I fixed it so it'd be two less errors in the log (and potentially not break ingame, didn't test if these things could happen in natural gameplay)
2024-02-29 20:07:07 +10:00
dhi_holo 34cc2cda46 Maybe Masterball Fixes?
Need to break so just pushing this
2024-02-29 13:58:11 +10:00
dhi_holo 696e58bd1a Update snowstorm.json
removed unneeded/erroring lines
2024-02-29 13:50:40 +10:00
Tyzillion 10412b80ca Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-02-28 21:59:22 -05:00
dhi_holo 458c2ce0ed Merge branch 'main' into amo/sendout-upgrade 2024-02-29 12:34:00 +10:00
Tyzillion 6182715644 Implemented Salandit, Salazzle, Skarmory, Flabebe, Floette, Florges, Ferroseed Carbink, Goomy, Sliggoo, Goodra, Hisuian Goomy, Sliggoo, and Goodra, Flabebe, Floette, Florges, Jangmo-o, Hakamo-o, and Kommo-o.
Caught up a little on Profile and Portrait frames.
2024-02-28 21:26:20 -05:00
Hiroku b41c4c21a8 Merge branch 'publish-versioning-fix' into 'main'
fix versioning

See merge request cable-mc/cobblemon!894
2024-02-28 22:07:33 +00:00
miasmus e1893f50ae fix versioning 2024-02-28 16:52:13 -05:00
Tyzillion a1bdf3ded6 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2024-02-28 15:21:29 -05:00
Lily a458b31c9f Merge branch 'main' into display_case
# Conflicts:
#	.gitignore
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlocks.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonItems.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonSounds.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/battle/subscreen/BattleGeneralActionSelection.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/item/group/CobblemonItemGroups.kt
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
#	common/src/main/resources/assets/cobblemon/models/item/relic_coin_pouch.json
#	common/src/main/resources/assets/cobblemon/sounds.json
2024-02-28 14:07:19 -05:00
Lily 03b5336eb8 refactor getPositioningType to avoid using tags 2024-02-28 14:02:29 -05:00
Apion a270371632 Merge branch 'sturdier_tumblestones' into 'main'
fix tumblestone blocks being breakable without a pickaxe

See merge request cable-mc/cobblemon!892
2024-02-28 18:23:21 +00:00
LilyandApion a9caf92d2f fix tumblestone blocks being breakable without a pickaxe 2024-02-28 18:23:21 +00:00
apion 9e2d00df63 Finished Anorith, Armaldo, Tyrantrum, Zorua, Zoroark, ZoruaH 2024-02-28 11:11:37 -05:00
apion e8003bb29a Added a few comments 2024-02-28 04:15:02 -05:00
apion a248d661fa Finished omastar 2024-02-28 01:07:05 -05:00
apion 59390f4d84 Finished archen line 2024-02-28 01:00:51 -05:00
apion 99b7e4a89e Finished tyrunt 2024-02-28 00:49:36 -05:00
apion fb37e543cf Fixed issues with json posers 2024-02-28 00:43:25 -05:00
apion c0c75a9735 Finished Rowlet line 2024-02-28 00:25:58 -05:00
apion 3febee21b6 Changed increment of debug keybindings 2024-02-28 00:03:44 -05:00
apion c3a017687c Finished Gen VIII fossil mons 2024-02-28 00:01:05 -05:00
apion afd082c966 Added scaling/translation key binds to portrait view, enableable/disableable via config 2024-02-27 23:34:52 -05:00
apion a6a1f7b75b Added scaling/translation keybinds to summary menu 2024-02-27 22:00:10 -05:00
apion 72738a45e6 Made portraitScale, portraitTranslation, profileScale, and profileTranslation vars instead of vals in every model file 2024-02-27 21:46:44 -05:00
Apion ff4d9ae208 Merge branch 'gimmighoul_gholdengo' into 'main'
Add Gimmighoul, Gholdengo, Relic Coins and Gilded Chests

See merge request cable-mc/cobblemon!888
2024-02-28 02:03:37 +00:00
LilyandApion a87d522f6d Add Gimmighoul, Gholdengo, Relic Coins and Gilded Chests 2024-02-28 02:03:37 +00:00
apion 8a0076acb4 Start working on dragovish 2024-02-27 20:54:53 -05:00
apion f7e1def555 Fixed arctovish scaling and translations 2024-02-27 20:45:44 -05:00
apion c13f6ae627 Implemented Ferrothorn, fixed missing anim on Dragonair 2024-02-27 19:12:39 -05:00
Licious c24ab2049d Merge branch 'main' into ability-fix
# Conflicts:
#	CHANGELOG.md
2024-02-26 11:45:32 +00:00
Licious b7b1850a4e Clarify changelog. 2024-02-26 11:41:49 +00:00
Licious 8995c107f7 Fix abilities, add ability capsule & patch. 2024-02-26 11:38:22 +00:00
Hiroku dca6b5273d Merge branch 'FossilAssetUpdate2' into 'main'
New animation assets for fetuses

See merge request cable-mc/cobblemon!889
2024-02-26 07:57:15 +00:00
dhi_holo d6a412b91a tags
tags
2024-02-26 17:38:30 +10:00
JazzMcNade 2e8483cdc7 Corrected comment, fixed machine not dropping fossils when destroyed while not started. 2024-02-26 01:29:11 -06:00
dhi_holo 5984d7a126 Cups and Functions
Adds Masterpiece and Unremarkable Teacups (Sinistea evolution items), and makes Medicinal Leek, Bone, and Snowball work as the Leek, Thick Club, and Snowball held items.
Snowballs do have a small issue with being thrown when trying to give it to a Pokemon though, for someone cool to investigate.
2024-02-26 16:44:26 +10:00
dhi_holo 6d8e645092 Merge branch 'main' into MoreHoldItems 2024-02-26 15:03:45 +10:00
Hiroku 6b1c2e2074 Merge branch 'showdown_gen9dlc' into 'main'
Update Showdown with Gen9 DLC.

See merge request cable-mc/cobblemon!890
2024-02-26 03:52:34 +00:00
Segfault Guy 8af5b5e07a Update Showdown with Gen9 DLC. 2024-02-25 22:44:27 -05:00
Hiroku 7ae19ca774 Merge branch 'issue-763' into 'main'
Stop Rails from being Spawnable tiles

Closes #763

See merge request cable-mc/cobblemon!881
2024-02-26 03:13:27 +00:00
Dhyan PatelandHiroku 830f00553e Stop Rails from being Spawnable tiles 2024-02-26 03:13:27 +00:00
Tyzillion 55f0db2263 Implemented Lunatone, Solrock, Woobat, Swoobat, Sandile, Krokorok, Krookodile, Frillish, Jellicent, Cubchoo, Beartic, Deino, Zweilous, Hydreigon, Larvesta, Volcarona, Fomantis, Lurantis, Dreepy, Drakloak, Dragapult, Makuhita, Hariyama, Alolan Diglett, Alolan Dugtrio, and Alomomola.
Updated Diglett and Dugtrio models.
2024-02-25 19:38:27 -05:00
Tyzillion 411788a07e Implemented Turtonator, Stonjourner, Cufant, Copperajah, Budew, Roselia, and Roserade.
Updated Growlithe's model.
2024-02-24 21:52:09 -05:00
Tyzillion f6151041c5 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2024-02-24 21:51:27 -05:00
Hiroku c87f56c83f Merge branch 'lang-fixes' into 'main'
brought a couple inconsistent lang keys into consistency

See merge request cable-mc/cobblemon!887
2024-02-25 02:06:17 +00:00
tmetcalfe89 4478532bcb brought a couple inconsistent lang keys into consistency 2024-02-24 18:02:02 -08:00
Flarkinater f99168f1c3 Pokeball items no longer drift backwards when thrown directly overhead 2024-02-24 06:33:34 -05:00
Flarkinater adce1d8838 Fixed Pokemon not appearing when sent out from shoulder 2024-02-24 05:58:35 -05:00
Flarkinater e95c82b5af Greatly improved send-out location targeting 2024-02-24 05:16:44 -05:00
Flarkinater dd273ffef2 Added beam mode for sending out Pokemon with no delay 2024-02-23 19:18:11 -05:00
Hiroku 184348d6fa Merge branch 'lazy-psf' into 'main'
made the spawns lazy so we can ref the object's other properties without violating the lateinit

Closes #765

See merge request cable-mc/cobblemon!886
2024-02-23 23:31:03 +00:00
Hiroku 04d288ed7e Merge branch 'issue-760' into 'main'
Fix Medicinal Brews / Potions Stacking in Brewing Stand

See merge request cable-mc/cobblemon!876
2024-02-23 23:29:52 +00:00
Dhyan PatelandHiroku 0d5cce730e Fix Medicinal Brews / Potions Stacking in Brewing Stand 2024-02-23 23:29:51 +00:00
tmetcalfe89 3e01535203 license 2024-02-23 12:03:45 -08:00
tmetcalfe89 f0d99a9d83 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into lazy-psf 2024-02-23 11:42:40 -08:00
tmetcalfe89 b4eb46d632 it's lazy, but it can change 2024-02-23 11:42:35 -08:00
Hiroku 7e52336255 Merge branch 'InconsistentHpBarFix' into 'main'
InconsistentHpBarFix

Closes #761

See merge request cable-mc/cobblemon!875
2024-02-23 02:39:42 +00:00
Hiroku 2b40b5b689 Merge branch 'feather-dusting' into 'main'
Feathers

See merge request cable-mc/cobblemon!882
2024-02-23 02:39:01 +00:00
tmetcalfe89 da889f220b made the spawns lazy so we can ref the object's other properties without violating the lateinit 2024-02-22 14:55:29 -08:00
Lily ac65910380 updated the relic coin pouch rendering inside display case 2024-02-22 17:18:20 -05:00
Lily ba6847be9a Merge branch 'gimmighoul_gholdengo' into display_case
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlocks.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonSounds.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/item/group/CobblemonItemGroups.kt
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
#	common/src/main/resources/assets/cobblemon/sounds.json
2024-02-22 16:27:39 -05:00
Lily 5ddbcd1830 various changes to display case 2024-02-22 15:03:17 -05:00
Lily 47605646d0 Merge branch 'main' into display_case 2024-02-22 14:26:33 -05:00
Lily d9fdf089c2 fix display case z-fighting 2024-02-22 14:00:15 -05:00
dhi_holo 41db2a53ce Update en_us.json
just adding the feather tag to the translations so EMI stops complaining about it (and fixing a typo)
2024-02-22 11:28:58 +10:00
dhi_holo 85d8779818 The Sound of... Feathers?
it seems to be working correctly, so let's ship it out
2024-02-22 11:27:54 +10:00
Lily e9a405694c display case sounds 2024-02-21 18:47:20 -05:00
Hiroku d817ce1471 Merge branch 'gui-mod-compat-fixes' into 'main'
Client screen crash fixes with other mods

See merge request cable-mc/cobblemon!885
2024-02-21 11:44:38 +00:00
LiciousandHiroku ce09b66db5 Client screen crash fixes with other mods 2024-02-21 11:44:38 +00:00
Hiroku d0c666a20d Merge branch 'main' into 'feather-dusting'
# Conflicts:
#   CHANGELOG.md
2024-02-21 10:03:38 +00:00
Hiroku 04cef915e4 Merge branch 'tagging-youre-it' into 'main'
Big Tags

See merge request cable-mc/cobblemon!884
2024-02-21 09:50:44 +00:00
dhi_holo e50412443e Update CHANGELOG.md
Removed weird incorrect text from Type Gem changelog entry, mentioned additions from this branch.
2024-02-21 19:11:24 +10:00
dhi_holo 3fe1f87f18 apricorn trapdoor now doesn't look jank when opening
just changed the blockstate from the oak trapdoor style to the spruce trapdoor style, so the pokeball direction stays consistent when opened or closed
2024-02-21 19:08:38 +10:00
dhi_holo 5a0fc199ff Create feathers.json
item tag, since I forgot that would be smart to have
2024-02-21 17:35:07 +10:00
dhi_holo beb769c2a5 Update CobblemonItemGroups.kt
small tweak to how the items are placed for gaurenteed consistency
2024-02-21 17:31:29 +10:00
dhi_holo a7b6fae4ed gems, fang, claw, and armors get tagged
Type Gems are now considered held items, and four evolution items are considered evolution items (by tags)
2024-02-21 17:28:00 +10:00
dhi_holo af2ff7bbfa Gems
Type Gems given an item tag, and moved from Evolution Items to Archeology and Held Items
2024-02-21 17:11:17 +10:00
dhi_holo 4f3575b2c6 Poke Ball Materials and Bud Item Tag
adds the tumblestone clusters and buds to the item tags, and adds fire stone ore to each ore tag, but primarily

Redoes every Poké Ball recipe (besides Master) to use tags to handle the tier material, allowing datapacks to easily add alternate recipes besides Copper, Iron, Gold, or Diamonds
2024-02-21 16:41:41 +10:00
dhi_holo 8555168a6a Undoing commit "Tags on top of Tags"
Moving it to a new branch, so just removing it from here so my new changes don't conflict later
2024-02-21 15:41:48 +10:00
dhi_holo 98c248ef13 corrections
renaming some stuff to be prepared for the next step of this insane idea
2024-02-21 15:34:20 +10:00
dhi_holo 4a2c69d47c Tags on top of Tags
Added a very large amount of tags.
The different tiers of Poké balls, also the Apricorn balls so it's easier for people to see what balls count for that advancement, different healing and battle item types, some evolution item sets which made sense to make tags (may add more later, these ones were just the obvious ones to make thing easier for future), the three colours for tumblestones, machine blocks, as well as adding the fence gate item tag, and adding the new tumblestone stuff to the pickaxe tag (although they can still be mined with an axe, probably something that needs fixing)

Mod loader tags were not tested on Forge, due to a crash involving CobblemonEntities, but Fabric works all nicely
2024-02-21 15:29:55 +10:00
Tyzillion 1b5c0be975 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2024-02-20 23:25:41 -05:00
dhi_holo 5924398eff Update CobblemonItemGroups.kt
soothe bell to creative tab
2024-02-21 10:47:10 +10:00
dhi_holoandPlastered_Crab a08855ab37 Heal and Harm
Added translations for the battle text of Dry Skin, Cheek Pouch, Earth Eater, Icy Body, Volt Absorb, Water Absorb, and Sand Tomb.
2024-02-20 16:09:52 -08:00
Plastered_Crab 91abe39cdd Merge remote-tracking branch 'origin/MoreHoldItems' into MoreHoldItems
# Conflicts:
#	CHANGELOG.md
2024-02-20 16:07:49 -08:00
Plastered_Crab ad8aab7c19 - Added Soothe Bell 2024-02-20 16:06:45 -08:00
Plastered_Crab aa6b196c29 Merge branch 'main' into MoreHoldItems
# Conflicts:
#	common/src/main/resources/data/minecraft/tags/blocks/mineable/pickaxe.json
#	common/src/main/resources/data/minecraft/tags/items/decorated_pot_sherds.json
2024-02-20 15:58:50 -08:00
dhi_holo c23cb644d9 Update CHANGELOG.md
grr evil file
2024-02-21 09:43:33 +10:00
dhi_holo a8b12cfca3 Feathers
Adds the six EV Feathers, hopefully they work first try :)
2024-02-21 09:32:05 +10:00
dhi_holo 5268447fa3 could've sworn I pushed these yesterday
placeholder particles for balls which aren't getting particles yet
2024-02-21 09:11:07 +10:00
Apion b489e747bb Merge branch 'type_gem' into 'main'
added type gems

See merge request cable-mc/cobblemon!880
2024-02-20 13:22:41 +00:00
Segfault Guy acf467c8a3 Track battle time. 2024-02-19 22:51:16 -05:00
Lily 08f957e33b Update CHANGELOG.md 2024-02-19 21:32:30 -05:00
Lily e17d38c53a added type gems 2024-02-19 21:24:29 -05:00
Segfault Guy 0ff5b95c44 Hello, I'm the Interpreter critic. I refactor it so you don't have to! 2024-02-19 21:12:51 -05:00
dhi_holo 818b39e945 Dusky
Apparently missed this one

But why do Ancient Feather, Wing, Jet, Leaden, Gigaton no worky??
(remaining unimplemented: cherish, dream, beast, origin)
2024-02-20 12:08:29 +10:00
apion 0397e39735 I have become the very thing I swore to destroy (Pushing a license to main D:) 2024-02-19 20:18:55 -05:00
Apion 6ca1d23f45 Merge branch 'no_more_pick_block' into 'main'
disallow pick-stacking blocks that are part of a multiblock structure to prevent weird issues with NBT copying

See merge request cable-mc/cobblemon!874
2024-02-19 23:38:26 +00:00
dhi_holo 30666349a1 [WIP] Ancient Send Outs
base 7, great, and ultra work right, but the heavy/wing sets have broken send out flashes (besides ancient heavy specifically)
Just pushing because it's 11pm and it's honkshnoomemememememe time
2024-02-19 23:09:17 +10:00
JazzMcNade 44def2be76 Fossil is returned if the machine is broken before completion. Restoration Block now uses glass sounds. Mobs no longer attempt to pathfind through the restoration tank. 2024-02-17 20:37:05 -06:00
JazzMcNade 507f70c2d5 Fixed tank missing blockstates, fixed hoppers inserting into tank 2024-02-17 18:46:02 -06:00
JazzMcNade d91118d05f Updated helix fossil item image 2024-02-17 14:17:34 -06:00
JazzMcNade 07d8e6ed09 Adjusted fetus offset and scaling 2024-02-16 21:20:09 -06:00
Lily fb34d4bd23 suppressed gimmighoul's desire to be a necromancer 2024-02-16 20:50:03 -05:00
Paul 6ca1337ff9 Merge branch 'gimmighoul_gholdengo' into 1.5_Structures 2024-02-17 10:29:18 +10:00
Tyzillion 98106cad12 Implemented Darumaka line, and Petilil line with Hisuian counterparts. 2024-02-16 16:14:43 -05:00
Lily 0d344337dd Merge branch 'main' into display_case
# Conflicts:
#	.gitignore
#	CHANGELOG.md
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
2024-02-16 11:55:15 -05:00
Hiroku 64d160020b Merge branch 'issue-745' into 'main'
Sobble Line Can Swim and Breathe Underwater

Closes #745

See merge request cable-mc/cobblemon!878
2024-02-16 06:36:50 +00:00
Dhyan PatelandHiroku fb4c80f68c Sobble Line Can Swim and Breathe Underwater 2024-02-16 06:36:50 +00:00
Paul 3d27681aaa Randomize Pokémon spawn positions and position gimmighoul reveals better 2024-02-16 16:31:00 +10:00
Paul 2b5433f9da Added hit effect for pokemon receiving battle damage 2024-02-16 15:37:52 +10:00
Paul 352202203a Merge branch 'gimmighoul_gholdengo' into 1.5_Structures 2024-02-16 15:04:51 +10:00
Paul 62cfbd7087 Licenses 2024-02-16 15:03:53 +10:00
Paul 5a64e8ea1b Animated the trap chest opening 2024-02-16 15:03:15 +10:00
Paul 8dc9863a5d Conflict resolution and cleanup 2024-02-16 14:39:22 +10:00
JazzMcNade 9bad141c3f Added remaining fetus animations, updated embryo animations 2024-02-15 21:57:42 -06:00
Myslippy 9280258413 Implemented most of the Fossil & Ruin Structures 2024-02-16 03:13:32 +00:00
Paul 51a11163dd Merge remote-tracking branch 'origin/main' into gimmighoul_gholdengo
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlocks.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonSounds.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/events/CobblemonEvents.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/FossilTubeRenderer.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/bedrock/animation/BedrockStatefulAnimation.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/item/group/CobblemonItemGroups.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/Species.kt
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
#	common/src/main/resources/assets/cobblemon/sounds.json
2024-02-16 12:43:35 +10:00
Paul fe8e4dcaff Improved Pokémon pathfinding so they don't run through cactus and such so recklessly 2024-02-16 12:24:58 +10:00
Paul e0bd6766fc Fixed basculin stripe spawning 2024-02-16 11:37:16 +10:00
Paul 4da800d396 Fixed Arbok patterns not being used properly in spawn files 2024-02-16 11:19:24 +10:00
JazzMcNade f3246ae14a Updated fossil sprites, refactored Galar fossil names 2024-02-15 01:33:11 -06:00
Flarkinater 82548b5383 Pokémon recoil when hit by a ball 2024-02-13 22:48:27 -05:00
Segfault Guy 8d7ebeef4f Merge branch 'main' into illusion 2024-02-13 21:15:49 -05:00
Lily d5ad84a495 refactored PositioningType 2024-02-13 19:02:53 -05:00
Flarkinater ad73202e17 Adjusted timing on breaking free animation + sound 2024-02-13 18:50:08 -05:00
Tyzillion 1560b142d2 Updated quirks for implemented Pokemon. 2024-02-13 08:22:50 -05:00
JazzMcNade 47f87b1be3 Rearranged pokemon creation so that currentHealth is assigned after ivs and evs are set 2024-02-13 00:08:04 -06:00
Flarkinater 2965a04742 Implemented existing "break free" animation when capture fails 2024-02-12 23:02:55 -05:00
Lily b01086270a fix positioning on certain items that use block entity renderers 2024-02-12 19:18:18 -05:00
Lily da6a09c942 disallow pick-stacking blocks that are part of a multiblock structure to prevent weird issues with NBT copying 2024-02-12 17:40:39 -05:00
Lily 8d5eb5883d gilded chests now get blocked with blocks above them like regular chests do 2024-02-12 14:57:24 -05:00
Tyzillion d5fa693f43 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen1/BlastoiseModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen1/ChanseyModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen1/DragonairModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen1/DratiniModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen1/ElectabuzzModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen2/ElekidModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen3/IllumiseModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen3/NumelModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen3/VolbeatModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen4/CarnivineModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen4/DrifblimModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen4/DrifloonModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen5/ChandelureModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen5/LampentModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen5/LitwickModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen9/LechonkModel.kt
#	common/src/main/resources/assets/cobblemon/bedrock/pokemon/animations/0009_blastoise/blastoise.animation.json
#	common/src/main/resources/assets/cobblemon/bedrock/pokemon/models/0009_blastoise/blastoise.geo.json
#	common/src/main/resources/assets/cobblemon/particles/snowstorm.json
2024-02-11 12:52:08 -05:00
JazzMcNade 0d12bf1190 Relic Coins Sacks can be bartered with Piglins for loot.
Can always remove this if undesired or make it a tag, change the item, etc.
2024-02-10 21:23:05 -06:00
Nick 4217938ada Merge branch 'move-animations' into 'main'
Simplistic move animations

See merge request cable-mc/cobblemon!871
2024-02-10 22:51:29 +00:00
HirokuandNick 4c5f88db06 Simplistic move animations 2024-02-10 22:51:29 +00:00
Lily 4f773f63cb fix hopper dupe bug 2024-02-09 22:04:01 -05:00
Hiroku cfd743c4c0 Merge branch 'armor_trims' into 'main'
oops

See merge request cable-mc/cobblemon!872
2024-02-10 02:11:35 +00:00
Lily 1bbfc6dce5 Merge branch 'main' into armor_trims 2024-02-09 21:06:33 -05:00
Lily 6f2235c751 i swear if this doesn't work 2024-02-09 21:04:59 -05:00
Hiroku 50a0f2d858 Merge branch 'armor_trims' into 'main'
Added Automaton armor trim

See merge request cable-mc/cobblemon!868
2024-02-10 01:37:25 +00:00
Hiroku 27210512f6 Oops 2024-02-10 01:25:08 +00:00
Hiroku 53aa124de6 Merge branch 'main' into 'armor_trims'
# Conflicts:
#   CHANGELOG.md
2024-02-10 01:24:45 +00:00
Apion a18b54849f Merge branch 'FetusAnimsUpdate' into 'main'
Many updates, asset changes, and refactors for the fossil machine

See merge request cable-mc/cobblemon!863
2024-02-10 01:24:04 +00:00
Hiroku c868c63a5f Merge branch 'whatsy/evo_stone_blocks' into 'main'
added nether fire stone ore

See merge request cable-mc/cobblemon!867
2024-02-10 01:23:41 +00:00
Lily 31df7c92f4 remove leftovers from trim materials 2024-02-09 20:00:36 -05:00
Lily 3f3ae74535 update .gitignore 2024-02-09 19:58:44 -05:00
Lily 7429fea802 fixed crash on dedicated servers (again) + made cases compatible with hoppers 2024-02-09 19:46:23 -05:00
Hiroku 3b65d1967e Merge branch 'main' into 'whatsy/evo_stone_blocks'
# Conflicts:
#   CHANGELOG.md
2024-02-10 00:16:06 +00:00
Paul f30b15003f Remove lingering oceanic trim references 2024-02-10 10:05:10 +10:00
Hiroku c4c1b7ac27 Merge branch 'main' into 'armor_trims'
# Conflicts:
#   CHANGELOG.md
2024-02-09 23:56:54 +00:00
Paul ea9287cfb5 Fixed langs on interaction GUIs 2024-02-10 09:55:31 +10:00
Hiroku 02f845af5c Merge branch 'amo/sendout-upgrade' into 'main'
Added generic bedrock entity system, updated molang for fix, added test evo...

See merge request cable-mc/cobblemon!869
2024-02-09 23:11:04 +00:00
Lily ac5cd47715 multiple display case bugfixes 2024-02-09 17:59:57 -05:00
Paul 3bb3a00cef Renamed InteractionGUICreationEvent to PokemonInteractionGUICreationEvent 2024-02-10 08:28:31 +10:00
Paul f1ae4163c9 Cleaned up transition portion of PokemonRender#render and removed glow effect we don't want anymore 2024-02-10 08:27:31 +10:00
Paul 05957f2106 Renamed GenericBedrockModelRepository to GenericBedrockEntityModelRepository for clarity 2024-02-10 08:03:50 +10:00
Paul 4b9ea1d4cd Use an entity renderer for GenericBedrockEntities, obviously 2024-02-10 08:03:12 +10:00
Lily 78dff75db9 Update CHANGELOG.md 2024-02-09 16:46:56 -05:00
Lily dbab6404a1 Update CHANGELOG.md 2024-02-09 16:45:48 -05:00
Tyzillion 9901d39f9b Implemented Hisuian Sneasel, Sneasler, and Tropius. 2024-02-09 14:46:18 -05:00
Paul e5c4240ae0 Merge remote-tracking branch 'origin/main' into amo/sendout-upgrade
# Conflicts:
#	CHANGELOG.md
#	forge/src/main/kotlin/com/cobblemon/mod/forge/client/CobblemonForgeClient.kt
2024-02-09 20:22:27 +10:00
Paul 317112f9bb Cleanup 2024-02-09 19:38:32 +10:00
JazzMcNade c635a1d331 Removed duped block tag entry 2024-02-09 01:08:35 -06:00
Paul 58fda2e261 Changelog 2024-02-09 16:22:22 +10:00
JazzMcNade cf2173a281 Opening a gilded chest now aggros piglins 2024-02-09 00:15:55 -06:00
Paul 3b442d387a licenses good, pipeline errors bad 2024-02-09 16:04:53 +10:00
JazzMcNade 710d37f453 Added piglin related tags for glided chests and relic coin related items 2024-02-08 23:52:36 -06:00
Paul 2b575c888f Disable evo effect since it's not done yet 2024-02-09 14:15:58 +10:00
Paul 6e5e572412 Fixed some ball effects occurring even when snap-recalling before send out completes 2024-02-09 14:14:55 +10:00
Lily ce87d0dc48 Merge branch 'main' into whatsy/nether_fire_stone
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/item/group/CobblemonItemGroups.kt
2024-02-08 23:10:14 -05:00
Lily d43c91129c implemented nether fire stone ore 2024-02-08 23:02:26 -05:00
Lily d66b9c8d3b removed unused assets, oceanic pattern to be redone/possibly scrapped 2024-02-08 22:51:05 -05:00
Lily 1fb3416211 implemented the display case 2024-02-08 22:46:16 -05:00
JazzMcNade dc37b381a0 Review Changes: Refactored part of setStack into its own function 2024-02-07 21:17:56 -06:00
Lily 1206aaaf13 some updated textures 2024-02-07 21:13:12 -05:00
JazzMcNade 95bcb9a7b8 Most of the requested review changes 2024-02-06 23:28:15 -06:00
Lily c7d879ec57 removed custom trim materials, added automaton and oceanic trim patterns 2024-02-06 19:03:37 -05:00
Tyzillion f49f2a7305 Implemented Amaura, Aurorus, Hisuian Voltorb, Hisuian Electrode, Sentret, Furret, Qwilfish, Hisuian Qwilfish, and Overqwil.
Updated Dracovish model.
2024-02-06 14:30:54 -05:00
Tyzillion b0e9c1ab28 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2024-02-06 14:22:32 -05:00
Nick d5752982d7 Merge branch 'crystal_block' into 'main'
internal changes to tumblestones

See merge request cable-mc/cobblemon!865
2024-02-06 00:41:19 +00:00
Lily f1439ec724 internal changes to tumblestones 2024-02-05 19:18:53 -05:00
Nick 0cac5714ac Merge branch 'sherd_updates' into 'main'
added a missing sherd + added sherds to the vanilla ingredients tab

See merge request cable-mc/cobblemon!864
2024-02-05 22:45:46 +00:00
Lily 8529bb119f added a missing sherd + added sherds to the vanilla ingredients tab 2024-02-05 17:24:44 -05:00
JazzMcNade ac1c7d8b78 Mobs can now pathfind around Gilded Chests 2024-02-04 20:00:20 -06:00
JazzMcNade b68b3ad55e Fossil Machine now stores return items of natural materials fed via hopper. Return items can be retrieved via hopper or by breaking the machine. Restoration Tank block can now be place on hoppers. 2024-02-04 18:35:23 -06:00
Tyzillion dec5151eb8 /gradlew updateLicenses go brrrrrrrrr. 2024-02-04 00:11:14 -05:00
Hiroku 70c6b74f0f Merge branch 'pottery-sherds' into 'main'
Implemented pottery sherds

See merge request cable-mc/cobblemon!861
2024-02-04 05:00:54 +00:00
Tyzillion 196edc2711 Updated animations for Happiny, Carnivine, Litwick, Lampent, Chandelure, Lechonk, and Falinks.
Updated model for Lechonk, Drifloon, and Drifblim.
Fixed Drifloon eyes.
2024-02-03 23:35:35 -05:00
Hiroku 5cb7a51163 Merge branch 'test-build-rename' into 'main'
Made it so when a snapshot build is built the commit hash and branch is included

See merge request cable-mc/cobblemon!862
2024-02-04 04:27:50 +00:00
apion a68b6928aa Made it so when a snapshot build is built the commit hash and branch is included 2024-02-03 23:26:32 -05:00
Apion 0c26cb026c Remove extra braces 2024-02-04 03:57:40 +00:00
Hiroku 6078e22b14 Merge branch 'ball-entity-names' into 'main'
Empty Poké Ball Entity Name

Closes #755

See merge request cable-mc/cobblemon!852
2024-02-04 03:52:05 +00:00
Apion cb1226013d Removed unneeded access widener 2024-02-04 03:47:39 +00:00
apion 0c8318d317 Licenses :P 2024-02-03 22:46:04 -05:00
apion 8d80bcfd6b Fixed remaining patterns 2024-02-03 22:45:26 -05:00
apion cfd4fa1785 Fix dome, helix, and sus patterns 2024-02-03 22:35:56 -05:00
apion 86bd70177c Sherds work :O 2024-02-03 22:28:57 -05:00
Tyzillion 18015a26fd Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2024-02-03 21:10:07 -05:00
Tyzillion aa296a79a9 Added placeholder walk animations to Zoroark. Updated animations for Galarian Meowth, Galarian Rapidash, Venonat, Venomoth, Phanphy, Donphan, Dratini, Dragonair, Chansey, Blissey, Volbeat, Illumise, Numel, Drifloon, and Drifblim.
Updated model and texture for Danphan.
Updated model for Illumise, Dratini, Dragonair, Drifloon, and Drifblim.
Added cries for all Meowth variants.
Added missing blink to Psyduck.
2024-02-03 21:09:04 -05:00
Lily 92dd85643e Merge branch 'amo/sendout-upgrade' into gimmighoul_gholdengo
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/events/CobblemonEvents.kt
2024-02-03 19:45:47 -05:00
Lily 8849de1bfd Merge remote-tracking branch 'origin/amo/sendout-upgrade' into amo/sendout-upgrade
# Conflicts:
#	common/src/main/resources/assets/cobblemon/bedrock/particles/balls/capture/capturestar.particle.json
#	common/src/main/resources/assets/cobblemon/bedrock/particles/balls/capture/hisui/hisuicapturestar.particle.json
2024-02-03 19:44:41 -05:00
Nick ce668b31ff Merge branch 'dynamic-lighting-compat' into 'main'
Dynamic lighting compat

See merge request cable-mc/cobblemon!860
2024-02-03 21:49:28 +00:00
LiciousandNick 943d6e0c55 Dynamic lighting compat 2024-02-03 21:49:27 +00:00
apion 7d82a2f7c8 Start working on injecting sherd textures, bunch of immutable maps need to not be immutable 2024-02-02 20:53:04 -05:00
Lily 782ba524df fossil block break speed + loot table 2024-02-02 20:24:07 -05:00
apion c571d79035 Added sherd tag 2024-02-02 19:48:31 -05:00
Hiroku 054c22b926 Merge branch 'inkay-grumm' into 'main'
Inkay: Add 2nd easter egg nickname evo

See merge request cable-mc/cobblemon!859
2024-02-02 22:20:48 +00:00
KyozennoandHiroku d2fce5edb5 Inkay: Add 2nd easter egg nickname evo 2024-02-02 22:20:48 +00:00
jeffw773 cba32b7443 - Adding Tweaked textures for fossil embryo goopies that are a tad darker in case they are liked better 2024-02-02 13:32:56 -08:00
JazzMcNade 4a81c24a3d Hopefully less mobs will get hung up on the Monitor Block 2024-02-02 01:03:41 -06:00
Lily 776e629850 updated CobblemonItemTags and fixed hand animation not playing on pure client instances 2024-02-01 21:38:20 -05:00
Paul 9afb8b04c2 Fixed edge case in FPS particles 2024-02-02 11:54:12 +10:00
Lily 2a349697b4 colored gilded chest variants :3 2024-02-01 20:28:12 -05:00
Tyzillion a4055e6206 Been a minute since I've last added stuff...
Updated models and textures for Omanyte, Squirtle, Rowlet line, Psyduck, Dusknoir, Swinub, and Piloswine.

Implemented Aron, Gossifleur, Zorua, Hisui Zorua, Hippopotas, Tyrunt, Anorith, and Archen line.
2024-01-31 20:58:23 -05:00
Lily 03bda4e27d fixes to be compatible with the updated held item event 2024-01-30 17:33:51 -05:00
Lily 5d8abbd4c7 Merge branch 'main' into gimmighoul_gholdengo
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/Pokemon.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/evolution/adapters/CobbledRequirementAdapter.kt
2024-01-30 16:51:56 -05:00
Lily 6b167a7a17 gilded chest variants are implemented, waiting for textures 2024-01-30 16:46:22 -05:00
Tyzillion 5c64bc94ff Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-01-30 13:32:04 -05:00
Nick 90c74eddc8 Merge branch 'does_this_qualify_as_grafting' into 'main'
Implement #748 Allow players to plant apricorn sprouts on leaves

Closes #748

See merge request cable-mc/cobblemon!854
2024-01-30 17:53:47 +00:00
Nick 3600178d3b Merge branch 'lefties-not-the-store-pls-no-copyright' into 'main'
Adds leaves_leftovers item tag.

See merge request cable-mc/cobblemon!858
2024-01-30 17:52:26 +00:00
Apion 66d8a01917 Merge branch 'hold-my-event' into 'main'
Implement HeldItemEvent. Remove unnecessary setter method for already public var.

See merge request cable-mc/cobblemon!857
2024-01-29 23:55:57 +00:00
Licious 68e32b21b5 Adds leaves_leftovers item tag. 2024-01-29 23:21:47 +00:00
Licious 670882bb4d Implement HeldItemEvent. Remove unnecessary setter method for already public var. 2024-01-29 23:13:27 +00:00
apion d36c24075c Fixed rotations? 2024-01-29 16:48:21 -05:00
Lily d1a8122296 fixed rotation for gilded chest as well 2024-01-29 12:44:41 -05:00
Lily a8e6e684ab updated relic_coin_pouch.png 2024-01-29 12:22:55 -05:00
Lily 188fc2b5d9 fixed inconsistencies between the actual value of the facing property and the direction the coin pouch was facing 2024-01-29 12:19:50 -05:00
dhi_holo 9c0708651f Cobble Particles
Azure, Slate, Citrine, Verdant, Roseate
2024-01-29 17:09:34 +10:00
JazzMcNade 1b3bb3b5bc Ownership message can now identify players who are currently not connected to the server. 2024-01-29 01:08:57 -06:00
dhi_holo cd03ef68c3 Gen 3 4-7, Gen 4 1-2
Dive, Nest, Repeat, Timer, Heal, Quick
2024-01-29 17:03:20 +10:00
dhi_holo 69716b5050 Gen 2 7-9 and Gen 3 1-3
Friend, Love, Moon, Luxury, Premier, Net
2024-01-29 16:28:40 +10:00
dhi_holo 015deb4eeb Gen 2 1-6
Particles for Park, Sport, Fast, Level, Lure, Heavy Balls
2024-01-29 15:07:53 +10:00
dhi_holo 96023077ad Gen 1 Full
Should fix all of the remaining issues with the Gen 1 particles
2024-01-29 13:09:31 +10:00
JazzMcNade d96c68b5b4 All monitor blockstates now use the off state's particle texture. 2024-01-28 21:05:22 -06:00
JazzMcNade dc27867502 Dry stuff for markedRemoved (related to stopping sounds). Loop sound stops when the monitor block is destroyed. 2024-01-28 20:58:29 -06:00
JazzMcNade bfbea377c1 Monitor now switches to the OFF state if the fossil pokemon is retrieved while machine was in the protected state 2024-01-28 19:55:30 -06:00
dhi_holo f5954fcb33 Gen 1 Poomfs
Ultra, Master, and Safari complete the 5
2024-01-29 11:47:23 +10:00
JazzMcNade eaa909a9f2 Fossilmachine's owner now persists when the machine is loaded/unloaded and is now based on the user's uuid 2024-01-28 19:28:51 -06:00
dhi_holo 5ba4d460b1 great error
should mean the poke ball and great ball particles are all functional, and I can start working on the other balls!
2024-01-29 11:01:51 +10:00
dhi_holo 09143b7ad6 the identifiers need the directory
atleast, that's how they were, so let's redo that
2024-01-29 10:48:49 +10:00
dhi_holo aa1e14b4ac Merge branch 'main' into amo/sendout-upgrade 2024-01-29 10:24:07 +10:00
dhi_holo 0f29cdeaf9 update pokeball and greatball particles
lets see if this works
2024-01-29 10:15:41 +10:00
JazzMcNade b976b9dd68 Fossil machine now stops its loop sound when the machine finishes or is destroyed. 2024-01-28 16:51:40 -06:00
Tyzillion 2bc2e3f020 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	common/src/main/resources/data/cobblemon/species/generation8/basculegion.json
2024-01-28 12:36:36 -05:00
dhi_holo fa94ca8033 The Origin Master
Origin Ball is now Guaranteed, like the Master Ball, because that's the intended behaviour according to Chroma
2024-01-27 19:07:51 +10:00
dhi_holo f206352b6e I am a genius
origin ball go entity
2024-01-27 18:28:34 +10:00
dhi_holo cdee981933 Origin Textures
Tried fixing the Origin Ball not using the right texture. Only worked for the item texture, entity texture doesn't seem to load still
2024-01-27 15:06:16 +10:00
dhi_holo f2fc32b6a9 Updated Catch Particles
Up to date as of time of commit, mostly looking good, some minor issues to be fixed up.
2024-01-27 14:04:26 +10:00
Nick f46b581327 Merge branch 'new-model-repo' into 'main'
Added a bedrock model repo for miscellaneous models

See merge request cable-mc/cobblemon!855
2024-01-26 23:16:16 +00:00
ApionandNick ff1241304b Added a bedrock model repo for miscellaneous models 2024-01-26 23:16:16 +00:00
Lily 7a15e6b004 Merge remote-tracking branch 'origin/amo/sendout-upgrade' into amo/sendout-upgrade
# Conflicts:
#	CHANGELOG.md
#	common/src/main/resources/assets/cobblemon/bedrock/particles/balls/capture/hisui/hisuicapturestar.particle.json
2024-01-26 17:46:34 -05:00
Lily 6ee6beddeb capture particles... again 2024-01-26 17:45:31 -05:00
Lily b92960da77 Merge branch 'main' into amo/sendout-upgrade 2024-01-26 17:29:13 -05:00
dhi_holo dd746e6775 Merge branch 'main' into ball-entity-names 2024-01-22 16:39:51 +10:00
dhi_holo 99618184e7 Heal and Harm
Added translations for the battle text of Dry Skin, Cheek Pouch, Earth Eater, Icy Body, Volt Absorb, Water Absorb, and Sand Tomb.
2024-01-22 16:18:55 +10:00
dhi_holo fcdff126fd Merge branch 'main' into MoreHoldItems 2024-01-22 15:22:31 +10:00
Licious 44956ec6da Implement #748 Allow players to plant apricorn sprouts on leaves 2024-01-21 15:03:53 +00:00
Hiroku 83e7a1968a Merge branch 'can-moe-scrape' into 'main'
Blueberry allergy fix

See merge request cable-mc/cobblemon!851
2024-01-19 23:59:49 +00:00
jeffw773 3b285cc8bd - Changes to Relic Coin sack default placement direction for Structures 2024-01-19 10:51:21 -08:00
Paul 553ecc8509 Various corrections to pokeballs, including a fix for the delayed bounce animation 2024-01-19 13:48:58 +10:00
Paul 7b0d488b7c Improved fetus transitions 2024-01-19 12:34:50 +10:00
jeffw773 4dead98e6b - Pesky little chest Gimmieghouls spawn facing the direction of the chest block now 2024-01-18 18:16:09 -08:00
jeffw773 db36f8da2a - Gimmieghoul Chest and Gilded Chest now face the player when placed down 2024-01-18 16:07:45 -08:00
JazzMcNade 3f7a5e1318 Fossils in the analyzer block are now have a 1 item spaced gap between them for visibility. 2024-01-17 19:52:39 -06:00
JazzMcNade ce7485f557 Adjusted analyzer block's fossil positioning to avoid clipping and match the base item's orientation. 2024-01-17 01:09:08 -06:00
JazzMcNade b5ca5c29d4 Fixed an issue in which if the machine finished and then was unloaded, breaking the machine would not release the pokemon. 2024-01-17 00:13:24 -06:00
JazzMcNade 43f60da22e Refactored Monitor blockstate into a single enum driven screenid. Protection time of the fossil machine is now saved into nbt. 2024-01-16 23:32:11 -06:00
JazzMcNade 0102c8b392 Updated Restoration tank textures and connector model 2024-01-16 00:58:29 -06:00
dhi_holo 3a448071d7 Merge branch 'main' into MoreHoldItems 2024-01-16 11:38:51 +10:00
JazzMcNade 6bb5c5dadf Fix for Blockupdates interrupting the fetus animation, added phase offset for fetus animations (for real). 2024-01-14 22:18:41 -06:00
JazzMcNade dd21fe2ea3 Implemented locked state visual in the monitor block 2024-01-14 03:56:15 -06:00
JazzMcNade 656c46817a Implemented Resoration_tank's animated texture when the machine is currently running 2024-01-14 02:01:38 -06:00
JazzMcNade a373f437fa Refactored fossil machine block files out of fossil directories 2024-01-13 21:22:23 -06:00
JazzMcNade 0fe3637034 Deep rename of fossil_tube to restoration_tank, fossil_monitor to monitor, fossil_compartment to fossil_analyzer. Updated fossil machine component block assets. 2024-01-13 20:44:58 -06:00
Paul 7215860d74 Merge remote-tracking branch 'origin/gimmighoul_gholdengo' into gimmighoul_gholdengo 2024-01-14 08:08:04 +10:00
Paul dc899ffc1b Fixed gimmighoul stuff for realsies this time 2024-01-14 08:07:49 +10:00
Lily 88fe55bbb9 pouch blocks and bugfixes 2024-01-13 16:23:39 -05:00
dhi_holo 4b4be0e2cc Merge branch 'main' into ball-entity-names 2024-01-13 16:14:43 +10:00
dhi_holo 3e673ae8f0 Don't Forget
I'll keep my kneecaps today, thanks
2024-01-13 16:12:02 +10:00
dhi_holo 4b3b7443d3 Empty Poké Ball
Names the Empty Pokeball entity to `Empty Poké Ball`, so it has a name.

Closes #755, possibly. I'm not sure if this entity name is the same kind of entity name as the report, as the order of words is different, but yeah.
2024-01-13 16:10:21 +10:00
Hiroku 70c1b42ede Merge branch 'non-entity-spawning' into 'main'
Abstracted spawning so it could be made to support non-entity spawning

Closes #729

See merge request cable-mc/cobblemon!850
2024-01-13 05:58:32 +00:00
MoeBoy76 b2048bb66f git hates me [skip-ci] 2024-01-13 16:48:45 +11:00
MoeBoy76 9956f1c159 dipplin fix [skip-ci] 2024-01-13 14:14:43 +11:00
MoeBoy76 25857dafc5 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into can-moe-scrape
# Conflicts:
#	common/src/main/resources/data/cobblemon/species/generation9/dipplin.json
2024-01-13 14:10:22 +11:00
MoeBoy76 80345b3810 blueberry allergy fix [skip-ci] 2024-01-13 14:01:59 +11:00
JazzMcNade d4dc24ec49 Updated fossil item sprites. 2024-01-12 20:52:32 -06:00
Paul 2209ee10b6 Licenses 2024-01-13 12:05:07 +10:00
Paul a91aa9835c interop improvement on PokemonProperties.parse 2024-01-13 11:48:29 +10:00
Paul 0e980a846c Abstracted spawning so it could be made to support non-entity spawning 2024-01-13 11:36:31 +10:00
Paul 3d3c421b5c Fixed syncing issues with species feature providers 2024-01-12 18:15:10 +10:00
JazzMcNade f54bbe754f Adjust Aerodactyl's y offset inside the fossil tube 2024-01-11 21:31:24 -06:00
Apion 92fff27b4e Merge branch 'can-moe-scrape' into 'main'
Add gen 9 DLC movesets

See merge request cable-mc/cobblemon!846
2024-01-12 03:16:58 +00:00
MoeBoy76andApion 255874cbe4 Add gen 9 DLC movesets 2024-01-12 03:16:58 +00:00
Apion 824bc1b080 Merge branch 'botanypots' into 'main'
Botanypots integration - with additional fixes

See merge request cable-mc/cobblemon!844
2024-01-12 03:12:38 +00:00
GregerandApion 3ee55f24d8 Botanypots integration - with additional fixes 2024-01-12 03:12:38 +00:00
Lily c3379ddf21 fix crash with fossil machine on servers 2024-01-11 17:48:45 -05:00
jeffw773 5983b17e87 - Added in Retro's adjusted capture animation JSON for regular ball and ancient ball 2024-01-11 08:31:24 -08:00
Hiroku 27986d28a7 Merge branch 'musical-blocks' into 'main'
Musical Blocks

See merge request cable-mc/cobblemon!845
2024-01-11 13:06:09 +00:00
Hiroku 8807f2134e Merge branch 'main' into 'musical-blocks'
# Conflicts:
#   CHANGELOG.md
2024-01-11 11:31:10 +00:00
Hiroku d74b1228c1 Merge branch 'new_poison_touch_fix' into 'main'
- Fixed battle lang for Poison Touch in a much simpler way

See merge request cable-mc/cobblemon!849
2024-01-11 11:30:38 +00:00
Hiroku a3dcfe8bfb Merge branch 'main' into 'main'
Update PokemonEntity to be an open class.

See merge request cable-mc/cobblemon!847
2024-01-11 11:24:10 +00:00
jeffw773 8725ef2b54 - Fixed battle lang for Poison Touch in a much simpler way 2024-01-10 19:22:47 -08:00
Tyzillion 3c2cfa4ffc Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-01-10 18:46:04 -05:00
Pebbles 3074b067dc Update PokemonEntity to be an open class. 2024-01-10 19:08:23 +00:00
Lily 8d0ee6dd6f more particle changes 2024-01-10 11:44:12 -05:00
JazzMcNade a1c1c9bc90 Updated Fossil Tube textures. Fluid opacity increased, Line removed from tank. 2024-01-10 00:41:45 -06:00
MoeBoy76 5e52d350c1 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into can-moe-scrape
# Conflicts:
#	CHANGELOG.md
2024-01-10 12:25:21 +11:00
MoeBoy76 e3ad34e023 changelogs [skip-ci] 2024-01-10 12:23:30 +11:00
MoeBoy76 f308918fd1 update Z species for gen 9 movesets 2024-01-10 12:19:26 +11:00
MoeBoy76 82a8257fa9 update Y species for gen 9 movesets 2024-01-10 12:13:30 +11:00
MoeBoy76 6c06c91cca update W species for gen 9 movesets 2024-01-10 12:07:12 +11:00
MoeBoy76 c5e44031a6 update V species for gen 9 movesets 2024-01-10 11:53:58 +11:00
MoeBoy76 6be2e14af4 update U species for gen 9 movesets 2024-01-10 11:29:04 +11:00
MoeBoy76 5cae25c059 update T species for gen 9 movesets 2024-01-10 11:25:17 +11:00
Lily 87e4f94af5 hisui capture particles, modern capture particles still need to be fixed 2024-01-09 19:18:55 -05:00
MoeBoy76 90ac9ae4df update S species for gen 9 movesets 2024-01-10 10:38:34 +11:00
Apion 527518d0c2 Merge branch 'funny_butterfly' into 'main'
changes to vivillon advancements and patterns

See merge request cable-mc/cobblemon!842
2024-01-09 21:21:10 +00:00
LilyandApion bcb326cd87 changes to vivillon advancements and patterns 2024-01-09 21:21:09 +00:00
Lily 89a4edb327 drops and creative inv 2024-01-09 15:59:33 -05:00
Lily ab37580258 gimmighoul chests crash ur game a little bit less now :o 2024-01-09 14:56:50 -05:00
Lily c116c01fd6 licenses 2024-01-09 14:16:09 -05:00
Lily e3ad8f8079 gimmi now challenges the player on reveal 2024-01-09 13:54:35 -05:00
Lily a491d508b6 gilded chest visuals, loot tables/recipes, sounds, etc. 2024-01-09 12:38:58 -05:00
Lily 43075f1cb8 updated capture particles, waiting for the animation files 2024-01-09 08:27:31 -05:00
dhi_holo 3e11d0550f More item sprites!
24 left, I think, since there's 4 updates and 4 news today
2024-01-09 18:49:20 +10:00
JazzMcNade e1b1e3d5e9 embryo stages now shrink down to nothing before disappearing 2024-01-09 02:44:25 -06:00
MoeBoy76 c226b80430 update R species for gen 9 movesets 2024-01-09 15:38:58 +11:00
dhi_holo 935f7039cf Musical Blocks
Note Block Instruments!
2024-01-09 13:19:32 +10:00
dhi_holo e8b50f8115 Merge branch 'main' into MoreHoldItems 2024-01-09 11:40:46 +10:00
apion 02fb825328 Update Gimmighoul model, add disguised chest block entity, gilded chests now save contents 2024-01-08 14:05:09 -05:00
JazzMcNade a7095b30a3 FossilTuberRenderer now gradually shifts between embryo models. Still needs more turning. 2024-01-08 03:09:18 -06:00
Paul ac5a03eebc Made particles use particle sheet translucent 2024-01-08 13:51:56 +10:00
Paul 8df6eea107 Fixed various issues with the gilded chest and its animations 2024-01-08 11:00:20 +10:00
apion 1376bb68f4 Tried again, failed again 2024-01-07 11:53:38 -05:00
apion beb8f2ccf1 Merge branch 'main' into gimmighoul_gholdengo
# Conflicts:
#	CHANGELOG.md
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonNetwork.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonSounds.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/party/PlayerPartyStore.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/repository/PokemonModelRepository.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/PokemonDTO.kt
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
#	common/src/main/resources/assets/cobblemon/sounds.json
#	common/src/main/resources/data/cobblemon/species/generation9/gimmighoul.json
2024-01-07 10:41:34 -05:00
JazzMcNade bd79b58571 Added Embryo model. Very rough draft on swapping embryo stages. 2024-01-07 05:38:14 -06:00
Paul 5e1c233493 Fixed some ancient pokeball animation stuff 2024-01-07 14:02:17 +10:00
Paul 95e95afef3 Conflict resolution stuff 2024-01-07 13:39:46 +10:00
Paul bf9c54e539 Merge remote-tracking branch 'origin/main' into amo/sendout-upgrade
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/entity/PokemonClientDelegate.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/JsonPokemonPoseableModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/Poseable.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/DataKeys.kt
#	fabric/src/main/kotlin/com/cobblemon/mod/fabric/client/CobblemonFabricClient.kt
2024-01-07 13:28:42 +10:00
Segfault Guy d9de8f2678 Update showdown to send UUID of Zoroark on switch. 2024-01-06 22:03:00 -05:00
dhi_holo 510dfec0e5 Merge branch 'main' into MoreHoldItems 2024-01-06 13:12:24 +10:00
dhi_holo e54932c876 8 Textures
Replaced Black Belt and Focus Band textures, added Covert Cloak, Expert Belt, Focus Sash, Iron Ball, Red Card, and Shell Bell
2024-01-06 13:12:00 +10:00
Tyzillion dd14c3bbdd Implemented Basculegion, Cranidos, and Rampardos. Tyrogue can mount shoulder.
Updated models and textures for Basculin and Squirtle line.
2024-01-05 13:30:57 -05:00
Tyzillion 5ea237f8a0 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2024-01-05 13:29:56 -05:00
JazzMcNade b7addd0203 Added rudimentary randomized phase offset for fetus animations 2024-01-05 02:12:47 -06:00
JazzMcNade 7e64938ec9 Updated fetus anims for Aerodactyl, Archen, Galarian Fossils, Omanyte, Shieldon, Cranidos, and Substitute. Slowed Fossil animation rate to expected speed. 2024-01-05 01:35:19 -06:00
amo 618f66c775 fix up sendout particle code and implement greatball particles 2024-01-05 01:36:37 +00:00
MoeBoy76 9eb9c782ce update Q species for gen 9 movesets 2024-01-05 12:24:54 +11:00
MoeBoy76 49149c9c54 update P species for gen 9 movesets 2024-01-05 12:18:58 +11:00
Paul fd1d1075db Corrections to textures on ballsparkles 2024-01-05 10:16:59 +10:00
Paul 1648926aa6 Fixed direction vectors not being normalized 2024-01-05 10:16:42 +10:00
MoeBoy76 7784794689 update O species for gen 9 movesets 2024-01-05 10:16:26 +11:00
MoeBoy76 07b41d7c0a update N species for gen 9 movesets 2024-01-05 10:08:14 +11:00
MoeBoy76 f5287c7e83 update M species for gen 9 movesets 2024-01-05 09:45:46 +11:00
dhi_holo fb154ba457 Merge branch 'main' into MoreHoldItems 2024-01-05 08:39:23 +10:00
dhi_holo f7812896a8 Weather Rock Textures
4 down, 36 to go (+6 unimplemented)
2024-01-05 08:38:55 +10:00
Lily b0d57dd875 coin bags and blocks and stuff 2024-01-04 15:56:58 -05:00
Lily 6c09e2b553 Merge remote-tracking branch 'origin/gimmighoul_gholdengo' into gimmighoul_gholdengo 2024-01-04 13:47:21 -05:00
Lily 593104fb0a BIG COIN BAG!! 2024-01-04 13:45:43 -05:00
apion e314664731 Throw some stuff in and hope Hiro can fix it (I need a hero! I'm holding out for a hero...) 2024-01-04 07:31:29 -05:00
apion d0a38a9704 Add chest assets, do some work on getting chest animation working 2024-01-04 06:48:59 -05:00
Lily 6e155d7651 Merge remote-tracking branch 'origin/gimmighoul_gholdengo' into gimmighoul_gholdengo 2024-01-04 00:04:41 -05:00
Lily ae8f8a2fb8 working run button!!! wow!!! 2024-01-04 00:04:26 -05:00
apion 5a6a83aac1 Cleanup, add new model 2024-01-03 23:50:55 -05:00
dhi_holo e8236b55a4 Recipe Fixes plus Information in Description
There are 6 items left unimplemented from the recipe document.
Soothe Bell, due to being an out of battle effect, I don't want to attempt, and Amulet Coin needs design work before implementation.
The four terrain seeds, due to future plans, I'm not sure if need to be set up differently. Beyond those six held items, this branch has all currently requested held items to my knowledge, all should now work as intended, although I have not confirmed all battle dialogue works, in part due to not wanting to find all the documentations of what the lines should be. I might come back to that another day, though.

Commits marked with "No Obtain Method" refer to items which have obtain methods of loot or whatever, which can be handled later by people familiar with those systems. If not, I'm down to learn, just not a thing for today.
2024-01-04 13:52:21 +10:00
dhi_holo 2ea07899ea -Added Sticky Barb
No Obtain Method
2024-01-04 13:01:30 +10:00
dhi_holo d0ce03cd5e -Added Shed Shell
No Obtain Method
2024-01-04 13:00:02 +10:00
dhi_holo 8ae0c409a3 -Added Light Ball
No Obtain Method
2024-01-04 12:58:15 +10:00
dhi_holo 2782cb5f34 -Added Lagging Tail
No Obtain Method
2024-01-04 12:56:09 +10:00
dhi_holo 2f10707211 -Added Grip Claw
No Obtain Method
2024-01-04 12:54:48 +10:00
dhi_holo f40a9d762a -Added Float Stone
No Obtain Method
2024-01-04 12:53:17 +10:00
dhi_holo 17587f97e5 -Added Absorb Bulb
No Obtain Method
2024-01-04 12:51:46 +10:00
dhi_holo 5230820657 -Added Punching Glove 2024-01-04 12:49:01 +10:00
dhi_holo 61c55e136f -Added Throat Spray
need to figure out how to add the potion brewing later, not a huge priority at this stage
2024-01-04 12:45:59 +10:00
dhi_holo 22cced74f5 -Added Luminous Moss 2024-01-04 12:43:40 +10:00
dhi_holo 3cd2dec8e0 -Added Loaded Dice 2024-01-04 12:40:34 +10:00
amo 3ce22c0759 particle stuff 2024-01-04 01:32:35 +00:00
dhi_holo cea930893a -Added Iron Ball 2024-01-04 10:26:54 +10:00
dhi_holo 8662364ca8 -Added Wide Lens and Zoom Lens 2024-01-04 10:24:00 +10:00
dhi_holo 1fd079b1b4 -Added Weather Rocks
Damp Rock, Heat Rock, Smooth Rock, Icy Rock, terrible items
2024-01-04 10:19:53 +10:00
dhi_holo 244876a26c -Added Weakness Policy 2024-01-04 10:11:52 +10:00
dhi_holo e7790f530f -Added Utility Umbrella 2024-01-04 10:08:56 +10:00
dhi_holo 04a9ab0e67 -Adds Terrain Extender
If someone wants to work out how to make it so we can have a recipe that costs a water bucket, rather than water from a bucket, that'd be good, for now the recipe just costs an empty bucket
2024-01-04 10:06:39 +10:00
dhi_holo 3f338d27c3 -Added Scope Lens 2024-01-04 09:55:46 +10:00
dhi_holo 5da3dfb451 -Added Room Service 2024-01-04 09:54:00 +10:00
dhi_holo fd329e00cd -Added Ring Target 2024-01-04 09:52:00 +10:00
dhi_holo 6da47a8b2c -Added Red Card
Not gonna test this one for now, don't feel like setting up a second instance test. But, given Eject Button works, I'd say decent shot this one also works
2024-01-04 09:49:02 +10:00
dhi_holo 860c73fac9 -Added Protective Pads 2024-01-04 09:45:50 +10:00
dhi_holo e26fdd4bdd -Added Metronome
Deciding I'll ignore all held items with a * next to the name for now, not sure what they mean but hey, makes it easier to work through, and I can come back to them afterwards
2024-01-04 09:42:31 +10:00
dhi_holo 8e642f71b8 Merge branch 'main' into MoreHoldItems 2024-01-04 09:32:19 +10:00
MoeBoy76 797eeb09cc update L species for gen 9 movesets 2024-01-04 10:20:15 +11:00
MoeBoy76 e6df322556 update K species for gen 9 movesets 2024-01-04 08:32:17 +11:00
MoeBoy76 744d1e1263 update J species for gen 9 movesets 2024-01-04 07:53:07 +11:00
MoeBoy76 7987713179 update I species for gen 9 movesets 2024-01-04 07:45:43 +11:00
MoeBoy76 f8efe0a7d1 update H species for gen 9 movesets 2024-01-04 07:12:13 +11:00
MoeBoy76 be558ed0ab update G species for gen 9 movesets 2024-01-04 06:32:46 +11:00
amo a786adee9e Merge branch 'evolution-effect' into amo/balls
# Conflicts:
#	common/src/main/java/com/cobblemon/mod/common/mixin/GameRendererMixin.java
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/entity/PokemonClientDelegate.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/interact/wheel/InteractWheelGuiFactory.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/pokemon/PokemonRenderer.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/command/TestCommand.kt
#	common/src/main/resources/assets/cobblemon/particles/snowstorm.json
#	common/src/main/resources/mixins.cobblemon-common.json
#	fabric/src/main/kotlin/com/cobblemon/mod/fabric/client/CobblemonFabricClient.kt
2024-01-03 15:02:26 +00:00
MoeBoy76 f3f3bfead4 update F species for gen 9 movesets 2024-01-03 22:44:49 +11:00
MoeBoy76 506ff8d1e4 update E species for gen 9 movesets 2024-01-03 22:14:04 +11:00
MoeBoy76 4764264c9a update D species for gen 9 movesets 2024-01-03 21:44:03 +11:00
dhi_holo f17884b4e1 Eject Button Lang, Read Description
All of the items added just now by me were tested besides Eviolite (don't feel like crunching those numbers today), Eject Pack is broken in my testing (see https://canary.discord.com/channels/725110639554592879/993671151870017656/1192009424282320957 for details), and ofc no item sprites yet, but that's dev life
2024-01-03 17:53:57 +10:00
dhi_holo c40b456948 -Added Eviolite and Expert Belt
test and finalise this little bit time (also corrected some jsons)
2024-01-03 17:19:31 +10:00
dhi_holo 7e74e85315 -Added Eject Button and Pack
I'm not testing these in game rn, I'll do that at the end of the session, which will probably be in a couple more items. But, these all hit the internet at the same time, so haha
2024-01-03 17:09:13 +10:00
dhi_holo 21fd4d7cbf -Added Covert Cloak 2024-01-03 17:00:58 +10:00
dhi_holo 908bff9892 -Added Cell Battery and Clear Amulet 2024-01-03 16:57:32 +10:00
dhi_holo fa14f70bbb -Added Shell Bell
Bell Go Heal
2024-01-03 15:59:01 +10:00
MoeBoy76 1bc22f1afc update C species for gen 9 movesets 2024-01-03 16:49:27 +11:00
MoeBoy76 3480085a29 update B species for gen 9 movesets 2024-01-03 14:04:43 +11:00
MoeBoy76 f5c0bfb40e update A species for gen 9 movesets (again) 2024-01-03 13:04:28 +11:00
MoeBoy76 9dc9740363 Revert "update A species for gen 9 movesets"
This reverts commit be16d00dd5.
2024-01-03 12:20:30 +11:00
MoeBoy76 be16d00dd5 update A species for gen 9 movesets 2024-01-03 10:15:21 +11:00
MoeBoy76 777ece02cc Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into can-moe-scrape 2024-01-03 08:35:03 +11:00
Lily 188ae2ac85 changes to the gimmighoul evolution system. added relic coins, updated bars, removed NetheriteMaterials and GoldMaterials 2024-01-02 14:09:52 -05:00
dhi_holo 346559f292 Tags on top of Tags
Added a very large amount of tags.
The different tiers of Poké balls, also the Apricorn balls so it's easier for people to see what balls count for that advancement, different healing and battle item types, some evolution item sets which made sense to make tags (may add more later, these ones were just the obvious ones to make thing easier for future), the three colours for tumblestones, machine blocks, as well as adding the fence gate item tag, and adding the new tumblestone stuff to the pickaxe tag (although they can still be mined with an axe, probably something that needs fixing)

Mod loader tags were not tested on Forge, due to a crash involving CobblemonEntities, but Fabric works all nicely
2024-01-02 14:44:01 +10:00
dhi_holo 331b282fcf Decorated sherds tag, and fixed Focus Sash not being named
`focus_Sash` isn't valid, sadly
2024-01-02 12:41:28 +10:00
dhi_holo 7f97eeafed Update is_held_item.json
Reorganized alphabetically, for the most part, roughly matches the registry now.
2024-01-02 11:45:38 +10:00
dhi_holo 51f5a1f5a8 Merge branch 'main' into MoreHoldItems 2024-01-02 11:35:53 +10:00
dhi_holo 7c0535b8bd Merge branch 'main' into MoreHoldItems 2024-01-01 21:08:33 +10:00
dhi_holo 4f15ac0cbc Update CobblemonItems.kt
No More "why are the held items not in alphabetical order" for the time being (besides the three Powders and four Herbs, I left them together at the bottom because nobody cares about them)
2024-01-01 18:37:53 +10:00
JazzMcNade 35a0d8a80d -Added Blunder Policy 2024-01-01 01:31:08 -06:00
JazzMcNade c0270d3ef0 -Added Binding Band 2023-12-31 23:58:24 -06:00
JazzMcNade 82a1eb2a55 -Finished Air Balloon implementation. Fixed white space on recipes for for focus sash and Ability Shield 2023-12-31 21:44:26 -06:00
JazzMcNade a528ea952a -Added Ability Shield and Focus Sash. Begin work on Air Balloon. 2023-12-31 21:20:10 -06:00
Tyzillion af2df51a2a Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2023-12-30 18:25:27 -05:00
Lily 95a0f9603c gilded chest model stuffs 2023-12-27 14:54:28 -05:00
Paul de89c11f24 Fixed issue with localPosition on inward/outward motion particles 2023-12-26 11:40:41 +10:00
MoeBoy76 a8e4f87c59 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into can-moe-scrape 2023-12-26 07:49:22 +11:00
Paul f16d233693 Put the evolution effect behind a switch so we can pull the fixes into main 2023-12-25 20:49:26 +10:00
Paul 54d2711583 Resolved issues from merging main 2023-12-25 20:44:30 +10:00
Paul e54f179ccf Merge remote-tracking branch 'origin/main' into evolution-effect
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityState.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/command/TestCommand.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/client/spawn/SpawnPokemonPacket.kt
#	deps/local/com/bedrockk/molang/maven-metadata-local.xml
2023-12-25 20:33:56 +10:00
Tyzillion d38aa6b1a2 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2023-12-24 22:45:50 -05:00
Tyzillion 4566e1b33f Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2023-12-24 07:07:56 -05:00
MoeBoy76 c426f4154b Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into can-moe-scrape 2023-12-24 10:18:55 +11:00
MoeBoy76 a326eb3832 Blueberry dex additions 2023-12-24 10:18:06 +11:00
Tyzillion f2d16ca9b7 Implemented Lileep, Cradily, Tirtouga, Carracosta, Arctovish, Dracovish, Arctozolt, Dracozolt, Shieldon, Bastiodon.
Updated models for Kabuto, Kabutops, Piplup, Prinplup, Elekid, Electabuzz, Cubone, Marowak, Paras, Venonat, Venomoth, Yanma, and Yanmega, and Raboot. Resized Snorlax.
2023-12-23 17:47:44 -05:00
Paul 22441e0b09 More evo effect reworking 2023-12-23 08:20:36 +10:00
Paul 8418bc87c8 Merge remote-tracking branch 'origin/main' into evolution-effect
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonEntities.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/adapter/flatfile/NBTStoreAdapter.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/command/TestCommand.kt
#	fabric/src/main/kotlin/com/cobblemon/mod/fabric/client/CobblemonFabricClient.kt
#	forge/src/main/kotlin/com/cobblemon/mod/forge/client/CobblemonForgeClient.kt
2023-12-22 15:41:11 +10:00
Lily d6fbb70db0 add level ranges to DisguisedPokemonBlock 2023-12-11 16:10:13 -05:00
Lily 150a5c668a redid disguised gimmighouls 2023-12-11 14:55:43 -05:00
Paul 94ad2f1250 Added Waffle's particles but they're kinda busted ngl 2023-12-11 13:32:08 +10:00
Lily 1bf01a2826 more bar stuff 2023-11-30 15:16:32 -05:00
Lily 4d1bf677a1 bar color update 2023-11-29 21:49:06 -05:00
Lily 069f56acfd gholdengo/gimmighoul are basically done, gilded chests still unfinished 2023-11-29 20:32:20 -05:00
Lily bd4df4485e added nether fire stone ores, and storage blocks for evo stones (need textures) 2023-11-27 21:39:03 -05:00
Lily 19cdc8fbef Merge remote-tracking branch 'origin/gimmighoul_gholdengo' into gimmighoul_gholdengo 2023-11-27 17:31:27 -05:00
Lily 1408b94f06 started on gilded chests 2023-11-27 17:31:17 -05:00
Paul de081dc514 Added aspects support for int range features 2023-11-27 11:53:06 +10:00
Lily 1538f12934 more gimmighoul changes 2023-11-14 20:59:10 -05:00
Paul 857f67604c Fixed some logic in held item event + gimmighoul item 2023-11-14 19:30:27 +10:00
Paul ae49e3f977 Fixed gold materials data registry not being loaded 2023-11-14 19:18:45 +10:00
Lily ec01a03820 pushed some stuff idk what to put here 2023-11-14 00:47:15 -05:00
Lily 96cc3671da Merge branch 'held_item_event' into gimmighoul_gholdengo 2023-11-13 18:36:09 -05:00
Lily ad7c9c560c add an event for updating a pokemon's held item 2023-11-13 18:33:45 -05:00
Tyzillion ee15ff6b35 Corrected Gimmighoul chest and roaming size. 2023-11-13 16:49:00 -05:00
Tyzillion ca83103703 Bling, bling, every time I come around your city. 2023-11-13 16:33:07 -05:00
Tyzillion 1aeb894b09 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into gimmighoul_gholdengo 2023-11-13 13:42:38 -05:00
Lily 8e9ab26963 json files for gold and netherite materials (doesnt work in-game yet) 2023-11-13 18:09:34 +00:00
Paul 44b4fbcfe3 Minor license thing 2023-11-13 20:04:29 +10:00
Paul 42cc1dd8a9 Upgraded species features so they can be synced and rendered in summary screen 2023-11-13 19:39:17 +10:00
Lily d69310e52c re-do the way the other stats screen draws stuff 2023-11-10 20:15:40 -05:00
Lily a0f89274d1 started work on SummaryValue properties (CW: messy, incomplete systems) 2023-11-10 18:57:11 -05:00
amo 0ad45df8f5 white glow happens but its buggy 2023-11-08 18:13:45 +00:00
amo 03f377cf0a white glow happens but its buggy 2023-10-22 21:06:03 +01:00
amo 373092f572 interact gui upgrades 2023-10-21 19:55:13 +01:00
Paul 8bfc0fefaf Improvements to evolution effect 2023-10-21 08:13:56 +10:00
amo 4e44807523 new throwout sounds & timings 2023-10-20 19:02:55 +01:00
Paul 36251fea75 Merge remote-tracking branch 'origin/main' into evolution-effect
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/Cobblemon.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/LocatorAccess.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/command/TestCommand.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/client/spawn/SpawnPokemonPacket.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/Species.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/MoLangExtensions.kt
#	common/src/main/resources/assets/cobblemon/particles/snowstorm.json
#	deps/local/com/bedrockk/molang/1.1.5/molang-1.1.5.pom
2023-10-20 19:28:23 +10:00
amo 06206a7447 pokeball anim 2023-10-20 06:37:09 +01:00
amo 66e901f88d sync pokeball 2023-10-19 17:08:53 +01:00
amo 05f089d390 attempt to fix particle materials but fabric fucking sucks 2023-10-19 17:01:05 +01:00
amo 23df8f70cf testing 2023-10-19 02:39:48 +01:00
amo bd25e8682a Merge remote-tracking branch 'origin/tracked-data-cleanup' into amo/balls
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/entity/PokemonClientDelegate.kt
2023-10-18 13:16:01 +01:00
amo 906cd54c98 initial mockup 2023-10-17 03:15:06 +01:00
Paul a1897f69ca Improved generic bedrock entity initializing and evolution entity handling so it crashes fewer times 2023-09-01 16:39:48 +10:00
Paul a88700969d Fixed positioning of generic bedrock entities and particle locator matrices 2023-09-01 16:39:05 +10:00
Paul 91eb9e597e Improved scaling of evolution particles 2023-09-01 16:38:19 +10:00
Paul e762542e49 Merge branch 'main' into evolution-effect
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityModel.kt
2023-09-01 09:02:33 +10:00
Paul b3e5734f39 Merge remote-tracking branch 'origin/main' into evolution-effect
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/particle/ParticleStorm.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/bedrock/animation/BedrockAnimation.kt
2023-08-28 18:35:09 +10:00
jmmcp 2d5296288f Cleaned up evolution code 2023-08-27 22:55:28 -04:00
jmmcp cab3f2bf38 Adjusted timing of evolution when outside poke ball 2023-08-27 17:47:54 -04:00
Paul 31efdc4254 Made evolution particle appropriately scale with entity size 2023-08-27 15:15:35 +10:00
Paul 34aace8a1b Fixed compile errors 2023-08-27 14:21:52 +10:00
Paul a877ad5a69 Merge branch 'berry' into evolution-effect
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/repository/VaryingModelRepository.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/MoLangExtensions.kt
2023-08-27 14:11:55 +10:00
Paul 5a8c090055 Merge branch 'main' into evolution-effect
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/util/MoLangExtensions.kt
2023-08-27 14:10:10 +10:00
jmmcp 98ccf39728 Progress towards implementing evolution effects when evolved outside a poke ball 2023-08-27 00:04:46 -04:00
Paul 3222e2ebca Fixed crash with generic bedrock entities + updated evolve sound for timing 2023-07-18 19:20:52 +10:00
Paul ba89ed1574 Merge remote-tracking branch 'origin/main' into evolution-effect 2023-07-17 19:02:28 +10:00
Paul 68ab953644 Heaps of fixes for particle engine 2023-07-17 19:02:13 +10:00
Paul 4d3030e20e Merge stuff 2023-07-15 18:37:47 +10:00
JosephBedsole 2e324e65a1 Added a fallback locator for particle animations 2023-07-08 07:47:02 -05:00
Paul a34b7481f5 Updated explanation of look_at_direction camera mode [skip-ci] 2023-06-30 09:46:53 +10:00
Paul d2a3905b03 Fixed look_at_direction camera mode for particles 2023-06-29 22:02:38 +10:00
Paul 16b3d76504 Gotten closer to fixing look_at_direction camera mode 2023-06-16 10:55:00 +10:00
Paul 363fe76dd1 Merge remote-tracking branch 'origin/main' into evolution-effect
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonNetwork.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/command/TestCommand.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/DataKeys.kt
2023-06-11 21:58:45 +10:00
Paul 040a29f66e Added generic bedrock entity system, updated molang for fix, added test evo effect, and fixed some particle issues 2023-05-28 06:39:55 +10:00
Yaseen 65aec87382 mute battle 2023-05-20 16:54:49 +01:00
Yaseen 21198eab29 more forfeit stuff 2023-05-20 16:54:14 +01:00
Yaseen c4c060cbbf Dont wait for action if one of the players has forfeited 2023-04-28 15:36:45 +01:00
Yaseen 6cf7c681d4 Merge branch 'main' into ys/forfeit 2023-04-28 00:28:30 +01:00
Yaseen c420fd4705 Attempt to add forfeit button and showdown action 2023-04-28 00:26:52 +01:00
Yaseen 1278654e9f merge main 2023-04-28 00:26:09 +01:00
6584 changed files with 431881 additions and 39933 deletions
+6
View File
@@ -21,6 +21,8 @@ build
# other
eclipse
run
runClient
runServer
# Files from Forge MDK
forge*changelog.txt
@@ -33,3 +35,7 @@ common/src/main/resources/assets/cobblemon/showdown
# Generated files
*/generated/resources/*
/fabric/src/generated/resources/cobblemon-common.accesswidener
/.ignored/
# MacOS
.DS_Store
+338 -20
View File
@@ -1,38 +1,339 @@
# Changelog
## [1.5.0](#1-5-0)
## [1.5.1](#1-5-1)
### Fixes
-Fixed a bug in which adding organic material to the fossil tank via right click was adding the full count of the stack currently in hand
## [1.5.0 - The Ruins and Revival Update (May Xth, 2024)](#1-5-0)
#### "You're telling me that Mojang has added archaeology to the game? Hmm... that gives me an idea."
### Additions
- Added over (number here) ruin structures, where you can find Pokémon-themed Armor Trims and Pottery Sherds, Tumblestones, and more.
- Added (number here) fossil structures, where you can brush Suspicious Sand/Gravel for Fossils.
- Added the Data Monitor, Fossil Compartment, and Restoration Tube. 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 17 ruin structures, where you can find Pokémon-themed Armor Trims and Pottery Sherds, Tumblestones, and more.
- 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 recieve 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 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 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.
- 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.
- Added Nether Fire Stone Ore to, surprisingly, the Nether.
- Added Terracotta Sun Stone Ore to Badlands biomes.
- Added the EV Boosting Feathers.
- 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. 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
- Sentret
- Furret
- Qwilfish
- Heracross
- Skarmory
- Larvitar
- Pupitar
- Tyranitar
#### Gen 3
- Lileep
- Cradily
- Anorith
- Armaldo
- Tropius
- Roselia
- Aron
- Lairon
- Aggron
- Solrock
- Lunatone
- Makuhita
- Hariyama
- Trapinch
- Vibrava
- Flygon
#### Gen 4
- Shieldon
- Bastiodon
- Cranidos
- Rampardos
- Budew
- Roserade
- Hippopotas
- Hippowdon
#### Gen 5
- Tirtouga
- Carracosta
- Archen
- Archeops
- Zorua
- Zoroark
- Petilil
- Lilligant
- Darumaka
- Darmanitan
- Woobat
- Swoobat
- Sandile
- Krokorok
- Krookodile
- Frillish
- Jellicent
- Cubchoo
- Beartic
- Deino
- Zweilous
- Hydreigon
- Larvesta
- Volcarona
- Alomomola
- Ferroseed
- Ferrothorn
#### Gen 6
- Tyrunt
- Tyrantrum
- Amaura
- Aurorus
- Goomy
- Sliggoo
- Goodra
- Carbink
- Flabébé
- Floette
- Florges
- Klefki
#### Gen 7
- Turtonator
- Fomantis
- Lurantis
- Salandit
- Salazzle
- Jangmo-o
- Hakamo-o
- Kommo-o
- Alolan Diglett
- Alolan Dugtrio
#### Gen 8
- Gossifleur
- Eldegoss
- Arctozolt
- Arctovish
- Dracozolt
- Dracovish
- Basculegion
- Hisuian Decidueye
- Hisuian Typhlosion
- Hisuian Samurott
- Hisuian Lilligant
- Hisuian Sliggoo
- Hisuian Goodra
- Hisuian Zorua
- Hisuian Zoroark
- Hisuian Voltorb
- Hisuian Electrode
- Hisuian Qwilfish
- Overqwil
- Hisuian Sneasel
- Sneasler
- Stonjourner
- Cufant
- Copperajah
- Dreepy
- Drakloak
- Dragapult
- Impidimp
- Morgrem
- Grimmsnarl
#### 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. But what will that do to when you evolve it?
- Gholdengo
#### Cobblemon Exclusives
- Hisui Bias Rowlet
- Hisui Bias Dartrix
- Hisui Bias Cyndaquil
- Hisui Bias Quilava
- Hisui Bias Oshawott
- Hisui Bias Dewott
- 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.
- 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, 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 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 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 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.
- 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
- 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 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. 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'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 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 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 (albeit in a quick-fix way).
- Rebuilt the scheduling API to more clearly force side choices and allow more local temporal frames of reference for tasks.
- Added dialogue API.
- 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 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``.
- Corrections to the ability implementation have been made that make ``Ability.forced`` function as intended and never reroll an ability for a Pokémon, please check your implementations to ensure the corrected behavior is intended for your use case.
- ``Pokemon.ability`` no longer has a public setter. Please migrate to using ``Pokemon#updateAbility``, this handles the ability coordinate storage for you when necessary.
- ``Ability.forced``, ``Ability.index`` and ``Ability.priority`` have all had their setters internalized, there is no longer any need to manually adjust these migrate to the method mentioned above to handle that process for you.
- ``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.
- 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 Compartment can be adjusted in the config.
- The maximum amount of fossils that can fit in the Fossil Analyzer can be adjusted in the config.
- Custom fossils can be defined using a list of items and the resulting Pokémon. An example of `aerodactyl.json`:
```JSON
{
@@ -50,9 +351,22 @@
- `returnItem`: Identifier of an item to return to the player after consumption.
- Added 3 new item tags: `ancient_poke_balls`, `fossils`, and `tumblestones`.
- Added a spawn rules system to modify general spawning behaviour, see the [wiki](https://wiki.cobblemon.com/index.php/Spawn_Rules) for more information.
- 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.
- Added dialogue datapack folder and /opendialogue command.
- Added the item tag ``cobblemon:held/leaves_leftovers`` this can be used to flag apple-like items that can create leftovers when eaten.
- You can now add support for dynamic lighting implementations, Cobblemon ships with a default implementation for [LambDynamicLights](https://modrinth.com/mod/lambdynamiclights) and the [Dynamic Lights Reforged](https://www.curseforge.com/minecraft/mc-mods/dynamiclights-reforged), add the following to any species or form:
```JSON
{
"lightingData": {
"lightLevel": 14,
"_lightLevelCommentRemoveMe": "Above supports 0 to 15",
"liquidGlowMode": "LAND",
"_liquidGlowModeCommentRemoveMe": "Above supports LAND, UNDERWATER or BOTH"
}
}
```
- Following up on this change ``light_source`` was removed as a possible shoulder effect due to becoming unnecessary and never having had a default implementation.
- Added the item tag ``cobblemon:ability_changers``, contains the ``cobblemon:ability_capsule`` & ``cobblemon:ability_patch`` by default.
- Added the item tag ``cobblemon:held/is_friendship_booster``, allows items to give the Soothe Bell effect of a boost of 1.5x Friendship gained, contains ``cobblemon:soothe_bell`` by default.
## [1.4.1 (December 23rd, 2023)](#1-4-1)
@@ -70,6 +384,7 @@
- Added cries to Beldum, Metang and Metagross.
- Added a /bedrockparticle command to run Snowstorm-format particle effects.
- Added data for Dipplin, Fezandipiti, Munkidori, Ogerpon, Okidogi, Poltchageist and Sinistcha.
- Added additional nickname trigger "Grumm" for Inkay's evolution.
### Changes
- Using Potions, Status Heals, Ethers, and Antidotes will now return a glass bottle
@@ -185,6 +500,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).
@@ -725,6 +1041,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
@@ -874,6 +1191,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.
@@ -987,4 +1305,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()
}
+4 -4
View File
@@ -1,12 +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-SNAPSHOT"
}
val fixedBranchName = versioning.info.branch.substringAfter("/")
version = "$version-${fixedBranchName}-${versioning.info.build}"
}
+55 -20
View File
@@ -1,3 +1,9 @@
import utilities.isSnapshot
import utilities.version
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
/*
*
* * Copyright (C) 2023 Cobblemon Contributors
@@ -11,6 +17,10 @@
plugins {
id("cobblemon.base-conventions")
id("cobblemon.publish-conventions")
id("net.kyori.blossom")
id("org.jetbrains.gradle.plugin.idea-ext")
id("net.nemerosa.versioning") version "2.8.2"
}
architectury {
@@ -24,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)
// 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)
testRuntimeOnly(libs.junitEngine)
testImplementation(libs.junitApi)
testImplementation(libs.junitParams)
testImplementation(libs.mockito)
testImplementation(libs.mockk)
testImplementation(libs.classgraph)
// Unit Testing
testImplementation(libs.bundles.unitTesting)
}
tasks.withType<Test> {
@@ -58,3 +63,33 @@ tasks.withType<Test> {
setExceptionFormat("full")
}
}
sourceSets {
main {
blossom {
kotlinSources {
fun generateLicenseHeader() : String {
val builder = StringBuilder()
builder.append("/*\n")
rootProject.file("HEADER").forEachLine {
if(it.isEmpty()) {
builder.append(" *").append("\n")
} else {
builder.append(" * ").append(it).append("\n")
}
}
return builder.append(" */").append("\n").toString()
}
property("license", generateLicenseHeader())
property("modid", "cobblemon")
property("version", project.version())
property("isSnapshot", if(rootProject.isSnapshot()) "true" else "false")
property("gitCommit", versioning.info.commit)
property("branch", versioning.info.branch)
System.getProperty("buildNumber")?.let { property("buildNumber", it) }
}
}
}
}
@@ -0,0 +1,96 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.compat;
import com.cobblemon.mod.common.CobblemonEntities;
import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokemon.FormData;
import com.cobblemon.mod.common.pokemon.lighthing.LightingData;
import dev.lambdaurora.lambdynlights.api.DynamicLightHandler;
import dev.lambdaurora.lambdynlights.api.DynamicLightHandlers;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
// Java class due to relying on entrypoint on Fabric side
public class LambDynamicLightsCompat {
// This is all called on client side
// These things are checked every tick so try to keep it as free as possible
// That being said it's unlikely school Toshiba person is running dynamic lighting and shaders to enjoy this
// Make sure not to call anything Fabric specific :)
public static void hookCompat() {
// Pokémon entities
DynamicLightHandlers.registerDynamicLightHandler(
CobblemonEntities.POKEMON,
DynamicLightHandler.makeHandler(
pokemon -> resolvedPokemonLightLevel(pokemon, false),
pokemon -> true
)
);
DynamicLightHandlers.registerDynamicLightHandler(
CobblemonEntities.POKEMON,
DynamicLightHandler.makeHandler(
pokemon -> resolvedPokemonLightLevel(pokemon, true),
pokemon -> false
)
);
// Shouldered Pokémon
DynamicLightHandlers.registerDynamicLightHandler(
EntityType.PLAYER,
DynamicLightHandler.makeHandler(
player -> resolvedShoulderLightLevel(player, false),
player -> true
)
);
DynamicLightHandlers.registerDynamicLightHandler(
EntityType.PLAYER,
DynamicLightHandler.makeHandler(
player -> resolvedShoulderLightLevel(player, true),
player -> false
)
);
}
private static int resolvedPokemonLightLevel(PokemonEntity pokemon, boolean underwater) {
return extractFormLightLevel(pokemon.getForm(), underwater).orElse(0);
}
private static int resolvedShoulderLightLevel(PlayerEntity player, boolean underwater) {
final Pair<PokemonOnShoulderRenderer.ShoulderData, PokemonOnShoulderRenderer.ShoulderData> shoulderDataPair = PokemonOnShoulderRenderer.shoulderDataOf(player);
final Optional<Integer> leftLightLevel = extractShoulderLightLevel(shoulderDataPair.getLeft(), underwater);
final Optional<Integer> rightLightLevel = extractShoulderLightLevel(shoulderDataPair.getRight(), underwater);
return Math.max(leftLightLevel.orElse(0), rightLightLevel.orElse(0));
}
private static Optional<Integer> extractFormLightLevel(@NotNull FormData form, boolean underwater) {
if (form.getLightingData() == null || !liquidGlowModeSupport(form.getLightingData().getLiquidGlowMode(), underwater)) {
return Optional.empty();
}
return Optional.of(form.getLightingData().getLightLevel());
}
private static Optional<Integer> extractShoulderLightLevel(@Nullable PokemonOnShoulderRenderer.ShoulderData shoulderData, boolean underwater) {
if (shoulderData == null) {
return Optional.empty();
}
return extractFormLightLevel(shoulderData.getForm(), underwater);
}
private static boolean liquidGlowModeSupport(@NotNull LightingData.LiquidGlowMode liquidGlowMode, boolean underwater) {
return underwater ? liquidGlowMode.getGlowsUnderwater() : liquidGlowMode.getGlowsInLand();
}
}
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.CobblemonBuildDetails;
import net.minecraft.util.crash.CrashReport;
import net.minecraft.util.crash.CrashReportSection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(CrashReport.class)
public final class CrashReportMixin {
@Inject(method = "addStackTrace", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/SystemDetails;writeTo(Ljava/lang/StringBuilder;)V"))
public void cobblemon$printCobblemonDetails(StringBuilder builder, CallbackInfo callback) {
CrashReportSection cobblemon = new CrashReportSection("Cobblemon");
cobblemon.add("Version", CobblemonBuildDetails.VERSION);
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.addStackTrace(builder);
builder.append("\n\n");
}
}
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.sherds.CobblemonSherds;
import net.minecraft.block.DecoratedPotPatterns;
import net.minecraft.item.Item;
import net.minecraft.registry.RegistryKey;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(DecoratedPotPatterns.class)
public abstract class DecoratedPotPatternsMixin {
@Inject(method = "fromSherd", at=@At("HEAD"), cancellable = true)
private static void cobblemon$getCobblemonSherdTexture(Item sherd,
CallbackInfoReturnable<RegistryKey<String>> cir) {
if (CobblemonSherds.INSTANCE.getSherdToPattern().containsKey(sherd)) {
cir.setReturnValue(CobblemonSherds.INSTANCE.getSherdToPattern().get(sherd));
return;
}
}
}
@@ -40,4 +40,5 @@ public class GameRendererMixin {
}
lastTime = newTime;
}
}
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.api.snowstorm.ParticleMaterials;
import com.google.common.collect.ImmutableList;
import net.minecraft.client.particle.ParticleManager;
import net.minecraft.client.particle.ParticleTextureSheet;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
@Mixin(ParticleManager.class)
final class ParticleManagerMixin {
@Mutable
@Final
@Shadow
private static List<ParticleTextureSheet> PARTICLE_TEXTURE_SHEETS;
@Inject(at = @At("RETURN"), method = "<clinit>")
private static void lodestone$addTypes(CallbackInfo ci) {
PARTICLE_TEXTURE_SHEETS = ImmutableList.<ParticleTextureSheet>builder().addAll(PARTICLE_TEXTURE_SHEETS)
.add(ParticleMaterials.INSTANCE.getADD(), ParticleMaterials.INSTANCE.getALPHA(), ParticleMaterials.INSTANCE.getBLEND(), ParticleMaterials.INSTANCE.getOPAQUE()).build();
}
}
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.CobblemonItems;
import net.minecraft.entity.mob.PiglinBrain;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PiglinBrain.class)
public class PiglinBarterMixin {
@Inject(method = "acceptsForBarter", at = @At(value = "RETURN"), cancellable = true)
private static void cobblemon$acceptsForBarter(ItemStack stack, CallbackInfoReturnable<Boolean> ci) {
if(!ci.getReturnValue()) {
//TODO: Make a tag?
if(stack.isOf(CobblemonItems.RELIC_COIN_POUCH))
ci.setReturnValue(true);
}
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.CobblemonItems;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.mob.PiglinEntity;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PiglinEntity.class)
public abstract class PiglinEntityMixin {
@Inject(method = "equipToOffHand", at = @At(value = "HEAD"), cancellable = true)
public void cobblemon$isValidBarteringItem(ItemStack stack, CallbackInfo ci) {
PiglinEntity entity = (PiglinEntity)(Object) this;
if (stack.isOf(CobblemonItems.RELIC_COIN_POUCH)) {
entity.equipStack(EquipmentSlot.OFFHAND, stack);
entity.updateDropChances(EquipmentSlot.OFFHAND);
ci.cancel();
}
}
}
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.api.events.CobblemonEvents;
import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent;
import com.cobblemon.mod.common.api.storage.NoPokemonStoreException;
import com.cobblemon.mod.common.api.storage.party.PartyStore;
import com.cobblemon.mod.common.api.tags.CobblemonItemTags;
import com.cobblemon.mod.common.pokemon.Pokemon;
import com.cobblemon.mod.common.util.CompoundTagExtensionsKt;
import com.cobblemon.mod.common.util.DataKeys;
@@ -22,11 +23,8 @@ import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Text;
import net.minecraft.world.World;
import org.objectweb.asm.Opcodes;
@@ -40,8 +38,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Objects;
import java.util.UUID;
import static com.cobblemon.mod.common.util.LocalizationUtilsKt.lang;
@Mixin(PlayerEntity.class)
public abstract class PlayerMixin extends LivingEntity {
@@ -144,7 +140,7 @@ public abstract class PlayerMixin extends LivingEntity {
)
public void onEatFood(World world, ItemStack stack, CallbackInfoReturnable<ItemStack> cir) {
if (!getWorld().isClient) {
if (stack.getItem() == Items.APPLE && getWorld().random.nextDouble() < Cobblemon.config.getAppleLeftoversChance()) {
if (stack.isIn(CobblemonItemTags.LEAVES_LEFTOVERS) && getWorld().random.nextDouble() < Cobblemon.config.getAppleLeftoversChance()) {
ItemStack leftovers = new ItemStack(CobblemonItems.LEFTOVERS);
ServerPlayerEntity player = Objects.requireNonNull(getServer()).getPlayerManager().getPlayer(uuid);
assert player != null;
@@ -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);
}
}
@@ -0,0 +1,17 @@
{{ license }}
package com.cobblemon.mod.common
object CobblemonBuildDetails {
const val MOD_ID = "{{ modid }}"
const val VERSION = "{{ version }}"
const val SNAPSHOT = {{ isSnapshot }}
const val GIT_COMMIT = "{{ gitCommit | default("Not Specified") }}"
const val BRANCH = "{{ branch | default("Not Specified") }}"
fun smallCommitHash(): String {
return this.GIT_COMMIT.substring(0, 7)
}
}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.CobblemonBuildDetails.smallCommitHash
import com.cobblemon.mod.common.advancement.CobblemonCriteria
import com.cobblemon.mod.common.advancement.criterion.EvolvePokemonContext
import com.cobblemon.mod.common.api.Priority
@@ -16,12 +17,14 @@ import com.cobblemon.mod.common.api.data.DataProvider
import com.cobblemon.mod.common.api.drop.CommandDropEntry
import com.cobblemon.mod.common.api.drop.DropEntry
import com.cobblemon.mod.common.api.drop.ItemDropEntry
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.CobblemonEvents.BATTLE_VICTORY
import com.cobblemon.mod.common.api.events.CobblemonEvents.DATA_SYNCHRONIZED
import com.cobblemon.mod.common.api.events.CobblemonEvents.EVOLUTION_COMPLETE
import com.cobblemon.mod.common.api.events.CobblemonEvents.LEVEL_UP_EVENT
import com.cobblemon.mod.common.api.events.CobblemonEvents.POKEMON_CAPTURED
import com.cobblemon.mod.common.api.events.CobblemonEvents.TRADE_COMPLETED
import com.cobblemon.mod.common.api.net.serializers.IdentifierDataSerializer
import com.cobblemon.mod.common.api.net.serializers.PoseTypeDataSerializer
import com.cobblemon.mod.common.api.net.serializers.StringSetDataSerializer
import com.cobblemon.mod.common.api.net.serializers.Vec3DataSerializer
@@ -35,6 +38,7 @@ import com.cobblemon.mod.common.api.pokemon.experience.ExperienceGroups
import com.cobblemon.mod.common.api.pokemon.experience.StandardExperienceCalculator
import com.cobblemon.mod.common.api.pokemon.feature.ChoiceSpeciesFeatureProvider
import com.cobblemon.mod.common.api.pokemon.feature.FlagSpeciesFeatureProvider
import com.cobblemon.mod.common.api.pokemon.feature.IntSpeciesFeatureProvider
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
import com.cobblemon.mod.common.api.pokemon.helditem.HeldItemProvider
import com.cobblemon.mod.common.api.pokemon.stats.EvCalculator
@@ -62,6 +66,7 @@ import com.cobblemon.mod.common.api.storage.player.PlayerDataStoreManager
import com.cobblemon.mod.common.api.storage.player.factory.JsonPlayerDataStoreFactory
import com.cobblemon.mod.common.api.storage.player.factory.MongoPlayerDataStoreFactory
import com.cobblemon.mod.common.api.tags.CobblemonEntityTypeTags
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.battles.BagItems
import com.cobblemon.mod.common.battles.BattleFormat
import com.cobblemon.mod.common.battles.BattleRegistry
@@ -97,6 +102,7 @@ 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
@@ -113,15 +119,6 @@ import com.mongodb.ConnectionString
import com.mongodb.MongoClientSettings
import com.mongodb.client.MongoClient
import com.mongodb.client.MongoClients
import java.io.File
import java.io.FileReader
import java.io.FileWriter
import java.io.PrintWriter
import java.util.UUID
import kotlin.properties.Delegates
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaField
import net.minecraft.client.MinecraftClient
import net.minecraft.command.argument.serialize.ConstantArgumentSerializer
import net.minecraft.entity.data.TrackedDataHandlerRegistry
@@ -131,12 +128,23 @@ import net.minecraft.registry.RegistryKey
import net.minecraft.util.WorldSavePath
import net.minecraft.world.World
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import java.io.File
import java.io.FileReader
import java.io.FileWriter
import java.io.PrintWriter
import java.util.*
import kotlin.properties.Delegates
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
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 = LogManager.getLogger()
val LOGGER: Logger = LogManager.getLogger()
lateinit var implementation: CobblemonImplementation
@Deprecated("This field is now a config value", ReplaceWith("Cobblemon.config.captureCalculator"))
@@ -166,6 +174,13 @@ object Cobblemon {
fun preInitialize(implementation: CobblemonImplementation) {
this.implementation = implementation
this.LOGGER.info("Launching Cobblemon ${CobblemonBuildDetails.VERSION}${if(CobblemonBuildDetails.SNAPSHOT) "-SNAPSHOT" else ""} ")
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}")
}
implementation.registerPermissionValidator()
implementation.registerSoundEvents()
implementation.registerBlocks()
@@ -228,6 +243,9 @@ object Cobblemon {
}
}
// Register the grow_tumblestone advancement
PlatformEvents.RIGHT_CLICK_BLOCK.subscribe { AdvancementHandler.onTumbleStonePlaced(it) }
PlatformEvents.CHANGE_DIMENSION.subscribe {
it.player.party().forEach { pokemon -> pokemon.entity?.recallWithAnimation() }
}
@@ -235,6 +253,17 @@ object Cobblemon {
TrackedDataHandlerRegistry.register(Vec3DataSerializer)
TrackedDataHandlerRegistry.register(StringSetDataSerializer)
TrackedDataHandlerRegistry.register(PoseTypeDataSerializer)
TrackedDataHandlerRegistry.register(IdentifierDataSerializer)
// Lowest priority because this applies after luxury ball bonus as of gen 4
CobblemonEvents.FRIENDSHIP_UPDATED.subscribe(Priority.LOWEST) { event ->
var increment = (event.newFriendship - event.pokemon.friendship).toFloat()
// Our Luxury ball spec is diff from official, but we will still assume these stack
if (event.pokemon.heldItemNoCopy().isIn(CobblemonItemTags.IS_FRIENDSHIP_BOOSTER)) {
increment += increment * 0.5F
}
event.newFriendship = event.pokemon.friendship + increment.roundToInt()
}
HeldItemProvider.register(CobblemonHeldItemManager, Priority.LOWEST)
}
@@ -250,6 +279,7 @@ object Cobblemon {
SpeciesFeatures.types["choice"] = ChoiceSpeciesFeatureProvider::class.java
SpeciesFeatures.types["flag"] = FlagSpeciesFeatureProvider::class.java
SpeciesFeatures.types["integer"] = IntSpeciesFeatureProvider::class.java
SpeciesFeatures.register(
DataKeys.CAN_BE_MILKED,
@@ -385,6 +415,8 @@ object Cobblemon {
true
).ifSuccessful { it.mute = true }
}
CobblemonSherds.registerSherds()
}
fun getLevel(dimension: RegistryKey<World>): World? {
@@ -12,11 +12,12 @@ import com.cobblemon.mod.common.block.entity.BerryBlockEntity
import com.cobblemon.mod.common.block.entity.HealingMachineBlockEntity
import com.cobblemon.mod.common.block.entity.PCBlockEntity
import com.cobblemon.mod.common.block.entity.PokemonPastureBlockEntity
import com.cobblemon.mod.common.block.entity.fossil.FossilCompartmentBlockEntity
import com.cobblemon.mod.common.block.entity.fossil.FossilMultiblockEntity
import com.cobblemon.mod.common.block.entity.fossil.FossilTubeBlockEntity
import com.cobblemon.mod.common.block.entity.FossilAnalyzerBlockEntity
import com.cobblemon.mod.common.block.entity.FossilMultiblockEntity
import com.cobblemon.mod.common.block.entity.RestorationTankBlockEntity
import com.cobblemon.mod.common.block.multiblock.FossilMultiblockBuilder
import com.cobblemon.mod.common.block.entity.*
import com.cobblemon.mod.common.block.entity.DisplayCaseBlockEntity
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.block.entity.BlockEntityType
import net.minecraft.registry.Registries
@@ -45,24 +46,41 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
@JvmField
val HANGING_SIGN: BlockEntityType<CobblemonHangingSignBlockEntity> = this.create("hanging_sign", BlockEntityType.Builder.create(::CobblemonHangingSignBlockEntity, CobblemonBlocks.APRICORN_HANGING_SIGN, CobblemonBlocks.APRICORN_WALL_HANGING_SIGN).build(null))
@JvmField
val GILDED_CHEST: BlockEntityType<GildedChestBlockEntity> = this.create("chest", BlockEntityType.Builder.create(::GildedChestBlockEntity,
CobblemonBlocks.GILDED_CHEST,
CobblemonBlocks.BLUE_GILDED_CHEST,
CobblemonBlocks.YELLOW_GILDED_CHEST,
CobblemonBlocks.PINK_GILDED_CHEST,
CobblemonBlocks.BLACK_GILDED_CHEST,
CobblemonBlocks.WHITE_GILDED_CHEST,
CobblemonBlocks.GREEN_GILDED_CHEST,
CobblemonBlocks.GIMMIGHOUL_CHEST
).build(null))
@JvmField
val FOSSIL_MULTIBLOCK: BlockEntityType<FossilMultiblockEntity> = this.create("fossil_multiblock",
BlockEntityType.Builder.create({ pos, state -> FossilMultiblockEntity(pos, state, FossilMultiblockBuilder(pos)) },
CobblemonBlocks.FOSSIL_MONITOR
CobblemonBlocks.MONITOR
).build(null)
)
@JvmField
val FOSSIL_TUBE: BlockEntityType<FossilTubeBlockEntity> = this.create("fossil_tube",
BlockEntityType.Builder.create({ pos, state -> FossilTubeBlockEntity(pos, state, FossilMultiblockBuilder(pos)) },
CobblemonBlocks.FOSSIL_TUBE
val RESTORATION_TANK: BlockEntityType<RestorationTankBlockEntity> = this.create("restoration_tank",
BlockEntityType.Builder.create({ pos, state -> RestorationTankBlockEntity(pos, state, FossilMultiblockBuilder(pos)) },
CobblemonBlocks.RESTORATION_TANK
).build(null)
)
@JvmField
val FOSSIL_COMPARTMENT: BlockEntityType<FossilCompartmentBlockEntity> = this.create("fossil_compartment",
BlockEntityType.Builder.create({ pos, state -> FossilCompartmentBlockEntity(pos, state, FossilMultiblockBuilder(pos)) },
CobblemonBlocks.FOSSIL_COMPARTMENT
val FOSSIL_ANALYZER: BlockEntityType<FossilAnalyzerBlockEntity> = this.create("fossil_analyzer",
BlockEntityType.Builder.create({ pos, state -> FossilAnalyzerBlockEntity(pos, state, FossilMultiblockBuilder(pos)) },
CobblemonBlocks.FOSSIL_ANALYZER
).build(null)
)
@JvmField
val DISPLAY_CASE: BlockEntityType<DisplayCaseBlockEntity> = this.create("display_case",
BlockEntityType.Builder.create(::DisplayCaseBlockEntity, CobblemonBlocks.DISPLAY_CASE).build(null)
)
}
@@ -11,9 +11,9 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.apricorn.Apricorn
import com.cobblemon.mod.common.block.*
import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.block.fossilmachine.FossilCompartmentBlock
import com.cobblemon.mod.common.block.fossilmachine.FossilMonitorBlock
import com.cobblemon.mod.common.block.fossilmachine.FossilTubeBlock
import com.cobblemon.mod.common.block.FossilAnalyzerBlock
import com.cobblemon.mod.common.block.MonitorBlock
import com.cobblemon.mod.common.block.RestorationTankBlock
import com.cobblemon.mod.common.mixin.invoker.DoorBlockInvoker
import com.cobblemon.mod.common.mixin.invoker.PressurePlateBlockInvoker
import com.cobblemon.mod.common.mixin.invoker.StairsBlockInvoker
@@ -22,11 +22,13 @@ import com.cobblemon.mod.common.mixin.invoker.*
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.block.BerryBlock
import com.cobblemon.mod.common.block.chest.GildedChestBlock
import com.cobblemon.mod.common.block.sign.CobblemonHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
import net.minecraft.block.*
import net.minecraft.block.enums.Instrument
import net.minecraft.block.piston.PistonBehavior
import net.minecraft.entity.effect.StatusEffects
import net.minecraft.registry.Registries
@@ -56,6 +58,8 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
@JvmField
val FIRE_STONE_ORE = evolutionStoneOre("fire_stone_ore")
@JvmField
val NETHER_FIRE_STONE_ORE = evolutionStoneOre("nether_fire_stone_ore")
@JvmField
val ICE_STONE_ORE = evolutionStoneOre("ice_stone_ore")
@JvmField
val LEAF_STONE_ORE = evolutionStoneOre("leaf_stone_ore")
@@ -68,6 +72,8 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
@JvmField
val SUN_STONE_ORE = evolutionStoneOre("sun_stone_ore")
@JvmField
val TERRACOTTA_SUN_STONE_ORE = evolutionStoneOre("terracotta_sun_stone_ore")
@JvmField
val THUNDER_STONE_ORE = evolutionStoneOre("thunder_stone_ore")
@JvmField
val WATER_STONE_ORE = evolutionStoneOre("water_stone_ore")
@@ -103,17 +109,17 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
@JvmField
val STRIPPED_APRICORN_WOOD = log("stripped_apricorn_wood")
@JvmField
val APRICORN_PLANKS = this.create("apricorn_planks", Block(AbstractBlock.Settings.create().mapColor(MapColor.DIRT_BROWN).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
val APRICORN_PLANKS = this.create("apricorn_planks", Block(AbstractBlock.Settings.create().mapColor(MapColor.DIRT_BROWN).instrument(Instrument.BASS).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
@JvmField
val APRICORN_LEAVES = leaves("apricorn_leaves")
@JvmField
val APRICORN_FENCE = this.create("apricorn_fence", FenceBlock(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
val APRICORN_FENCE = this.create("apricorn_fence", FenceBlock(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).instrument(Instrument.BASS).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
@JvmField
val APRICORN_FENCE_GATE = this.create("apricorn_fence_gate", FenceGateBlock(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD), APRICORN_WOOD_TYPE))
val APRICORN_FENCE_GATE = this.create("apricorn_fence_gate", FenceGateBlock(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).instrument(Instrument.BASS).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD), APRICORN_WOOD_TYPE))
@JvmField // Note At the time of 1.20.0 we don't need our own BlockSetType for Apricorn wood
val APRICORN_BUTTON = this.create("apricorn_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
@JvmField
val APRICORN_PRESSURE_PLATE = this.create("apricorn_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(PressurePlateBlock.ActivationRule.EVERYTHING, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).noCollision().strength(0.5f).sounds(BlockSoundGroup.WOOD), APRICORN_BLOCK_SET_TYPE))
val APRICORN_PRESSURE_PLATE = this.create("apricorn_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(PressurePlateBlock.ActivationRule.EVERYTHING, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).instrument(Instrument.BASS).noCollision().strength(0.5f).sounds(BlockSoundGroup.WOOD), APRICORN_BLOCK_SET_TYPE))
@JvmField
val APRICORN_SIGN = this.create("apricorn_sign", CobblemonSignBlock(AbstractBlock.Settings.copy(Blocks.OAK_SIGN), APRICORN_WOOD_TYPE))
@JvmField
@@ -123,13 +129,13 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
@JvmField
val APRICORN_WALL_HANGING_SIGN = this.create("apricorn_wall_hanging_sign", CobblemonWallHangingSignBlock(AbstractBlock.Settings.copy(Blocks.OAK_HANGING_SIGN), APRICORN_WOOD_TYPE))
@JvmField
val APRICORN_SLAB = this.create("apricorn_slab", SlabBlock(AbstractBlock.Settings.create().mapColor(MapColor.OAK_TAN).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
val APRICORN_SLAB = this.create("apricorn_slab", SlabBlock(AbstractBlock.Settings.create().mapColor(MapColor.OAK_TAN).instrument(Instrument.BASS).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
@JvmField
val APRICORN_STAIRS = this.create("apricorn_stairs", StairsBlockInvoker.`cobblemon$create`(APRICORN_PLANKS.defaultState, AbstractBlock.Settings.copy(APRICORN_PLANKS)))
@JvmField
val APRICORN_DOOR = this.create("apricorn_door", DoorBlockInvoker.`cobblemon$create`(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque(), APRICORN_BLOCK_SET_TYPE))
val APRICORN_DOOR = this.create("apricorn_door", DoorBlockInvoker.`cobblemon$create`(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).instrument(Instrument.BASS).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque(), APRICORN_BLOCK_SET_TYPE))
@JvmField
val APRICORN_TRAPDOOR = this.create("apricorn_trapdoor", TrapdoorBlockInvoker.`cobblemon$create`(AbstractBlock.Settings.create().mapColor(MapColor.OAK_TAN).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque().allowsSpawning { _, _, _, _ -> false }, APRICORN_BLOCK_SET_TYPE))
val APRICORN_TRAPDOOR = this.create("apricorn_trapdoor", TrapdoorBlockInvoker.`cobblemon$create`(AbstractBlock.Settings.create().mapColor(MapColor.OAK_TAN).instrument(Instrument.BASS).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque().allowsSpawning { _, _, _, _ -> false }, APRICORN_BLOCK_SET_TYPE))
private val PLANT_PROPERTIES = AbstractBlock.Settings.create().mapColor(MapColor.DARK_GREEN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.GRASS).pistonBehavior(PistonBehavior.DESTROY)
@JvmField
@@ -148,58 +154,64 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
val YELLOW_APRICORN_SAPLING = this.create("yellow_apricorn_sapling", ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.YELLOW))
@JvmField
val MEDICINAL_LEEK = this.create("medicinal_leek", MedicinalLeekBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DULL_RED).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
val MEDICINAL_LEEK = this.create("medicinal_leek", MedicinalLeekBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DULL_RED).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MEDICINAL_LEEK_SOUNDS)))
@JvmField
val ENERGY_ROOT = this.create("energy_root", EnergyRootBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DIRT_BROWN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.ROOTS)))
val ENERGY_ROOT = this.create("energy_root", EnergyRootBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DIRT_BROWN).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.ENERGY_ROOT_SOUNDS)))
@JvmField
val BIG_ROOT = this.create("big_root", BigRootBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DARK_GREEN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.ROOTS)))
val BIG_ROOT = this.create("big_root", BigRootBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DARK_GREEN).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.BIG_ROOT_SOUNDS)))
@JvmField
val REVIVAL_HERB = this.create("revival_herb", RevivalHerbBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).mapColor(MapColor.DARK_GREEN).burnable().noCollision().breakInstantly().sounds(BlockSoundGroup.CROP)))
val REVIVAL_HERB = this.create("revival_herb", RevivalHerbBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).mapColor(MapColor.DARK_GREEN).burnable().noCollision().breakInstantly().sounds(CobblemonSounds.REVIVAL_HERB_SOUNDS)))
@JvmField
val TUMBLESTONE_CLUSTER = tumblestoneBlock("tumblestone_cluster", TumblestoneBlock.STAGE_3, 7, 3, null)
val TUMBLESTONE_CLUSTER = tumblestoneBlock("tumblestone_cluster", GrowableStoneBlock.STAGE_3, 7, 3, null)
@JvmField
val LARGE_BUDDING_TUMBLESTONE = tumblestoneBlock("large_budding_tumblestone", TumblestoneBlock.STAGE_2, 5, 3, TUMBLESTONE_CLUSTER)
val LARGE_BUDDING_TUMBLESTONE = tumblestoneBlock("large_budding_tumblestone", GrowableStoneBlock.STAGE_2, 5, 3, TUMBLESTONE_CLUSTER)
@JvmField
val MEDIUM_BUDDING_TUMBLESTONE = tumblestoneBlock("medium_budding_tumblestone", TumblestoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_TUMBLESTONE)
val MEDIUM_BUDDING_TUMBLESTONE = tumblestoneBlock("medium_budding_tumblestone", GrowableStoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_TUMBLESTONE)
@JvmField
val SMALL_BUDDING_TUMBLESTONE = tumblestoneBlock("small_budding_tumblestone", TumblestoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_TUMBLESTONE)
val SMALL_BUDDING_TUMBLESTONE = tumblestoneBlock("small_budding_tumblestone", GrowableStoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_TUMBLESTONE)
@JvmField
val SKY_TUMBLESTONE_CLUSTER = tumblestoneBlock("sky_tumblestone_cluster", TumblestoneBlock.STAGE_3, 7, 3, null)
val SKY_TUMBLESTONE_CLUSTER = tumblestoneBlock("sky_tumblestone_cluster", GrowableStoneBlock.STAGE_3, 7, 3, null)
@JvmField
val LARGE_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("large_budding_sky_tumblestone", TumblestoneBlock.STAGE_2, 5, 3, SKY_TUMBLESTONE_CLUSTER)
val LARGE_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("large_budding_sky_tumblestone", GrowableStoneBlock.STAGE_2, 5, 3, SKY_TUMBLESTONE_CLUSTER)
@JvmField
val MEDIUM_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("medium_budding_sky_tumblestone", TumblestoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_SKY_TUMBLESTONE)
val MEDIUM_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("medium_budding_sky_tumblestone", GrowableStoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_SKY_TUMBLESTONE)
@JvmField
val SMALL_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("small_budding_sky_tumblestone", TumblestoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_SKY_TUMBLESTONE)
val SMALL_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("small_budding_sky_tumblestone", GrowableStoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_SKY_TUMBLESTONE)
@JvmField
val BLACK_TUMBLESTONE_CLUSTER = tumblestoneBlock("black_tumblestone_cluster", TumblestoneBlock.STAGE_3, 7, 3, null)
val BLACK_TUMBLESTONE_CLUSTER = tumblestoneBlock("black_tumblestone_cluster", GrowableStoneBlock.STAGE_3, 7, 3, null)
@JvmField
val LARGE_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("large_budding_black_tumblestone", TumblestoneBlock.STAGE_2, 5, 3, BLACK_TUMBLESTONE_CLUSTER)
val LARGE_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("large_budding_black_tumblestone", GrowableStoneBlock.STAGE_2, 5, 3, BLACK_TUMBLESTONE_CLUSTER)
@JvmField
val MEDIUM_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("medium_budding_black_tumblestone", TumblestoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_BLACK_TUMBLESTONE)
val MEDIUM_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("medium_budding_black_tumblestone", GrowableStoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_BLACK_TUMBLESTONE)
@JvmField
val SMALL_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("small_budding_black_tumblestone", TumblestoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_BLACK_TUMBLESTONE)
val SMALL_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("small_budding_black_tumblestone", GrowableStoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_BLACK_TUMBLESTONE)
@JvmField
val TUMBLESTONE_BLOCK = this.create("tumblestone_block", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val SKY_TUMBLESTONE_BLOCK = this.create("sky_tumblestone_block", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.LIGHT_BLUE)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
val BLACK_TUMBLESTONE_BLOCK = this.create("black_tumblestone_block", Block(AbstractBlock.Settings.create()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresTool()
.instrument(Instrument.BASEDRUM)
))
@JvmField
@@ -218,38 +230,134 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
val YELLOW_APRICORN = apricornBlock("yellow_apricorn", Apricorn.YELLOW)
@JvmField
val FOSSIL_MONITOR = create(
"fossil_monitor",
FossilMonitorBlock(
val RELIC_COIN_POUCH = create(
"relic_coin_pouch",
CoinPouchBlock(
AbstractBlock.Settings.create()
.mapColor(MapColor.IRON_GRAY)
.sounds(BlockSoundGroup.METAL)
.pistonBehavior(PistonBehavior.BLOCK)
.strength(2f)
.luminance { if (it.get(FossilMonitorBlock.PROGRESS) > 0) 15 else 0 }
.sounds(CobblemonSounds.COIN_POUCH_SOUNDS)
.pistonBehavior(PistonBehavior.DESTROY)
.strength(0.4f)
.nonOpaque(), true
)
)
@JvmField
val FOSSIL_COMPARTMENT = create(
"fossil_compartment",
FossilCompartmentBlock(
val RELIC_COIN_SACK = create(
"relic_coin_sack",
CoinPouchBlock(
AbstractBlock.Settings.create()
.sounds(CobblemonSounds.COIN_POUCH_SOUNDS)
.pistonBehavior(PistonBehavior.DESTROY)
.strength(0.4f), false
))
@JvmField
val GILDED_CHEST = create(
"gilded_chest",
GildedChestBlock(
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.RED
)
)
@JvmField
val BLUE_GILDED_CHEST = create(
"blue_gilded_chest",
GildedChestBlock(
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.BLUE
)
)
@JvmField
val BLACK_GILDED_CHEST = create(
"black_gilded_chest",
GildedChestBlock(
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.BLACK
)
)
@JvmField
val YELLOW_GILDED_CHEST = create(
"yellow_gilded_chest",
GildedChestBlock(
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.YELLOW
)
)
@JvmField
val WHITE_GILDED_CHEST = create(
"white_gilded_chest",
GildedChestBlock(
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.WHITE
)
)
@JvmField
val GREEN_GILDED_CHEST = create(
"green_gilded_chest",
GildedChestBlock(
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.GREEN
)
)
@JvmField
val PINK_GILDED_CHEST = create(
"pink_gilded_chest",
GildedChestBlock(
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.PINK
)
)
@JvmField
val GIMMIGHOUL_CHEST = create(
"gimmighoul_chest",
GildedChestBlock(
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
GildedChestBlock.Type.FAKE
)
)
@JvmField
val MONITOR = create(
"monitor",
MonitorBlock(
AbstractBlock.Settings.create()
.mapColor(MapColor.IRON_GRAY)
.sounds(BlockSoundGroup.METAL)
.pistonBehavior(PistonBehavior.BLOCK)
.strength(2f)
.requiresTool()
.strength(5.0F, 6.0F)
.luminance { if (it.get(MonitorBlock.SCREEN) != MonitorBlock.MonitorScreen.OFF) 15 else 0 }
)
)
@JvmField
val FOSSIL_ANALYZER = create(
"fossil_analyzer",
FossilAnalyzerBlock(
AbstractBlock.Settings.create()
.mapColor(MapColor.IRON_GRAY)
.sounds(BlockSoundGroup.METAL)
.pistonBehavior(PistonBehavior.BLOCK)
.requiresTool()
.strength(5.0F, 6.0F)
.nonOpaque()
)
)
@JvmField
val FOSSIL_TUBE = create(
"fossil_tube",
FossilTubeBlock(
val RESTORATION_TANK = create(
"restoration_tank",
RestorationTankBlock(
AbstractBlock.Settings.create()
.mapColor(MapColor.IRON_GRAY)
.sounds(BlockSoundGroup.METAL)
.sounds(BlockSoundGroup.GLASS)
.pistonBehavior(PistonBehavior.BLOCK)
.strength(2f)
.requiresTool()
.strength(5.0F, 6.0F)
.nonOpaque()
)
)
@@ -281,17 +389,29 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
)
@JvmField
val RED_MINT = create("red_mint", MintBlock(MintType.RED, AbstractBlock.Settings.create().mapColor(MapColor.RED).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
val DISPLAY_CASE = create(
"display_case",
DisplayCaseBlock(
AbstractBlock.Settings.create()
.sounds(CobblemonSounds.DISPLAY_CASE_SOUNDS)
.nonOpaque()
.pistonBehavior(PistonBehavior.BLOCK)
.mapColor(MapColor.STONE_GRAY)
.strength(0.3f)
)
)
val RED_MINT = create("red_mint", MintBlock(MintType.RED, AbstractBlock.Settings.create().mapColor(MapColor.RED).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
@JvmField
val BLUE_MINT = create("blue_mint", MintBlock(MintType.BLUE, AbstractBlock.Settings.create().mapColor(MapColor.BLUE).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
val BLUE_MINT = create("blue_mint", MintBlock(MintType.BLUE, AbstractBlock.Settings.create().mapColor(MapColor.BLUE).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
@JvmField
val CYAN_MINT = create("cyan_mint", MintBlock(MintType.CYAN, AbstractBlock.Settings.create().mapColor(MapColor.CYAN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
val CYAN_MINT = create("cyan_mint", MintBlock(MintType.CYAN, AbstractBlock.Settings.create().mapColor(MapColor.CYAN).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
@JvmField
val PINK_MINT = create("pink_mint", MintBlock(MintType.PINK, AbstractBlock.Settings.create().mapColor(MapColor.PINK).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
val PINK_MINT = create("pink_mint", MintBlock(MintType.PINK, AbstractBlock.Settings.create().mapColor(MapColor.PINK).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
@JvmField
val GREEN_MINT = create("green_mint", MintBlock(MintType.GREEN, AbstractBlock.Settings.create().mapColor(MapColor.GREEN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
val GREEN_MINT = create("green_mint", MintBlock(MintType.GREEN, AbstractBlock.Settings.create().mapColor(MapColor.GREEN).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
@JvmField
val WHITE_MINT = create("white_mint", MintBlock(MintType.WHITE, AbstractBlock.Settings.create().mapColor(MapColor.WHITE).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
val WHITE_MINT = create("white_mint", MintBlock(MintType.WHITE, AbstractBlock.Settings.create().mapColor(MapColor.WHITE).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
@JvmField
val PASTURE = create(
@@ -308,7 +428,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
)
@JvmField
val VIVICHOKE_SEEDS = this.create("vivichoke_seeds", VivichokeBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DARK_GREEN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
val VIVICHOKE_SEEDS = this.create("vivichoke_seeds", VivichokeBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DARK_GREEN).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.VIVICHOKE_SOUNDS)))
@JvmField
val PEP_UP_FLOWER = this.create("pep_up_flower", FlowerBlock(StatusEffects.LEVITATION, 10, AbstractBlock.Settings.create().mapColor(MapColor.DARK_GREEN).noCollision().breakInstantly().sounds(BlockSoundGroup.GRASS).offset(AbstractBlock.OffsetType.XZ).pistonBehavior(PistonBehavior.DESTROY)))
@JvmField
@@ -432,7 +552,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
private fun berryBlock(name: String): BerryBlock {
val identifier = cobblemonResource("${name}_berry")
val block = this.create(identifier.path, BerryBlock(identifier, AbstractBlock.Settings.copy(Blocks.WHEAT).dynamicBounds().sounds(BlockSoundGroup.CROP).strength(0.2F)))
val block = this.create(identifier.path, BerryBlock(identifier, AbstractBlock.Settings.copy(Blocks.WHEAT).dynamicBounds().sounds(CobblemonSounds.BERRY_BUSH_SOUNDS).strength(0.2F)))
this.berries[identifier] = block
return block
}
@@ -48,5 +48,9 @@ object CobblemonCommands {
PokemonRestartCommand.register(dispatcher)
BedrockParticleCommand.register(dispatcher)
OpenDialogueCommand.register(dispatcher)
// Possibly lock down registration if and only if under dev environment or running in an environment
// with a certain system environment variable set
CobblemonInfoCommand.register(dispatcher)
}
}
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.pokeball.PokeBalls
import com.cobblemon.mod.common.entity.boat.CobblemonBoatEntity
import com.cobblemon.mod.common.entity.boat.CobblemonChestBoatEntity
import com.cobblemon.mod.common.entity.generic.GenericBedrockEntity
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.platform.PlatformRegistry
@@ -65,6 +66,15 @@ object CobblemonEntities : PlatformRegistry<Registry<EntityType<*>>, RegistryKey
.build(CHEST_BOAT_KEY.toString())
)
@JvmField
val GENERIC_BEDROCK_ENTITY_KEY = cobblemonResource("generic_bedrock")
@JvmField
val GENERIC_BEDROCK_ENTITY: EntityType<GenericBedrockEntity> = this.create(
GENERIC_BEDROCK_ENTITY_KEY.path,
EntityType.Builder.create({ _, world -> GenericBedrockEntity(world) }, SpawnGroup.MISC)
.build(GENERIC_BEDROCK_ENTITY_KEY.toString())
)
fun registerAttributes(consumer: (EntityType<out LivingEntity>, DefaultAttributeContainer.Builder) -> Unit) {
consumer(POKEMON, PokemonEntity.createAttributes())
}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.item.ability.AbilityChanger
import com.cobblemon.mod.common.api.mulch.MulchVariant
import com.cobblemon.mod.common.api.pokeball.PokeBalls
import com.cobblemon.mod.common.api.pokemon.Natures
@@ -18,6 +19,7 @@ import com.cobblemon.mod.common.block.MintBlock
import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.item.*
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
@@ -28,6 +30,8 @@ import com.cobblemon.mod.common.item.berry.PortionHealingBerryItem
import com.cobblemon.mod.common.item.berry.StatusCuringBerryItem
import com.cobblemon.mod.common.item.berry.VolatileCuringBerryItem
import com.cobblemon.mod.common.item.interactive.*
import com.cobblemon.mod.common.item.interactive.PotionItem
import com.cobblemon.mod.common.item.interactive.ability.AbilityChangeItem
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.cobblemon.mod.common.pokeball.PokeBall
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
@@ -36,13 +40,7 @@ import net.minecraft.block.Block
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.effect.StatusEffectInstance
import net.minecraft.entity.effect.StatusEffects
import net.minecraft.item.BlockItem
import net.minecraft.item.FoodComponent
import net.minecraft.item.HangingSignItem
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.item.SignItem
import net.minecraft.item.StewItem
import net.minecraft.item.*
import net.minecraft.registry.Registries
import net.minecraft.registry.Registry
import net.minecraft.registry.RegistryKey
@@ -176,19 +174,19 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val WHITE_APRICORN = apricornItem("white", ApricornItem(CobblemonBlocks.WHITE_APRICORN))
@JvmField
val RED_APRICORN_SEED = apricornSeedItem("red", ApricornSeedItem(CobblemonBlocks.RED_APRICORN_SAPLING))
val RED_APRICORN_SEED = apricornSeedItem("red", ApricornSeedItem(CobblemonBlocks.RED_APRICORN_SAPLING, CobblemonBlocks.RED_APRICORN))
@JvmField
val YELLOW_APRICORN_SEED = apricornSeedItem("yellow", ApricornSeedItem(CobblemonBlocks.YELLOW_APRICORN_SAPLING))
val YELLOW_APRICORN_SEED = apricornSeedItem("yellow", ApricornSeedItem(CobblemonBlocks.YELLOW_APRICORN_SAPLING, CobblemonBlocks.YELLOW_APRICORN))
@JvmField
val GREEN_APRICORN_SEED = apricornSeedItem("green", ApricornSeedItem(CobblemonBlocks.GREEN_APRICORN_SAPLING))
val GREEN_APRICORN_SEED = apricornSeedItem("green", ApricornSeedItem(CobblemonBlocks.GREEN_APRICORN_SAPLING, CobblemonBlocks.GREEN_APRICORN))
@JvmField
val BLUE_APRICORN_SEED = apricornSeedItem("blue", ApricornSeedItem(CobblemonBlocks.BLUE_APRICORN_SAPLING))
val BLUE_APRICORN_SEED = apricornSeedItem("blue", ApricornSeedItem(CobblemonBlocks.BLUE_APRICORN_SAPLING, CobblemonBlocks.BLUE_APRICORN))
@JvmField
val PINK_APRICORN_SEED = apricornSeedItem("pink", ApricornSeedItem(CobblemonBlocks.PINK_APRICORN_SAPLING))
val PINK_APRICORN_SEED = apricornSeedItem("pink", ApricornSeedItem(CobblemonBlocks.PINK_APRICORN_SAPLING, CobblemonBlocks.PINK_APRICORN))
@JvmField
val BLACK_APRICORN_SEED = apricornSeedItem("black", ApricornSeedItem(CobblemonBlocks.BLACK_APRICORN_SAPLING))
val BLACK_APRICORN_SEED = apricornSeedItem("black", ApricornSeedItem(CobblemonBlocks.BLACK_APRICORN_SAPLING, CobblemonBlocks.BLACK_APRICORN))
@JvmField
val WHITE_APRICORN_SEED = apricornSeedItem("white", ApricornSeedItem(CobblemonBlocks.WHITE_APRICORN_SAPLING))
val WHITE_APRICORN_SEED = apricornSeedItem("white", ApricornSeedItem(CobblemonBlocks.WHITE_APRICORN_SAPLING, CobblemonBlocks.WHITE_APRICORN))
@JvmField
val APRICORN_LOG = blockItem("apricorn_log", CobblemonBlocks.APRICORN_LOG)
@@ -227,19 +225,37 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val APRICORN_SIGN = this.create("apricorn_sign", SignItem(Item.Settings().maxCount(16), CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN))
@JvmField
val APRICORN_HANGING_SIGN = this.create("apricorn_hanging_sign", HangingSignItem(CobblemonBlocks.APRICORN_HANGING_SIGN, CobblemonBlocks.APRICORN_WALL_HANGING_SIGN, Item.Settings().maxCount(16)))
@JvmField
val GILDED_CHEST = this.create("gilded_chest", BlockItem(CobblemonBlocks.GILDED_CHEST, Item.Settings()))
@JvmField
val BLUE_GILDED_CHEST = this.create("blue_gilded_chest", BlockItem(CobblemonBlocks.BLUE_GILDED_CHEST, Item.Settings()))
@JvmField
val YELLOW_GILDED_CHEST = this.create("yellow_gilded_chest", BlockItem(CobblemonBlocks.YELLOW_GILDED_CHEST, Item.Settings()))
@JvmField
val PINK_GILDED_CHEST = this.create("pink_gilded_chest", BlockItem(CobblemonBlocks.PINK_GILDED_CHEST, Item.Settings()))
@JvmField
val BLACK_GILDED_CHEST = this.create("black_gilded_chest", BlockItem(CobblemonBlocks.BLACK_GILDED_CHEST, Item.Settings()))
@JvmField
val WHITE_GILDED_CHEST = this.create("white_gilded_chest", BlockItem(CobblemonBlocks.WHITE_GILDED_CHEST, Item.Settings()))
@JvmField
val GREEN_GILDED_CHEST = this.create("green_gilded_chest", BlockItem(CobblemonBlocks.GREEN_GILDED_CHEST, Item.Settings()))
@JvmField
val GIMMIGHOUL_CHEST = this.create("gimmighoul_chest", BlockItem(CobblemonBlocks.GIMMIGHOUL_CHEST, Item.Settings()))
@JvmField
val FOSSIL_TUBE = blockItem("fossil_tube", CobblemonBlocks.FOSSIL_TUBE)
val RESTORATION_TANK = blockItem("restoration_tank", CobblemonBlocks.RESTORATION_TANK)
@JvmField
val FOSSIL_COMPARTMENT = blockItem("fossil_compartment", CobblemonBlocks.FOSSIL_COMPARTMENT)
val FOSSIL_ANALYZER = blockItem("fossil_analyzer", CobblemonBlocks.FOSSIL_ANALYZER)
@JvmField
val FOSSIL_MONITOR = blockItem("fossil_monitor", CobblemonBlocks.FOSSIL_MONITOR)
val MONITOR = blockItem("monitor", CobblemonBlocks.MONITOR)
@JvmField
val HEALING_MACHINE = blockItem("healing_machine", CobblemonBlocks.HEALING_MACHINE)
@JvmField
val PC = blockItem("pc", CobblemonBlocks.PC)
@JvmField
val PASTURE = blockItem("pasture", CobblemonBlocks.PASTURE)
@JvmField
val DISPLAY_CASE = blockItem("display_case", CobblemonBlocks.DISPLAY_CASE)
// Evolution items
@JvmField val LINK_CABLE = create("link_cable", LinkCableItem())
@@ -267,6 +283,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField val RIBBON_SWEET = noSettingsItem("ribbon_sweet")
@JvmField val CHIPPED_POT = noSettingsItem("chipped_pot")
@JvmField val CRACKED_POT = noSettingsItem("cracked_pot")
@JvmField val MASTERPIECE_TEACUP = noSettingsItem("masterpiece_teacup")
@JvmField val UNREMARKABLE_TEACUP = noSettingsItem("unremarkable_teacup")
@JvmField val SWEET_APPLE = noSettingsItem("sweet_apple")
@JvmField val TART_APPLE = noSettingsItem("tart_apple")
@JvmField val GALARICA_CUFF = noSettingsItem("galarica_cuff")
@@ -378,7 +396,19 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField
val ZINC = create("zinc", VitaminItem(Stats.SPECIAL_DEFENCE))
@JvmField
val MEDICINAL_LEEK = create("medicinal_leek", MedicinalLeekItem(CobblemonBlocks.MEDICINAL_LEEK, Item.Settings().food(FoodComponent.Builder().snack().hunger(1).saturationModifier(0.2f).build())))
val GENIUS_FEATHER = create("genius_feather", FeatherItem(Stats.SPECIAL_ATTACK))
@JvmField
val SWIFT_FEATHER = create("swift_feather", FeatherItem(Stats.SPEED))
@JvmField
val HEALTH_FEATHER = create("health_feather", FeatherItem(Stats.HP))
@JvmField
val RESIST_FEATHER = create("resist_feather", FeatherItem(Stats.DEFENCE))
@JvmField
val MUSCLE_FEATHER = create("muscle_feather", FeatherItem(Stats.ATTACK))
@JvmField
val CLEVER_FEATHER = create("clever_feather", FeatherItem(Stats.SPECIAL_DEFENCE))
@JvmField
val MEDICINAL_LEEK = heldItem("medicinal_leek", MedicinalLeekItem(CobblemonBlocks.MEDICINAL_LEEK, Item.Settings().food(FoodComponent.Builder().snack().hunger(1).saturationModifier(0.2f).build())), "leek")
@JvmField
val ROASTED_LEEK = create("roasted_leek", Item(Item.Settings().food(FoodComponent.Builder().snack().hunger(3).saturationModifier(0.3f).build())))
@JvmField
@@ -528,6 +558,11 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField val ELIXIR = create("elixir", ElixirItem(max = false))
@JvmField val MAX_ELIXIR = create("max_elixir", ElixirItem(max = true))
@JvmField
val ABILITY_CAPSULE = this.create("ability_capsule", AbilityChangeItem(AbilityChanger.COMMON_ABILITY))
@JvmField
val ABILITY_PATCH = this.create("ability_patch", AbilityChangeItem(AbilityChanger.HIDDEN_ABILITY))
/**
* Evolution Ores and Stones
*/
@@ -548,6 +583,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField
val SUN_STONE_ORE = blockItem("sun_stone_ore", CobblemonBlocks.SUN_STONE_ORE)
@JvmField
val TERRACOTTA_SUN_STONE_ORE = blockItem("terracotta_sun_stone_ore", CobblemonBlocks.TERRACOTTA_SUN_STONE_ORE)
@JvmField
val THUNDER_STONE_ORE = blockItem("thunder_stone_ore", CobblemonBlocks.THUNDER_STONE_ORE)
@JvmField
val WATER_STONE_ORE = blockItem("water_stone_ore", CobblemonBlocks.WATER_STONE_ORE)
@@ -573,6 +610,9 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val DEEPSLATE_WATER_STONE_ORE = blockItem("deepslate_water_stone_ore", CobblemonBlocks.DEEPSLATE_WATER_STONE_ORE)
@JvmField
val DRIPSTONE_MOON_STONE_ORE = blockItem("dripstone_moon_stone_ore", CobblemonBlocks.DRIPSTONE_MOON_STONE_ORE)
@JvmField
val NETHER_FIRE_STONE_ORE = blockItem("nether_fire_stone_ore", CobblemonBlocks.NETHER_FIRE_STONE_ORE)
@JvmField
val DAWN_STONE = noSettingsItem("dawn_stone")
@JvmField
@@ -596,16 +636,28 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
// Held Items
@JvmField
val ABILITY_SHIELD = heldItem("ability_shield")
@JvmField
val ABSORB_BULB = heldItem("absorb_bulb")
@JvmField
val AIR_BALLOON = heldItem("air_balloon")
@JvmField
val ASSAULT_VEST = heldItem("assault_vest")
@JvmField
val BIG_ROOT = blockItem("big_root", CobblemonBlocks.BIG_ROOT)
@JvmField
val BINDING_BAND = heldItem("binding_band")
@JvmField
val BLACK_BELT = heldItem("black_belt")
@JvmField
val BLACK_GLASSES = heldItem("black_glasses")
@JvmField
val BLACK_SLUDGE = heldItem("black_sludge")
@JvmField
val BLUNDER_POLICY = heldItem("blunder_policy")
@JvmField
val CELL_BATTERY = heldItem("cell_battery")
@JvmField
val CHARCOAL = heldItem("charcoal_stick", remappedName = "charcoal")
@JvmField
val CHOICE_BAND = heldItem("choice_band")
@@ -615,26 +667,64 @@ 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 COVERT_CLOAK = heldItem("covert_cloak")
@JvmField
val DESTINY_KNOT = heldItem("destiny_knot")
@JvmField
val DRAGON_FANG = heldItem("dragon_fang")
@JvmField
val EJECT_BUTTON = heldItem("eject_button")
@JvmField
val EJECT_PACK = heldItem("eject_pack")
@JvmField
val EVERSTONE = heldItem("everstone")
@JvmField
val EVIOLITE = heldItem("eviolite")
@JvmField
val EXP_SHARE = heldItem("exp_share")
@JvmField
val EXPERT_BELT = heldItem("expert_belt")
@JvmField
val FAIRY_FEATHER = heldItem("fairy_feather")
@JvmField
val FLAME_ORB = heldItem("flame_orb")
@JvmField
val FLOAT_STONE = heldItem("float_stone")
@JvmField
val FOCUS_BAND = heldItem("focus_band")
@JvmField
val FOCUS_SASH = heldItem("focus_sash")
// @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 LEFTOVERS = heldItem("leftovers")
@JvmField
val LIFE_ORB = heldItem("life_orb")
@JvmField
val LIGHT_BALL = heldItem("light_ball")
@JvmField
val LIGHT_CLAY = heldItem("light_clay")
@JvmField
val LOADED_DICE = heldItem("loaded_dice")
@JvmField
val LUCKY_EGG = heldItem("lucky_egg")
// @JvmField
// val LUMINOUS_MOSS = heldItem("luminous_moss")
@JvmField
val MAGNET = heldItem("magnet")
// @JvmField
// val METRONOME = heldItem("metronome")
@JvmField
val MIRACLE_SEED = heldItem("miracle_seed")
@JvmField
@@ -645,14 +735,42 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val NEVER_MELT_ICE = heldItem("never_melt_ice")
@JvmField
val POISON_BARB = heldItem("poison_barb")
@JvmField
val POWER_ANKLET = heldItem("power_anklet")
@JvmField
val POWER_BAND = heldItem("power_band")
@JvmField
val POWER_BELT = heldItem("power_belt")
@JvmField
val POWER_BRACER = heldItem("power_bracer")
@JvmField
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 QUICK_CLAW = heldItem("quick_claw")
@JvmField
val RED_CARD = heldItem("red_card")
@JvmField
val RING_TARGET = heldItem("ring_target")
@JvmField
val ROCKY_HELMET = heldItem("rocky_helmet")
// @JvmField
// val ROOM_SERVICE = heldItem("room_service")
@JvmField
val SAFETY_GOGGLES = heldItem("safety_goggles")
// @JvmField
// val SCOPE_LENS = heldItem("scope_lens")
@JvmField
val SHARP_BEAK = heldItem("sharp_beak")
// @JvmField
// val SHED_SHELL = heldItem("shed_shell")
@JvmField
val SHELL_BELL = heldItem("shell_bell")
@JvmField
val SILK_SCARF = heldItem("silk_scarf")
@JvmField
@@ -662,9 +780,29 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField
val SPELL_TAG = heldItem("spell_tag")
@JvmField
val SMOKE_BALL = heldItem("smoke_ball")
@JvmField
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 TOXIC_ORB = heldItem("toxic_orb")
@JvmField
val TWISTED_SPOON = heldItem("twisted_spoon")
// @JvmField
// val UTILITY_UMBRELLA = heldItem("utility_umbrella")
@JvmField
val WEAKNESS_POLICY = heldItem("weakness_policy")
// @JvmField
// val WIDE_LENS = heldItem("wide_lens")
@JvmField
val WISE_GLASSES = heldItem("wise_glasses")
// @JvmField
// val ZOOM_LENS = heldItem("zoom_lens")
@JvmField
val MENTAL_HERB = compostableHeldItem("mental_herb", null, 1F)
@JvmField
@@ -680,29 +818,13 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField
val QUICK_POWDER = heldItem("quick_powder")
@JvmField
val DESTINY_KNOT = heldItem("destiny_knot")
val DAMP_ROCK = heldItem("damp_rock")
@JvmField
val EVERSTONE = heldItem("everstone")
val HEAT_ROCK = heldItem("heat_rock")
@JvmField
val POWER_ANKLET = heldItem("power_anklet")
val SMOOTH_ROCK = heldItem("smooth_rock")
@JvmField
val POWER_BAND = heldItem("power_band")
@JvmField
val POWER_BELT = heldItem("power_belt")
@JvmField
val POWER_BRACER = heldItem("power_bracer")
@JvmField
val POWER_LENS = heldItem("power_lens")
@JvmField
val POWER_WEIGHT = heldItem("power_weight")
@JvmField
val FLAME_ORB = heldItem("flame_orb")
@JvmField
val LIFE_ORB = heldItem("life_orb")
@JvmField
val TOXIC_ORB = heldItem("toxic_orb")
@JvmField
val SMOKE_BALL = heldItem("smoke_ball")
val ICY_ROCK = heldItem("icy_rock")
// Mulch
@JvmField
@@ -728,19 +850,19 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField
val ARMOR_FOSSIL = noSettingsItem("armor_fossil")
@JvmField
val BIRD_FOSSIL = noSettingsItem("bird_fossil")
val FOSSILIZED_BIRD = noSettingsItem("fossilized_bird")
@JvmField
val CLAW_FOSSIL = noSettingsItem("claw_fossil")
@JvmField
val COVER_FOSSIL = noSettingsItem("cover_fossil")
@JvmField
val DINO_FOSSIL = noSettingsItem("dino_fossil")
val FOSSILIZED_DINO = noSettingsItem("fossilized_dino")
@JvmField
val DOME_FOSSIL = noSettingsItem("dome_fossil")
@JvmField
val DRAKE_FOSSIL = noSettingsItem("drake_fossil")
val FOSSILIZED_DRAKE = noSettingsItem("fossilized_drake")
@JvmField
val FISH_FOSSIL = noSettingsItem("fish_fossil")
val FOSSILIZED_FISH = noSettingsItem("fossilized_fish")
@JvmField
val HELIX_FOSSIL = noSettingsItem("helix_fossil")
@JvmField
@@ -766,6 +888,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val HELIX_SHERD = noSettingsItem("helix_sherd")
@JvmField
val NOSTALGIC_SHERD = noSettingsItem("nostalgic_sherd")
@JvmField
val SUSPICIOUS_SHERD = noSettingsItem("suspicious_sherd")
@JvmField
val TUMBLESTONE = this.create("tumblestone", TumblestoneItem(Item.Settings(), CobblemonBlocks.SMALL_BUDDING_TUMBLESTONE))
@@ -808,9 +932,59 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField
val BLACK_TUMBLESTONE_BLOCK = blockItem("black_tumblestone_block", CobblemonBlocks.BLACK_TUMBLESTONE_BLOCK)
@JvmField
val AUTOMATON_ARMOR_TRIM_SMITHING_TEMPLATE: SmithingTemplateItem = this.create(
"automaton_armor_trim_smithing_template",
SmithingTemplateItem.of(CobblemonArmorTrims.AUTOMATON)
)
// Misc
@JvmField
val POKEMON_MODEL = this.create("pokemon_model", PokemonItem())
@JvmField
val RELIC_COIN = noSettingsItem("relic_coin")
@JvmField
val RELIC_COIN_POUCH = blockItem("relic_coin_pouch", CobblemonBlocks.RELIC_COIN_POUCH)
@JvmField
val RELIC_COIN_SACK = blockItem("relic_coin_sack", CobblemonBlocks.RELIC_COIN_SACK)
// Type Gems
@JvmField
val NORMAL_GEM = noSettingsItem("normal_gem")
@JvmField
val FIRE_GEM = noSettingsItem("fire_gem")
@JvmField
val WATER_GEM = noSettingsItem("water_gem")
@JvmField
val GRASS_GEM = noSettingsItem("grass_gem")
@JvmField
val ELECTRIC_GEM = noSettingsItem("electric_gem")
@JvmField
val ICE_GEM = noSettingsItem("ice_gem")
@JvmField
val FIGHTING_GEM = noSettingsItem("fighting_gem")
@JvmField
val POISON_GEM = noSettingsItem("poison_gem")
@JvmField
val GROUND_GEM = noSettingsItem("ground_gem")
@JvmField
val FLYING_GEM = noSettingsItem("flying_gem")
@JvmField
val PSYCHIC_GEM = noSettingsItem("psychic_gem")
@JvmField
val BUG_GEM = noSettingsItem("bug_gem")
@JvmField
val ROCK_GEM = noSettingsItem("rock_gem")
@JvmField
val GHOST_GEM = noSettingsItem("ghost_gem")
@JvmField
val DRAGON_GEM = noSettingsItem("dragon_gem")
@JvmField
val DARK_GEM = noSettingsItem("dark_gem")
@JvmField
val STEEL_GEM = noSettingsItem("steel_gem")
@JvmField
val FAIRY_GEM = noSettingsItem("fairy_gem")
private fun blockItem(name: String, block: Block): BlockItem = this.create(name, BlockItem(block, Item.Settings()))
@@ -837,6 +1011,16 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
}
}
)
private fun heldItem(name: String, item: Item, remappedName: String? = null) = create(
name = name,
entry = item.also {
if (remappedName != null) {
CobblemonHeldItemManager.registerRemap(it, remappedName)
CobblemonHeldItemManager.registerRemap(Items.BONE, "thickclub")
CobblemonHeldItemManager.registerRemap(Items.SNOWBALL, "snowball")
}
}
)
private fun compostable(item: Item, increaseLevelChance: Float) = Cobblemon.implementation.registerCompostable(item, increaseLevelChance)
@@ -13,32 +13,17 @@ import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.client.net.PlayerInteractOptionsHandler
import com.cobblemon.mod.common.client.net.SetClientPlayerDataHandler
import com.cobblemon.mod.common.client.net.battle.BattleApplyPassResponseHandler
import com.cobblemon.mod.common.client.net.battle.BattleCaptureEndHandler
import com.cobblemon.mod.common.client.net.battle.BattleCaptureShakeHandler
import com.cobblemon.mod.common.client.net.battle.BattleCaptureStartHandler
import com.cobblemon.mod.common.client.net.battle.BattleChallengeExpiredHandler
import com.cobblemon.mod.common.client.net.battle.BattleChallengeNotificationHandler
import com.cobblemon.mod.common.client.net.battle.BattleEndHandler
import com.cobblemon.mod.common.client.net.battle.BattleFaintHandler
import com.cobblemon.mod.common.client.net.battle.BattleHealthChangeHandler
import com.cobblemon.mod.common.client.net.battle.BattleInitializeHandler
import com.cobblemon.mod.common.client.net.battle.BattleMadeInvalidChoiceHandler
import com.cobblemon.mod.common.client.net.battle.BattleMakeChoiceHandler
import com.cobblemon.mod.common.client.net.battle.BattleMessageHandler
import com.cobblemon.mod.common.client.net.battle.BattleMusicHandler
import com.cobblemon.mod.common.client.net.battle.BattlePersistentStatusHandler
import com.cobblemon.mod.common.client.net.battle.BattleQueueRequestHandler
import com.cobblemon.mod.common.client.net.battle.BattleSetTeamPokemonHandler
import com.cobblemon.mod.common.client.net.battle.BattleSwitchPokemonHandler
import com.cobblemon.mod.common.client.net.battle.BattleUpdateTeamPokemonHandler
import com.cobblemon.mod.common.client.net.animation.PlayPoseableAnimationHandler
import com.cobblemon.mod.common.client.net.battle.*
import com.cobblemon.mod.common.client.net.callback.move.OpenMoveCallbackHandler
import com.cobblemon.mod.common.client.net.callback.party.OpenPartyCallbackHandler
import com.cobblemon.mod.common.client.net.callback.partymove.OpenPartyMoveCallbackHandler
import com.cobblemon.mod.common.client.net.data.DataRegistrySyncPacketHandler
import com.cobblemon.mod.common.client.net.data.UnlockReloadPacketHandler
import com.cobblemon.mod.common.client.net.effect.RunPosableMoLangHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueClosedHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueOpenedHandler
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormEntityParticleHandler
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormParticleHandler
import com.cobblemon.mod.common.client.net.gui.InteractPokemonUIPacketHandler
import com.cobblemon.mod.common.client.net.gui.SummaryUIPacketHandler
@@ -48,7 +33,6 @@ import com.cobblemon.mod.common.client.net.pasture.PokemonPasturedHandler
import com.cobblemon.mod.common.client.net.pasture.PokemonUnpasturedHandler
import com.cobblemon.mod.common.client.net.pokemon.update.PokemonUpdatePacketHandler
import com.cobblemon.mod.common.client.net.settings.ServerSettingsPacketHandler
import com.cobblemon.mod.common.client.net.sound.PokemonCryHandler
import com.cobblemon.mod.common.client.net.sound.UnvalidatedPlaySoundS2CPacketHandler
import com.cobblemon.mod.common.client.net.spawn.SpawnExtraDataEntityHandler
import com.cobblemon.mod.common.client.net.starter.StarterUIPacketHandler
@@ -73,18 +57,24 @@ import com.cobblemon.mod.common.client.net.trade.TradeOfferNotificationHandler
import com.cobblemon.mod.common.client.net.trade.TradeStartedHandler
import com.cobblemon.mod.common.client.net.trade.TradeUpdatedHandler
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
import com.cobblemon.mod.common.net.messages.client.animation.PlayPoseableAnimationPacket
import com.cobblemon.mod.common.net.messages.client.battle.*
import com.cobblemon.mod.common.net.messages.client.callback.OpenMoveCallbackPacket
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyCallbackPacket
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyMoveCallbackPacket
import com.cobblemon.mod.common.net.messages.client.data.AbilityRegistrySyncPacket
import com.cobblemon.mod.common.net.messages.client.data.BerryRegistrySyncPacket
import com.cobblemon.mod.common.net.messages.client.data.GlobalSpeciesFeatureSyncPacket
import com.cobblemon.mod.common.net.messages.client.data.MovesRegistrySyncPacket
import com.cobblemon.mod.common.net.messages.client.data.PropertiesCompletionRegistrySyncPacket
import com.cobblemon.mod.common.net.messages.client.data.SpeciesFeatureAssignmentSyncPacket
import com.cobblemon.mod.common.net.messages.client.data.SpeciesRegistrySyncPacket
import com.cobblemon.mod.common.net.messages.client.data.StandardSpeciesFeatureSyncPacket
import com.cobblemon.mod.common.net.messages.client.data.UnlockReloadPacket
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueClosedPacket
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueOpenedPacket
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
import com.cobblemon.mod.common.net.messages.client.fossil.FossilRegistrySyncPacket
import com.cobblemon.mod.common.net.messages.client.fossil.NaturalMaterialRegistrySyncPacket
@@ -97,8 +87,8 @@ import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.Add
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.ClearEvolutionsPacket
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.RemoveEvolutionPacket
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
import com.cobblemon.mod.common.net.messages.client.sound.PokemonCryPacket
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnGenericBedrockPacket
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokeballPacket
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokemonPacket
import com.cobblemon.mod.common.net.messages.client.starter.OpenStarterUIPacket
@@ -243,6 +233,7 @@ object CobblemonNetwork : NetworkManager {
this.createClientBound(PokemonStateUpdatePacket.ID, PokemonStateUpdatePacket::decode, PokemonUpdatePacketHandler())
this.createClientBound(TetheringUpdatePacket.ID, TetheringUpdatePacket::decode, PokemonUpdatePacketHandler())
this.createClientBound(TradeableUpdatePacket.ID, TradeableUpdatePacket::decode, PokemonUpdatePacketHandler())
this.createClientBound(SpeciesFeatureUpdatePacket.ID, SpeciesFeatureUpdatePacket::decode, PokemonUpdatePacketHandler())
this.createClientBound(OriginalTrainerUpdatePacket.ID, OriginalTrainerUpdatePacket::decode, PokemonUpdatePacketHandler())
// Evolution start
@@ -296,6 +287,8 @@ object CobblemonNetwork : NetworkManager {
this.createClientBound(BattleMadeInvalidChoicePacket.ID, BattleMadeInvalidChoicePacket::decode, BattleMadeInvalidChoiceHandler)
this.createClientBound(BattleMusicPacket.ID, BattleMusicPacket::decode, BattleMusicHandler)
this.createClientBound(BattleChallengeExpiredPacket.ID, BattleChallengeExpiredPacket::decode, BattleChallengeExpiredHandler)
this.createClientBound(BattleReplacePokemonPacket.ID, BattleReplacePokemonPacket::decode, BattleReplacePokemonHandler)
this.createClientBound(BattleTransformPokemonPacket.ID, BattleTransformPokemonPacket::decode, BattleTransformPokemonHandler)
@@ -309,17 +302,23 @@ object CobblemonNetwork : NetworkManager {
this.createClientBound(PropertiesCompletionRegistrySyncPacket.ID, PropertiesCompletionRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
this.createClientBound(UnlockReloadPacket.ID, UnlockReloadPacket::decode, UnlockReloadPacketHandler)
this.createClientBound(BerryRegistrySyncPacket.ID, BerryRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
this.createClientBound(StandardSpeciesFeatureSyncPacket.ID, StandardSpeciesFeatureSyncPacket::decode, DataRegistrySyncPacketHandler())
this.createClientBound(GlobalSpeciesFeatureSyncPacket.ID, GlobalSpeciesFeatureSyncPacket::decode, DataRegistrySyncPacketHandler())
this.createClientBound(SpeciesFeatureAssignmentSyncPacket.ID, SpeciesFeatureAssignmentSyncPacket::decode, DataRegistrySyncPacketHandler())
this.createClientBound(NaturalMaterialRegistrySyncPacket.ID, NaturalMaterialRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
this.createClientBound(FossilRegistrySyncPacket.ID, FossilRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
// Effects
this.createClientBound(SpawnSnowstormParticlePacket.ID, SpawnSnowstormParticlePacket::decode, SpawnSnowstormParticleHandler)
this.createClientBound(SpawnSnowstormEntityParticlePacket.ID, SpawnSnowstormEntityParticlePacket::decode, SpawnSnowstormEntityParticleHandler)
this.createClientBound(RunPosableMoLangPacket.ID, RunPosableMoLangPacket::decode, RunPosableMoLangHandler)
// Hax
this.createClientBound(UnvalidatedPlaySoundS2CPacket.ID, UnvalidatedPlaySoundS2CPacket::decode, UnvalidatedPlaySoundS2CPacketHandler)
this.createClientBound(SpawnPokemonPacket.ID, SpawnPokemonPacket::decode, SpawnExtraDataEntityHandler())
this.createClientBound(SpawnPokeballPacket.ID, SpawnPokeballPacket::decode, SpawnExtraDataEntityHandler())
this.createClientBound(ToastPacket.ID, ToastPacket::decode, ToastPacketHandler)
this.createClientBound(SpawnGenericBedrockPacket.ID, SpawnGenericBedrockPacket::decode, SpawnExtraDataEntityHandler())
// Trade packets
this.createClientBound(TradeAcceptanceChangedPacket.ID, TradeAcceptanceChangedPacket::decode, TradeAcceptanceChangedHandler)
@@ -337,7 +336,7 @@ object CobblemonNetwork : NetworkManager {
this.createClientBound(PokemonUnpasturedPacket.ID, PokemonUnpasturedPacket::decode, PokemonUnpasturedHandler)
// Behaviours
this.createClientBound(PokemonCryPacket.ID, PokemonCryPacket::decode, PokemonCryHandler)
this.createClientBound(PlayPoseableAnimationPacket.ID, PlayPoseableAnimationPacket::decode, PlayPoseableAnimationHandler)
// Move select packets
this.createClientBound(OpenMoveCallbackPacket.ID, OpenMoveCallbackPacket::decode, OpenMoveCallbackHandler)
@@ -16,6 +16,7 @@ import net.minecraft.registry.RegistryKey
import net.minecraft.registry.RegistryKeys
import net.minecraft.sound.BlockSoundGroup
import net.minecraft.sound.SoundEvent
import net.minecraft.sound.SoundEvents
object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Registry<SoundEvent>>, SoundEvent>() {
@@ -55,6 +56,10 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
val POKE_BALL_SEND_OUT = this.create("poke_ball.send_out")
@JvmField
val POKE_BALL_RECALL = this.create("poke_ball.recall")
@JvmField
val POKE_BALL_THROW = this.create("poke_ball.throw")
@JvmField
val POKE_BALL_TRAIL = this.create("poke_ball.trail")
@JvmField
val ITEM_USE = this.create("item.use")
@@ -62,6 +67,8 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
val CAN_EVOLVE = this.create("pokemon.can_evolve")
@JvmField
val EVOLVING = this.create("pokemon.evolving")
@JvmField
val EVOLVE = this.create("evolution.evolve")
@JvmField
val PVN_BATTLE = this.create("battle.pvn.default")
@@ -78,6 +85,8 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
val MEDICINE_PILLS_USE = this.create("medicine_pills.use")
@JvmField
val MEDICINE_SPRAY_USE = this.create("medicine_spray.use")
@JvmField
val MEDICINE_FEATHER_USE = this.create("medicine_feather.use")
@JvmField
val BERRY_HARVEST = this.create("berry.harvest")
@@ -90,28 +99,36 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
val MULCH_REMOVE = this.create("mulch.remove")
@JvmField
val FOSSIL_MACHINE_ACTIVATE = this.create("fossilmachine.activate")
val FOSSIL_MACHINE_ACTIVATE = this.create("fossil_machine.activate")
@JvmField
val FOSSIL_MACHINE_ACTIVE_LOOP = this.create("fossilmachine.active_loop")
val FOSSIL_MACHINE_ACTIVE_LOOP = this.create("fossil_machine.active_loop")
@JvmField
val FOSSIL_MACHINE_ASSEMBLE = this.create("fossilmachine.assemble")
val FOSSIL_MACHINE_ASSEMBLE = this.create("fossil_machine.assemble")
@JvmField
val FOSSIL_MACHINE_DNA_FULL = this.create("fossilmachine.dna_full")
val FOSSIL_MACHINE_DNA_FULL = this.create("fossil_machine.dna_full")
@JvmField
val FOSSIL_MACHINE_FINISHED = this.create("fossilmachine.finished")
val FOSSIL_MACHINE_FINISHED = this.create("fossil_machine.finished")
@JvmField
val FOSSIL_MACHINE_INSERT_DNA = this.create("fossilmachine.insert_dna")
val FOSSIL_MACHINE_INSERT_DNA = this.create("fossil_machine.insert_dna")
@JvmField
val FOSSIL_MACHINE_INSERT_DNA_SMALL = this.create("fossilmachine.insert_dna_small")
val FOSSIL_MACHINE_INSERT_DNA_SMALL = this.create("fossil_machine.insert_dna_small")
@JvmField
val FOSSIL_MACHINE_INSERT_FOSSIL = this.create("fossilmachine.insert_fossil")
val FOSSIL_MACHINE_INSERT_FOSSIL = this.create("fossil_machine.insert_fossil")
@JvmField
val FOSSIL_MACHINE_RETRIEVE_FOSSIL = this.create("fossilmachine.retrieve_fossil")
val FOSSIL_MACHINE_RETRIEVE_FOSSIL = this.create("fossil_machine.retrieve_fossil")
@JvmField
val FOSSIL_MACHINE_RETRIEVE_POKEMON = this.create("fossilmachine.retrieve_pokemon")
val FOSSIL_MACHINE_RETRIEVE_POKEMON = this.create("fossil_machine.retrieve_pokemon")
@JvmField
val FOSSIL_MACHINE_UNPROTECTED = this.create("fossilmachine.unprotected")
val FOSSIL_MACHINE_UNPROTECTED = this.create("fossil_machine.unprotected")
@JvmField
val COIN_POUCH_BREAK = this.create("coin_pouch.break")
@JvmField
val COIN_POUCH_HIT = this.create("coin_pouch.hit")
@JvmField
val COIN_POUCH_STEP = this.create("coin_pouch.step")
@JvmField
val COIN_POUCH_PLACE = this.create("coin_pouch.place")
@JvmField
val TUMBLESTONE_BREAK = this.create("tumblestone.break")
@JvmField
@@ -123,6 +140,99 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
@JvmField
val TUMBLESTONE_STEP = this.create("tumblestone.step")
@JvmField
val GIMMIGHOUL_GIVE_ITEM_SMALL = this.create("gimmighoul.give_item_small")
@JvmField
val GIMMIGHOUL_REVEAL = this.create("gimmighoul.reveal")
@JvmField
val BERRY_BUSH_BREAK = this.create("berry_bush.break")
@JvmField
val BERRY_BUSH_PLACE = this.create("berry_bush.place")
@JvmField
val BIG_ROOT_BREAK = this.create("big_root.break")
@JvmField
val ENERGY_ROOT_PLACE = this.create("energy_root.place")
@JvmField
val VIVICHOKE_BREAK = this.create("vivichoke.break")
@JvmField
val VIVICHOKE_PLACE = this.create("vivichoke.place")
@JvmField
val MINT_BREAK = this.create("mint.break")
@JvmField
val MINT_PLACE = this.create("mint.place")
@JvmField
val REVIVAL_HERB_BREAK = this.create("revival_herb.break")
@JvmField
val REVIVAL_HERB_PLACE = this.create("revival_herb.place")
@JvmField
val MEDICINAL_LEEK_BREAK = this.create("medicinal_leek.break")
@JvmField
val MEDICINAL_LEEK_PLACE = this.create("medicinal_leek.plant")
@JvmField
val GILDED_CHEST_OPEN = this.create("gilded_chest.open")
@JvmField
val GILDED_CHEST_CLOSE = this.create("gilded_chest.close")
@JvmField
val GILDED_CHEST_STEP = this.create("gilded_chest.step")
@JvmField
val GILDED_CHEST_HIT = this.create("gilded_chest.hit")
@JvmField
val GILDED_CHEST_BREAK = this.create("gilded_chest.break")
@JvmField
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
)
@JvmField
val IMPACT_NORMAL = this.create("impact.normal")
@JvmField
val IMPACT_BUG = this.create("impact.bug")
@JvmField
val IMPACT_DARK = this.create("impact.dark")
@JvmField
val IMPACT_DRAGON = this.create("impact.dragon")
@JvmField
val IMPACT_ELECTRIC = this.create("impact.electric")
@JvmField
val IMPACT_FAIRY = this.create("impact.fairy")
@JvmField
val IMPACT_FIGHTING = this.create("impact.fighting")
@JvmField
val IMPACT_FIRE = this.create("impact.fire")
@JvmField
val IMPACT_FLYING = this.create("impact.flying")
@JvmField
val IMPACT_GHOST = this.create("impact.ghost")
@JvmField
val IMPACT_GRASS = this.create("impact.grass")
@JvmField
val IMPACT_GROUND = this.create("impact.ground")
@JvmField
val IMPACT_ICE = this.create("impact.ice")
@JvmField
val IMPACT_POISON = this.create("impact.poison")
@JvmField
val IMPACT_PSYCHIC = this.create("impact.psychic")
@JvmField
val IMPACT_ROCK = this.create("impact.rock")
@JvmField
val IMPACT_STEEL = this.create("impact.steel")
@JvmField
val IMPACT_WATER = this.create("impact.water")
@JvmField
val TUMBLESTONE_SOUNDS = BlockSoundGroup(1f, 1f,
TUMBLESTONE_BREAK,
@@ -141,5 +251,99 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
TUMBLESTONE_STEP
)
@JvmField
val BERRY_BUSH_SOUNDS = BlockSoundGroup(1f, 1f,
BERRY_BUSH_BREAK,
SoundEvents.BLOCK_GRASS_STEP,
BERRY_BUSH_PLACE,
SoundEvents.BLOCK_GRASS_HIT,
SoundEvents.BLOCK_GRASS_STEP
)
@JvmField
val BIG_ROOT_SOUNDS = BlockSoundGroup(1f, 1f,
BIG_ROOT_BREAK,
SoundEvents.BLOCK_ROOTS_STEP,
SoundEvents.BLOCK_ROOTS_PLACE,
SoundEvents.BLOCK_ROOTS_HIT,
SoundEvents.BLOCK_ROOTS_FALL
)
@JvmField
val ENERGY_ROOT_SOUNDS = BlockSoundGroup(1f, 1f,
SoundEvents.BLOCK_ROOTS_BREAK,
SoundEvents.BLOCK_ROOTS_STEP,
ENERGY_ROOT_PLACE,
SoundEvents.BLOCK_ROOTS_HIT,
SoundEvents.BLOCK_ROOTS_FALL
)
@JvmField
val MEDICINAL_LEEK_SOUNDS = BlockSoundGroup(1f, 1f,
MEDICINAL_LEEK_BREAK,
SoundEvents.BLOCK_GRASS_STEP,
MEDICINAL_LEEK_PLACE,
SoundEvents.BLOCK_GRASS_HIT,
SoundEvents.BLOCK_GRASS_FALL
)
@JvmField
val VIVICHOKE_SOUNDS = BlockSoundGroup(1f, 1f,
VIVICHOKE_BREAK,
SoundEvents.BLOCK_GRASS_STEP,
VIVICHOKE_PLACE,
SoundEvents.BLOCK_GRASS_HIT,
SoundEvents.BLOCK_GRASS_FALL
)
@JvmField
val MINT_SOUNDS = BlockSoundGroup(1f, 1f,
MINT_BREAK,
SoundEvents.BLOCK_GRASS_STEP,
MINT_PLACE,
SoundEvents.BLOCK_GRASS_HIT,
SoundEvents.BLOCK_GRASS_FALL
)
@JvmField
val REVIVAL_HERB_SOUNDS = BlockSoundGroup(1f, 1f,
REVIVAL_HERB_BREAK,
SoundEvents.BLOCK_GRASS_STEP,
REVIVAL_HERB_PLACE,
SoundEvents.BLOCK_GRASS_HIT,
SoundEvents.BLOCK_GRASS_FALL
)
@JvmField
val GILDED_CHEST_SOUNDS = BlockSoundGroup(1f, 1f,
GILDED_CHEST_BREAK,
GILDED_CHEST_STEP,
GILDED_CHEST_PLACE,
GILDED_CHEST_HIT,
GILDED_CHEST_STEP
)
@JvmField
val DISPLAY_CASE_ADD_ITEM = this.create("display_case.add_item")
@JvmField
val DISPLAY_CASE_REMOVE_ITEM = this.create("display_case.remove_item")
@JvmField
val DISPLAY_CASE_BREAK = this.create("display_case.break")
@JvmField
val DISPLAY_CASE_HIT = this.create("display_case.hit")
@JvmField
val DISPLAY_CASE_PLACE = this.create("display_case.place")
@JvmField
val DISPLAY_CASE_STEP = this.create("display_case.step")
@JvmField
val DISPLAY_CASE_SOUNDS = BlockSoundGroup(1f, 1f,
DISPLAY_CASE_BREAK,
DISPLAY_CASE_STEP,
DISPLAY_CASE_PLACE,
DISPLAY_CASE_HIT,
DISPLAY_CASE_STEP
)
private fun create(name: String): SoundEvent = this.create(name, SoundEvent.of(cobblemonResource(name)))
}
@@ -113,6 +113,14 @@ object CobblemonCriteria {
)
)
// Advancement criteria for [grow_tumblestone.json]
val PLANT_TUMBLESTONE = this.create(
SimpleCriterionTrigger(
cobblemonResource("plant_tumblestone"),
PlantTumblestoneCriterionCondition::class.java
)
)
private fun <T : Criterion<*>> create(criteria: T): T = Cobblemon.implementation.registerCriteria(criteria)
}
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.advancement.criterion
import com.cobblemon.mod.common.block.TumblestoneBlock
import com.google.gson.JsonObject
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos
/**
* A criterion condition for when a tumblestone block is planted
* @param id The identifier of the criterion
* @param predicate The predicate for the criterion
*
* @author Aethen
* @since 02/28/2024
*/
class PlantTumblestoneCriterionCondition(id: Identifier, predicate: LootContextPredicate) :
SimpleCriterionCondition<PlantTumblestoneContext>(id, predicate) {
override fun toJson(json: JsonObject) {
// Add properties to json if needed. None needed for this criterion
}
override fun fromJson(json: JsonObject) {
// Parse properties from json if needed. None needed for this criterion
}
/**
* Checks if the tumblestone block can grow at the given position
* @param player The player that planted the tumblestone block
* @param context The context of the criterion
* @return True if the tumblestone block can grow at the given position, false otherwise
*/
override fun matches(player: ServerPlayerEntity, context: PlantTumblestoneContext): Boolean {
return context.tumbleStoneBlock.canGrow(context.pos, player.world)
}
}
/**
* The context of the [PlantTumblestoneCriterionCondition]
* @param pos The position of the tumblestone block
* @param tumbleStoneBlock The tumblestone block
*/
open class PlantTumblestoneContext(var pos: BlockPos, var tumbleStoneBlock: TumblestoneBlock)
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.api.abilities
import com.cobblemon.mod.common.api.Priority
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.DataKeys
import com.google.gson.JsonObject
import net.minecraft.nbt.NbtCompound
@@ -21,7 +22,7 @@ import net.minecraft.nbt.NbtCompound
* @author Qu
* @since January 9th, 2022
*/
open class Ability internal constructor(var template: AbilityTemplate, var forced: Boolean) {
open class Ability internal constructor(var template: AbilityTemplate, forced: Boolean) {
val name: String
get() = template.name
@@ -34,16 +35,26 @@ open class Ability internal constructor(var template: AbilityTemplate, var force
/**
* This represents the last known index of this backing ability in the species data.
* If -1 the ability will attempt to find the correct index or reroll itself, this is done in order to be compatible with existing data
* The value can be mutated however this is not recommended by API users.
* @see [Pokemon.updateAbility].
*/
var forced: Boolean = forced
internal set
/**
* This represents the last known index of this backing ability in the species data.
*
* @see [Pokemon.updateAbility].
*/
var index: Int = -1
internal set
/**
* The last known priority of this ability in the species data.
* The value can be mutated however this is not recommended by API users.
*
* @see [Pokemon.updateAbility].
*/
var priority = Priority.LOWEST
internal set
open fun saveToNBT(nbt: NbtCompound): NbtCompound {
nbt.putString(DataKeys.POKEMON_ABILITY_NAME, name)
@@ -62,19 +73,23 @@ open class Ability internal constructor(var template: AbilityTemplate, var force
}
open fun loadFromNBT(nbt: NbtCompound): Ability {
forced = nbt.getBoolean(DataKeys.POKEMON_ABILITY_FORCED)
this.template = Abilities.getOrException(nbt.getString(DataKeys.POKEMON_ABILITY_NAME))
this.forced = nbt.getBoolean(DataKeys.POKEMON_ABILITY_FORCED)
if (nbt.contains(DataKeys.POKEMON_ABILITY_INDEX) && nbt.contains(DataKeys.POKEMON_ABILITY_PRIORITY)) {
this.index = nbt.getInt(DataKeys.POKEMON_ABILITY_INDEX)
this.priority = Priority.valueOf(nbt.getString(DataKeys.POKEMON_ABILITY_PRIORITY))
}
return this
}
open fun loadFromJSON(json: JsonObject): Ability {
forced = json.get(DataKeys.POKEMON_ABILITY_FORCED)?.asBoolean ?: false
this.template = Abilities.getOrException(json.get(DataKeys.POKEMON_ABILITY_NAME).asString)
this.forced = json.get(DataKeys.POKEMON_ABILITY_FORCED)?.asBoolean ?: false
if (json.has(DataKeys.POKEMON_ABILITY_INDEX) && json.has(DataKeys.POKEMON_ABILITY_PRIORITY)) {
this.index = json.get(DataKeys.POKEMON_ABILITY_INDEX).asInt
this.priority = Priority.valueOf(json.get(DataKeys.POKEMON_ABILITY_PRIORITY).asString)
}
return this
}
}
@@ -28,7 +28,6 @@ class AbilityTemplate(
*/
fun create(forced: Boolean = false) = builder(this, forced)
/**
* Returns the Ability and loads the given NBT Tag into it.
*
@@ -42,4 +41,5 @@ class AbilityTemplate(
* Ability extensions need to write and read their needed data from here.
*/
fun create(json: JsonObject) = create().loadFromJSON(json)
}
@@ -135,28 +135,31 @@ class BattleMessage(rawMessage: String) {
return this.actorAndActivePokemon(pnx, battle)
}
/*
Example:
|-curestatus|p1: a8e5710e-6835-4387-99d3-331b45f848e6|slp|[msg]
|-curestatus|p1: 0686b20d-3019-4167-92e2-786834245743|slp|[msg]
// Function used to grab BattlePokemon (As we need to be able to grab non active pokemon to cure their status)
// by using playerNumber(actorID) and pokemon uuid(pokemonID)
/**
* Queries an argument at the given [index] for a 'pnx' and uuid that will be parsed into a [BattlePokemon].
*
* @param index The index of the argument referencing the [BattlePokemon].
* @param battle The [PokemonBattle] being queried.
* @return The [BattlePokemon] if the argument exists and is successfully parsed; otherwise null.
*/
fun getBattlePokemon(index: Int, battle: PokemonBattle): BattlePokemon? {
val actorAndPokemonID = this.argumentAt(index)?.takeIf { it.length >= 2 }?.split(": ") ?: return null
if (actorAndPokemonID.count() < 2) return null
val actorID = actorAndPokemonID[0]
val pokemonID = actorAndPokemonID[1]
return this.getBattlePokemon(actorID, pokemonID, battle)
fun battlePokemon(index: Int, battle: PokemonBattle): BattlePokemon? {
val (actorID, pokemonID) = this.pnxAndUuid(index) ?: return null
return this.battlePokemon(actorID, pokemonID, battle)
}
fun getSourceBattlePokemon(battle: PokemonBattle): BattlePokemon? {
val sourcePokemonArgument = this.optionalArguments.get("of") ?: return null
val actorAndPokemonID = sourcePokemonArgument.takeIf { it.length >= 2 }?.split(": ") ?: return null
if (actorAndPokemonID.count() < 2) return null
val actorID = actorAndPokemonID[0]
val pokemonID = actorAndPokemonID[1]
return this.getBattlePokemon(actorID, pokemonID, battle)
/**
* Queries an optional argument identified by [optionalArg] for a 'pnx' and uuid that will be parsed into a [BattlePokemon].
*
* @param optionalArg The id of the optional argument referencing the [BattlePokemon].
* @param battle The [PokemonBattle] being queried.
* @return The [BattlePokemon] if the argument exists and is successfully parsed; otherwise null.
*/
fun battlePokemonFromOptional(battle: PokemonBattle, optionalArg: String = "of"): BattlePokemon? {
val optional = this.optionalArguments.get(optionalArg) ?: return null
val pokemonID = optional.takeIf { it.length >= 2 }?.split(":")?.takeIf { it.size == 2 } ?: return null
val pnx = pokemonID[0].takeIf { it.matches(PNX_MATCHER) || it.matches(PN_MATCHER) } ?: return null
val uuid = pokemonID[1].trim()
return this.battlePokemon(pnx, uuid, battle)
}
/**
@@ -167,7 +170,7 @@ class BattleMessage(rawMessage: String) {
*/
fun pnxAndUuid(index: Int): Pair<String, String>? {
val argument = this.argumentAt(index)?.takeIf { it.length >= 2 }?.split(":")?.takeIf { it.size == 2 } ?: return null
val pnx = argument[0].takeIf { it.matches(PNX_MATCHER) } ?: return null
val pnx = argument[0].takeIf { it.matches(PNX_MATCHER) || it.matches(PN_MATCHER) } ?: return null
val uuid = argument[1].trim()
return pnx to uuid
}
@@ -234,7 +237,7 @@ class BattleMessage(rawMessage: String) {
null
}
private fun getBattlePokemon(pnx: String, pokemonID: String, battle: PokemonBattle): BattlePokemon? = try {
private fun battlePokemon(pnx: String, pokemonID: String, battle: PokemonBattle): BattlePokemon? = try {
battle.getBattlePokemon(pnx, pokemonID)
} catch (_: Exception) {
null
@@ -8,6 +8,8 @@
package com.cobblemon.mod.common.api.battles.model
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.Cobblemon.LOGGER
import com.cobblemon.mod.common.CobblemonNetwork
@@ -35,10 +37,10 @@ import com.cobblemon.mod.common.battles.dispatch.WaitDispatch
import com.cobblemon.mod.common.battles.interpreter.ContextManager
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.battles.runner.ShowdownService
import com.cobblemon.mod.common.battles.ForfeitActionResponse
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.net.messages.client.battle.BattleEndPacket
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
import com.cobblemon.mod.common.net.messages.client.battle.BattleMusicPacket
import com.cobblemon.mod.common.pokemon.evolution.progress.DefeatEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.progress.LastBattleCriticalHitsEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.requirements.DefeatRequirement
@@ -101,6 +103,11 @@ open class PokemonBattle(
var turn: Int = 1
private set
private var ticks: Int = 0
set(value) { field = value.coerceAtMost(Int.MAX_VALUE) } // go outside
/** The current duration of the battle in seconds. */
val time: Int get() = ticks % 20
var dispatchResult = GO
val dispatches = ConcurrentLinkedDeque<BattleDispatch>()
@@ -160,7 +167,7 @@ open class PokemonBattle(
fun getActor(player: ServerPlayerEntity) = actors.firstOrNull { it.isForPlayer(player) }
/**
* Gets a BattleActor and an [ActiveBattlePokemon] from a pnx key, e.g. p2a
* Gets a [BattleActor] and an [ActiveBattlePokemon] from a pnx key, e.g. p2a
*
* Returns null if either the pn or x is invalid.
*/
@@ -173,6 +180,11 @@ open class PokemonBattle(
return actor to pokemon
}
/**
* Gets a [BattlePokemon] from a pnx key and uuid.
*
* Returns null if the pnx key is invalid or the uuid does not exist.
*/
fun getBattlePokemon(pnx: String, pokemonID: String): BattlePokemon {
val actor = actors.find { it.showdownId == pnx.substring(0, 2) }
?: throw IllegalStateException("Invalid pnx: $pnx - unknown actor")
@@ -384,8 +396,9 @@ open class PokemonBattle(
return
}
if (started && isPvW && !ended && dispatches.isEmpty()) {
checkFlee()
if (started) {
ticks++
if (isPvW && !ended && dispatches.isEmpty()) checkFlee()
}
}
@@ -427,13 +440,24 @@ open class PokemonBattle(
}
fun checkForInputDispatch() {
val readyToInput = actors.any { !it.mustChoose && it.responses.isNotEmpty() } && actors.none { it.mustChoose }
if (checkForfeit()) return // ignore actors that are still choosing, their choices don't matter anymore
val readyToInput = (actors.any { !it.mustChoose && it.responses.isNotEmpty() } && actors.none { it.mustChoose })
if (readyToInput && captureActions.isEmpty()) {
actors.filter { it.responses.isNotEmpty() }.forEach { it.writeShowdownResponse() }
actors.forEach { it.responses.clear() ; it.request = null }
}
}
/** Forces Showdown to end the battle when a [BattleActor] chooses to forfeit. */
private fun checkForfeit(): Boolean {
val forfeit = actors.find { it.responses.any { it is ForfeitActionResponse } }
return forfeit?.let {
this.dispatchWaiting { this.broadcastChatMessage(battleLang("forfeit", it.getName()).red()) }
writeShowdownAction(">forcelose ${it.showdownId}")
true
} ?: false
}
/**
* Creates a [Text] representation of an error to interpret a battle message.
* This also logs the error, the goal of this function is to make sure users see missing interpretations and report them to us.
@@ -464,4 +488,13 @@ open class PokemonBattle(
LOGGER.error("Missing interpretation on '{}' action: \nPublic » {}\nPrivate » {}", publicMessage.id, publicMessage.rawMessage, privateMessage.rawMessage)
return Text.literal("Missing interpretation on '${publicMessage.id}' action please report to the developers").red()
}
fun addQueryFunctions(queryStruct: QueryStruct): QueryStruct {
queryStruct.addFunction("pvp") { DoubleValue(isPvP) }
queryStruct.addFunction("pvn") { DoubleValue(isPvN) }
queryStruct.addFunction("pvw") { DoubleValue(isPvW) }
queryStruct.addFunction("has_rule") { params -> DoubleValue(params.getString(0) in format.ruleSet) }
return queryStruct
}
}
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.api.drop
import com.cobblemon.mod.common.api.events.CobblemonEvents.LOOT_DROPPED
import com.cobblemon.mod.common.api.events.drops.LootDroppedEvent
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.entity.LivingEntity
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.server.world.ServerWorld
@@ -88,6 +89,8 @@ class DropTable {
amount: IntRange = this.amount
) {
val drops = getDrops(amount).toMutableList()
val heldItem = (entity as PokemonEntity).pokemon.heldItemNoCopy()
if (!heldItem.isEmpty) entity.dropItem(heldItem.item)
LOOT_DROPPED.postThen(
event = LootDroppedEvent(this, player, entity, drops),
ifSucceeded = { it.drops.forEach { it.drop(entity, world, pos, player) } }
@@ -0,0 +1,97 @@
/*
* 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.entity.pokemon
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.effects.IllusionEffect
import com.cobblemon.mod.common.entity.pokemon.effects.TransformEffect
import com.cobblemon.mod.common.pokemon.FormData
import com.cobblemon.mod.common.pokemon.Species
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import net.minecraft.nbt.NbtCompound
import java.util.concurrent.CompletableFuture
import kotlin.reflect.KClass
/**
* Represents a temporary alteration to how a [PokemonEntity] is rendered and behaves. May include a temporary visual effect
* when applied.
*
* @author Segfault Guy
* @since March 5th, 2024
*/
interface EntityEffect {
/**
* Starts this effect for the provided [PokemonEntity].
*
* @return A [CompletableFuture] that completes after the effect has been applied. Or null if the effect failed to start.
*/
fun start(entity: PokemonEntity): CompletableFuture<PokemonEntity>?
/**
* Ends this effect for the provided [PokemonEntity].
*
* @return A [CompletableFuture] that completes after the effect has been reverted. Or null if the effect failed to end.
*/
fun end(entity: PokemonEntity): CompletableFuture<PokemonEntity>?
/** Saves this effect to NBT. */
fun saveToNbt(): NbtCompound
/** Loads this effect from NBT. */
fun loadFromNBT(nbt: NbtCompound)
companion object {
private val effects = mutableMapOf<String, KClass<out EntityEffect>>()
private val defaults = mutableMapOf<String, () -> EntityEffect>()
init {
register(IllusionEffect.ID, IllusionEffect::class, ::IllusionEffect)
register(TransformEffect.ID, TransformEffect::class, ::TransformEffect)
}
fun <T : EntityEffect> register(id: String, type: KClass<T>, default: () -> T) {
effects[id] = type
defaults[id] = default
}
fun createDefault(id: String): EntityEffect? = defaults[id]?.invoke()
fun loadFromNbt(nbt: NbtCompound): EntityEffect? {
if (nbt.contains(DataKeys.ENTITY_EFFECT_ID)) {
val id = nbt.getString(DataKeys.ENTITY_EFFECT_ID)
return createDefault(id)?.also { it.loadFromNBT(nbt) }
}
return null
}
}
}
/** An [EntityEffect] that modifies the dimensions of a [PokemonEntity]. */
interface PhysicalEffect : EntityEffect {
val scale: Float
}
/** An [EntityEffect] that alters the physical appearance of a [PokemonEntity] to match a [mock]. */
interface MocKEffect : PhysicalEffect {
val mock: PokemonProperties
val exposedSpecies: Species?
get() = this.mock.species?.let { PokemonSpecies.getByIdentifier(it.asIdentifierDefaultingNamespace()) }
val exposedForm: FormData?
get() = this.mock.form?.let {
formID -> this.exposedSpecies?.forms?.firstOrNull { it.formOnlyShowdownId().equals(formID, true) } }
?: this.exposedSpecies?.standardForm
}
@@ -33,6 +33,8 @@ import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionCompleteEv
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionDisplayEvent
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionTestedEvent
import com.cobblemon.mod.common.api.events.pokemon.interaction.ExperienceCandyUseEvent
import com.cobblemon.mod.common.api.events.pokemon.interaction.HeldItemUpdatedEvent
import com.cobblemon.mod.common.api.events.pokemon.interaction.PokemonInteractionGUICreationEvent
import com.cobblemon.mod.common.api.events.starter.StarterChosenEvent
import com.cobblemon.mod.common.api.events.storage.ReleasePokemonEvent
import com.cobblemon.mod.common.api.events.world.BigRootPropagatedEvent
@@ -65,6 +67,8 @@ object CobblemonEvents {
val EVOLUTION_COMPLETE = EventObservable<EvolutionCompleteEvent>()
@JvmField
val POKEMON_NICKNAMED = CancelableObservable<PokemonNicknamedEvent>()
@JvmField
val HELD_ITEM_UPDATED = CancelableObservable<HeldItemUpdatedEvent>()
@JvmField
val THROWN_POKEBALL_HIT = CancelableObservable<ThrownPokeballHitEvent>()
@@ -100,6 +104,9 @@ object CobblemonEvents {
@JvmField
val LEVEL_UP_EVENT = EventObservable<LevelUpEvent>()
@JvmField
/** CLIENT ONLY! */
val POKEMON_INTERACTION_GUI_CREATION = EventObservable<PokemonInteractionGUICreationEvent>()
@JvmField
val POKEMON_ENTITY_SAVE = EventObservable<PokemonEntitySaveEvent>()
@JvmField
@@ -153,4 +160,8 @@ object CobblemonEvents {
val LEFTOVERS_CREATED = CancelableObservable<LeftoversCreatedEvent>()
@JvmField
val BIG_ROOT_PROPAGATED = CancelableObservable<BigRootPropagatedEvent>()
@JvmField
val HELD_ITEM_PRE = CancelableObservable<HeldItemEvent.Pre>()
@JvmField
val HELD_ITEM_POST = EventObservable<HeldItemEvent.Post>()
}
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.events.pokemon
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.item.ItemStack
/**
* The base for all the events related to held items.
*
* @see [Pre]
* @see [Post]
*/
interface HeldItemEvent {
/**
* The [Pokemon] triggering this event.
*/
val pokemon: Pokemon
/**
* Fired at the start of [Pokemon.swapHeldItem].
*
* This event should be used to mutate the results of this transaction.
*
* Canceling this event will prevent the operation and causes the return to be item attempted to be given originally.
*
* @property pokemon The [Pokemon] triggering this event.
* @property receiving The [ItemStack] being sent received from the transaction. By default, this is the item that triggered the interaction.
* @property returning The [ItemStack] being sent back from the transaction. By default, this is the currently held item.
* @property decrement If the operation should decrement the [receiving] [ItemStack.count], this is handled in the implementation.
*
* @see [Post]
*/
data class Pre(override val pokemon: Pokemon, var receiving: ItemStack, var returning: ItemStack, var decrement: Boolean) : HeldItemEvent, Cancelable()
/**
* Fired at the end of [Pokemon.swapHeldItem].
*
* @property pokemon The [Pokemon] triggering this event.
* @property received The [ItemStack] considered as received and set to the [pokemon]. This is a copy and mutation will not be taken into account.
* @property returned The [ItemStack] returned by the method call. This is a copy and mutation will not be taken into account.
* @property decremented If the [received] [ItemStack] got decremented.
*
* @see [Pre]
*/
data class Post(override val pokemon: Pokemon, val received: ItemStack, val returned: ItemStack, val decremented: Boolean) : HeldItemEvent
}
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.events.pokemon.interaction
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.entity.LivingEntity
import net.minecraft.item.ItemStack
/**
* Event published when a held item is being updated on a [Pokemon].
* Cancelling the event will prevent any action from being taken on
* the Pokémon.
*
* [newItem] differs from [originalStack] in that the former is a
* one-sized version of the original (Pokémon cannot hold stacks) and
* changing it in any way will not affect the original item held by
* the player.
*
* @author Whatsy, Hiroku
* @since November 13th, 2023
*/
data class HeldItemUpdatedEvent(
val cause: LivingEntity?,
val pokemon: Pokemon,
val originalStack: ItemStack,
val decrement: Boolean,
val oldItem: ItemStack,
val newItem: ItemStack
) : Cancelable()
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.events.pokemon.interaction
import com.cobblemon.mod.common.client.gui.interact.wheel.InteractWheelOption
import com.cobblemon.mod.common.client.gui.interact.wheel.Orientation
import com.google.common.collect.Multimap
import java.util.UUID
data class PokemonInteractionGUICreationEvent(
val pokemonID: UUID,
val mountShoulder: Boolean,
val options: Multimap<Orientation, InteractWheelOption>
) {
fun addFillingOption(option: InteractWheelOption) {
options.put(getNextFreeOrientation(), option)
}
fun addOption(orientation: Orientation, option: InteractWheelOption) {
options.put(orientation, option)
}
private fun getNextFreeOrientation(): Orientation {
var largest = Orientation.TOP_LEFT
for(orientation in Orientation.values()) {
if(!options.containsKey(orientation)) {
return orientation
} else {
if(options.get(orientation).size < options.get(largest).size) {
largest = orientation
}
}
}
return largest
}
}
@@ -0,0 +1,74 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.item.ability
import com.cobblemon.mod.common.api.abilities.*
import com.cobblemon.mod.common.item.interactive.ability.AbilityTypeChanger
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.abilities.HiddenAbility
import com.cobblemon.mod.common.pokemon.abilities.HiddenAbilityType
/**
* Represents a change operation for a [Pokemon.ability].
* This is backed by the associated [PotentialAbility].
*
* @param T The type of [PotentialAbility].
*/
interface AbilityChanger<T : PotentialAbility> {
/**
* The [PotentialAbilityType] of type [T].
*/
val type: PotentialAbilityType<T>
/**
* Collects all the possible targets for the [type] and the given [pokemon].
*
* @param pokemon The [Pokemon] being queried.
* @return A set containing all their legal abilities associated with [type], can be empty.
*/
fun queryPossible(pokemon: Pokemon): Set<AbilityTemplate>
/**
* Attempts to update the ability of the given [pokemon].
*
* @param pokemon The [Pokemon] attempting to change an ability.
* @return If the operation was successful.
*/
fun performChange(pokemon: Pokemon): Boolean
/**
* Checks if the current [PotentialAbilityType] of a [Pokemon.ability] is possible to swap from with this.
*
* @param type The [PotentialAbilityType] or null if the ability is forced and/or illegal.
* @return If the operation can be performed.
*/
fun canChangeFrom(type: PotentialAbilityType<*>?): Boolean
companion object {
/**
* An implementation of [AbilityChanger] for [CommonAbility].
*
* While this can be used in custom data scenarios this functions most "game-like" if the Pokémon only has 2 common abilities.
*/
@JvmStatic
val COMMON_ABILITY: AbilityChanger<CommonAbility> = AbilityTypeChanger(CommonAbilityType) { other -> other == CommonAbilityType }
/**
* An implementation of [AbilityChanger] for [HiddenAbility].
*
* While this can be used in custom data scenarios this functions most "game-like" if the Pokémon only has 1 hidden ability.
*/
@JvmStatic
val HIDDEN_ABILITY: AbilityChanger<HiddenAbility> = AbilityTypeChanger(HiddenAbilityType) { other -> other == CommonAbilityType || other == HiddenAbilityType }
}
}
@@ -19,7 +19,8 @@ import com.bedrockk.molang.runtime.value.MoValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.dialogue.PlayerDialogueFaceProvider
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunction
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunctions
import com.cobblemon.mod.common.util.isInt
import com.cobblemon.mod.common.util.itemRegistry
import net.minecraft.block.Block
@@ -51,7 +52,30 @@ object MoLangFunctions {
"is_number" to java.util.function.Function { params -> DoubleValue(params.get<MoValue>(0).asString().toDoubleOrNull() != null) },
"to_number" to java.util.function.Function { params -> DoubleValue(params.get<MoValue>(0).asString().toDoubleOrNull() ?: 0.0) },
"to_int" to java.util.function.Function { params -> DoubleValue(params.get<MoValue>(0).asString().toIntOrNull() ?: 0) },
"to_string" to java.util.function.Function { params -> StringValue(params.get<MoValue>(0).asString()) }
"to_string" to java.util.function.Function { params -> StringValue(params.get<MoValue>(0).asString()) },
"do_effect_walks" to java.util.function.Function { _ ->
DoubleValue(Cobblemon.config.walkingInBattleAnimations)
},
"random" to java.util.function.Function { params ->
val options = mutableListOf<MoValue>()
var index = 0
while (params.contains(index)) {
options.add(params.get(index))
index++
}
return@Function options.random() // Can throw an exception if they specified no args. They'd be idiots though.
},
"curve" to java.util.function.Function { params ->
val curveName = params.getString(0)
val curve = WaveFunctions.functions[curveName] ?: throw IllegalArgumentException("Unknown curve: $curveName")
return@Function ObjectValue(curve)
},
"array" to java.util.function.Function { params ->
val values = params.params
val array = ArrayStruct(hashMapOf())
values.forEachIndexed { index, moValue -> array.setDirectly("$index", moValue) }
return@Function array
}
)
val biomeFunctions = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
val worldFunctions = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
@@ -110,6 +134,11 @@ object MoLangFunctions {
return this
}
fun <T : QueryStruct> T.addFunction(name: String, function: java.util.function.Function<MoParams, Any>): T {
this.functions[name] = function
return this
}
fun MoLangEnvironment.getQueryStruct(name: String = "query") = structs.getOrPut(name) { QueryStruct(hashMapOf()) } as QueryStruct
fun MoLangRuntime.setup(): MoLangRuntime {
@@ -8,6 +8,12 @@
package com.cobblemon.mod.common.api.moves
import com.bedrockk.molang.runtime.struct.MoStruct
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addFunction
import com.cobblemon.mod.common.api.moves.animations.ActionEffectTimeline
import com.cobblemon.mod.common.api.moves.categories.DamageCategories
import com.cobblemon.mod.common.api.moves.categories.DamageCategory
import com.cobblemon.mod.common.api.types.ElementalType
@@ -45,8 +51,22 @@ open class MoveTemplate(
val pp: Int,
val priority: Int,
val critRatio: Double,
val effectChances: Array<Double>
val effectChances: Array<Double>,
val actionEffect: ActionEffectTimeline?
) {
val struct: MoStruct by lazy {
QueryStruct(hashMapOf())
.addFunction("name") { StringValue(name) }
.addFunction("type") { StringValue(elementalType.name) }
.addFunction("damage_category") { StringValue(damageCategory.name) }
.addFunction("power") { DoubleValue(power) }
.addFunction("target") { StringValue(target.name) }
.addFunction("accuracy") { DoubleValue(accuracy) }
.addFunction("pp") { DoubleValue(pp) }
.addFunction("priority") { DoubleValue(priority) }
.addFunction("crit_ratio") { DoubleValue(critRatio) }
}
val displayName: MutableText
get() = lang("move.$name")
@@ -65,7 +85,8 @@ open class MoveTemplate(
pp = 5,
priority = 0,
critRatio = 0.0,
effectChances = emptyArray()
effectChances = emptyArray(),
actionEffect = null
)
companion object {
@@ -10,12 +10,15 @@ package com.cobblemon.mod.common.api.moves
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.data.DataRegistry
import com.cobblemon.mod.common.api.moves.animations.ActionEffectTimeline
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
import com.cobblemon.mod.common.api.moves.categories.DamageCategories
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.battles.MoveTarget
import com.cobblemon.mod.common.battles.runner.ShowdownService
import com.cobblemon.mod.common.net.messages.client.data.MovesRegistrySyncPacket
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.JsonArray
import com.google.gson.JsonObject
@@ -72,7 +75,18 @@ object Moves : DataRegistry {
effectChances += secondaryMember.get("chance").asDouble
}
}
val move = MoveTemplate(id, num, elementalType, damageCategory, power, target, accuracy, pp, priority, critRatio, effectChances.toTypedArray())
val actionEffect = ActionEffects.actionEffects[id.asIdentifierDefaultingNamespace()]
?: run {
ActionEffects.actionEffects["generic_move".asIdentifierDefaultingNamespace()]
// if (damageCategory == DamageCategories.STATUS) {
// ActionEffects.actionEffects[cobblemonResource("status")]
// } else {
// val type = elementalType.name.lowercase()
// val category = damageCategory.name.lowercase()
// ActionEffects.actionEffects["${category}_$type".asIdentifierDefaultingNamespace()]
// }
}
val move = MoveTemplate(id, num, elementalType, damageCategory, power, target, accuracy, pp, priority, critRatio, effectChances.toTypedArray(), actionEffect)
this.register(move)
} catch (e: Exception) {
Cobblemon.LOGGER.error("Caught exception trying to resolve the move '{}'", id, e)
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.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
import net.minecraft.entity.Entity
/**
* An action effect will run and execute a series of 'keyframes', with each running once
* the previous has completed. The entire effect is considered complete for the given context
* once all the 'holds' provided in the context have been cleared or once every keyframe
* has finished.
*
* @author Hiroku
* @since October 20th, 2023
*/
class ActionEffectTimeline(
val timeline: List<ActionEffectKeyframe> = mutableListOf(),
val condition: Expression = "true".asExpression()
) {
companion object {
val NONE = ActionEffectTimeline()
}
fun run(context: ActionEffectContext): CompletableFuture<Unit> {
return if (timeline.isEmpty() || !context.runtime.resolveBoolean(condition)) {
CompletableFuture.completedFuture(Unit)
} else {
val finalFuture = CompletableFuture<Unit>()
// .toList copy because I'm paranoid about iterators being trying to share between identical effects playing
chainKeyframes(context, timeline.toList().iterator(), finalFuture)
finalFuture
}
}
fun chainKeyframes(context: ActionEffectContext, iterator: Iterator<ActionEffectKeyframe>, finalFuture: CompletableFuture<Unit>) {
if (!iterator.hasNext()) {
finalFuture.complete(Unit)
} else {
val keyframe = iterator.next()
context.currentKeyframes.add(keyframe)
keyframe.play(context)
.thenRun { context.currentKeyframes.remove(keyframe) }
.thenApply { chainKeyframes(context, iterator, finalFuture) }
}
}
}
class ActionEffectContext(
val actionEffect: ActionEffectTimeline,
val holds: MutableSet<String> = mutableSetOf(),
val providers: MutableList<Any> = mutableListOf(),
val runtime: MoLangRuntime,
var canBeInterrupted: Boolean = false,
var interrupted: Boolean = false,
var currentKeyframes: MutableList<ActionEffectKeyframe> = mutableListOf()
) {
inline fun <reified T> findOneProvider() = providers.filterIsInstance<T>().firstOrNull()
}
class UsersProvider(users: List<Entity>): EntityProvider {
override val entities = users
constructor(vararg users: Entity): this(users.toList())
}
class TargetsProvider(targets: List<Entity>): EntityProvider {
override val entities = targets
constructor(vararg targets: Entity): this(targets.toList())
}
interface EntityProvider {
val entities: List<Entity>
}
//class MoveAnimationKeyframe(
// val sound: Identifier? = null,
// val animation: List<AnimationWithMoments> = listOf(),
// val effects: List<ActionEffect> = listOf()
//)
@@ -0,0 +1,95 @@
/*
* 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.moves.animations
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.moves.animations.keyframes.*
import com.cobblemon.mod.common.api.pokemon.stats.Stat
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.pokemon.adapters.CobblemonStatTypeAdapter
import com.cobblemon.mod.common.util.adapters.*
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import java.awt.Color
import net.minecraft.predicate.NumberRange
import net.minecraft.resource.ResourceType
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.math.Box
import net.minecraft.util.math.Vec3d
/**
* Data registry containing all of the [ActionEffectTimeline]s that can be triggered from various actions.
*
* @author Hiroku
* @since October 21st, 2023
*/
object ActionEffects : JsonDataRegistry<ActionEffectTimeline> {
override val id: Identifier = cobblemonResource("action_effects")
override val type: ResourceType = ResourceType.SERVER_DATA
override val observable = SimpleObservable<ActionEffects>()
init {
ActionEffectKeyframe.register<AnimationActionEffectKeyframe>("animation")
ActionEffectKeyframe.register<EntityMoLangActionEffectKeyframe>("entity_molang")
ActionEffectKeyframe.register<MoLangActionEffectKeyframe>("molang")
ActionEffectKeyframe.register<ParallelActionEffectKeyframe>("parallel")
ActionEffectKeyframe.register<CanInterruptActionEffectKeyframe>("can_interrupt")
ActionEffectKeyframe.register<CannotInterruptActionEffectKeyframe>("cannot_interrupt")
ActionEffectKeyframe.register<RemoveHoldsActionEffectKeyframe>("remove_holds")
ActionEffectKeyframe.register<AddHoldsActionEffectKeyframe>("add_holds")
ActionEffectKeyframe.register<MoveToTargetActionEffectKeyframe>("move_to_target")
ActionEffectKeyframe.register<ReturnToPositionActionEffectKeyframe>("return_to_position")
ActionEffectKeyframe.register<PauseActionEffectKeyframe>("pause")
ActionEffectKeyframe.register<SavePositionActionEffectKeyframe>("save_position")
ActionEffectKeyframe.register<ForkActionEffectKeyframe>("fork")
ActionEffectKeyframe.register<SequenceActionEffectKeyframe>("sequence")
ActionEffectKeyframe.register<RunActionEffectKeyframe>("run_action_effect")
ActionEffectKeyframe.register<EntityParticlesActionEffectKeyframe>("entity_particles")
ActionEffectKeyframe.register<EntitySoundActionEffectKeyframe>("entity_sound")
}
override val gson = GsonBuilder()
.disableHtmlEscaping()
.setPrettyPrinting()
.registerTypeAdapter(ActionEffectKeyframe::class.java, ActionEffectKeyframeAdapter)
.registerTypeAdapter(NumberRange.FloatRange::class.java, FloatNumberRangeAdapter)
.registerTypeAdapter(TypeToken.getParameterized(Collection::class.java, Box::class.java).type, BoxCollectionAdapter)
.registerTypeAdapter(Box::class.java, BoxAdapter)
.registerTypeAdapter(Vec3d::class.java, VerboseVec3dAdapter)
.registerTypeAdapter(Identifier::class.java, IdentifierAdapter)
.registerTypeAdapter(IntRange::class.java, VerboseIntRangeAdapter)
.registerTypeAdapter(Color::class.java, LiteralHexColorAdapter)
.registerTypeAdapter(Stat::class.java, CobblemonStatTypeAdapter)
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(
TypeToken.getParameterized(
TypeToken.get(List::class.java).type,
TypeToken.get(ActionEffectKeyframe::class.java).type
).type,
SingleToPluralAdapter(ActionEffectKeyframe::class.java) { it }
)
.create()
override val typeToken: TypeToken<ActionEffectTimeline> = TypeToken.get(ActionEffectTimeline::class.java)
override val resourcePath = "action_effects"
val actionEffects = mutableMapOf<Identifier, ActionEffectTimeline>()
override fun reload(data: Map<Identifier, ActionEffectTimeline>) {
actionEffects.clear()
actionEffects.putAll(data)
observable.emit(this)
}
override fun sync(player: ServerPlayerEntity) {}
}
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import java.util.concurrent.CompletableFuture
/**
* A single component of an action effect. When played it must return a completable future that completes
* when the action this keyframe represents is finished. [interrupt] is provided for when something successfully
* interrupts the effect so that if any cancellation logic is necessary, it can be provided.
*
* @author Hiroku
* @since October 26th, 2023
*/
interface ActionEffectKeyframe {
companion object {
val types = mutableMapOf<String, Class<out ActionEffectKeyframe>>()
inline fun <reified T : ActionEffectKeyframe> register(type: String) {
types[type] = T::class.java
}
}
fun play(context: ActionEffectContext): CompletableFuture<Unit>
fun interrupt(context: ActionEffectContext) {}
fun skip(): CompletableFuture<Unit> = CompletableFuture.completedFuture(Unit)
}
@@ -0,0 +1,27 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import java.util.concurrent.CompletableFuture
/**
* An [ActionEffectKeyframe] that adds some holds from the context for future code to recognize as blocking some
* functionality from proceeding.
*
* @author Hiroku
* @since October 27th, 2023
*/
class AddHoldsActionEffectKeyframe : ActionEffectKeyframe {
val holds = mutableSetOf<String>()
override fun play(context: ActionEffectContext): CompletableFuture<Unit> {
context.holds.addAll(holds)
return CompletableFuture.completedFuture(Unit)
}
}
@@ -0,0 +1,54 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.EntityProvider
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
import com.cobblemon.mod.common.api.scheduling.delayedFuture
import com.cobblemon.mod.common.net.messages.client.animation.PlayPoseableAnimationPacket
import com.cobblemon.mod.common.util.asExpressionLike
import java.util.concurrent.CompletableFuture
import net.minecraft.server.world.ServerWorld
class AnimationActionEffectKeyframe : ConditionalActionEffectKeyframe(), EntityConditionalActionEffectKeyframe {
var delay = "0".asExpressionLike()
var visibilityRange = 200
var animation: Set<String> = setOf("physical")
var variables: List<Expression> = listOf()
override val entityCondition = "q.entity.is_user".asExpressionLike()
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
val entities = context.providers
.filterIsInstance<EntityProvider>()
.flatMap { prov -> prov.entities.filter { test(context, it, isUser = prov is UsersProvider) } }
val expressions = variables.map { it.originalString }.toSet()
// Treat them as expressions if possible but otherwise yeah just send them as strings
val animation = animation.map {
try {
it.asExpressionLike().resolveString(context.runtime).takeIf { it != "0.0" } ?: it
} catch (e: Exception) {
it
}
}.toSet()
for (entity in entities) {
val world = entity.world as ServerWorld
val players = world.getPlayers { it.distanceTo(entity) <= visibilityRange }
val pkt = PlayPoseableAnimationPacket(entity.id, animation = animation, expressions = expressions)
players.forEach { it.sendPacket(pkt) }
}
return delayedFuture(seconds = delay.resolveFloat(context.runtime), serverThread = true)
}
}
@@ -0,0 +1,19 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import java.util.concurrent.CompletableFuture
class CanInterruptActionEffectKeyframe : ConditionalActionEffectKeyframe() {
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
context.canBeInterrupted = true
return CompletableFuture.completedFuture(Unit)
}
}
@@ -0,0 +1,19 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import java.util.concurrent.CompletableFuture
class CannotInterruptActionEffectKeyframe : ConditionalActionEffectKeyframe() {
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
context.canBeInterrupted = true
return CompletableFuture.completedFuture(Unit)
}
}
@@ -0,0 +1,27 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.util.asExpressionLike
import java.util.concurrent.CompletableFuture
abstract class ConditionalActionEffectKeyframe : ActionEffectKeyframe {
var condition: ExpressionLike = "true".asExpressionLike()
override fun play(context: ActionEffectContext): CompletableFuture<Unit> {
return if (condition.resolveBoolean(context.runtime)) {
playWhenTrue(context)
} else {
skip()
}
}
abstract fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit>
}
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.molang.MoLangFunctions.getQueryStruct
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import net.minecraft.entity.Entity
/**
* An action effect keyframe that plays for all entities for which the condition is true.
*
* @author Hiroku
* @since January 21st, 2024
*/
interface EntityConditionalActionEffectKeyframe {
val entityCondition: ExpressionLike
fun test(context: ActionEffectContext, entity: Entity, isUser: Boolean): Boolean {
// TODO this should use the entity's own query struct
context.runtime.environment.getQueryStruct().addFunction("entity") {
QueryStruct(hashMapOf())
.addFunction("uuid") { StringValue(entity.uuidAsString) }
.addFunction("is_user") { DoubleValue(isUser) }
}
return entityCondition.resolveBoolean(context.runtime)
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.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
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
import com.cobblemon.mod.common.api.scheduling.delayedFuture
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
import com.cobblemon.mod.common.util.asExpressionLike
import java.util.concurrent.CompletableFuture
import net.minecraft.server.world.ServerWorld
/**
* An action effect keyframe that will run client-side MoLang for all entities that fit the entity condition.
*
* This MoLang executes within that entity's runtime, meaning you can trigger animations or locational particles
* or sounds.
*
* @author Hiroku
* @since October 30th, 2023
*/
class EntityMoLangActionEffectKeyframe : ConditionalActionEffectKeyframe(), EntityConditionalActionEffectKeyframe {
var delay = "0".asExpressionLike()
val expressions = mutableSetOf<String>()
val visibilityRange = 200
override val entityCondition: ExpressionLike = "q.entity.is_user".asExpressionLike()
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
val entities = context.providers
.filterIsInstance<EntityProvider>()
.flatMap { prov -> prov.entities.filter { test(context, it, isUser = prov is UsersProvider) } }
for (entity in entities) {
val world = entity.world as ServerWorld
val players = world.getPlayers { it.distanceTo(entity) <= visibilityRange }
val pkt = RunPosableMoLangPacket(entityId = entity.id, expressions = expressions)
players.forEach { it.sendPacket(pkt) }
}
return delayedFuture(seconds = delay.resolveFloat(context.runtime), serverThread = true)
}
}
@@ -0,0 +1,56 @@
/*
* 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.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
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
import com.cobblemon.mod.common.api.scheduling.delayedFuture
import com.cobblemon.mod.common.entity.Poseable
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import java.util.concurrent.CompletableFuture
import net.minecraft.server.world.ServerWorld
/**
* Spawns particles on the entity based on the given particle effect and locator.
*
* @author Hiroku
* @since January 21st, 2024
*/
class EntityParticlesActionEffectKeyframe : ConditionalActionEffectKeyframe(), EntityConditionalActionEffectKeyframe {
override val entityCondition = "q.entity.is_user".asExpressionLike()
var effect: String? = null
var locator: String = "root"
val delay: ExpressionLike = "0".asExpressionLike()
val visibilityRange = 200
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
val entities = context.providers
.filterIsInstance<EntityProvider>()
.flatMap { prov -> prov.entities.filter { test(context, it, isUser = prov is UsersProvider) } }
val effectIdentifier = try {
effect?.asExpressionLike()?.resolveString(context.runtime)
} catch (e: Exception) {
effect
}?.asIdentifierDefaultingNamespace() ?: return skip()
entities.filter { it is Poseable }.forEach { entity ->
val packet = SpawnSnowstormEntityParticlePacket(effectIdentifier, entity.id, locator)
val players = (entity.world as ServerWorld).getPlayers { it.distanceTo(entity) <= visibilityRange }
packet.sendToPlayers(players)
}
return delayedFuture(seconds = delay.resolveFloat(context.runtime), serverThread = true)
}
}
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
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
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
import com.cobblemon.mod.common.api.scheduling.delayedFuture
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import java.util.concurrent.CompletableFuture
import net.minecraft.registry.RegistryKeys
/**
* An action effect keyframe that plays a positioned sound for all matching entities.
*
* @author Hiroku
* @since January 21st, 2024
*/
class EntitySoundActionEffectKeyframe : ConditionalActionEffectKeyframe(), EntityConditionalActionEffectKeyframe {
override val entityCondition = "q.entity.is_user".asExpressionLike()
var sound: String? = null
val delay: ExpressionLike = "0".asExpressionLike()
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
val entities = context.providers
.filterIsInstance<EntityProvider>()
.flatMap { prov -> prov.entities.filter { test(context, it, isUser = prov is UsersProvider) } }
val soundIdentifier = try {
sound?.asExpressionLike()?.resolveString(context.runtime)?.takeIf { it != "0.0" } ?: sound
} catch (e: Exception) {
sound
}?.asIdentifierDefaultingNamespace() ?: return skip()
entities.forEach { entity ->
val soundEvent = entity.world.registryManager.get(RegistryKeys.SOUND_EVENT).get(soundIdentifier) ?: return skip()
entity.playSound(soundEvent, 1f, 1f)
}
return delayedFuture(seconds = delay.resolveFloat(context.runtime), serverThread = true)
}
}
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.util.asExpressionLike
import java.util.concurrent.CompletableFuture
class ForkActionEffectKeyframe(
val condition: ExpressionLike = "true".asExpressionLike(),
val ifTrue: List<ActionEffectKeyframe> = listOf(),
val ifFalse: List<ActionEffectKeyframe> = listOf()
) : ActionEffectKeyframe {
override fun play(context: ActionEffectContext): CompletableFuture<Unit> {
val future = CompletableFuture<Unit>()
/*
* Using .toList() before running chainKeyframes because iterators can be weird about sharing,
* .toList() creates a copy of the list and then grabs its iterator so much safer (three parachutes)
*/
if (!condition.resolveBoolean(context.runtime)) {
context.actionEffect.chainKeyframes(context, ifFalse.toList().iterator(), future)
} else {
context.actionEffect.chainKeyframes(context, ifTrue.toList().iterator(), future)
}
return future
}
}
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.scheduling.delayedFuture
import com.cobblemon.mod.common.util.asExpressionLike
import java.util.concurrent.CompletableFuture
/**
* An action effect keyframe that simply executes some MoLang on the effect context's runtime.
*
* @author Hiroku
* @since January 21st, 2024
*/
class MoLangActionEffectKeyframe : ActionEffectKeyframe {
val expressions: ExpressionLike = "0".asExpressionLike()
val delay: ExpressionLike = "0".asExpressionLike()
override fun play(context: ActionEffectContext): CompletableFuture<Unit> {
expressions.resolve(context.runtime)
return delayedFuture(seconds = delay.resolveFloat(context.runtime), serverThread = true)
}
}
@@ -0,0 +1,75 @@
/*
* 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.moves.animations.keyframes
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.ActionEffectTimeline
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
import com.cobblemon.mod.common.api.moves.animations.TargetsProvider
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
import com.cobblemon.mod.common.api.scheduling.afterOnServer
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.PokemonNavigation
import com.cobblemon.mod.common.util.asExpressionLike
import java.util.concurrent.CompletableFuture
import kotlin.math.pow
import kotlin.math.sqrt
import net.minecraft.util.Identifier
class MoveToTargetActionEffectKeyframe : ActionEffectKeyframe {
val speed = 1F
val timeout = "4".asExpressionLike()
var proximity = -1F
val timeoutActionEffect: Identifier? = null
override fun play(context: ActionEffectContext): CompletableFuture<Unit> {
val user = context.findOneProvider<UsersProvider>()?.entities?.firstOrNull() as? PokemonEntity ?: return CompletableFuture.completedFuture(Unit)
val target = context.findOneProvider<TargetsProvider>()?.entities?.firstOrNull() ?: return CompletableFuture.completedFuture(Unit)
val future = CompletableFuture<Unit>()
var timedOut = false
val proximity = this.proximity.takeIf { it != -1F } ?: (sqrt(2 * user.boundingBox.xLength.pow(2)) + 1.5F + sqrt(2 * target.boundingBox.xLength.pow(2))).toFloat()
if (target.distanceTo(user) !in proximity..20F) {
future.complete(Unit)
return future
}
val timeoutEffect = timeoutActionEffect?.let { ActionEffects.actionEffects[it] } ?: ActionEffectTimeline.NONE
val nav = user.navigation
val navContext = PokemonNavigation.NavigationContext(
destinationProximity = proximity,
onArrival = {
if (!future.isDone && !timedOut) {
future.complete(Unit)
}
},
onCannotReach = {
if (!future.isDone && !timedOut) {
timedOut = true
timeoutEffect.run(context).thenApply { future.complete(Unit) }
}
}
)
afterOnServer(seconds = timeout.resolveFloat(context.runtime)) {
if (!future.isDone && !timedOut) {
timedOut = true
timeoutEffect.run(context).thenApply { future.complete(Unit) }
nav.stop()
}
}
nav.startMovingTo(target.x, target.y, target.z, speed.toDouble(), navContext)
return future
}
}
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import java.util.concurrent.CompletableFuture
class ParallelActionEffectKeyframe : ConditionalActionEffectKeyframe() {
var keyframes: MutableList<ActionEffectKeyframe> = mutableListOf()
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
return CompletableFuture.allOf(
*keyframes.map {
context.currentKeyframes.add(it)
it.play(context).thenRun { context.currentKeyframes.remove(it) }
}.toTypedArray()
).thenApply {} // Map Void -> Unit at the end
}
}
@@ -0,0 +1,18 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.scheduling.delayedFuture
import com.cobblemon.mod.common.util.asExpressionLike
class PauseActionEffectKeyframe : ConditionalActionEffectKeyframe() {
val pause = "1".asExpressionLike()
override fun playWhenTrue(context: ActionEffectContext) = delayedFuture(seconds = pause.resolveFloat(context.runtime), serverThread = true)
}
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.scheduling.delayedFuture
import java.util.concurrent.CompletableFuture
/**
* An [ActionEffectKeyframe] that clears some holds from the context, potentially marking the effect as
* complete as far as any blocked actions are concerned. If no holds are specified, then all holds are
* removed.
*
* @author Hiroku
* @since October 27th, 2023
*/
class RemoveHoldsActionEffectKeyframe : ActionEffectKeyframe {
val delay = 0F
val holds = mutableSetOf<String>()
override fun play(context: ActionEffectContext): CompletableFuture<Unit> {
return delayedFuture(seconds = delay, serverThread = true).thenApply {
if (holds.isEmpty()) {
context.holds.clear()
} else {
context.holds.removeAll(holds)
}
}
}
}
@@ -0,0 +1,70 @@
/*
* 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.moves.animations.keyframes
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.ActionEffectTimeline
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
import com.cobblemon.mod.common.api.scheduling.after
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.PokemonNavigation
import com.cobblemon.mod.common.util.asExpressionLike
import java.util.concurrent.CompletableFuture
import net.minecraft.util.Identifier
import net.minecraft.util.math.Vec3d
class ReturnToPositionActionEffectKeyframe : ActionEffectKeyframe {
val speed = 1F
val timeout = "4".asExpressionLike()
val timeoutActionEffect: Identifier? = null
override fun play(context: ActionEffectContext): CompletableFuture<Unit> {
val user = context.findOneProvider<UsersProvider>()?.entities?.firstOrNull() as? PokemonEntity ?: return skip()
val future = CompletableFuture<Unit>()
val pos = (context.runtime.environment.getValue(setOf("${user.uuidAsString}-pos").iterator())?.value() as? ObjectValue<*>)?.obj as? Vec3d ?: return skip()
var timedOut = false
if (pos.distanceTo(user.pos) > 20) {
future.complete(Unit)
return future
}
val timeoutEffect = timeoutActionEffect?.let { ActionEffects.actionEffects[it] } ?: ActionEffectTimeline.NONE
val nav = user.navigation
val navContext = PokemonNavigation.NavigationContext(
onArrival = {
if (!future.isDone && !timedOut) {
future.complete(Unit)
}
},
onCannotReach = {
if (!future.isDone && !timedOut) {
timedOut = true
timeoutEffect.run(context).thenApply { future.complete(Unit) }
}
}
)
after(seconds = timeout.resolveFloat(context.runtime), serverThread = true) {
if (!future.isDone && !timedOut) {
timedOut = true
timeoutEffect.run(context).thenApply { future.complete(Unit) }
nav.stop()
}
}
nav.startMovingTo(pos.x, pos.y, pos.z, speed.toDouble(), navContext)
return future
}
}
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
import java.util.concurrent.CompletableFuture
import net.minecraft.util.Identifier
/**
* An action effect keyframe that simply runs another action effect based on an identifier. This action
* effect is marked complete only when the action effect it runs is complete unless [waitForActionEffect] is
* false.
*
* @author Hiroku
* @since January 21st, 2024
*/
class RunActionEffectKeyframe : ConditionalActionEffectKeyframe() {
val actionEffect: Identifier? = null
val waitForActionEffect = true
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
return if (actionEffect != null) {
ActionEffects.actionEffects[actionEffect]?.run(context)?.takeIf { waitForActionEffect } ?: skip()
} else {
skip()
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
import java.util.concurrent.CompletableFuture
class SavePositionActionEffectKeyframe: ConditionalActionEffectKeyframe() {
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
val user = context.findOneProvider<UsersProvider>()?.entities?.firstOrNull() ?: return skip()
context.runtime.environment.setSimpleVariable("${user.uuidAsString}-pos", ObjectValue(user.pos))
return skip()
}
}
@@ -0,0 +1,26 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import java.util.concurrent.CompletableFuture
/**
* A sequence of action effects that are dependent on a condition.
*
* @author Hiroku
* @since October 29th, 2023
*/
class SequenceActionEffectKeyframe(val keyframes: List<ActionEffectKeyframe> = listOf()) : ConditionalActionEffectKeyframe() {
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
val future = CompletableFuture<Unit>()
context.actionEffect.chainKeyframes(context, keyframes.toList().iterator(), future)
return future
}
}
@@ -8,7 +8,7 @@
package com.cobblemon.mod.common.api.multiblock
import com.cobblemon.mod.common.block.entity.fossil.FossilMultiblockEntity
import com.cobblemon.mod.common.block.entity.FossilMultiblockEntity
import net.minecraft.block.*
import net.minecraft.block.entity.BlockEntity
import net.minecraft.entity.LivingEntity
@@ -19,6 +19,7 @@ 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.BlockView
import net.minecraft.world.World
/**
@@ -34,8 +35,8 @@ abstract class MultiblockBlock(properties: Settings) : BlockWithEntity(propertie
itemStack: ItemStack?
) {
if (world is ServerWorld) {
val multiblockEntity = world.getBlockEntity(pos) as MultiblockEntity
multiblockEntity.multiblockBuilder?.validate(world)
val multiblockEntity = world.getBlockEntity(pos) as? MultiblockEntity
multiblockEntity?.multiblockBuilder?.validate(world)
}
super.onPlaced(world, pos, state, placer, itemStack)
}
@@ -51,8 +52,8 @@ abstract class MultiblockBlock(properties: Settings) : BlockWithEntity(propertie
if(hand == Hand.OFF_HAND) {
return ActionResult.SUCCESS
}
val entity = world.getBlockEntity(pos) as MultiblockEntity
if (entity.multiblockStructure != null) {
val entity = world.getBlockEntity(pos) as MultiblockEntity?
if (entity?.multiblockStructure != null) {
return entity.multiblockStructure!!.onUse(state, world, pos, player, hand, hit)
}
return super.onUse(state, world, pos, player, hand, hit)
@@ -77,6 +78,11 @@ abstract class MultiblockBlock(properties: Settings) : BlockWithEntity(propertie
return BlockRenderType.MODEL
}
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
}
abstract fun createMultiBlockEntity(pos: BlockPos, state: BlockState): FossilMultiblockEntity
}
@@ -42,5 +42,7 @@ interface MultiblockStructure {
fun getComparatorOutput(state: BlockState, world: World?, pos: BlockPos?): Int {
return 0
}
fun markRemoved(world: World):Unit
fun onTriggerEvent(state: BlockState?, world: ServerWorld?, pos: BlockPos?, random: Random?)
}
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.net.serializers
import net.minecraft.entity.data.TrackedDataHandler
import net.minecraft.network.PacketByteBuf
import net.minecraft.util.Identifier
/**
* Data serializer of [Identifier] for DataTracker things.
*
* @author Hiroku
* @since May 22nd, 2023
*/
object IdentifierDataSerializer : TrackedDataHandler<Identifier> {
override fun copy(value: Identifier) = Identifier(value.namespace, value.path)
override fun read(buf: PacketByteBuf) = Identifier(buf.readString(), buf.readString())
override fun write(buf: PacketByteBuf, value: Identifier) {
buf.writeString(value.namespace)
buf.writeString(value.path)
}
}
@@ -204,9 +204,9 @@ object PokeBalls : JsonDataRegistry<PokeBall> {
createDefault("ancient_feather_ball", throwPower = 2.5f, ancient = true)
createDefault("ancient_wing_ball", throwPower = 2.5f, ancient = true)
createDefault("ancient_jet_ball", throwPower = 2.5f, ancient = true)
createDefault("ancient_origin_ball", ancient = true)
// Luxury ball effect
CobblemonEvents.FRIENDSHIP_UPDATED.subscribe(priority = Priority.LOWEST) { event ->
createDefault("ancient_origin_ball", GuaranteedModifier(), ancient = true)
// Luxury ball effect, low priority as it must be triggered before soothe bell as of gen 4
CobblemonEvents.FRIENDSHIP_UPDATED.subscribe(priority = Priority.LOW) { event ->
var increment = (event.newFriendship - event.pokemon.friendship).toFloat()
if (increment <= 1F) {
event.pokemon.caughtBall.effects.filterIsInstance<FriendshipEarningBoostEffect>()
@@ -13,12 +13,14 @@ import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.abilities.Abilities
import com.cobblemon.mod.common.api.abilities.Ability
import com.cobblemon.mod.common.api.pokeball.PokeBalls
import com.cobblemon.mod.common.api.pokemon.aspect.AspectProvider
import com.cobblemon.mod.common.api.pokemon.stats.Stats
import com.cobblemon.mod.common.api.pokemon.status.Statuses
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.api.types.tera.TeraTypes
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.pokemon.*
import com.cobblemon.mod.common.pokemon.status.PersistentStatus
@@ -52,6 +54,7 @@ import java.util.UUID
*/
open class PokemonProperties {
companion object {
@JvmOverloads
fun parse(string: String, delimiter: String = " ", assigner: String = "="): PokemonProperties {
val props = PokemonProperties()
props.originalString = string
@@ -293,6 +296,18 @@ open class PokemonProperties {
)
fun apply(pokemon: Pokemon) {
// Custom properties check could be duplicated but can't assume 3rd party hasn't done anything type specific
this.customProperties.forEach { it.apply(pokemon) }
this.commonApply(pokemon)
}
fun apply(pokemonEntity: PokemonEntity) {
// Custom properties check could be duplicated but can't assume 3rd party hasn't done anything type specific
this.customProperties.forEach { it.apply(pokemonEntity) }
this.commonApply(pokemonEntity.pokemon)
}
private fun commonApply(pokemon: Pokemon) {
species?.let {
return@let try {
if (it == "random") {
@@ -312,8 +327,8 @@ open class PokemonProperties {
friendship?.let { pokemon.setFriendship(it) }
pokeball?.let { PokeBalls.getPokeBall(it.asIdentifierDefaultingNamespace())?.let { pokeball -> pokemon.caughtBall = pokeball } }
nature?.let { Natures.getNature(it.asIdentifierDefaultingNamespace())?.let { nature -> pokemon.nature = nature } }
ability?.let { Abilities.getOrException(it).create(true).let { ability -> pokemon.ability = ability } }
status?.let { Statuses.getStatus(it)?.let { pokemon.applyStatus(it as PersistentStatus) } }
ability?.let { this.createAbility(it, pokemon.form)?.let(pokemon::updateAbility) }
status?.let { Statuses.getStatus(it)?.let { status -> if (status is PersistentStatus) pokemon.applyStatus(status) } }
customProperties.forEach { it.apply(pokemon) }
ivs?.let { ivs ->
ivs.forEach { stat ->
@@ -325,7 +340,7 @@ open class PokemonProperties {
pokemon.setEV(stat.key, stat.value)
}
}
teraType?.let { ElementalTypes.get(it)?.let { type -> pokemon.teraType = type } }
teraType?.let { TeraTypes.get(it.asIdentifierDefaultingNamespace())?.let { type -> pokemon.teraType = type } }
dmaxLevel?.let { pokemon.dmaxLevel = it }
gmaxFactor?.let { pokemon.gmaxFactor = it }
tradeable?.let { pokemon.tradeable = it }
@@ -354,69 +369,17 @@ open class PokemonProperties {
pokemon.updateAspects()
}
fun apply(pokemonEntity: PokemonEntity) {
species?.let {
return@let try {
if (it == "random") {
PokemonSpecies.species.random()
} else {
PokemonSpecies.getByIdentifier(it.asIdentifierDefaultingNamespace())
}
} catch (e: InvalidIdentifierException) {
null
}
}?.let { pokemonEntity.pokemon.species = it }
nickname?.let { pokemonEntity.pokemon.nickname = it }
form?.let { formID -> pokemonEntity.pokemon.species.forms.firstOrNull { it.formOnlyShowdownId().equals(formID, true) } }?.let { form -> pokemonEntity.pokemon.form = form }
level?.let { pokemonEntity.pokemon.level = it }
shiny?.let { pokemonEntity.pokemon.shiny = it }
gender?.let { pokemonEntity.pokemon.gender = it }
friendship?.let { pokemonEntity.pokemon.setFriendship(it) }
pokeball?.let { PokeBalls.getPokeBall(it.asIdentifierDefaultingNamespace())?.let { pokeball -> pokemonEntity.pokemon.caughtBall = pokeball } }
nature?.let { Natures.getNature(it.asIdentifierDefaultingNamespace())?.let { nature -> pokemonEntity.pokemon.nature = nature } }
ability?.let { Abilities.getOrException(it).create(true).let { ability -> pokemonEntity.pokemon.ability = ability } }
status?.let { Statuses.getStatus(it)?.let { pokemonEntity.pokemon.applyStatus(it as PersistentStatus) } }
customProperties.forEach { it.apply(pokemonEntity) }
ivs?.let { ivs ->
ivs.forEach { stat ->
pokemonEntity.pokemon.setIV(stat.key, stat.value)
}
}
evs?.let { evs ->
evs.forEach { stat ->
pokemonEntity.pokemon.setEV(stat.key, stat.value)
}
}
teraType?.let { ElementalTypes.get(it)?.let { type -> pokemonEntity.pokemon.teraType = type } }
dmaxLevel?.let { pokemonEntity.pokemon.dmaxLevel = it }
gmaxFactor?.let { pokemonEntity.pokemon.gmaxFactor = it }
tradeable?.let { pokemonEntity.pokemon.tradeable = it }
// If it has been explicitly set to NONE, clear the stored information, including the originalTrainer property
originalTrainerType?.let {
if (it == OriginalTrainerType.NONE) {
pokemonEntity.pokemon.removeOriginalTrainer()
originalTrainer = null
}
}
originalTrainer?.let { ot ->
val type = originalTrainerType ?: pokemonEntity.pokemon.originalTrainerType
when (type) {
OriginalTrainerType.PLAYER -> {
when (ot.length) {
in 3..16 -> server()?.userCache?.findByName(ot)?.get()?.id // OT is a Username
36 -> UUID.fromString(ot) // OT is a UUID
else -> null // OT is invalid
}?.let { uuid -> pokemonEntity.pokemon.setOriginalTrainer(uuid) }
}
OriginalTrainerType.NPC -> pokemonEntity.pokemon.setOriginalTrainer(ot)
else -> {}
}
pokemonEntity.pokemon.refreshOriginalTrainer()
}
pokemonEntity.pokemon.updateAspects()
fun matches(pokemon: Pokemon): Boolean {
// Custom properties check could be duplicated but can't assume 3rd party hasn't done anything type specific
return this.commonMatches(pokemon) && this.customProperties.none { !it.matches(pokemon) }
}
fun matches(pokemon: Pokemon): Boolean {
fun matches(pokemonEntity: PokemonEntity): Boolean {
// Custom properties check could be duplicated but can't assume 3rd party hasn't done anything type specific
return this.commonMatches(pokemonEntity.pokemon) && this.customProperties.none { !it.matches(pokemonEntity) }
}
private fun commonMatches(pokemon: Pokemon): Boolean {
level?.takeIf { it != pokemon.level }?.let { return false }
shiny?.takeIf { it != pokemon.shiny }?.let { return false }
gender?.takeIf { it != pokemon.gender }?.let { return false }
@@ -434,7 +397,7 @@ open class PokemonProperties {
return false
}
}
nickname?.takeIf { it != pokemon.nickname }?.let { return false }
nickname?.takeIf { it.string != pokemon.nickname?.string }?.let { return false }
form?.takeIf { !it.equals(pokemon.form.name, true) }?.let { return false }
friendship?.takeIf { it != pokemon.friendship }?.let { return false }
pokeball?.takeIf { it != pokemon.caughtBall.name.toString() }?.let { return false }
@@ -447,59 +410,23 @@ open class PokemonProperties {
evs?.forEach{ stat ->
if (stat.value != pokemon.evs[stat.key]) { return false }
}
teraType?.takeIf { it != pokemon.teraType.name }?.let { return false }
teraType?.takeIf { it.asIdentifierDefaultingNamespace() != pokemon.teraType.id }?.let { return false }
dmaxLevel?.takeIf { it != pokemon.dmaxLevel }?.let { return false }
gmaxFactor?.takeIf { it != pokemon.gmaxFactor }?.let { return false }
tradeable?.takeIf { it != pokemon.tradeable }?.let { return false }
originalTrainer?.takeIf { it != pokemon.originalTrainer }?.let{ return false }
originalTrainerType?.takeIf { it != pokemon.originalTrainerType }?.let{ return false }
return customProperties.none { !it.matches(pokemon) }
}
fun matches(pokemonEntity: PokemonEntity): Boolean {
level?.takeIf { it != pokemonEntity.pokemon.level }?.let { return false }
shiny?.takeIf { it != ("shiny" in pokemonEntity.pokemon.aspects) }?.let { return false }
gender?.takeIf { it != pokemonEntity.pokemon.gender }?.let { return false }
species?.run {
try {
val species = if (this == "random") {
PokemonSpecies.species.random()
} else {
PokemonSpecies.getByIdentifier(this.asIdentifierDefaultingNamespace()) ?: return@run
}
if (pokemonEntity.pokemon.species != species) {
return false
}
} catch (e: InvalidIdentifierException) {}
}
nickname?.takeIf { it != pokemonEntity.pokemon.nickname }?.let { return false }
form?.takeIf { !it.equals(pokemonEntity.pokemon.form.name, true) }?.let { return false }
friendship?.takeIf { it != pokemonEntity.pokemon.friendship }?.let { return false }
pokeball?.takeIf { it != pokemonEntity.pokemon.caughtBall.name.toString() }?.let { return false }
nature?.takeIf { it != pokemonEntity.pokemon.nature.name.toString() }?.let { return false }
ability?.takeIf { it != pokemonEntity.pokemon.ability.name }?.let { return false }
status?.takeIf { it != pokemonEntity.pokemon.status?.status?.showdownName }?.let { return false }
ivs?.forEach{ stat ->
if (stat.value != pokemonEntity.pokemon.ivs[stat.key]) { return false }
}
evs?.forEach{ stat ->
if (stat.value != pokemonEntity.pokemon.evs[stat.key]) { return false }
}
teraType?.takeIf { it != pokemonEntity.pokemon.teraType.name }?.let { return false }
dmaxLevel?.takeIf { it != pokemonEntity.pokemon.dmaxLevel }?.let { return false }
gmaxFactor?.takeIf { it != pokemonEntity.pokemon.gmaxFactor }?.let { return false }
tradeable?.takeIf { it != pokemonEntity.pokemon.tradeable }?.let { return false }
originalTrainer?.takeIf { it != pokemonEntity.pokemon.originalTrainer }?.let{ return false }
originalTrainerType?.takeIf { it != pokemonEntity.pokemon.originalTrainerType }?.let{ return false }
return customProperties.none { !it.matches(pokemonEntity) }
return true
}
// TODO Review the need for this, usage for us is in commands that deviate from the behavior established by multiple Pokémon query equivalent
fun isSubSetOf(properties: PokemonProperties): Boolean {
level?.takeIf { it != properties.level }?.let { return false }
shiny?.takeIf { it != ("shiny" in properties.aspects) }?.let { return false }
gender?.takeIf { it != properties.gender }?.let { return false }
species?.run {
try {
// TODO get context on this bit, it's highly unlikely two randoms would result in the same Pokémon, doesn't mean the prop is not equal?
val species = if (this == "random") {
PokemonSpecies.species.random()
} else {
@@ -508,9 +435,9 @@ open class PokemonProperties {
if (properties.species != species.toString()) {
return false
}
} catch (e: InvalidIdentifierException) {}
} catch (_: InvalidIdentifierException) {}
}
nickname?.takeIf { it != properties.nickname }?.let { return false }
nickname?.takeIf { it.string != properties.nickname?.string }?.let { return false }
form?.takeIf { !it.equals(properties.form, true) }?.let { return false }
friendship?.takeIf { it != properties.friendship }?.let { return false }
pokeball?.takeIf { it != properties.pokeball }?.let { return false }
@@ -550,20 +477,18 @@ open class PokemonProperties {
// TEST YOUR LUCK!
fun roll(pokemon: Pokemon) {
val baseTypes = pokemon.species.types.toList()
val baseTypes = pokemon.form.types.toList()
if (this.shiny == null) pokemon.shiny = Cobblemon.config.shinyRate.checkRate()
if (this.teraType == null) pokemon.teraType =
if (Cobblemon.config.teraTypeRate.checkRate()) ElementalTypes.all().filter { !baseTypes.contains(it) }.random()
else baseTypes.random()
if (Cobblemon.config.teraTypeRate.checkRate()) TeraTypes.random(true)
else TeraTypes.forElementalType(baseTypes.random())
}
// If the config value is at least 1, then do 1/x and use that as the property chance
private fun Float.checkRate(): Boolean = this >= 1 && (Random.Default.nextFloat() < 1 / this)
fun createEntity(world: World): PokemonEntity {
return PokemonEntity(world, create())
}
// TODO Codecs at some point
fun saveToNBT(): NbtCompound {
val nbt = NbtCompound()
originalString.let { nbt.putString(DataKeys.POKEMON_PROPERTIES_ORIGINAL_TEXT, it) }
@@ -592,6 +517,7 @@ open class PokemonProperties {
return nbt
}
// TODO Codecs at some point
fun loadFromNBT(tag: NbtCompound): PokemonProperties {
originalString = tag.getString(DataKeys.POKEMON_PROPERTIES_ORIGINAL_TEXT)
level = if (tag.contains(DataKeys.POKEMON_LEVEL)) tag.getInt(DataKeys.POKEMON_LEVEL) else null
@@ -620,6 +546,7 @@ open class PokemonProperties {
return this
}
// TODO Codecs at some point
fun saveToJSON(): JsonObject {
val json = JsonObject()
originalString.let { json.addProperty(DataKeys.POKEMON_PROPERTIES_ORIGINAL_TEXT, it) }
@@ -649,6 +576,7 @@ open class PokemonProperties {
return json
}
// TODO Codecs at some point
fun loadFromJSON(json: JsonObject): PokemonProperties {
originalString = json.get(DataKeys.POKEMON_PROPERTIES_ORIGINAL_TEXT)?.asString ?: ""
level = json.get(DataKeys.POKEMON_LEVEL)?.asInt
@@ -726,4 +654,21 @@ open class PokemonProperties {
fun copy(): PokemonProperties {
return PokemonProperties().loadFromJSON(saveToJSON())
}
// If the config value is at least 1, then do 1/x and use that as the property chance
private fun Float.checkRate(): Boolean = this >= 1 && (Random.Default.nextFloat() < 1 / this)
/**
* Attempts to find an ability by ID and resolve if it should be forced or if it's legal for the given form.
*
* @param id The literal ID of the [Ability] being mapped.
* @param form The [FormData] whose [FormData.abilities] is queried for legality.
* @return The [Ability] with the [Ability.forced] state necessary for the given [form].
*/
private fun createAbility(id: String, form: FormData): Ability? {
val ability = Abilities.get(id) ?: return null
val potentialAbility = form.abilities.firstOrNull { potential -> potential.template == ability } ?: return ability.create(true)
return potentialAbility.template.create(false)
}
}
@@ -48,6 +48,11 @@ fun interface PokemonPropertyExtractor {
@JvmField
val STATUS = add { pokemon, properties -> properties.status = pokemon.status?.status?.showdownName }
@JvmField
val ILLUSION = mutableListOf(SPECIES, FORM, ASPECTS, GENDER, NICKNAME, SHINY)
@JvmField
val TRANSFORM = mutableListOf(SPECIES, FORM, ASPECTS, GENDER)
fun add(extractor: PokemonPropertyExtractor): PokemonPropertyExtractor {
ALL.add(extractor)
return extractor
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.api.pokemon.effect
import com.cobblemon.mod.common.api.scheduling.ServerTaskTracker
import com.cobblemon.mod.common.platform.events.PlatformEvents
import com.cobblemon.mod.common.pokemon.activestate.ShoulderedState
import com.cobblemon.mod.common.pokemon.effects.LightSourceEffect
import com.cobblemon.mod.common.pokemon.effects.PotionBaseEffect
import com.cobblemon.mod.common.util.party
import net.minecraft.server.network.ServerPlayerEntity
@@ -29,7 +28,6 @@ object ShoulderEffectRegistry {
private val effects = mutableMapOf<String, Class<out ShoulderEffect>>()
// Effects - START
val LIGHT_SOURCE = register("light_source", LightSourceEffect::class.java)
val POTION_EFFECT = register("potion_effect", PotionBaseEffect::class.java)
// Effects - END
@@ -16,11 +16,14 @@ import com.cobblemon.mod.common.api.moves.BenchedMove
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.entity.generic.GenericBedrockEntity
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.activestate.ShoulderedState
import com.cobblemon.mod.common.pokemon.evolution.variants.ItemInteractionEvolution
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 net.minecraft.item.ItemStack
import net.minecraft.sound.SoundCategory
@@ -92,6 +95,7 @@ interface Evolution : EvolutionLike {
return true
}
/**
* Starts this evolution as soon as possible.
* This will not present a choice to the client regardless of [optional].
@@ -99,25 +103,57 @@ interface Evolution : EvolutionLike {
* @param pokemon The [Pokemon] being evolved.
*/
fun forceEvolve(pokemon: Pokemon) {
// This is a switch to enable/disable the evolution effect while we get particles improved
val useEvolutionEffect = false
if (pokemon.state is ShoulderedState) {
pokemon.tryRecallWithAnimation()
}
// ToDo Once implemented queue evolution for a pokemon state that is not in battle, start animation instead of instantly doing all of this
val pokemonEntity = pokemon.entity
if (pokemonEntity == null || !useEvolutionEffect) {
evolutionMethod(pokemon)
} else {
pokemonEntity.evolutionEntity = pokemon.getOwnerPlayer()?.let { GenericBedrockEntity(world = it.world) }
val evolutionEntity = pokemon.entity!!.evolutionEntity
evolutionEntity?.apply {
category = cobblemonResource("evolution")
colliderHeight = pokemonEntity.height
colliderWidth = pokemonEntity.width
scale = pokemonEntity.scaleFactor
syncAge = true // Otherwise particle animation will be starting from zero even if you come along partway through
setPosition(pokemonEntity.x, pokemonEntity.y, pokemonEntity.z)
}
pokemon.getOwnerPlayer()?.world?.spawnEntity(evolutionEntity)
afterOnServer(seconds = 9F) {
if (!pokemonEntity.isRemoved) {
evolutionMethod(pokemon)
afterOnServer(seconds = 1.5F) { pokemonEntity.cry() }
afterOnServer(seconds = 3F) {
if (evolutionEntity != null) {
evolutionEntity.kill()
if (!pokemonEntity.isRemoved) {
pokemonEntity.evolutionEntity = null
}
}
}
}
}
}
}
fun evolutionMethod(pokemon: Pokemon) {
this.result.apply(pokemon)
this.learnableMoves.forEach { move ->
if (pokemon.moveSet.hasSpace()) {
pokemon.moveSet.add(move.create())
}
else {
} else {
pokemon.benchedMoves.add(BenchedMove(move, 0))
}
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.evolutions.filterIsInstance<PassiveEvolution>().forEach { evolution -> evolution.attemptEvolution(pokemon) }
pokemon.getOwnerPlayer()?.playSound(CobblemonSounds.EVOLVING, SoundCategory.NEUTRAL, 1F, 1F)
CobblemonEvents.EVOLUTION_COMPLETE.post(EvolutionCompleteEvent(pokemon, this))
}
@@ -34,4 +34,10 @@ interface PassiveEvolution : Evolution {
return false
}
/**
* If the evolution will disappear once the conditions are no longer met.
*/
val permanent: Boolean
}
@@ -11,10 +11,12 @@ package com.cobblemon.mod.common.api.pokemon.feature
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.aspect.AspectProvider
import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType
import com.cobblemon.mod.common.client.gui.summary.featurerenderers.SummarySpeciesFeatureRenderer
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.substitute
import com.google.gson.JsonObject
import net.minecraft.nbt.NbtCompound
import net.minecraft.network.PacketByteBuf
/**
* A [SpeciesFeatureProvider] which is a string value selected from a fixed list of choices. Parameters exist
@@ -24,15 +26,46 @@ import net.minecraft.nbt.NbtCompound
* @since November 30th, 2022
*/
open class ChoiceSpeciesFeatureProvider(
override val keys: List<String>,
override var keys: List<String>,
var default: String? = null,
var choices: List<String> = listOf(),
var isAspect: Boolean = true,
var aspectFormat: String = "{{choice}}"
) : SpeciesFeatureProvider<StringSpeciesFeature>, CustomPokemonPropertyType<StringSpeciesFeature>, AspectProvider {
override val needsKey = true
) : SynchronizedSpeciesFeatureProvider<StringSpeciesFeature>, CustomPokemonPropertyType<StringSpeciesFeature>, AspectProvider {
override var needsKey = true
override var visible = false
fun getAspect(feature: StringSpeciesFeature) = aspectFormat.substitute("choice", feature.value)
override fun encode(buffer: PacketByteBuf) {
buffer.writeCollection(keys) { _, value -> buffer.writeString(value) }
buffer.writeNullable(default) { _, value -> buffer.writeString(value) }
buffer.writeCollection(choices) { _, value -> buffer.writeString(value) }
buffer.writeBoolean(isAspect)
buffer.writeString(aspectFormat)
buffer.writeBoolean(needsKey)
}
override fun decode(buffer: PacketByteBuf) {
keys = buffer.readList { buffer.readString() }
default = buffer.readNullable { buffer.readString() }
choices = buffer.readList { buffer.readString() }
isAspect = buffer.readBoolean()
aspectFormat = buffer.readString()
needsKey = buffer.readBoolean()
}
override fun getRenderer(pokemon: Pokemon): SummarySpeciesFeatureRenderer<StringSpeciesFeature>? {
return null
}
override fun invoke(buffer: PacketByteBuf, name: String): StringSpeciesFeature? {
return if (name in keys) {
StringSpeciesFeature(name, "").also { it.decode(buffer) }
} else {
null
}
}
fun getAllAspects(): MutableList<String> {
val aspects = choices.toMutableList()
choices.forEach {
@@ -45,10 +78,10 @@ open class ChoiceSpeciesFeatureProvider(
internal constructor(): this(emptyList())
fun get(pokemon: Pokemon) = pokemon.getFeature<StringSpeciesFeature>(keys.first())
override fun get(pokemon: Pokemon) = pokemon.getFeature<StringSpeciesFeature>(keys.first())
override fun invoke(pokemon: Pokemon): StringSpeciesFeature? {
val existing = pokemon.getFeature<StringSpeciesFeature>(keys.first())
val existing = get(pokemon)
return if (existing != null && existing.value in choices) {
existing
} else {
@@ -88,7 +121,7 @@ open class ChoiceSpeciesFeatureProvider(
override fun provide(pokemon: Pokemon): Set<String> {
return if (isAspect) {
pokemon.getFeature<StringSpeciesFeature>(keys.first())?.let { setOf(getAspect(it)) } ?: emptySet()
get(pokemon)?.let { setOf(getAspect(it)) } ?: emptySet()
} else {
emptySet()
}
@@ -12,10 +12,12 @@ import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.aspect.AspectProvider
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType
import com.cobblemon.mod.common.client.gui.summary.featurerenderers.SummarySpeciesFeatureRenderer
import com.cobblemon.mod.common.pokemon.Pokemon
import com.google.gson.JsonObject
import kotlin.random.Random
import net.minecraft.nbt.NbtCompound
import net.minecraft.network.PacketByteBuf
/**
* A simple [SpeciesFeature] that is a true/false flag value. It implements [CustomPokemonProperty] for use in
@@ -26,7 +28,7 @@ import net.minecraft.nbt.NbtCompound
* @author Hiroku
* @since May 13th, 2022
*/
open class FlagSpeciesFeature(override val name: String) : SpeciesFeature, CustomPokemonProperty {
open class FlagSpeciesFeature(override val name: String) : SynchronizedSpeciesFeature, CustomPokemonProperty {
constructor(name: String, enabled: Boolean): this(name) {
this.enabled = enabled
}
@@ -53,6 +55,14 @@ open class FlagSpeciesFeature(override val name: String) : SpeciesFeature, Custo
return this
}
override fun encode(buffer: PacketByteBuf) {
buffer.writeBoolean(enabled)
}
override fun decode(buffer: PacketByteBuf) {
enabled = buffer.readBoolean()
}
override fun asString() = "$name=$enabled"
override fun apply(pokemon: Pokemon) {
@@ -71,11 +81,37 @@ open class FlagSpeciesFeature(override val name: String) : SpeciesFeature, Custo
override fun matches(pokemon: Pokemon) = pokemon.getFeature<FlagSpeciesFeature>(name)?.enabled == enabled
}
class FlagSpeciesFeatureProvider : SpeciesFeatureProvider<FlagSpeciesFeature>, CustomPokemonPropertyType<FlagSpeciesFeature>, AspectProvider {
override val keys: List<String>
class FlagSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<FlagSpeciesFeature>, CustomPokemonPropertyType<FlagSpeciesFeature>, AspectProvider {
override var keys: List<String> = emptyList()
// Uses get() = true because that way there's no backing field. It MUST be true, this way no JSON trickery will overwrite it
override val needsKey get() = true
var default: String? = null
val isAspect = true
var isAspect = true
override var visible: Boolean = false
override fun invoke(buffer: PacketByteBuf, name: String): FlagSpeciesFeature? {
return if (name in keys) {
FlagSpeciesFeature(name).also { it.decode(buffer) }
} else {
null
}
}
override fun encode(buffer: PacketByteBuf) {
buffer.writeCollection(keys) { _, value -> buffer.writeString(value) }
buffer.writeNullable(default) { _, value -> buffer.writeString(value) }
buffer.writeBoolean(isAspect)
}
override fun decode(buffer: PacketByteBuf) {
keys = buffer.readList { it.readString() }
default = buffer.readNullable { it.readString() }
isAspect = buffer.readBoolean()
}
override fun getRenderer(pokemon: Pokemon): SummarySpeciesFeatureRenderer<FlagSpeciesFeature>? {
return null
}
override fun examples() = setOf("true", "false")
@@ -94,8 +130,10 @@ class FlagSpeciesFeatureProvider : SpeciesFeatureProvider<FlagSpeciesFeature>, C
constructor(vararg keys: String) : this(keys.toList())
override fun get(pokemon: Pokemon) = pokemon.getFeature<FlagSpeciesFeature>(keys.first())
override fun invoke(pokemon: Pokemon): FlagSpeciesFeature? {
return pokemon.getFeature(keys.first())
return get(pokemon)
?: when (default) {
"random" -> FlagSpeciesFeature(keys.first(), Random.Default.nextBoolean())
in setOf("true", "false") -> FlagSpeciesFeature(keys.first(), default.toBoolean())
@@ -8,13 +8,17 @@
package com.cobblemon.mod.common.api.pokemon.feature
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.pokemon.aspect.AspectProvider
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.messages.client.data.GlobalSpeciesFeatureSyncPacket
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.adapters.SpeciesFeatureProviderAdapter
import com.cobblemon.mod.common.util.adapters.Vec3dAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.Gson
import com.google.gson.GsonBuilder
@@ -24,6 +28,7 @@ import net.minecraft.nbt.NbtCompound
import net.minecraft.resource.ResourceType
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.math.Vec3d
/**
* A registry very similar to [SpeciesFeatures] but the [SpeciesFeatureProvider] contained within it
@@ -42,11 +47,15 @@ object GlobalSpeciesFeatures : JsonDataRegistry<SpeciesFeatureProvider<*>> {
override val gson: Gson = GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(SpeciesFeatureProvider::class.java, SpeciesFeatureProviderAdapter)
.registerTypeAdapter(Vec3d::class.java, Vec3dAdapter)
.registerTypeAdapter(Identifier::class.java, IdentifierAdapter)
.create()
override val typeToken: TypeToken<SpeciesFeatureProvider<*>> = TypeToken.get(SpeciesFeatureProvider::class.java)
override val resourcePath: String = "global_species_features"
override fun sync(player: ServerPlayerEntity) {}
override fun sync(player: ServerPlayerEntity) {
player.sendPacket(GlobalSpeciesFeatureSyncPacket(codeFeatures + resourceFeatures))
}
override fun reload(data: Map<Identifier, SpeciesFeatureProvider<*>>) {
resourceFeatures.keys.toList().forEach(this::unregister)
@@ -59,6 +68,10 @@ object GlobalSpeciesFeatures : JsonDataRegistry<SpeciesFeatureProvider<*>> {
fun getFeatures() = (resourceFeatures.keys + codeFeatures.keys).mapNotNull(this::getFeature)
fun loadOnClient(entries: Collection<Map.Entry<String, SpeciesFeatureProvider<*>>>) {
codeFeatures.putAll(entries.map { it.toPair() })
}
private fun register(name: String, provider: SpeciesFeatureProvider<*>, isCoded: Boolean) {
val mapping = if (isCoded) codeFeatures else resourceFeatures
if (provider is AspectProvider) {
@@ -0,0 +1,181 @@
/*
* 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.pokemon.feature
import com.cobblemon.mod.common.api.net.Decodable
import com.cobblemon.mod.common.api.net.Encodable
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType
import com.cobblemon.mod.common.client.gui.summary.featurerenderers.BarSummarySpeciesFeatureRenderer
import com.cobblemon.mod.common.client.gui.summary.featurerenderers.SummarySpeciesFeatureRenderer
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.asTranslated
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.JsonObject
import com.google.gson.annotations.SerializedName
import net.minecraft.nbt.NbtCompound
import net.minecraft.network.PacketByteBuf
import net.minecraft.util.Identifier
import net.minecraft.util.math.Vec3d
/**
* A species feature value that's just an integer. Complex stuff.
* @author Hiroku
*/
class IntSpeciesFeature(override var name: String) : SynchronizedSpeciesFeature, CustomPokemonProperty {
var value = 0
constructor(): this("")
constructor(name: String, value: Int): this(name) {
this.value = value
}
override fun saveToNBT(pokemonNBT: NbtCompound): NbtCompound {
pokemonNBT.putInt(name, value)
return pokemonNBT
}
override fun loadFromNBT(pokemonNBT: NbtCompound): SynchronizedSpeciesFeature {
value = pokemonNBT.getInt(name)
return this
}
override fun saveToJSON(pokemonJSON: JsonObject): JsonObject {
pokemonJSON.addProperty(name, value)
return pokemonJSON
}
override fun loadFromJSON(pokemonJSON: JsonObject): SpeciesFeature {
value = pokemonJSON.get(name).asInt
return this
}
override fun encode(buffer: PacketByteBuf) {
buffer.writeInt(value)
}
override fun decode(buffer: PacketByteBuf) {
value = buffer.readInt()
}
override fun asString() = "$name=$value"
override fun apply(pokemon: Pokemon) {
val featureProvider = SpeciesFeatures.getFeature(name) ?: return
if (featureProvider in SpeciesFeatures.getFeaturesFor(pokemon.species)) {
val existingFeature = pokemon.getFeature<IntSpeciesFeature>(name)
if (existingFeature != null) {
existingFeature.value = value
} else {
pokemon.features.add(IntSpeciesFeature(name, value))
}
pokemon.updateAspects()
}
}
override fun matches(pokemon: Pokemon) = pokemon.getFeature<IntSpeciesFeature>(name)?.value == value
}
class IntSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<IntSpeciesFeature>, CustomPokemonPropertyType<IntSpeciesFeature> {
class DisplayData : Encodable, Decodable {
var name: String = ""
@SerializedName(value = "colour" /* fuck you we use real english */, alternate = ["color"])
var colour = Vec3d(255.0, 255.0, 255.0)
var underlay: Identifier? = null
var overlay: Identifier? = null
override fun decode(buffer: PacketByteBuf) {
name = buffer.readString()
colour = Vec3d(buffer.readDouble(), buffer.readDouble(), buffer.readDouble())
underlay = buffer.readNullable { buffer.readIdentifier() }
overlay = buffer.readNullable { buffer.readIdentifier() }
}
override fun encode(buffer: PacketByteBuf) {
buffer.writeString(name)
buffer.writeDouble(colour.x)
buffer.writeDouble(colour.y)
buffer.writeDouble(colour.z)
buffer.writeNullable(underlay) { _, value -> buffer.writeIdentifier(value) }
buffer.writeNullable(overlay) { _, value -> buffer.writeIdentifier(value) }
}
}
override var keys = listOf<String>()
// Uses get() = true because that way there's no backing field. It MUST be true, this way no JSON trickery will overwrite it
override val needsKey get() = true
override var visible = false
var default: Int? = null
var min = 0
var max = 100
var display: DisplayData? = null
override fun fromString(value: String?) = value?.toIntOrNull()?.takeIf { it in min..max }?.let { IntSpeciesFeature(keys.first(), it) }
override fun examples() = emptyList<String>()
override fun invoke(buffer: PacketByteBuf, name: String): IntSpeciesFeature? {
return if (name in keys) {
IntSpeciesFeature(name, buffer.readInt())
} else {
null
}
}
override fun invoke(pokemon: Pokemon): IntSpeciesFeature? {
return get(pokemon) ?: default?.let { IntSpeciesFeature(keys.first(), it) }
}
override fun invoke(nbt: NbtCompound): IntSpeciesFeature? {
return if (nbt.contains(keys.first())) {
IntSpeciesFeature(keys.first(), nbt.getInt(keys.first()))
} else {
null
}
}
override fun invoke(json: JsonObject): IntSpeciesFeature? {
return if (json.has(keys.first())) {
IntSpeciesFeature(keys.first(), json.get(keys.first()).asInt)
} else {
null
}
}
override fun get(pokemon: Pokemon) = pokemon.features.filterIsInstance<IntSpeciesFeature>().find { it.name in keys }
override fun encode(buffer: PacketByteBuf) {
buffer.writeCollection(keys) { _, value -> buffer.writeString(value) }
buffer.writeNullable(default) { _, value -> buffer.writeInt(value) }
buffer.writeInt(min)
buffer.writeInt(max)
buffer.writeNullable(display) { _, value -> value.encode(buffer) }
}
override fun decode(buffer: PacketByteBuf) {
keys = buffer.readList { buffer.readString() }
default = buffer.readNullable { buffer.readInt() }
min = buffer.readInt()
max = buffer.readInt()
display = buffer.readNullable { DisplayData().also { it.decode(buffer) } }
}
override fun getRenderer(pokemon: Pokemon): SummarySpeciesFeatureRenderer<IntSpeciesFeature>? {
return display?.let {
BarSummarySpeciesFeatureRenderer(
name = keys.first(),
displayName = it.name.asTranslated(),
min = min,
max = max,
colour = it.colour,
underlay = it.underlay ?: cobblemonResource("textures/gui/summary/summary_stats_other_bar.png"),
overlay = it.overlay ?: cobblemonResource("textures/gui/summary/summary_stats_generic_overlay.png"),
pokemon = pokemon
)
}
}
}
@@ -8,10 +8,13 @@
package com.cobblemon.mod.common.api.pokemon.feature
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.messages.client.data.SpeciesFeatureAssignmentSyncPacket
import com.cobblemon.mod.common.pokemon.Species
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.Gson
import com.google.gson.GsonBuilder
@@ -38,17 +41,24 @@ object SpeciesFeatureAssignments : JsonDataRegistry<SpeciesFeatureAssignment> {
override val typeToken = TypeToken.get(SpeciesFeatureAssignment::class.java)
override val resourcePath = "species_feature_assignments"
private val assignments = mutableMapOf<String, MutableSet<String>>()
private val assignments = mutableMapOf<Identifier, MutableSet<String>>()
override fun sync(player: ServerPlayerEntity) {}
override fun sync(player: ServerPlayerEntity) {
player.sendPacket(SpeciesFeatureAssignmentSyncPacket(assignments))
}
override fun reload(data: Map<Identifier, SpeciesFeatureAssignment>) {
data.values.forEach {
it.pokemon.forEach { pokemon ->
assignments.getOrPut(pokemon) { mutableSetOf() }.addAll(it.features)
assignments.getOrPut(pokemon.asIdentifierDefaultingNamespace()) { mutableSetOf() }.addAll(it.features)
}
}
this.observable.emit(this)
}
fun getFeatures(species: Species) = assignments[species.showdownId()] ?: emptySet()
fun loadOnClient(data: Map<Identifier, MutableSet<String>>) {
this.assignments.clear()
this.assignments.putAll(data)
}
fun getFeatures(species: Species) = assignments[species.resourceIdentifier] ?: emptySet()
}
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.pokemon.feature
import com.cobblemon.mod.common.pokemon.Pokemon
import com.google.gson.JsonObject
import net.minecraft.nbt.NbtCompound
import net.minecraft.network.PacketByteBuf
/**
* A provider of [SpeciesFeature]s. These must be registered via [SpeciesFeatures] either programmatically or
@@ -8,13 +8,17 @@
package com.cobblemon.mod.common.api.pokemon.feature
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.pokemon.aspect.AspectProvider
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.messages.client.data.StandardSpeciesFeatureSyncPacket
import com.cobblemon.mod.common.pokemon.Species
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.adapters.SpeciesFeatureProviderAdapter
import com.cobblemon.mod.common.util.adapters.Vec3dAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.Gson
import com.google.gson.GsonBuilder
@@ -22,6 +26,7 @@ import com.google.gson.reflect.TypeToken
import net.minecraft.resource.ResourceType
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.math.Vec3d
/**
* A registry for [SpeciesFeatureProvider]s. This is the backbone of species-specific data such as
@@ -48,11 +53,15 @@ object SpeciesFeatures : JsonDataRegistry<SpeciesFeatureProvider<*>> {
override val gson: Gson = GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(SpeciesFeatureProvider::class.java, SpeciesFeatureProviderAdapter)
.registerTypeAdapter(Vec3d::class.java, Vec3dAdapter)
.registerTypeAdapter(Identifier::class.java, IdentifierAdapter)
.create()
override val typeToken: TypeToken<SpeciesFeatureProvider<*>> = TypeToken.get(SpeciesFeatureProvider::class.java)
override val resourcePath: String = "species_features"
override fun sync(player: ServerPlayerEntity) {}
override fun sync(player: ServerPlayerEntity) {
player.sendPacket(StandardSpeciesFeatureSyncPacket(codeFeatures + resourceFeatures))
}
override fun reload(data: Map<Identifier, SpeciesFeatureProvider<*>>) {
resourceFeatures.keys.toList().forEach(this::unregister)
@@ -62,6 +71,9 @@ object SpeciesFeatures : JsonDataRegistry<SpeciesFeatureProvider<*>> {
fun getCodeFeature(name: String) = resourceFeatures[name]
fun getResourceFeature(name: String) = codeFeatures[name]
fun getFeature(name: String) = getCodeFeature(name) ?: getResourceFeature(name)
fun loadOnClient(entries: Collection<Map.Entry<String, SpeciesFeatureProvider<*>>>) {
codeFeatures.putAll(entries.map { it.toPair() })
}
fun getFeatures() = (resourceFeatures.keys + codeFeatures.keys).mapNotNull(this::getFeature)
fun getFeaturesFor(species: Species): List<SpeciesFeatureProvider<*>> {
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
import com.cobblemon.mod.common.pokemon.Pokemon
import com.google.gson.JsonObject
import net.minecraft.nbt.NbtCompound
import net.minecraft.network.PacketByteBuf
/**
* A species feature value that is a string value.
@@ -22,7 +23,7 @@ import net.minecraft.nbt.NbtCompound
class StringSpeciesFeature(
override val name: String,
var value: String
) : SpeciesFeature, CustomPokemonProperty {
) : SynchronizedSpeciesFeature, CustomPokemonProperty {
override fun saveToNBT(pokemonNBT: NbtCompound): NbtCompound {
pokemonNBT.putString(name, value)
return pokemonNBT
@@ -43,6 +44,14 @@ class StringSpeciesFeature(
return this
}
override fun encode(buffer: PacketByteBuf) {
buffer.writeString(value)
}
override fun decode(buffer: PacketByteBuf) {
value = buffer.readString()
}
override fun asString() = "$name=$value"
override fun apply(pokemon: Pokemon) {
@@ -0,0 +1,20 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.pokemon.feature
import com.cobblemon.mod.common.api.net.Decodable
import com.cobblemon.mod.common.api.net.Encodable
/**
* A species feature that can be synchronized to the client. These must be managed by a [SynchronizedSpeciesFeatureProvider].
*
* @author Hiroku
* @since November 13th, 2023
*/
interface SynchronizedSpeciesFeature : SpeciesFeature, Encodable, Decodable
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.pokemon.feature
import com.cobblemon.mod.common.api.net.Decodable
import com.cobblemon.mod.common.api.net.Encodable
import com.cobblemon.mod.common.client.gui.summary.featurerenderers.SummarySpeciesFeatureRenderer
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.network.PacketByteBuf
/**
* A species feature provider that will be synchronized to the client. For it to be renderable in the summary
* screen of a Pokémon it must also provide a [SummarySpeciesFeatureRenderer] in [getRenderer]. Note that you
* really don't want to initialize a renderer outside of that function call because if the server ever initializes
* it then you're going to get crashes on dedicated servers (this is a bad thing).
*
* @author Hiroku
* @since November 13th, 2023
*/
interface SynchronizedSpeciesFeatureProvider<T : SynchronizedSpeciesFeature> : SpeciesFeatureProvider<T>, Encodable, Decodable {
var visible: Boolean
operator fun invoke(buffer: PacketByteBuf, name: String): T?
/** Gets the feature from this Pokémon, if it has been created yet. */
fun get(pokemon: Pokemon): T?
/** Only run this from the client. */
fun getRenderer(pokemon: Pokemon): SummarySpeciesFeatureRenderer<T>?
}
@@ -49,6 +49,25 @@ enum class Stats(override val identifier: Identifier, override val displayName:
*/
val BATTLE_ONLY: Set<Stat> = EnumSet.of(EVASION, ACCURACY)
/** Gets the [Stat] from the respective Showdown id. */
fun getStat(statKey: String) = when(statKey) {
"atk" -> ATTACK
"def" -> DEFENCE
"spa" -> SPECIAL_ATTACK
"spd" -> SPECIAL_DEFENCE
"spe" -> SPEED
"evasion" -> EVASION
else -> ACCURACY
}
/** Gets the severity lang key from the respective boost/unboost stage. */
fun getSeverity(stages: Int) = when(stages) {
0 -> "cap.single"
1 -> "slight"
2 -> "sharp"
else -> "severe"
}
}
}
@@ -8,13 +8,27 @@
package com.cobblemon.mod.common.api.scheduling
import java.util.concurrent.CompletableFuture
@Deprecated("Use afterOnServer or afterOnClient; ambiguous side is not good for your health")
@JvmOverloads
fun after(ticks: Int = 0, seconds: Float = 0F, serverThread: Boolean = false, action: () -> Unit) {
val scheduler = if (serverThread) ServerTaskTracker else ClientTaskTracker
scheduler.after(seconds = seconds + ticks / 20F, action)
}
fun delayedFuture(ticks: Int = 0, seconds: Float = 0F, serverThread: Boolean = false): CompletableFuture<Unit> {
val future = CompletableFuture<Unit>()
if (ticks == 0 && seconds == 0F) {
future.complete(Unit)
} else {
after(ticks = ticks, seconds = seconds, serverThread = serverThread) { future.complete(Unit) }
}
return future
}
/**
* Delayed task is created to run on the main thread. This is for when the task
* being completed after the delay does things like entity removal or other thread-unsafe actions.
@@ -20,7 +20,6 @@ import com.mojang.serialization.codecs.PrimitiveCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.network.PacketByteBuf
import net.minecraft.util.Identifier
import net.minecraft.util.math.Vec3d
/**
* Effect details for the actual particles of a particle effect.
@@ -29,7 +28,7 @@ import net.minecraft.util.math.Vec3d
* @since January 4th, 2023
*/
class BedrockParticle(
var texture: Identifier = Identifier("minecraft:textures/particle/bubble.png"),
var texture: Identifier = Identifier("minecraft:textures/particles/bubble.png"),
var material: ParticleMaterial = ParticleMaterial.ALPHA,
var uvMode: ParticleUVMode = StaticParticleUVMode(),
var sizeX: Expression = NumberExpression(0.15),
@@ -44,48 +43,106 @@ class BedrockParticle(
var cameraMode: ParticleCameraMode = RotateXYZCameraMode(),
var tinting: ParticleTinting = ExpressionParticleTinting(),
var collision: ParticleCollision = ParticleCollision(),
var environmentLighting: Boolean = false
var environmentLighting: Boolean = false,
var creationEvents: MutableList<SimpleEventTrigger> = mutableListOf(),
var expirationEvents: MutableList<SimpleEventTrigger> = mutableListOf(),
var timeline: EventTriggerTimeline = EventTriggerTimeline(mutableMapOf())
) {
class ExpressionSet(
val sizeX: Expression,
val sizeY: Expression,
val maxAge: Expression,
val killExpression: Expression,
val updateExpressions: MutableList<Expression>,
val renderExpressions: MutableList<Expression>
)
/*
"creation_event": "event_sendspark",
"expiration_event": ["event_spark", "event_afterspark", "event_capturestar"],
"timeline": {
"21.00": "event_spark"
}
*/
class EventSet(
val creationEvents: MutableList<SimpleEventTrigger>,
val expirationEvents: MutableList<SimpleEventTrigger>,
val timeline: EventTriggerTimeline
)
// kill plane maybe
companion object {
val CODEC: Codec<BedrockParticle> = RecordCodecBuilder.create { instance ->
val EXPRESSION_SET_CODEC = RecordCodecBuilder.create<ExpressionSet> { instance ->
instance.group(
Identifier.CODEC.fieldOf("texture").forGetter { it.texture },
PrimitiveCodec.STRING.fieldOf("material").forGetter { it.material.name },
ParticleUVMode.codec.fieldOf("uvMode").forGetter { it.uvMode },
EXPRESSION_CODEC.fieldOf("sizeX").forGetter { it.sizeX },
EXPRESSION_CODEC.fieldOf("sizeY").forGetter { it.sizeY },
EXPRESSION_CODEC.fieldOf("maxAge").forGetter { it.maxAge },
EXPRESSION_CODEC.fieldOf("killExpression").forGetter { it.killExpression },
ListCodec(EXPRESSION_CODEC).fieldOf("updateExpressions").forGetter { it.updateExpressions },
ListCodec(EXPRESSION_CODEC).fieldOf("renderExpressions").forGetter { it.renderExpressions },
ListCodec(EXPRESSION_CODEC).fieldOf("renderExpressions").forGetter { it.renderExpressions }
).apply(instance, ::ExpressionSet)
}
val EVENT_SET_CODEC = RecordCodecBuilder.create<EventSet> { instance ->
instance.group(
ListCodec(SimpleEventTrigger.CODEC).fieldOf("creationEvents").forGetter { it.creationEvents },
ListCodec(SimpleEventTrigger.CODEC).fieldOf("expirationEvents").forGetter { it.expirationEvents },
EventTriggerTimeline.CODEC.fieldOf("timeline").forGetter { it.timeline }
).apply(instance, ::EventSet)
}
val CODEC: Codec<BedrockParticle> = RecordCodecBuilder.create { instance ->
instance.group(
Identifier.CODEC.fieldOf("texture").forGetter { it.texture },
PrimitiveCodec.STRING.fieldOf("material").forGetter { it.material.name },
ParticleUVMode.codec.fieldOf("uvMode").forGetter { it.uvMode },
EXPRESSION_SET_CODEC.fieldOf("expressionSet").forGetter {
ExpressionSet(
it.sizeX,
it.sizeY,
it.maxAge,
it.killExpression,
it.updateExpressions,
it.renderExpressions
)
},
ParticleMotion.codec.fieldOf("motion").forGetter { it.motion },
ParticleRotation.codec.fieldOf("rotation").forGetter { it.rotation },
ParticleViewDirection.codec.fieldOf("viewDirection").forGetter { it.viewDirection },
ParticleCameraMode.codec.fieldOf("cameraMode").forGetter { it.cameraMode },
ParticleTinting.codec.fieldOf("tinting").forGetter { it.tinting },
ParticleCollision.CODEC.fieldOf("collision").forGetter { it.collision },
PrimitiveCodec.BOOL.fieldOf("environmentLighting").forGetter { it.environmentLighting }
PrimitiveCodec.BOOL.fieldOf("environmentLighting").forGetter { it.environmentLighting },
EVENT_SET_CODEC.fieldOf("eventSet").forGetter {
EventSet(
it.creationEvents,
it.expirationEvents,
it.timeline
)
}
).apply(instance) {
texture, materialStr, uvMode, sizeX, sizeY, maxAge, killExpression, updateExpressions,
renderExpressions, motion, rotation, viewDirection, cameraMode, tinting, collision, environmentLighting ->
texture, materialStr, uvMode, expressionSet, motion, rotation, viewDirection, cameraMode, tinting, collision, environmentLighting, eventSet ->
BedrockParticle(
texture = texture,
material = ParticleMaterial.valueOf(materialStr),
uvMode = uvMode,
sizeX = sizeX,
sizeY = sizeY,
maxAge = maxAge,
killExpression = killExpression,
updateExpressions = updateExpressions,
renderExpressions = renderExpressions,
sizeX = expressionSet.sizeX,
sizeY = expressionSet.sizeY,
maxAge = expressionSet.maxAge,
killExpression = expressionSet.killExpression,
updateExpressions = expressionSet.updateExpressions,
renderExpressions = expressionSet.renderExpressions,
motion = motion,
rotation = rotation,
viewDirection = viewDirection,
cameraMode = cameraMode,
tinting = tinting,
collision = collision,
environmentLighting = environmentLighting
environmentLighting = environmentLighting,
creationEvents = eventSet.creationEvents,
expirationEvents = eventSet.expirationEvents,
timeline = eventSet.timeline
)
}
}
@@ -108,6 +165,9 @@ class BedrockParticle(
ParticleTinting.writeToBuffer(buffer, tinting)
collision.writeToBuffer(buffer)
buffer.writeBoolean(environmentLighting)
buffer.writeCollection(creationEvents) { pb, event -> event.encode(pb) }
buffer.writeCollection(expirationEvents) { pb, event -> event.encode(pb) }
timeline.encode(buffer)
}
fun readFromBuffer(buffer: PacketByteBuf) {
@@ -127,5 +187,8 @@ class BedrockParticle(
tinting = ParticleTinting.readFromBuffer(buffer)
collision.readFromBuffer(buffer)
environmentLighting = buffer.readBoolean()
creationEvents = buffer.readList { SimpleEventTrigger("").also { it.decode(buffer) } }
expirationEvents = buffer.readList { SimpleEventTrigger("").also { it.decode(buffer) } }
timeline.decode(buffer)
}
}
@@ -10,7 +10,9 @@ package com.cobblemon.mod.common.api.snowstorm
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.ListCodec
import com.mojang.serialization.codecs.PrimitiveCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import com.mojang.serialization.codecs.UnboundedMapCodec
import net.minecraft.network.PacketByteBuf
import net.minecraft.util.Identifier
@@ -27,7 +29,8 @@ class BedrockParticleEffect(
var emitter: BedrockParticleEmitter = BedrockParticleEmitter(),
var particle: BedrockParticle = BedrockParticle(),
var curves: MutableList<MoLangCurve> = mutableListOf(),
var space: ParticleSpace = ParticleSpace()
var space: ParticleSpace = ParticleSpace(),
var events: MutableMap<String, ParticleEvent> = mutableMapOf()
) {
companion object {
val CODEC: Codec<BedrockParticleEffect> = RecordCodecBuilder.create { instance ->
@@ -36,14 +39,16 @@ class BedrockParticleEffect(
BedrockParticleEmitter.CODEC.fieldOf("emitter").forGetter { it.emitter },
BedrockParticle.CODEC.fieldOf("particle").forGetter { it.particle },
ListCodec(MoLangCurve.codec).fieldOf("curves").forGetter { it.curves },
ParticleSpace.CODEC.fieldOf("space").forGetter { it.space }
).apply(instance) { id, emitter, particle, curves, space ->
ParticleSpace.CODEC.fieldOf("space").forGetter { it.space },
UnboundedMapCodec(PrimitiveCodec.STRING, ParticleEvent.CODEC).fieldOf("events").forGetter { it.events }
).apply(instance) { id, emitter, particle, curves, space, events ->
BedrockParticleEffect(
id = id,
emitter = emitter,
particle = particle,
curves = curves.toMutableList(),
space = space
space = space,
events = events
)
}
}
@@ -55,6 +60,7 @@ class BedrockParticleEffect(
particle.writeToBuffer(buffer)
buffer.writeCollection(curves) { pb, curve -> MoLangCurve.writeToBuffer(buffer, curve) }
space.writeToBuffer(buffer)
buffer.writeMap(events, { _, v -> buffer.writeString(v) }) { _, event -> event.encode(buffer) }
}
fun readFromBuffer(buffer: PacketByteBuf) {
@@ -63,5 +69,6 @@ class BedrockParticleEffect(
particle.readFromBuffer(buffer)
curves = buffer.readList { MoLangCurve.readFromBuffer(buffer) }
space.readFromBuffer(buffer)
events = buffer.readMap({ buffer.readString() }) { ParticleEvent().also { it.decode(buffer) } }
}
}
@@ -29,7 +29,12 @@ class BedrockParticleEmitter(
var updateExpressions: MutableList<Expression> = mutableListOf(),
var rate: ParticleEmitterRate = InstantParticleEmitterRate(),
var shape: ParticleEmitterShape = SphereParticleEmitterShape(),
var lifetime: ParticleEmitterLifetime = OnceEmitterLifetime(NumberExpression(1.0))
var lifetime: ParticleEmitterLifetime = OnceEmitterLifetime(NumberExpression(1.0)),
var eventTimeline: EventTriggerTimeline = EventTriggerTimeline(mutableMapOf()),
var creationEvents: MutableList<SimpleEventTrigger> = mutableListOf(),
var expirationEvents: MutableList<SimpleEventTrigger> = mutableListOf(),
var travelDistanceEvents: EventTriggerTimeline = EventTriggerTimeline(mutableMapOf()),
var loopingTravelDistanceEvents: MutableList<LoopingTravelDistanceEventTrigger> = mutableListOf()
) {
companion object {
val CODEC: Codec<BedrockParticleEmitter> = RecordCodecBuilder.create { instance ->
@@ -38,14 +43,24 @@ class BedrockParticleEmitter(
ListCodec(EXPRESSION_CODEC).fieldOf("updateExpressions").forGetter { it.updateExpressions },
ParticleEmitterRate.codec.fieldOf("rate").forGetter { it.rate },
ParticleEmitterShape.codec.fieldOf("shape").forGetter { it.shape },
ParticleEmitterLifetime.codec.fieldOf("lifetime").forGetter { it.lifetime }
).apply(instance) { startExpressions, updateExpressions, rate, shape, lifetime ->
ParticleEmitterLifetime.codec.fieldOf("lifetime").forGetter { it.lifetime },
EventTriggerTimeline.CODEC.fieldOf("eventTimeline").forGetter { it.eventTimeline },
ListCodec(SimpleEventTrigger.CODEC).fieldOf("creationEvents").forGetter { it.creationEvents },
ListCodec(SimpleEventTrigger.CODEC).fieldOf("expirationEvents").forGetter { it.expirationEvents },
EventTriggerTimeline.CODEC.fieldOf("travelDistanceEvents").forGetter { it.travelDistanceEvents },
ListCodec(LoopingTravelDistanceEventTrigger.CODEC).fieldOf("loopingTravelDistanceEvents").forGetter { it.loopingTravelDistanceEvents }
).apply(instance) { startExpressions, updateExpressions, rate, shape, lifetime, eventTimeline, creationEvents, expirationEvents, travelDistanceEvents, loopingTravelDistanceEvents ->
BedrockParticleEmitter(
startExpressions = startExpressions,
updateExpressions = updateExpressions,
shape = shape,
rate = rate,
lifetime = lifetime
lifetime = lifetime,
eventTimeline = eventTimeline,
creationEvents = creationEvents,
expirationEvents = expirationEvents,
travelDistanceEvents = travelDistanceEvents,
loopingTravelDistanceEvents = loopingTravelDistanceEvents
)
}
}
@@ -57,6 +72,11 @@ class BedrockParticleEmitter(
ParticleEmitterRate.writeToBuffer(buffer, rate)
ParticleEmitterShape.writeToBuffer(buffer, shape)
ParticleEmitterLifetime.writeToBuffer(buffer, lifetime)
eventTimeline.encode(buffer)
buffer.writeCollection(creationEvents) { pb, event -> event.encode(pb) }
buffer.writeCollection(expirationEvents) { pb, event -> event.encode(pb) }
travelDistanceEvents.encode(buffer)
buffer.writeCollection(loopingTravelDistanceEvents) { pb, event -> event.encode(pb) }
}
fun readFromBuffer(buffer: PacketByteBuf) {
@@ -65,5 +85,10 @@ class BedrockParticleEmitter(
rate = ParticleEmitterRate.readFromBuffer(buffer)
shape = ParticleEmitterShape.readFromBuffer(buffer)
lifetime = ParticleEmitterLifetime.readFromBuffer(buffer)
eventTimeline.decode(buffer)
creationEvents = buffer.readList { SimpleEventTrigger("").also { it.decode(buffer) } }
expirationEvents = buffer.readList { SimpleEventTrigger("").also { it.decode(buffer) } }
travelDistanceEvents.decode(buffer)
loopingTravelDistanceEvents = buffer.readList { LoopingTravelDistanceEventTrigger(0.0, mutableListOf()).also { it.decode(buffer) } }
}
}
@@ -25,6 +25,7 @@ import com.mojang.serialization.DynamicOps
import com.mojang.serialization.codecs.ListCodec
import com.mojang.serialization.codecs.PrimitiveCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import com.mojang.serialization.codecs.UnboundedMapCodec
import kotlin.math.floor
import net.minecraft.network.PacketByteBuf
@@ -44,6 +45,7 @@ interface MoLangCurve : CodecMapped {
registerSubtype(CurveType.LINEAR, LinearMoLangCurve::class.java, LinearMoLangCurve.CODEC)
registerSubtype(CurveType.CATMULL_ROM, CatmullRomMoLangCurve::class.java, CatmullRomMoLangCurve.CODEC)
registerSubtype(CurveType.BEZIER, BezierMoLangCurve::class.java, BezierMoLangCurve.CODEC)
registerSubtype(CurveType.BEZIER_CHAIN, BezierChainMoLangCurve::class.java, BezierChainMoLangCurve.CODEC)
}
}
@@ -52,8 +54,7 @@ interface MoLangCurve : CodecMapped {
var input: Expression
fun resolve(runtime: MoLangRuntime, inputValue: Double): Double
fun apply(runtime: MoLangRuntime) {
val inputValue = runtime.resolveDouble(input)
runtime.environment.setSimpleVariable(name, DoubleValue(resolve(runtime, inputValue)))
runtime.environment.setSimpleVariable(name, DoubleValue(resolve(runtime, runtime.resolveDouble(input))))
}
}
@@ -165,6 +166,103 @@ class CatmullRomMoLangCurve(
}
}
class BezierChainMoLangCurve(
override var name: String = "variable",
override var input: Expression = NumberExpression(0.5),
var nodes: Map<Double, BezierChainNode> = emptyMap()
) : MoLangCurve {
var nodePairs: List<BezierChainNodePair> = emptyList()
fun deriveNodePairs() {
val nodePairs = mutableListOf<BezierChainNodePair>()
val sortedNodes = nodes.entries.sortedBy { it.key }
for (i in 1 until sortedNodes.size) {
val node1 = sortedNodes[i - 1]
val node2 = sortedNodes[i]
nodePairs.add(BezierChainNodePair(node1.key, node2.key, node1.value, node2.value))
}
this.nodePairs = nodePairs
}
init {
deriveNodePairs()
}
class BezierChainNode(var value: Double, var slope: Double) {
fun writeToBuffer(buffer: PacketByteBuf) {
buffer.writeDouble(value)
buffer.writeDouble(slope)
}
fun readFromBuffer(buffer: PacketByteBuf) {
value = buffer.readDouble()
slope = buffer.readDouble()
}
companion object {
val CODEC = RecordCodecBuilder.create<BezierChainNode> { instance ->
instance.group(
PrimitiveCodec.DOUBLE.fieldOf("value").forGetter { it.value },
PrimitiveCodec.DOUBLE.fieldOf("slope").forGetter { it.slope }
).apply(instance, ::BezierChainNode)
}
}
}
class BezierChainNodePair(
val startTime: Double,
val endTime: Double,
node1: BezierChainNode,
node2: BezierChainNode
) {
val curve: CubedBezierCurve
init {
val v1 = node1.value
val v2 = node1.value + node1.slope / 3
val v3 = node2.value - node2.slope / 3
val v4 = node2.value
curve = CubedBezierCurve(v1, v2, v3, v4)
}
}
class BezierChainPointData(val time: Double, val value: Double, val slope: Double)
companion object {
val CODEC: Codec<BezierChainMoLangCurve> = RecordCodecBuilder.create { instance ->
instance.group(
PrimitiveCodec.STRING.fieldOf("type").forGetter { it.type.name },
PrimitiveCodec.STRING.fieldOf("name").forGetter { it.name },
EXPRESSION_CODEC.fieldOf("input").forGetter { it.input },
UnboundedMapCodec(PrimitiveCodec.DOUBLE, BezierChainNode.CODEC).fieldOf("nodes").forGetter { it.nodes }
).apply(instance) { _, name, input, nodes -> BezierChainMoLangCurve(name, input, nodes) }
}
}
override val type: CurveType = CurveType.BEZIER_CHAIN
override fun resolve(runtime: MoLangRuntime, inputValue: Double): Double {
val position = inputValue.coerceIn(0.0, 1.0)
val nodePair = nodePairs.last { position >= it.startTime }
val curve = nodePair.curve
val t = (position - nodePair.startTime) / (nodePair.endTime - nodePair.startTime)
return curve.getY(t)
}
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
override fun readFromBuffer(buffer: PacketByteBuf) {
name = buffer.readString()
input = MoLang.createParser(buffer.readString()).parseExpression()
nodes = buffer.readMap({ buffer.readDouble() }, { BezierChainNode(0.0, 0.0).also { it.readFromBuffer(buffer) } })
deriveNodePairs()
}
override fun writeToBuffer(buffer: PacketByteBuf) {
buffer.writeString(name)
buffer.writeString(input.getString())
buffer.writeMap(nodes, { pb, key -> pb.writeDouble(key) }, { pb, value -> value.writeToBuffer(pb) })
}
}
class BezierMoLangCurve(
override var name: String = "variable",
override var input: Expression = NumberExpression(0.5),
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.api.codec.CodecMapped
import com.cobblemon.mod.common.api.data.ArbitrarilyMappedSerializableCompanion
import com.cobblemon.mod.common.client.render.MatrixWrapper
import com.cobblemon.mod.common.util.math.hamiltonProduct
import com.cobblemon.mod.common.util.set
import com.mojang.serialization.Codec
import com.mojang.serialization.DynamicOps
import com.mojang.serialization.codecs.PrimitiveCodec
@@ -26,6 +27,7 @@ import net.minecraft.util.math.RotationAxis
import net.minecraft.util.math.Vec3d
import org.joml.AxisAngle4d
import org.joml.Quaternionf
import org.joml.Vector3f
interface ParticleCameraMode : CodecMapped {
companion object : ArbitrarilyMappedSerializableCompanion<ParticleCameraMode, ParticleCameraModeType>(
@@ -54,6 +56,8 @@ interface ParticleCameraMode : CodecMapped {
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
@@ -77,6 +81,8 @@ class RotateXYZCameraMode : ParticleCameraMode {
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
@@ -109,16 +115,16 @@ class RotateYCameraMode : ParticleCameraMode {
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
viewDirection: Vec3d
): Quaternionf {
val i = if (angle == 0F) 0F else MathHelper.lerp(deltaTicks, prevAngle, angle)
val q2 = RotationAxis.POSITIVE_Y.rotationDegrees(/*180 - */cameraYaw)
val q2 = RotationAxis.POSITIVE_Y.rotationDegrees(-cameraYaw)
q2.hamiltonProduct(RotationAxis.POSITIVE_Z.rotationDegrees(i))
return q2
}
@@ -146,13 +152,15 @@ class LookAtXYZ : ParticleCameraMode {
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
viewDirection: Vec3d
): Quaternionf {
val i = if (angle == 0F) 0F else MathHelper.lerp(deltaTicks, prevAngle, angle)
val rotation = Quaternionf(0F, 0F, 0F, 1F)
val rotation = Quaternionf()
rotation.hamiltonProduct(RotationAxis.POSITIVE_Y.rotationDegrees(-cameraYaw))
rotation.hamiltonProduct(RotationAxis.POSITIVE_X.rotationDegrees(cameraPitch))
rotation.hamiltonProduct(RotationAxis.POSITIVE_Z.rotationDegrees(i))
@@ -174,14 +182,17 @@ class LookAtY : ParticleCameraMode {
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
viewDirection: Vec3d
): Quaternionf {
val rotation = Quaternionf(0F, 0F, 0F, 1F)
rotation.hamiltonProduct(RotationAxis.POSITIVE_Y.rotationDegrees(-cameraYaw))
return rotation
val i = if (angle == 0F) 0F else MathHelper.lerp(deltaTicks, prevAngle, angle)
val q2 = RotationAxis.POSITIVE_Y.rotationDegrees(-cameraYaw)
q2.hamiltonProduct(RotationAxis.POSITIVE_Z.rotationDegrees(i))
return q2
}
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
@@ -203,6 +214,8 @@ class DirectionZ : ParticleCameraMode {
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
@@ -236,6 +249,8 @@ class EmitterYZPlane : ParticleCameraMode {
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
@@ -274,6 +289,8 @@ class EmitterXZPlane : ParticleCameraMode {
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
@@ -311,6 +328,8 @@ class EmitterXYPlane : ParticleCameraMode {
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
@@ -347,6 +366,8 @@ class DirectionY : ParticleCameraMode {
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
@@ -380,6 +401,8 @@ class DirectionX : ParticleCameraMode {
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
@@ -398,6 +421,29 @@ class DirectionX : ParticleCameraMode {
override fun writeToBuffer(buffer: PacketByteBuf) {}
}
/**
* You can think of this camera mode as the one that does the following:
*
* - Uses the direction of motion as the particle X axis
* - Uses a vector parallel to the camera plane and perpendicular to the direction of motion as the particle Y axis.
*
* The second requirement is difficult to accomplish. The way it was eventually solved is by
* thinking of the plane generated by two specific vectors. One is the camera to the particle,
* the other is the camera to where the particle will be after it continues moving on its
* trajectory for some amount of time.
*
* That plane slices right through the camera, and so the normal vector of that plane is parallel
* lies on the camera plane (hard to explain that one). Since the plane includes the direction vector,
* the normal vector of that plane is perpendicular to the direction vector. Since the direction
* vector is being used for the X axis, and the normal vector is perpendicular, we can use that as
* the Y axis safely.
*
* The chicanery of this look direction is all simply to calculate the correct Y axis, use it,
* and then use the direction vector for the X axis.
*
* @author Hiroku
* @since June 29th, 2023
*/
class LookAtDirection : ParticleCameraMode {
override val type: ParticleCameraModeType = ParticleCameraModeType.LOOK_AT_DIRECTION
companion object {
@@ -408,21 +454,50 @@ class LookAtDirection : ParticleCameraMode {
}
}
// Reusable shit so fewer instantiations during rendering.
val viewDirectionF = Vector3f(0F, 0F, 0F)
val particlePositionF = Vector3f(0F, 0F, 0F)
val cameraPositionF = Vector3f(0F, 0F, 0F)
val axisAngle = AxisAngle4d()
override fun getRotation(
matrixWrapper: MatrixWrapper,
prevAngle: Float,
angle: Float,
deltaTicks: Float,
particlePosition: Vec3d,
cameraPosition: Vec3d,
cameraAngle: Quaternionf,
cameraYaw: Float,
cameraPitch: Float,
viewDirection: Vec3d
): Quaternionf {
val i = if (angle == 0F) 0F else MathHelper.lerp(deltaTicks, prevAngle, angle)
val rotation = Quaternionf(0F, 0F, 0F, 1F)
rotation.hamiltonProduct(RotationAxis.POSITIVE_Y.rotationDegrees((viewDirection.x * -cameraYaw).toFloat()))
rotation.hamiltonProduct(RotationAxis.POSITIVE_X.rotationDegrees((viewDirection.y * cameraPitch).toFloat()))
rotation.hamiltonProduct(RotationAxis.POSITIVE_Z.rotationDegrees((viewDirection.z * i).toFloat()))
viewDirectionF.set(viewDirection)
particlePositionF.set(particlePosition)
cameraPositionF.set(cameraPosition)
// Perform a rotation around the axis that should later become the particle Y axis
Quaternionf().rotateTo(
// Camera -> Particle
particlePositionF.sub(cameraPositionF, Vector3f()),
// Camera -> (Particle + Direction)
particlePositionF.add(viewDirectionF, Vector3f()).sub(cameraPositionF)
).get(axisAngle) // Extract the rotation into axis + angle, so we can pluck the axis out.
// Extract the axis of rotation, it is what we want the particle's local Y axis to be.
val correctY = Vector3f(axisAngle.x.toFloat(), axisAngle.y.toFloat(), axisAngle.z.toFloat())
// First make X look along the direction vector
val rotation = Quaternionf().rotateTo(Vector3f(1F, 0F, 0F), viewDirectionF)
// Now figure out what the local Y axis is
val currentY = Vector3f(0F, 1F, 0F).rotate(rotation)
// Move that local Y to the correct local Y
// Pre-multiply is because the previous transform won't affect the correct Y, but vice versa absolutely would; we don't want that.
rotation.premul(Quaternionf().rotateTo(currentY, correctY))
// Do the regular rotation around Z to spin the particle, same as all other modes.
val particleAngle = if (angle == 0.0f) 0F else MathHelper.lerp(deltaTicks, prevAngle, angle)
rotation.hamiltonProduct(RotationAxis.POSITIVE_Z.rotationDegrees(particleAngle))
return rotation
}
@@ -17,6 +17,7 @@ import com.cobblemon.mod.common.api.data.ArbitrarilyMappedSerializableCompanion
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.codec.EXPRESSION_CODEC
import com.cobblemon.mod.common.util.getString
import com.cobblemon.mod.common.util.resolve
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.resolveDouble
import com.mojang.serialization.Codec
@@ -55,7 +56,9 @@ class OnceEmitterLifetime(var activeTime: Expression = 1.0.asExpression()) : Par
override val type = ParticleEmitterLifetimeType.ONCE
override fun getAction(runtime: MoLangRuntime, started: Boolean, emitterAge: Double): ParticleEmitterAction {
return if (emitterAge > runtime.resolveDouble(activeTime)) {
val activeTime = runtime.resolve(activeTime)
runtime.environment.setSimpleVariable("emitter_lifetime", activeTime)
return if (emitterAge > activeTime.asDouble()) {
ParticleEmitterAction.STOP
} else {
ParticleEmitterAction.GO
@@ -127,11 +130,18 @@ class LoopingEmitterLifetime(var activeTime: Expression = 1.0.asExpression(), va
override val type = ParticleEmitterLifetimeType.LOOPING
override fun getAction(runtime: MoLangRuntime, started: Boolean, emitterAge: Double): ParticleEmitterAction {
val activeTime = runtime.resolveDouble(activeTime)
val activeTime = runtime.resolve(activeTime)
val activeTimeValue = activeTime.asDouble()
val sleepTime = runtime.resolveDouble(sleepTime)
val interval = activeTime + sleepTime
val interval = activeTimeValue + sleepTime
val displacement = emitterAge % interval
return if (displacement < activeTime) {
runtime.environment.setSimpleVariable("emitter_lifetime", activeTime)
if (emitterAge > activeTimeValue && sleepTime == 0.0) {
return ParticleEmitterAction.STOP
}
return if (displacement < activeTimeValue) {
ParticleEmitterAction.GO
} else {
ParticleEmitterAction.RESET
@@ -145,7 +155,6 @@ class LoopingEmitterLifetime(var activeTime: Expression = 1.0.asExpression(), va
}
override fun writeToBuffer(buffer: PacketByteBuf) {
val activeTimeString =
buffer.writeString(activeTime.getString())
buffer.writeString(sleepTime.getString())
}
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.api.snowstorm
import com.bedrockk.molang.Expression
import com.bedrockk.molang.MoLang
import com.bedrockk.molang.ast.NumberExpression
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.VariableStruct
@@ -17,9 +16,11 @@ import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.api.codec.CodecMapped
import com.cobblemon.mod.common.api.data.ArbitrarilyMappedSerializableCompanion
import com.cobblemon.mod.common.api.snowstorm.ParticleEmitterRate.Companion.OVERFLOW_VARIABLE
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.codec.EXPRESSION_CODEC
import com.cobblemon.mod.common.util.getString
import com.cobblemon.mod.common.util.resolveDouble
import com.cobblemon.mod.common.util.resolveInt
import com.mojang.serialization.Codec
import com.mojang.serialization.DynamicOps
import com.mojang.serialization.codecs.PrimitiveCodec
@@ -49,12 +50,12 @@ enum class ParticleEmitterRateType {
INSTANT
}
class InstantParticleEmitterRate(var amount: Int = 1) : ParticleEmitterRate {
class InstantParticleEmitterRate(var amount: Expression = "1".asExpression()) : ParticleEmitterRate {
companion object {
val CODEC: Codec<InstantParticleEmitterRate> = RecordCodecBuilder.create { instance ->
instance.group(
PrimitiveCodec.STRING.fieldOf("type").forGetter { it.type.name },
PrimitiveCodec.INT.fieldOf("amount").forGetter { it.amount }
EXPRESSION_CODEC.fieldOf("amount").forGetter { it.amount }
).apply(instance) { _, amount -> InstantParticleEmitterRate(amount) }
}
}
@@ -65,17 +66,17 @@ class InstantParticleEmitterRate(var amount: Int = 1) : ParticleEmitterRate {
if (started) {
return 0
} else {
return amount
return runtime.resolveInt(amount)
}
}
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
override fun readFromBuffer(buffer: PacketByteBuf) {
amount = buffer.readInt()
amount = buffer.readString().asExpression()
}
override fun writeToBuffer(buffer: PacketByteBuf) {
buffer.writeInt(amount)
buffer.writeString(amount.getString())
}
}
@@ -99,29 +100,38 @@ class SteadyParticleEmitterRate(
override val type = ParticleEmitterRateType.STEADY
override fun getEmitCount(runtime: MoLangRuntime, started: Boolean, currentlyActive: Int): Int {
// The emitting rates are all per second, but this runs every tick. Presents some difficulties.
val max = runtime.resolveDouble(maximum).toInt()
val variables = runtime.environment.structs["variable"] as VariableStruct
var currentOverflow = variables.map[OVERFLOW_VARIABLE]?.asDouble() ?: 0.0
/*
* The strategy is that per tick it might be calculated to be 1.2 particles. We can't spawn a fifth
* of a particle, so we consider the .2 to be overflow which will be added to the next total. If the
* next tick we end up with 1.9, the overflow from last time will bring it to 2.1, so 2 particles with
* 0.1 overflow for the next tick.
*/
val currentOverflow = variables.map[OVERFLOW_VARIABLE]?.asDouble() ?: 0.0
if (currentlyActive >= max) {
return 0
}
val perSecond = runtime.resolveDouble(rate)
val trySpawn = perSecond / 20.0 + currentOverflow
val intComponent = trySpawn.toInt()
val doubleComponent = trySpawn - intComponent
val intComponent = trySpawn.toInt() // round down
val doubleComponent = trySpawn - intComponent // decimal portion (the overflow)
currentOverflow = doubleComponent
variables.map[OVERFLOW_VARIABLE] = DoubleValue(currentOverflow)
variables.map[OVERFLOW_VARIABLE] = DoubleValue(doubleComponent)
return min(intComponent, max - currentlyActive)
}
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
override fun readFromBuffer(buffer: PacketByteBuf) {
rate = MoLang.createParser(buffer.readString()).parseExpression()
maximum = MoLang.createParser(buffer.readString()).parseExpression()
rate = buffer.readString().asExpression()
maximum = buffer.readString().asExpression()
}
override fun writeToBuffer(buffer: PacketByteBuf) {
@@ -145,7 +145,7 @@ class PointParticleEmitterShape(
override val type = ParticleEmitterShapeType.POINT
override fun getNewParticlePosition(runtime: MoLangRuntime, entity: Entity?) = runtime.resolveVec3d(offset)
override fun getCenter(runtime: MoLangRuntime, entity: Entity?): Vec3d {
return getNewParticlePosition(runtime, entity) // Questionable
return Vec3d.ZERO
}
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
@@ -0,0 +1,174 @@
/*
* 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.snowstorm
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.molang.MoLangFunctions.getQueryStruct
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.net.Decodable
import com.cobblemon.mod.common.api.net.Encodable
import com.cobblemon.mod.common.client.particle.BedrockParticleEffectRepository
import com.cobblemon.mod.common.client.particle.ParticleStorm
import com.cobblemon.mod.common.client.render.MatrixWrapper
import com.cobblemon.mod.common.client.render.SnowstormParticle
import com.cobblemon.mod.common.util.asExpressionLike
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.PrimitiveCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.network.PacketByteBuf
import net.minecraft.sound.SoundCategory
import net.minecraft.sound.SoundEvent
import net.minecraft.util.Identifier
import net.minecraft.util.math.Vec3d
/**
* An event that can be referenced from various particle event triggers. The events are not necessarily particles,
* but can be combinations of particles, sounds, and MoLang expressions.
*
* @author Hiroku
* @since March 2nd, 2024
*/
class ParticleEvent(
var particleEffect: EventParticleEffect? = null,
var soundEffect: EventSoundEffect? = null,
var expression: ExpressionLike? = null
): Encodable, Decodable {
companion object {
val CODEC: Codec<ParticleEvent> = RecordCodecBuilder.create { instance ->
instance.group(
EventParticleEffect.CODEC.optionalFieldOf("particle_effect", null).forGetter { it.particleEffect },
EventSoundEffect.CODEC.optionalFieldOf("sound_effect", null).forGetter { it.soundEffect },
PrimitiveCodec.STRING.optionalFieldOf("expression", null).forGetter { it.expression?.toString() }
).apply(instance) { particleEffect, soundEffect, expression ->
ParticleEvent(
particleEffect,
soundEffect,
expression?.asExpressionLike()
)
}
}
}
override fun encode(buffer: PacketByteBuf) {
buffer.writeNullable(particleEffect) { pb, effect ->
pb.writeIdentifier(effect.effect)
pb.writeEnumConstant(effect.type)
pb.writeNullable(effect.expression) { pb, expr -> pb.writeString(expr.toString()) }
}
buffer.writeNullable(soundEffect) { pb, effect -> pb.writeIdentifier(effect.sound) }
buffer.writeNullable(expression) { pb, expr -> pb.writeString(expr.toString()) }
}
override fun decode(buffer: PacketByteBuf) {
particleEffect = buffer.readNullable { pb -> EventParticleEffect(
pb.readIdentifier(),
pb.readEnumConstant(EventParticleEffect.EventParticleType::class.java),
pb.readNullable { pb.readString().asExpressionLike() }
) }
soundEffect = buffer.readNullable { pb -> EventSoundEffect(pb.readIdentifier()) }
expression = buffer.readNullable { pb -> pb.readString().asExpressionLike() }
}
fun run(storm: ParticleStorm, particle: SnowstormParticle?) {
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.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.PARTICLE -> { { Vec3d.ZERO } }
EventParticleEffect.EventParticleType.PARTICLE_WITH_VELOCITY -> (particle?.let { Vec3d(it.getVelocityX(), it.getVelocityY(), it.getVelocityZ()) } ?: Vec3d.ZERO).let { { it } }
}
val newStorm = ParticleStorm(
effect = bedrockParticleEffect,
matrixWrapper = rootMatrix,
world = storm.world,
sourceVelocity = sourceVelocity,
sourceAlive = storm.sourceAlive,
sourceVisible = storm.sourceVisible,
onDespawn = {},
runtime = MoLangRuntime().setup().also { it.environment.structs["query"] = storm.runtime.environment.getQueryStruct() },
entity = storm.entity
)
effect.expression?.resolve(newStorm.runtime)
newStorm.spawn()
}
soundEffect?.let { effect ->
val position = particle?.let { Vec3d(it.getX(), it.getY(), it.getZ()) } ?: Vec3d(storm.getX(), storm.getY(), storm.getZ())
val world = storm.world
val soundEvent = SoundEvent.of(effect.sound)
world.playSound(position.x, position.y, position.z, soundEvent, SoundCategory.NEUTRAL, 1F, 1F, true)
}
expression?.resolve(storm.runtime)
}
}
/**
* A particle component of a [ParticleEvent]. It contains the effect to play, the spawning type, and a pre-run
* expression to run in the new storm's runtime.
*
* @author Hiroku
* @since March 2nd, 2024
*/
class EventParticleEffect(
val effect: Identifier,
val type: EventParticleType,
val expression: ExpressionLike? = null
) {
companion object {
val CODEC = RecordCodecBuilder.create<EventParticleEffect> { instance ->
instance.group(
Identifier.CODEC.fieldOf("effect").forGetter { it.effect },
PrimitiveCodec.STRING.fieldOf("type").forGetter { it.type.name },
PrimitiveCodec.STRING.optionalFieldOf("expression", null).forGetter { it.expression?.toString() }
).apply(instance) { effect, type, expression ->
EventParticleEffect(
effect,
EventParticleType.valueOf(type),
expression?.asExpressionLike()
)
}
}
}
enum class EventParticleType {
EMITTER,
EMITTER_BOUND,
PARTICLE,
PARTICLE_WITH_VELOCITY
}
}
/**
* A simple sound effect component of a [ParticleEvent]. Plays a sound at the particle location, or if run from an
* emitter event, at the emitter's location.
*
* @author Hiroku
* @since March 2nd, 2024
*/
class EventSoundEffect(
val sound: Identifier,
) {
companion object {
val CODEC = RecordCodecBuilder.create<EventSoundEffect> { instance ->
instance.group(
Identifier.CODEC.fieldOf("sound").forGetter { it.sound }
).apply(instance, ::EventSoundEffect)
}
}
}
@@ -0,0 +1,118 @@
/*
* 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.snowstorm
import com.cobblemon.mod.common.api.net.Decodable
import com.cobblemon.mod.common.api.net.Encodable
import com.cobblemon.mod.common.client.particle.ParticleStorm
import com.cobblemon.mod.common.client.render.SnowstormParticle
import com.mojang.serialization.codecs.PrimitiveCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import com.mojang.serialization.codecs.UnboundedMapCodec
import net.minecraft.network.PacketByteBuf
/*
* The different references to events that can be triggered by an effect.
*/
/**
* It really is simple.
*
* @author Hiroku
* @since March 2nd, 2024
*/
class SimpleEventTrigger(var event: String): Encodable, Decodable {
companion object {
val CODEC = RecordCodecBuilder.create<SimpleEventTrigger> { instance ->
instance.group(
PrimitiveCodec.STRING.fieldOf("event").forGetter { it.event }
).apply(instance, ::SimpleEventTrigger)
}
}
override fun encode(buffer: PacketByteBuf) {
buffer.writeString(event)
}
override fun decode(buffer: PacketByteBuf) {
event = buffer.readString()
}
fun trigger(storm: ParticleStorm, particle: SnowstormParticle?) {
val event = storm.effect.events[event] ?: return
event.run(storm, particle)
}
}
/**
* An event trigger that outlines specific times at which point groups of effects will play. This can be used
* on the basis of time but is also used in the case of travel distance.
*
* @author Hiroku
* @since March 2nd, 2024
*/
class EventTriggerTimeline(var map: MutableMap<Double, MutableList<String>>): Encodable, Decodable {
companion object {
val CODEC = RecordCodecBuilder.create<EventTriggerTimeline> { instance ->
instance.group(
UnboundedMapCodec(PrimitiveCodec.DOUBLE, PrimitiveCodec.STRING.listOf()).fieldOf("map").forGetter { it.map }
).apply(instance, ::EventTriggerTimeline)
}
}
override fun encode(buffer: PacketByteBuf) {
buffer.writeMap(map, { pb, k -> pb.writeDouble(k) }, { pb, v -> pb.writeCollection(v) { _, s -> pb.writeString(s) } })
}
override fun decode(buffer: PacketByteBuf) {
map = buffer.readMap({ pb -> pb.readDouble() }, { pb -> pb.readList { pb.readString() } })
}
fun check(storm: ParticleStorm, particle: SnowstormParticle?, previousTime: Double, newTime: Double) {
val events = map.entries.filter { it.key in previousTime..newTime }.flatMap { it.value }
events.forEach { event ->
val event = storm.effect.events[event] ?: return
event.run(storm, particle)
}
}
}
/**
* An event trigger that takes the total distance travelled by the emitter and modulos it across [distance] to know
* if we need to play it again.
*
* @author Hiroku
* @since March 2nd, 2024
*/
class LoopingTravelDistanceEventTrigger(var distance: Double, var events: MutableList<String>): Encodable, Decodable {
companion object {
val CODEC = RecordCodecBuilder.create<LoopingTravelDistanceEventTrigger> { instance ->
instance.group(
PrimitiveCodec.DOUBLE.fieldOf("distance").forGetter { it.distance },
PrimitiveCodec.STRING.listOf().fieldOf("events").forGetter { it.events }
).apply(instance, ::LoopingTravelDistanceEventTrigger)
}
}
override fun encode(buffer: PacketByteBuf) {
buffer.writeDouble(distance)
buffer.writeCollection(events) { _, s -> buffer.writeString(s) }
}
override fun decode(buffer: PacketByteBuf) {
distance = buffer.readDouble()
events = buffer.readList { buffer.readString() }
}
fun check(storm: ParticleStorm, particle: SnowstormParticle?, previousDistance: Double, currentDistance: Double) {
if (previousDistance < distance && currentDistance >= distance) {
events.mapNotNull { storm.effect.events[it] }.forEach { it.run(storm, particle) }
}
}
}
@@ -11,5 +11,6 @@ package com.cobblemon.mod.common.api.snowstorm
enum class ParticleMaterial {
ALPHA,
OPAQUE,
BLEND
BLEND,
ADD
}
@@ -0,0 +1,103 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.snowstorm
import com.cobblemon.mod.common.client.render.shader.CobblemonShaders
import com.mojang.blaze3d.platform.GlStateManager
import com.mojang.blaze3d.systems.RenderSystem
import net.minecraft.client.particle.ParticleTextureSheet
import net.minecraft.client.render.*
import net.minecraft.client.texture.SpriteAtlasTexture
import net.minecraft.client.texture.TextureManager
object ParticleMaterials {
val ALPHA = object : ParticleTextureSheet {
override fun begin(builder: BufferBuilder, textureManager: TextureManager) {
RenderSystem.disableBlend()
RenderSystem.depthMask(true)
RenderSystem.setShader { CobblemonShaders.PARTICLE_CUTOUT }
RenderSystem.setShaderTexture(0, SpriteAtlasTexture.PARTICLE_ATLAS_TEXTURE)
builder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT)
}
override fun draw(tessellator: Tessellator) {
tessellator.draw()
}
override fun toString(): String {
return "ALPHA"
}
}
val ADD = object : ParticleTextureSheet {
override fun begin(builder: BufferBuilder, textureManager: TextureManager) {
RenderSystem.enableBlend()
RenderSystem.depthMask(true)
RenderSystem.setShader { CobblemonShaders.PARTICLE_BLEND }
RenderSystem.setShaderTexture(0, SpriteAtlasTexture.PARTICLE_ATLAS_TEXTURE)
RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA)
builder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT)
}
override fun draw(tessellator: Tessellator) {
tessellator.draw()
}
override fun toString(): String {
return "ADD"
}
}
val BLEND = object : ParticleTextureSheet {
override fun begin(builder: BufferBuilder, textureManager: TextureManager) {
RenderSystem.enableBlend()
RenderSystem.depthMask(true)
RenderSystem.setShader { CobblemonShaders.PARTICLE_BLEND }
RenderSystem.setShaderTexture(0, SpriteAtlasTexture.PARTICLE_ATLAS_TEXTURE)
RenderSystem.blendFunc(GlStateManager.SrcFactor.DST_COLOR, GlStateManager.DstFactor.ZERO)
builder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT)
}
override fun draw(tessellator: Tessellator) {
tessellator.draw()
}
override fun toString(): String {
return "BLEND"
}
}
val OPAQUE = object : ParticleTextureSheet {
override fun begin(builder: BufferBuilder, textureManager: TextureManager) {
RenderSystem.enableBlend()
RenderSystem.depthMask(true)
RenderSystem.setShader { CobblemonShaders.PARTICLE_BLEND }
RenderSystem.setShaderTexture(0, SpriteAtlasTexture.PARTICLE_ATLAS_TEXTURE)
RenderSystem.blendFunc(GlStateManager.SrcFactor.ONE, GlStateManager.DstFactor.ONE)
builder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT)
}
override fun draw(tessellator: Tessellator) {
tessellator.draw()
}
override fun toString(): String {
return "OPAQUE"
}
}
}
@@ -14,8 +14,10 @@ import com.bedrockk.molang.ast.NumberExpression
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.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.mojang.serialization.Codec
import com.mojang.serialization.DynamicOps
@@ -37,7 +39,7 @@ interface ParticleMotion : CodecMapped {
}
val type: ParticleMotionType
fun getInitialVelocity(runtime: MoLangRuntime, particlePos: Vec3d, emitterPos: Vec3d): Vec3d
fun getInitialVelocity(runtime: MoLangRuntime, storm: ParticleStorm, particlePos: Vec3d, emitterPos: Vec3d): Vec3d
fun getAcceleration(runtime: MoLangRuntime, velocity: Vec3d): Vec3d
}
@@ -73,8 +75,8 @@ class DynamicParticleMotion(
}
}
override fun getInitialVelocity(runtime: MoLangRuntime, particlePos: Vec3d, emitterPos: Vec3d): Vec3d {
return direction.getDirectionVector(runtime, emitterPos, particlePos).multiply(runtime.resolveDouble(speed))
override fun getInitialVelocity(runtime: MoLangRuntime, storm: ParticleStorm, particlePos: Vec3d, emitterPos: Vec3d): Vec3d {
return direction.getDirectionVector(runtime, storm, emitterPos, particlePos).normalize().multiply(runtime.resolveDouble(speed))
}
override fun getAcceleration(runtime: MoLangRuntime, velocity: Vec3d): Vec3d {
@@ -82,7 +84,7 @@ class DynamicParticleMotion(
runtime.resolveDouble(acceleration.first),
runtime.resolveDouble(acceleration.second),
runtime.resolveDouble(acceleration.third)
).subtract(velocity.multiply(runtime.resolveDouble(drag) / 20)/* Drag is measured in blocks per tick per tick, I know it sounds dumb. */)
).subtract(velocity.multiply(runtime.resolveDouble(drag)))
}
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
@@ -122,7 +124,7 @@ interface ParticleMotionDirection : CodecMapped {
}
}
val type: ParticleMotionDirectionType
fun getDirectionVector(runtime: MoLangRuntime, emitterPos: Vec3d, particlePos: Vec3d): Vec3d
fun getDirectionVector(runtime: MoLangRuntime, storm: ParticleStorm, emitterPos: Vec3d, particlePos: Vec3d): Vec3d
}
class InwardsMotionDirection : ParticleMotionDirection {
@@ -134,7 +136,13 @@ class InwardsMotionDirection : ParticleMotionDirection {
}
override val type = ParticleMotionDirectionType.INWARDS
override fun getDirectionVector(runtime: MoLangRuntime, emitterPos: Vec3d, particlePos: Vec3d) = emitterPos.subtract(particlePos).normalize()
override fun getDirectionVector(runtime: MoLangRuntime, storm: ParticleStorm, emitterPos: Vec3d, particlePos: Vec3d): Vec3d {
return if (particlePos == emitterPos) {
Vec3d(storm.world.random.nextDouble() - 0.5, storm.world.random.nextDouble() - 0.5, storm.world.random.nextDouble() - 0.5)
} else {
emitterPos.subtract(particlePos)
}.normalize()
}
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
override fun readFromBuffer(buffer: PacketByteBuf) {}
override fun writeToBuffer(buffer: PacketByteBuf) {}
@@ -149,8 +157,12 @@ class OutwardsMotionDirection : ParticleMotionDirection {
}
override val type = ParticleMotionDirectionType.OUTWARDS
override fun getDirectionVector(runtime: MoLangRuntime, emitterPos: Vec3d, particlePos: Vec3d): Vec3d {
return particlePos.subtract(emitterPos).normalize()
override fun getDirectionVector(runtime: MoLangRuntime, storm: ParticleStorm, emitterPos: Vec3d, particlePos: Vec3d): Vec3d {
return if (particlePos == emitterPos) {
Vec3d(storm.world.random.nextDouble() - 0.5, storm.world.random.nextDouble() - 0.5, storm.world.random.nextDouble() - 0.5)
} else {
particlePos.subtract(emitterPos)
}.normalize()
}
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
@@ -178,12 +190,13 @@ class CustomMotionDirection(
override val type = ParticleMotionDirectionType.CUSTOM
override fun getDirectionVector(runtime: MoLangRuntime, emitterPos: Vec3d, particlePos: Vec3d): Vec3d {
return Vec3d(
override fun getDirectionVector(runtime: MoLangRuntime, storm: ParticleStorm, emitterPos: Vec3d, particlePos: Vec3d): Vec3d {
val v = Vec3d(
runtime.resolveDouble(direction.first),
runtime.resolveDouble(direction.second),
runtime.resolveDouble(direction.third)
)
return storm.matrixWrapper.matrix.transformDirection(v)
}
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
@@ -220,7 +233,7 @@ class StaticParticleMotion : ParticleMotion {
@Transient
override val type = ParticleMotionType.STATIC
override fun getInitialVelocity(runtime: MoLangRuntime, particlePos: Vec3d, emitterPos: Vec3d) = Vec3d.ZERO
override fun getInitialVelocity(runtime: MoLangRuntime, storm: ParticleStorm, particlePos: Vec3d, emitterPos: Vec3d) = Vec3d.ZERO
override fun getAcceleration(runtime: MoLangRuntime, velocity: Vec3d) = Vec3d.ZERO
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
override fun readFromBuffer(buffer: PacketByteBuf) {}
@@ -65,7 +65,7 @@ class DynamicParticleRotation(
override val type = ParticleRotationType.DYNAMIC
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)
override fun getInitialAngularVelocity(runtime: MoLangRuntime) = runtime.resolveDouble(speed) / 20
override fun getAngularAcceleration(runtime: MoLangRuntime, angularVelocity: Double): Double {
val acceleration = runtime.resolveDouble(acceleration)
val nextVelocity = angularVelocity + acceleration
@@ -34,6 +34,9 @@ class ParticleSpace(
}
}
val isLocalSpace: Boolean
get() = localPosition || localRotation
fun readFromBuffer(buffer: PacketByteBuf) {
localPosition = buffer.readBoolean()
localRotation = buffer.readBoolean()
@@ -146,7 +146,7 @@ class AnimatedParticleUVMode(
} else {
val fps = runtime.resolveDouble(fps)
val effectiveFrame = ((age * fps) % maxFrame).toInt()
val frame = if (!loop && age * fps > maxFrame) {
val frame = if (!loop && age * fps >= maxFrame) {
maxFrame
} else {
effectiveFrame

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