Compare commits

..
Author SHA1 Message Date
Slippy 2895c0a2ef I hate the crumbling arch 2024-07-18 08:57:11 -05:00
Slippy acc87f9eae Solhenge, Lunahenge, and Stonjournerhenge structures completed. 2024-07-17 12:31:55 -05:00
Slippy 928dfcdadf i hate the crumbling arch 2024-06-01 08:47:58 -05:00
Slippy 21363405fc console log spam fix for real this time 2024-05-18 12:00:11 -05:00
Slippy 08c4f4a0ff added loot to the trapped chest in unstable caves so you can't tell which one is trapped if you're using lootr muwahahahaha 2024-05-16 01:57:41 -05:00
Slippy c4a1704a8b unstable cave loot table fixes 2024-05-15 20:35:24 -05:00
Slippy 837aa5acf5 missing loot table in deserted tower 2024-05-14 16:58:55 -05:00
Slippy 969d6ac7fc console spam fix 2024-05-12 09:23:39 -05:00
Slippy 46bb9e1aec console fix 2024-05-11 21:58:50 -05:00
Slippy 9792ff3392 console spam fix 2024-05-11 21:36:29 -05:00
Slippy e863c6d094 Deleted Duplicate Loot Table 2024-05-10 16:19:15 -05: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
Slippy e835b833b3 One more try 2024-04-26 16:48:04 -05:00
Slippy 3b653b745e suspicious mound shoved further into the ground 2024-04-22 17:20:46 -05: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
Slippy c07d7d304e It wasnt the last D: 2024-04-09 19:19:02 -05:00
Slippy 5f94999b4f Is this the last push? 2024-04-09 19:15:02 -05:00
Slippy 6515bfa108 Decaying Crypt no longer has a random floating granite block 2024-04-05 12:14:57 -05:00
Slippy c502fec709 more bug fixes and balancing 2024-04-01 02:48:33 -05: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
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
Slippy 703282eca1 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into 1.5-Structures 2024-03-30 19:39:12 -05: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
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
Slippy a9115bfb15 XL RCs are less common 2024-03-29 01:27:30 -05: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
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
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
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
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
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
Veraxiel 55dd486044 Updated Changelog. 2024-03-27 01:10:26 -04: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
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
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
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
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
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
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
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
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
Veraxiel 0415cf8a69 Added Carnivine spawn files. 2024-03-19 04:09:58 -04: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
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 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
dhi_holo aed2204483 Merge branch 'main' into amo/sendout-upgrade 2024-03-03 13:39:35 +10:00
Tyzillion 6e9bdb6019 Many hitboxes adjusted. Updated Squirtle and Wartortle animations. 2024-03-01 21:27:34 -05:00
Veraxiel 841a40c973 Added and updated spawns. 2024-03-01 01:42:54 -05: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
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
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
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 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
dhi_holo d6a412b91a tags
tags
2024-02-26 17:38:30 +10: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
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
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
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 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
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
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
Tyzillion 98106cad12 Implemented Darumaka line, and Petilil line with Hisuian counterparts. 2024-02-16 16:14:43 -05:00
Tyzillion 1560b142d2 Updated quirks for implemented Pokemon. 2024-02-13 08:22:50 -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
Tyzillion 9901d39f9b Implemented Hisuian Sneasel, Sneasler, and Tropius. 2024-02-09 14:46:18 -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
Tyzillion dec5151eb8 /gradlew updateLicenses go brrrrrrrrr. 2024-02-04 00:11:14 -05: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
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
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
Tyzillion 5c64bc94ff Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-01-30 13:32:04 -05: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 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
dhi_holo 3a448071d7 Merge branch 'main' into MoreHoldItems 2024-01-16 11:38:51 +10:00
Tyzillion 3c2cfa4ffc Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2024-01-10 18:46:04 -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
dhi_holo e8b50f8115 Merge branch 'main' into MoreHoldItems 2024-01-09 11:40:46 +10: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
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
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
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
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
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
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
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
3402 changed files with 193998 additions and 20168 deletions
-5
View File
@@ -35,10 +35,5 @@ common/src/main/resources/assets/cobblemon/showdown
/fabric/src/generated/resources/cobblemon-common.accesswidener
/.ignored/
# Logs
common/logs
fabric/logs
forge/logs
# MacOS
.DS_Store
+121 -3
View File
@@ -1,5 +1,6 @@
# Changelog
## [1.5.0](#1-5-0)
### 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.
@@ -18,6 +19,7 @@
- Added 6 Pokémon-themed Pottery Sherds, obtained from ruin structures.
- Added a Pokémon-themed armor trim, obtained from ruin structures.
- You can now find Nether Fire Stone Ore in, surprisingly, the Nether.
- You'll also find Terracotta Sun Stone Ore in Badlands biomes.
- Added effects for many Poké Balls when sending out Pokémon or capturing.
- Added a new send-out ball toss animation that showcases the ball used for the Pokémon.
- Added simple move animations for Pokémon in battle with a proof of concept for more complicated animations.
@@ -27,13 +29,119 @@
- Added the [Ability Capsule](https://bulbapedia.bulbagarden.net/wiki/Ability_Capsule) and [Patch](https://bulbapedia.bulbagarden.net/wiki/Ability_Patch), these have no acquisition method for now and only work as intended with the traditional ability format of 1 to 2 common abilities and 1 hidden ability.
- Added Gilded Chests, available in all Apricorn colors.
- Added Relic Coins, Relic Coin Pouches, and Relic Coin Sacks.
- Added Gimmighoul.
- Added various new tags for searchability and better compatibility.
- Added Type Gems. These items hold no functionality for now. Start collecting though...
- Added 6 custom Pottery Sherds, obtained from ruin structures.
- Added cries to Meowth, Alolan Meowth, Galaraian Meowth,
- Completed the advancement for placing a Tumblestone near Lava or Magma to make it grow.
- Added 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.
### Pokémon Added
#### Gen 2
- Sentret
- Furret
- Qwilfish
- Heracross
- Skarmory
- Ferroseed
- Ferrothorn
#### Gen 3
- Lileep
- Cradily
- Anorith
- Armaldo
- Tropius
- Roselia
#### Gen 4
- Shieldon
- Bastiodon
- Cranidos
- Rampardos
- Budew
- Roserade
#### 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
#### Gen 6
- Tyrunt
- Tyrantrum
- Amaura
- Aurorus
- Goomy
- Sliggoo
- Goodra
#### Gen 7
- Turtonator
- Fomantis
- Lurantis
- Salandit
- Salazzle
- Jangmo-o
- Hakamo-o
- Kommo-o
#### Gen 8
- Gossifleur
- Eldegoss
- Arctozolt
- Arctovish
- Dracozolt
- Dracovish
- Basculegion
- Hisuian Zorua
- Hisuian Zoroark
- Hisuian Voltorb
- Hisuian Electrode
- Hisuian Qwilfish
- Overqwil
- Hisuian Sneasel
- Sneasler
- Stonjourner
- Cufant
- Copperajah
- Dreepy
- Drakloak
- Dragapult
- Hisuian Sliggoo
- Hisuian Goodra
#### Gen 9
- Gimmighoul.
- Using Relic Coins, you can increase Gimmighoul's Coin Stash. Upon reaching 999, it can be evolved into Gholdengo.
- Additionally, if you give Gimmighoul a Netherite Scrap, you can increase its Netherite Stash. Who knows what might happen if it fills up?
- Completed the advancement for placing a Tumblestone near Lava or Magma to make it grow.
### Changes
- Pokémon now transition more smoothly between different poses.
- Updated models for Mimikyu, Alcremie, Squirtle, Wartortle, Blastoise, Omanyte, Omastar, Growlithe, Swinub, Piloswine, Basculine, Rowlet, Dartrix, Decidueye, Kabuto, Kabutops, Piplup, Prinplup, Elekid, Electabuzz, Cubone, Marowak, Paras, Drifloon, Drifblim, Venonat, Venomoth, Yanma, Yanmega, and Raboot.
- Updated animations for Diglett, Dugtrio, Dragonite, Omanyte, Omastar, Pinsir, Falinks, Lechonk, Litwick, Lampent, Chandelure, Carnivine, Galarian Meowth, Galarian Rapidash, Venonat, Venomoth, Phanphy, Donphan, Dratini, Dragonair, Happiny, Chansey, Blissey, Volbeat, Illumise, Numel, Drifloon, and Drifblim.
- 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.
@@ -44,8 +152,16 @@
- Apricorn Sprouts can now be planted directly on Apricorn leaves to create a new Apricorn of the same color.
- Added tooltips to interaction GUIs to make it clearer what they do.
- Poké Ball recipes now use tags for their center ingredient, rather than specificied Copper Ingot, Iron Ingot, Gold Ingot, and Diamond, allowing for further datapack customisation.
- Starter Toast now closes once corresponding button is pressed once.
- Moved some items in the vanilla Food & Drinks category.
- Stacked Cobblemon Potion Bases can now be quick moved into Brewing Stands.
- Changed Healer recipe to swap the Max Revive for a Revive.
- Upped the rate that Gastly drop Ghast Tears from 2.5% to 5%.
- Pokémon with a low Blaze Powder drop chance now drop it more frequently in the Nether.
- Reorganised a few advancements.
### Fixes
- Resized Snorlax.
- Re-added the recipe for the Iron Vitamin.
- Cleaned up empty evolutions declaration in species files (no, I'm not listing all 169 by name).
- Fixed Exeggcute not being able to evolve.
@@ -77,12 +193,13 @@
- Made PokemonProperties.parse more interoperable with Java.
- Added the ``HeldItemEvent``, this comes with 2 implementation ``HeldItemEvent.Pre`` and ``HeldItemEvent.Post``.
- API to support dynamic lighting in any mod that implements this feature has been added to all Species & Forms, see LightingData class for details.
- Added a Mixin for the BrewingStandScreenHandler to fix the incorrect handling of quickMove in Fabric.
- Corrections to the ability implementation have been made that make ``Ability.forced`` function as intended and never reroll an ability for a Pokémon, please check your implementations to ensure the corrected behavior is intended for your use case.
- ``Pokemon.ability`` no longer has a public setter, please migrate to using ``Pokemon#updateAbility``, this handles the ability coordinate storage for you when necessary.
- ``Ability.forced``, ``Ability.index`` and ``Ability.priority`` have all had their setters internalized, there is no longer any need to manually adjust these migrate to the method mentioned above to handle that process for you.
- ``AbilityChanger`` has been added to API alongside some implementations, this is subject to change as the ability capsule and patch currently only expect the traditional behaviour in the Pokémon games of 1 to 2 regular abilities and 1 hidden.
- ``Pokemon#rollAbility`` has been added, this rerolls a legal ability for the Pokémon.
- `docs/cobblemon-tags` tags and spawn-presets can now be auto-generated from the current tags in the cobblemon mod with the `generateSpawnPresetList.py` and `generateTagList.py` scripts.
- `public_spawns_to_json.py` script has been added to give the powerful spawn.json generator a simplistic UI.
### Datapack & Resourcepack Creators
- The maximum amount of fossils that can fit in the Fossil Analyzer can be adjusted in the config.
@@ -118,6 +235,7 @@
```
- 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)
+3
View File
@@ -15,4 +15,7 @@ dependencies {
implementation(libs.shadow)
implementation(libs.loom)
implementation(libs.architecturyPlugin)
implementation(libs.blossom)
implementation(libs.ideaExt)
}
@@ -1,3 +1,6 @@
import extensions.VersionType
import extensions.writeVersion
plugins {
java
`java-library`
@@ -31,7 +34,7 @@ publishing {
groupId = "com.cobblemon"
artifactId = project.findProperty("maven.artifactId")?.toString() ?: project.name
version = rootProject.version.toString()
version = project.writeVersion(VersionType.PUBLISHING)
}
}
}
@@ -0,0 +1,24 @@
package extensions
import org.gradle.api.Project
fun Project.version(): String {
return rootProject.property("mod_version").toString()
}
fun Project.isSnapshot(): Boolean {
return rootProject.property("snapshot") == "true"
}
fun Project.writeVersion(type: VersionType = VersionType.FULL): String {
val version = "${rootProject.property("mod_version")}+${rootProject.property("mc_version")}"
return when (type) {
VersionType.PUBLISHING -> if(this.isSnapshot()) "$version-SNAPSHOT" else version
VersionType.FULL -> if(this.isSnapshot()) rootProject.version.toString() else version
}
}
enum class VersionType {
PUBLISHING,
FULL
}
+1 -1
View File
@@ -9,5 +9,5 @@ version = "${project.property("mod_version")}+${project.property("mc_version")}"
val isSnapshot = project.property("snapshot")?.equals("true") ?: false
if (isSnapshot) {
version = "$version-${versioning.info.branch}-${versioning.info.build}-SNAPSHOT"
version = "$version-${versioning.info.branch}-${versioning.info.build}"
}
+42 -2
View File
@@ -1,3 +1,9 @@
import extensions.isSnapshot
import extensions.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 {
@@ -44,8 +54,7 @@ dependencies {
modCompileOnly(libs.mongoDriverCore)
modCompileOnly(libs.mongoDriverSync)
testRuntimeOnly(libs.junitEngine)
testImplementation(libs.junitApi)
testImplementation(libs.fabricJunit)
testImplementation(libs.junitParams)
testImplementation(libs.mockito)
testImplementation(libs.mockk)
@@ -59,3 +68,34 @@ 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) }
property("timestamp", OffsetDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss")) + " UTC")
}
}
}
}
-1
View File
@@ -1 +0,0 @@
[19:57:25] [Test worker/INFO]: Booting LaxPermissionValidator, permissions will be checked using Minecrafts permission level system, see https://minecraft.fandom.com/wiki/Permission_level
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.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.add("Timestamp", CobblemonBuildDetails.TIMESTAMP);
cobblemon.addStackTrace(builder);
builder.append("\n\n");
}
}
@@ -1,20 +0,0 @@
package com.cobblemon.mod.common.mixin.invoker;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockSetType;
import net.minecraft.block.PressurePlateBlock;
import net.minecraft.resource.featuretoggle.FeatureSet;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.screen.ScreenHandlerType.Factory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(ScreenHandlerType.class)
public interface ScreenHandlerTypeInvoker {
@Invoker("<init>")
static <T extends ScreenHandler> ScreenHandlerType<T> cobblemon$create(Factory<T> factory, FeatureSet requiredFeatures) {
throw new UnsupportedOperationException();
}
}
@@ -0,0 +1,18 @@
{{ 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") }}"
const val TIMESTAMP = "{{ timestamp }}"
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,10 +17,10 @@ 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.HELD_ITEM_UPDATED
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
@@ -35,7 +36,10 @@ import com.cobblemon.mod.common.api.pokemon.effect.ShoulderEffectRegistry
import com.cobblemon.mod.common.api.pokemon.experience.ExperienceCalculator
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.*
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
import com.cobblemon.mod.common.api.pokemon.stats.Generation8EvCalculator
@@ -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
@@ -83,7 +88,6 @@ import com.cobblemon.mod.common.config.starter.StarterConfig
import com.cobblemon.mod.common.data.CobblemonDataProvider
import com.cobblemon.mod.common.events.AdvancementHandler
import com.cobblemon.mod.common.events.ServerTickHandler
import com.cobblemon.mod.common.item.CobblemonItem
import com.cobblemon.mod.common.item.PokeBallItem
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
import com.cobblemon.mod.common.permission.LaxPermissionValidator
@@ -94,7 +98,6 @@ import com.cobblemon.mod.common.pokemon.aspects.SHINY_ASPECT
import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
import com.cobblemon.mod.common.pokemon.misc.GimmighoulStashHandler
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
@@ -116,31 +119,32 @@ 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
import net.minecraft.item.Items
import net.minecraft.item.NameTagItem
import net.minecraft.registry.RegistryKey
import net.minecraft.sound.SoundCategory
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 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"))
@@ -170,6 +174,14 @@ 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}")
this.LOGGER.info(" - Timestamp: ${CobblemonBuildDetails.TIMESTAMP}")
}
implementation.registerPermissionValidator()
implementation.registerSoundEvents()
implementation.registerBlocks()
@@ -244,6 +256,16 @@ object Cobblemon {
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)
}
@@ -45,8 +45,6 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
val SIGN: BlockEntityType<CobblemonSignBlockEntity> = this.create("sign", BlockEntityType.Builder.create(::CobblemonSignBlockEntity, CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN).build(null))
@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 TM_BLOCK: BlockEntityType<TMBlockEntity> = this.create("tm_block", BlockEntityType.Builder.create(::TMBlockEntity, CobblemonBlocks.TM_MACHINE).build(null))
@JvmField
val GILDED_CHEST: BlockEntityType<GildedChestBlockEntity> = this.create("chest", BlockEntityType.Builder.create(::GildedChestBlockEntity,
@@ -72,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")
@@ -158,7 +160,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
@JvmField
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", GrowableStoneBlock.STAGE_3, 7, 3, null)
@@ -385,17 +387,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
.luminance { if ((it.get(PCBlock.ON) as Boolean) && (it.get(PCBlock.PART) == PCBlock.PCPart.TOP)) 10 else 0 }
)
)
val TM_MACHINE = create(
"tm_machine",
TMBlock(
AbstractBlock.Settings.create()
.mapColor(MapColor.GREEN)
.sounds(BlockSoundGroup.METAL)
.pistonBehavior(PistonBehavior.BLOCK)
.nonOpaque()
.luminance { if (it.get(TMBlock.ON) as Boolean) 10 else 0 }
)
)
@JvmField
val DISPLAY_CASE = create(
@@ -410,19 +401,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
)
)
@JvmField
val MODIFICATION_STATION = create(
"modification_station",
ModStationBlock(
AbstractBlock.Settings.create()
.sounds(BlockSoundGroup.WOOD)
.nonOpaque()
.pistonBehavior(PistonBehavior.BLOCK)
.mapColor(MapColor.BROWN)
.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(CobblemonSounds.MINT_SOUNDS)))
@@ -450,73 +428,12 @@ 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
val POTTED_PEP_UP_FLOWER = this.create("potted_pep_up_flower", BlocksInvoker.createFlowerPotBlock(PEP_UP_FLOWER))
@JvmField
val NORMAL_TYPE_GEM_BLOCK = this.create("normal_type_gem_block", Block(AbstractBlock.Settings.copy(Blocks.AMETHYST_BLOCK)))
@JvmField
val NORMAL_TYPE_GEM = typeGem(
"normal_type_gem",
GrowableStoneBlock.STAGE_3,
7,
3,
null,
NORMAL_TYPE_GEM_BLOCK
)
@JvmField
val LARGE_BUDDING_NORMAL_TYPE_GEM = typeGem(
"large_budding_normal_type_gem",
GrowableStoneBlock.STAGE_2,
5,
3,
NORMAL_TYPE_GEM,
NORMAL_TYPE_GEM_BLOCK
)
@JvmField
val MEDIUM_BUDDING_NORMAL_TYPE_GEM = typeGem(
"medium_budding_normal_type_gem",
GrowableStoneBlock.STAGE_1,
4,
3,
LARGE_BUDDING_NORMAL_TYPE_GEM,
NORMAL_TYPE_GEM_BLOCK
)
@JvmField
val SMALL_BUDDING_NORMAL_TYPE_GEM = typeGem(
"small_budding_normal_type_gem",
GrowableStoneBlock.STAGE_0,
3,
4,
MEDIUM_BUDDING_NORMAL_TYPE_GEM,
NORMAL_TYPE_GEM_BLOCK
)
private fun typeGem(
name: String,
stage: Int,
height: Int,
xzOffset: Int,
nextStage: Block?,
baseBlock: Block
): TypeGemBlock {
return this.create(name, TypeGemBlock(
settings = AbstractBlock.Settings.create()
.pistonBehavior(PistonBehavior.DESTROY)
.nonOpaque()
.strength(1.5F)
.sounds(CobblemonSounds.TYPE_GEM_SOUNDS),
stage = stage,
height = height,
xzOffset = xzOffset,
nextStage = nextStage,
baseBlock = baseBlock
))
}
/**
* Returns a map of all the blocks that can be stripped with an axe in the format of input - output.
*
@@ -527,6 +444,8 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
APRICORN_LOG to STRIPPED_APRICORN_LOG
)
private fun apricornBlock(name: String, apricorn: Apricorn): ApricornBlock = this.create(name, ApricornBlock(AbstractBlock.Settings.create().mapColor(apricorn.mapColor()).ticksRandomly().strength(Blocks.OAK_LOG.hardness, Blocks.OAK_LOG.blastResistance).sounds(BlockSoundGroup.WOOD).nonOpaque(), apricorn))
private fun tumblestoneBlock(name: String, stage: Int, height: Int, xzOffset: Int, nextStage: Block?) : 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)
}
}
@@ -26,7 +26,6 @@ import net.minecraft.registry.tag.TagKey
import net.minecraft.resource.ResourceManager
import net.minecraft.resource.ResourceReloader
import net.minecraft.resource.ResourceType
import net.minecraft.screen.ScreenHandlerType
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.text.Text
@@ -159,8 +158,6 @@ interface CobblemonImplementation {
*/
fun registerResourceReloader(identifier: Identifier, reloader: ResourceReloader, type: ResourceType, dependencies: Collection<Identifier>)
fun registerScreenHandlerType(identifier: Identifier, screenHandlerType: ScreenHandlerType<*>)
/**
* TODO
*
@@ -30,6 +30,7 @@ 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
@@ -39,14 +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.SmithingTemplateItem
import net.minecraft.item.StewItem
import net.minecraft.item.*
import net.minecraft.registry.Registries
import net.minecraft.registry.Registry
import net.minecraft.registry.RegistryKey
@@ -258,13 +252,10 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val HEALING_MACHINE = blockItem("healing_machine", CobblemonBlocks.HEALING_MACHINE)
@JvmField
val PC = blockItem("pc", CobblemonBlocks.PC)
val TM_MACHINE = blockItem("tm_machine", CobblemonBlocks.TM_MACHINE)
@JvmField
val PASTURE = blockItem("pasture", CobblemonBlocks.PASTURE)
@JvmField
val DISPLAY_CASE = blockItem("display_case", CobblemonBlocks.DISPLAY_CASE)
@JvmField
val MOD_STATION = blockItem("modification_station", CobblemonBlocks.MODIFICATION_STATION)
// Evolution items
@JvmField val LINK_CABLE = create("link_cable", LinkCableItem())
@@ -292,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")
@@ -415,7 +408,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField
val CLEVER_FEATHER = create("clever_feather", FeatherItem(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 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
@@ -590,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)
@@ -641,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")
@@ -661,26 +668,64 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@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
val MUSCLE_BAND = heldItem("muscle_band")
@@ -691,14 +736,42 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@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
val SILVER_POWDER = heldItem("silver_powder")
@@ -707,10 +780,30 @@ 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
val MIRROR_HERB = compostableHeldItem("mirror_herb", null, 1F)
@@ -725,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
@@ -870,10 +947,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
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)
@JvmField
val TECHNICAL_MACHINE = this.create("technical_machine", TechnicalMachineItem(Item.Settings()))
@JvmField
val BLANK_TM = this.create("blank_tm", CobblemonItem(Item.Settings()))
// Type Gems
@JvmField
@@ -938,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)
@@ -43,8 +43,6 @@ 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.CraftBlankTMPacketHandler
import com.cobblemon.mod.common.client.net.gui.CraftTMPacketHandler
import com.cobblemon.mod.common.client.net.gui.InteractPokemonUIPacketHandler
import com.cobblemon.mod.common.client.net.gui.SummaryUIPacketHandler
import com.cobblemon.mod.common.client.net.pasture.ClosePastureHandler
@@ -133,8 +131,6 @@ import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferExpiredPacke
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferNotificationPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeUpdatedPacket
import com.cobblemon.mod.common.net.messages.client.ui.CraftBlankTMPacket
import com.cobblemon.mod.common.net.messages.client.ui.CraftTMPacket
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
import com.cobblemon.mod.common.net.messages.server.*
@@ -436,10 +432,6 @@ object CobblemonNetwork : NetworkManager {
this.createServerBound(PartyPokemonMoveSelectedPacket.ID, PartyPokemonMoveSelectedPacket::decode, PartyPokemonMoveSelectedHandler)
this.createServerBound(PartyMoveSelectCancelledPacket.ID, PartyMoveSelectCancelledPacket::decode, PartyMoveSelectCancelledHandler)
// TM Machine packets
this.createServerBound(CraftTMPacket.ID, CraftTMPacket::decode, CraftTMPacketHandler)
this.createServerBound(CraftBlankTMPacket.ID, CraftBlankTMPacket::decode, CraftBlankTMPacketHandler)
// Dialogue packets
this.createServerBound(EscapeDialoguePacket.ID, EscapeDialoguePacket::decode, EscapeDialogueHandler)
this.createServerBound(InputToDialoguePacket.ID, InputToDialoguePacket::decode, InputToDialogueHandler)
@@ -99,27 +99,27 @@ 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")
@@ -155,11 +155,21 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
@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
@@ -240,19 +250,6 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
TUMBLESTONE_HIT,
TUMBLESTONE_STEP
)
@JvmField
val TM_USE = this.create("tm.use")
@JvmField
val TMM_CRAFT = this.create("tmm.craft")
@JvmField
val TMM_CRAFT_BLANK = this.create("tmm.craft_blank")
@JvmField
val TMM_OFF = this.create("tmm.off")
@JvmField
val TMM_ON = this.create("tmm.on")
@JvmField
val TYPE_GEM_SOUNDS = TUMBLESTONE_BLOCK_SOUNDS
@JvmField
val BERRY_BUSH_SOUNDS = BlockSoundGroup(1f, 1f,
@@ -290,6 +287,15 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
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,
@@ -299,6 +305,15 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
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,
@@ -35,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)
}
@@ -52,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)
@@ -205,8 +205,8 @@ object PokeBalls : JsonDataRegistry<PokeBall> {
createDefault("ancient_wing_ball", throwPower = 2.5f, ancient = true)
createDefault("ancient_jet_ball", throwPower = 2.5f, ancient = true)
createDefault("ancient_origin_ball", GuaranteedModifier(), ancient = true)
// Luxury ball effect
CobblemonEvents.FRIENDSHIP_UPDATED.subscribe(priority = Priority.LOWEST) { event ->
// 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>()
@@ -20,6 +20,7 @@ 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
@@ -339,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 }
@@ -409,7 +410,7 @@ 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 }
@@ -476,11 +477,11 @@ 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())
}
fun createEntity(world: World): PokemonEntity {
@@ -8,7 +8,6 @@
package com.cobblemon.mod.common.api.pokemon.moves
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.data.ClientDataSynchronizer
import com.cobblemon.mod.common.api.moves.MoveTemplate
import com.cobblemon.mod.common.api.moves.Moves
@@ -94,20 +93,6 @@ open class Learnset : ClientDataSynchronizer<Learnset> {
.flatMap { it.value }
.toSet()
fun tmLearnableMoves(): MutableList<MoveTemplate> {
val moves = mutableListOf<MoveTemplate>()
moves.addAll(tmMoves)
moves.addAll(tutorMoves)
moves.addAll(eggMoves)
moves.addAll(getLevelUpMovesUpTo(Cobblemon.config.maxPokemonLevel))
moves.addAll(evolutionMoves)
moves.addAll(formChangeMoves)
return moves
}
// We only sync level up moves atm
override fun shouldSynchronize(other: Learnset) = other.levelUpMoves != this.levelUpMoves
@@ -12,6 +12,8 @@ import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawner
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawnerFactory
import com.cobblemon.mod.common.platform.events.PlatformEvents
import com.cobblemon.mod.common.util.server
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
import java.util.UUID
import net.minecraft.server.network.ServerPlayerEntity
@@ -34,7 +36,7 @@ object CobblemonWorldSpawnerManager : SpawnerManager() {
fun onPlayerLogin(player: ServerPlayerEntity) {
// Disables spawning
if (!Cobblemon.config.enableSpawning) {
if (!Cobblemon.config.enableSpawning || server()?.gameRules?.getBoolean(CobblemonGameRules.DO_POKEMON_SPAWNING) == false) {
return;
}
@@ -12,6 +12,8 @@ import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
import com.cobblemon.mod.common.api.spawning.spawner.Spawner
import com.cobblemon.mod.common.api.spawning.spawner.TickingSpawner
import com.cobblemon.mod.common.util.server
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules.DO_POKEMON_SPAWNING
/**
* A manager of various spawners. This is a class in which you should register
@@ -49,7 +51,7 @@ open class SpawnerManager {
open fun onServerTick() {
// Disables spawning
if (!Cobblemon.config.enableSpawning) {
if (!Cobblemon.config.enableSpawning || server()?.gameRules?.getBoolean(DO_POKEMON_SPAWNING) == false) {
return
}
influences.removeIf { it.isExpired() }
@@ -63,9 +63,6 @@ abstract class AreaSpawner(
override fun run(cause: SpawnCause): Pair<SpawningContext, SpawnDetail>? {
val area = getArea(cause)
if (area?.world?.gameRules?.getBoolean(DO_POKEMON_SPAWNING) == false) {
return null
}
val constrainedArea = if (area != null) constrainArea(area) else null
if (constrainedArea != null) {
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.api.storage.player
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.tms.TechnicalMachine
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.net.messages.client.starter.SetClientPlayerDataPacket
import java.util.UUID
@@ -24,7 +23,6 @@ data class PlayerData(
var starterSelected: Boolean,
var starterUUID: UUID?,
var keyItems: MutableSet<Identifier>,
var tmSet: MutableSet<Identifier>,
var battleTheme: Identifier?,
val extraData: MutableMap<String, PlayerDataExtension>,
) {
@@ -44,7 +42,6 @@ data class PlayerData(
starterUUID = null,
keyItems = mutableSetOf(),
battleTheme = CobblemonSounds.PVP_BATTLE.id,
tmSet = mutableSetOf(),
extraData = mutableMapOf()
)
}
@@ -10,8 +10,6 @@ package com.cobblemon.mod.common.api.storage.player.adapter
import com.cobblemon.mod.common.api.storage.player.PlayerData
import com.cobblemon.mod.common.api.storage.player.PlayerDataExtension
import com.cobblemon.mod.common.api.tms.ObtainMethod
import com.cobblemon.mod.common.util.adapters.CobblemonObtainMethodAdapter
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.fromJson
import com.google.gson.GsonBuilder
@@ -33,7 +31,6 @@ class JsonPlayerData: PlayerDataStoreAdapter {
.setPrettyPrinting()
.disableHtmlEscaping()
.registerTypeAdapter(PlayerDataExtension::class.java, PlayerDataExtensionAdapter)
.registerTypeAdapter(ObtainMethod::class.java, CobblemonObtainMethodAdapter)
.registerTypeAdapter(Identifier::class.java, IdentifierAdapter)
.create()
}
@@ -22,107 +22,15 @@ import net.minecraft.registry.tag.TagKey
object CobblemonBiomeTags {
@JvmField
val IS_DEEP_DARK = create("is_deep_dark")
val IS_AUTUMN = create("has_season/autumn")
@JvmField
val IS_ARID = create("is_arid")
val IS_SPRING = create("has_season/spring")
@JvmField
val IS_AUTUMN = create("is_autumn")
@JvmField
val IS_BADLANDS = create("is_badlands")
@JvmField
val IS_BAMBOO = create("is_bamboo")
@JvmField
val IS_CAVE = create("is_cave")
@JvmField
val IS_COAST = create("is_coast")
@JvmField
val IS_COLD = create("is_cold")
@JvmField
val IS_DEEP_OCEAN = create("is_deep_ocean")
@JvmField
val IS_DESERT = create("is_desert")
@JvmField
val IS_DRIPSTONE = create("is_dripstone")
@JvmField
val IS_FLORAL = create("is_floral")
@JvmField
val IS_FOREST = create("is_forest")
@JvmField
val IS_FREEZING = create("is_freezing")
@JvmField
val IS_FRESHWATER = create("is_freshwater")
@JvmField
val IS_COLD_OCEAN = create("is_cold_ocean")
@JvmField
val IS_FROZEN_OCEAN = create("is_frozen_ocean")
@JvmField
val IS_GLACIAL = create("is_glacial")
@JvmField
val IS_GRASSLAND = create("is_grassland")
@JvmField
val IS_HIGHLANDS = create("is_highlands")
@JvmField
val IS_HILLS = create("is_hills")
@JvmField
val IS_ISLAND = create("is_island")
@JvmField
val IS_JUNGLE = create("is_jungle")
@JvmField
val IS_LUKEWARM_OCEAN = create("is_lukewarm_ocean")
@JvmField
val IS_LUSH = create("is_lush")
@JvmField
val IS_MAGICAL = create("is_magical")
@JvmField
val IS_MOUNTAIN = create("is_mountain")
@JvmField
val IS_MUSHROOM = create("is_mushroom")
@JvmField
val IS_OVERWORLD = create("is_overworld")
@JvmField
val IS_PEAK = create("is_peak")
@JvmField
val IS_PLAINS = create("is_plains")
@JvmField
val IS_PLATEAU = create("is_plateau")
@JvmField
val IS_WARM_OCEAN = create("is_warm_ocean")
@JvmField
val IS_RIVER = create("is_river")
@JvmField
val IS_SANDY = create("is_sandy")
@JvmField
val IS_SAVANNA = create("is_savanna")
@JvmField
val IS_SKY = create("is_sky")
@JvmField
val IS_SNOWY_FOREST = create("is_snowy_forest")
@JvmField
val IS_SPOOKY = create("is_spooky")
@JvmField
val IS_SPRING = create("is_spring")
@JvmField
val IS_SUMMER = create("is_summer")
@JvmField
val IS_SWAMP = create("is_swamp")
@JvmField
val IS_TAIGA = create("is_taiga")
val IS_SUMMER = create("has_season/summer")
@JvmField
val IS_TEMPERATE = create("is_temperate")
@JvmField
val IS_THERMAL = create("is_thermal")
@JvmField
val IS_TUNDRA = create("is_tundra")
@JvmField
val IS_VOID = create("is_void")
@JvmField
val IS_VOlCANIC = create("is_volcanic")
@JvmField
val IS_WINTER = create("is_winter")
@JvmField
val IS_SPARSE = create("is_sparse")
@JvmField
val IS_DENSE = create("is_dense")
val IS_WINTER = create("has_season/winter")
// Has Feature tags
@JvmField
@@ -180,16 +88,5 @@ object CobblemonBiomeTags {
@JvmField
val HAS_WATER_STONE_ORE_RARE = create("has_ore/ore_water_stone_rare")
// ToDo remove in 1.3
@Deprecated(message = "This tag no longer exists", level = DeprecationLevel.ERROR)
@JvmField
val IS_CRAG = create("is_crag")
@Deprecated(message = "This tag no longer exists", level = DeprecationLevel.ERROR)
@JvmField
val IS_ICY = create("is_icy")
@Deprecated(message = "This tag no longer exists", replaceWith = ReplaceWith("com.cobblemon.mod.common.api.tags.CobblemonBiomeTags.IS_CAVE"), level = DeprecationLevel.ERROR)
@JvmField
val IS_UNDERGROUND = create("is_underground")
private fun create(path: String) = TagKey.of(RegistryKeys.BIOME, cobblemonResource(path))
}
@@ -147,6 +147,9 @@ object CobblemonItemTags {
@JvmField
val ABILITY_CHANGERS = create("ability_changers")
@JvmField
val IS_FRIENDSHIP_BOOSTER = create("is_friendship_booster")
private fun create(path: String) = TagKey.of(RegistryKeys.ITEM, cobblemonResource(path))
}
@@ -1,26 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.tms
import net.minecraft.server.network.ServerPlayerEntity
interface ObtainMethod {
/**
* Whether to check this [ObtainMethod] once every second.
*/
val passive: Boolean
/**
* Checks if the [ObtainMethod] condition is true.
*
* @param player The player to use when checking.
* @return Whether the check succeeded.
*/
fun matches(player: ServerPlayerEntity): Boolean
}
@@ -1,23 +0,0 @@
package com.cobblemon.mod.common.api.tms
import com.google.gson.JsonDeserializer
import com.google.gson.JsonSerializer
import net.minecraft.util.Identifier
import kotlin.reflect.KClass
/**
* A type adapter for [ObtainMethod]s.
* For the default implementation see [CobblemonObtainMethodAdapter].
*
* @author Apion
* @since November 22nd, 2023
*/
interface ObtainMethodAdapter : JsonDeserializer<ObtainMethod>, JsonSerializer<ObtainMethod> {
/**
* Register a [ObtainMethod] to be used by this adapter.
*
* @param type The [KClass] of the [ObtainMethod].
* @param identifier The expected [Identifier] in the parsed JSON.
*/
fun register(type: KClass<out ObtainMethod>, identifier: Identifier)
}
@@ -1,119 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.tms
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.moves.Moves
import com.cobblemon.mod.common.api.types.ElementalType
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.tms.obtain.NoneObtainMethod
import com.cobblemon.mod.common.util.lang
import net.minecraft.item.Item
import net.minecraft.item.Items
import net.minecraft.registry.Registries
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.text.MutableText
import net.minecraft.text.Text
import net.minecraft.util.Identifier
class TechnicalMachine(
val moveName: String,
val recipe: TechnicalMachineRecipe?,
val obtainMethods: List<ObtainMethod> = emptyList(),
val type: String,
val primaryColor: Int?,
val secondaryColor: Int?
) {
companion object {
/**
* Filters all available [TechnicalMachines] based on three optional arguments
*
* @param search A [String] to check against move names
* @param type An [ElementalType] to check for
* @param pokemon A [Pokemon] to check the [Learnset] of
* @return A [MutableSet] of [TechnicalMachine] that passed the filter
* @author whatsy
*/
fun filterTms(search: String?, type: ElementalType?, pokemon: Pokemon?): MutableSet<TechnicalMachine> {
val tms = TechnicalMachines.tmMap.values.toMutableSet()
type?.let {
val iterator = tms.iterator()
while (iterator.hasNext()) {
val tm = iterator.next()
if (ElementalTypes.get(tm.type) != type) {
iterator.remove()
}
}
}
pokemon?.let {
val iterator = tms.iterator()
while (iterator.hasNext()) {
val tm = iterator.next()
val move = Moves.getByName(tm.moveName)
if (!pokemon.species.moves.tmLearnableMoves().contains(move)) {
iterator.remove()
}
}
}
search?.let {
val iterator = tms.iterator()
while (iterator.hasNext()) {
val tm = iterator.next()
if (!tm.translatedMoveName().toString().contains(search, true)) {
iterator.remove()
}
}
}
return tms
}
}
/**
* Gets the [Identifier] of this [TechnicalMachine]
*
* @return The [Identifier] of this [TechnicalMachine] (or null if not found)
* @author whatsy
*/
fun id(): Identifier? {
TechnicalMachines.tmMap.forEach {
if (TechnicalMachines.tmMap[it.key] == this) return it.key
}
return null
}
/**
* Unlocks this [TechnicalMachine] for the player.
*
* @param player The [ServerPlayerEntity] to give this [TechnicalMachine] to.
* @return Whether the player was successfully granted the [TechnicalMachine]
* @author whatsy
*/
fun unlock(player: ServerPlayerEntity): Boolean {
if (id() == null) return false
Cobblemon.playerData.get(player).tmSet.add(id()!!)
if (!obtainMethods.any { it is NoneObtainMethod }) player.sendMessage(lang("tms.unlock_tm", lang("move.$moveName")))
return true
}
/**
* Returns a [MutableText] of the translated move name of this [TechnicalMachine]
*
* @return This [TechnicalMachine]'s move name, translated
* @author whatsy
*/
fun translatedMoveName(): MutableText {
return lang("move." + this.moveName)
}
}
@@ -1,76 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.tms
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.item.CobblemonItem
import com.cobblemon.mod.common.item.TechnicalMachineItem
import com.cobblemon.mod.common.registry.ItemTagCondition
import com.cobblemon.mod.common.util.adapters.CobblemonObtainMethodAdapter
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import net.minecraft.item.ItemStack
import net.minecraft.registry.Registries
import net.minecraft.resource.ResourceType
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
object TechnicalMachines : JsonDataRegistry<TechnicalMachine> {
override val gson = GsonBuilder()
.registerTypeAdapter(Identifier::class.java, IdentifierAdapter)
.registerTypeAdapter(ObtainMethod::class.java, CobblemonObtainMethodAdapter)
.create()
override val typeToken = TypeToken.get(TechnicalMachine::class.java)
override val resourcePath = "tms"
override val id = cobblemonResource("technical_machines")
override val type = ResourceType.SERVER_DATA
override val observable = SimpleObservable<TechnicalMachines>()
val tmMap = mutableMapOf<Identifier, TechnicalMachine>()
val tagMap = mutableMapOf<ItemTagCondition, TechnicalMachine>()
val passiveTms = mutableMapOf<Identifier, TechnicalMachine>()
override fun reload(data: Map<Identifier, TechnicalMachine>) {
data.forEach {id, tm ->
tmMap[id] = tm
if (tm.obtainMethods.any { it.passive }) passiveTms.put(id, tm)
}
}
override fun sync(player: ServerPlayerEntity) { }
fun getTechnicalMachineFromStack(item: ItemStack?): TechnicalMachine? {
if (item == null) {
return null
}
return TechnicalMachineItem.getMoveNbt(item)
}
fun getStackFromTechnicalMachine(tm: TechnicalMachine): ItemStack {
val tmItem = CobblemonItems.TECHNICAL_MACHINE.defaultStack
return CobblemonItems.TECHNICAL_MACHINE.setNbt(tmItem,tm.id().toString())
}
fun isTechnicalMachine(item: ItemStack): Boolean {
return item.item is TechnicalMachineItem
}
fun checkPassives(player: ServerPlayerEntity) {
val playerTms = Cobblemon.playerData.get(player).tmSet
passiveTms.forEach { (id, tm) ->
if (tm.obtainMethods.all { it.matches(player) } && !playerTms.contains(id)) tm.unlock(player)
}
}
}
@@ -13,23 +13,17 @@ import net.minecraft.text.MutableText
import net.minecraft.util.Identifier
/**
* Class representing a type of Pokémon or Move
* Class representing a type of a Pokemon or Move
*
* @param name: The English name used to load / find it (spaces -> _)
* @param displayName: A Component used to display the name, normally a TranslatableText
* @param textureXMultiplier: The multiplier by which the TypeWidget shall move the display
* @param resourceLocation: The location of the resource used in the TypeWidget
* @param primaryColor: The primary color of this type used to color [TechnicalMachineItem].
* @param secondaryColor: The secondary color of this type used to color [TechnicalMachineItem]
* @param typeGem: The Type Gem item used to craft a [TechnicalMachineItem] of this type.
*/
class ElementalType(
val name: String,
val displayName: MutableText,
val hue: Int,
val textureXMultiplier: Int,
val resourceLocation: Identifier = Identifier(Cobblemon.MODID, "ui/types.png"),
val primaryColor: Int,
val secondaryColor: Int,
val typeGem: Identifier
val resourceLocation: Identifier = Identifier(Cobblemon.MODID, "ui/types.png")
)
@@ -8,7 +8,6 @@
package com.cobblemon.mod.common.api.types
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.text.MutableText
import net.minecraft.text.Text
@@ -23,180 +22,134 @@ object ElementalTypes {
name = "normal",
displayName = Text.translatable("cobblemon.type.normal"),
hue = 0xDDDDCF,
textureXMultiplier = 0,
primaryColor = 0xCCCCC1,
secondaryColor = 0xF9FFFC
textureXMultiplier = 0
)
val FIRE = register(
name = "fire",
displayName = Text.translatable("cobblemon.type.fire"),
hue = 0xE55C32,
textureXMultiplier = 1,
primaryColor = 0xFF8766,
secondaryColor = 0xFFD9A5
textureXMultiplier = 1
)
val WATER = register(
name = "water",
displayName = Text.translatable("cobblemon.type.water"),
hue = 0x4A9BE8,
textureXMultiplier = 2,
primaryColor = 0x7F9DFF,
secondaryColor = 0xA5EEFF
textureXMultiplier = 2
)
val GRASS = register(
name = "grass",
displayName = Text.translatable("cobblemon.type.grass"),
hue = 0x4DBC3C,
textureXMultiplier = 3,
primaryColor = 0x66CC99,
secondaryColor = 0xD6FFA5
textureXMultiplier = 3
)
val ELECTRIC = register(
name = "electric",
displayName = Text.translatable("cobblemon.type.electric"),
hue = 0xEFD128,
textureXMultiplier = 4,
primaryColor = 0xFFCF3F,
secondaryColor = 0xFFFFBF
textureXMultiplier = 4
)
val ICE = register(
name = "ice",
displayName = Text.translatable("cobblemon.type.ice"),
hue = 0x6BC3EF,
textureXMultiplier = 5,
primaryColor = 0x8CC7FF,
secondaryColor = 0xD6FFFF
textureXMultiplier = 5
)
val FIGHTING = register(
name = "fighting",
displayName = Text.translatable("cobblemon.type.fighting"),
hue = 0xC44C5C,
textureXMultiplier = 6,
primaryColor = 0xCC6673,
secondaryColor = 0xFFADA5
textureXMultiplier = 6
)
val POISON = register(
name = "poison",
displayName = Text.translatable("cobblemon.type.poison"),
hue = 0xA24BD8,
textureXMultiplier = 7,
primaryColor = 0x8D66CC,
secondaryColor = 0xEDA5FF
textureXMultiplier = 7
)
val GROUND = register(
name = "ground",
displayName = Text.translatable("cobblemon.type.ground"),
hue = 0xD89950,
textureXMultiplier = 8,
primaryColor = 0xE5A27E,
secondaryColor = 0xFFE1A5
textureXMultiplier = 8
)
val FLYING = register(
name = "flying",
displayName = Text.translatable("cobblemon.type.flying"),
hue = 0xBCC1FF,
textureXMultiplier = 9,
primaryColor = 0x8CB6FF,
secondaryColor = 0xE8DDFF
textureXMultiplier = 9
)
val PSYCHIC = register(
name = "psychic",
displayName = Text.translatable("cobblemon.type.psychic"),
hue = 0xD86AD6,
textureXMultiplier = 10,
primaryColor = 0xE48CFF,
secondaryColor = 0xFFCCF6
textureXMultiplier = 10
)
val BUG = register(
name = "bug",
displayName = Text.translatable("cobblemon.type.bug"),
hue = 0xA2C831,
textureXMultiplier = 11,
primaryColor = 0xAFCC66,
secondaryColor = 0xF6FFBF
textureXMultiplier = 11
)
val ROCK = register(
name = "rock",
displayName = Text.translatable("cobblemon.type.rock"),
hue = 0xAA9666,
textureXMultiplier = 12,
primaryColor = 0x997F4C,
secondaryColor = 0xDBC6A4
textureXMultiplier = 12
)
val GHOST = register(
name = "ghost",
displayName = Text.translatable("cobblemon.type.ghost"),
hue = 0x9572E5,
textureXMultiplier = 13,
primaryColor = 0x8E8CFF,
secondaryColor = 0xE8A5FF
textureXMultiplier = 13
)
val DRAGON = register(
name = "dragon",
displayName = Text.translatable("cobblemon.type.dragon"),
hue = 0x535DE8,
textureXMultiplier = 14,
primaryColor = 0xBA8CFF,
secondaryColor = 0xA5E5FF
textureXMultiplier = 14
)
val DARK = register(
name = "dark",
displayName = Text.translatable("cobblemon.type.dark"),
hue = 0x5C6CB2,
textureXMultiplier = 15,
primaryColor = 0x5966B2,
secondaryColor = 0xA5B1FF
textureXMultiplier = 15
)
val STEEL = register(
name = "steel",
displayName = Text.translatable("cobblemon.type.steel"),
hue = 0xC3CCE0,
textureXMultiplier = 16,
primaryColor = 0x858EB2,
secondaryColor = 0xF4FFFD
textureXMultiplier = 16
)
val FAIRY = register(
name = "fairy",
displayName = Text.translatable("cobblemon.type.fairy"),
hue = 0xEA727E,
textureXMultiplier = 17,
primaryColor = 0xFF8CB6,
secondaryColor = 0xFFD0CC
textureXMultiplier = 17
)
fun register(
name: String,
displayName: MutableText,
hue: Int,
textureXMultiplier: Int,
primaryColor: Int,
secondaryColor: Int
): ElementalType {
fun register(name: String, displayName: MutableText, hue: Int, textureXMultiplier: Int): ElementalType {
return ElementalType(
name = name,
displayName = displayName,
hue = hue,
textureXMultiplier = textureXMultiplier,
primaryColor = primaryColor,
secondaryColor = secondaryColor,
typeGem = cobblemonResource("${name}_gem")
textureXMultiplier = textureXMultiplier
).also {
allTypes.add(it)
}
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.types.tera
import com.cobblemon.mod.common.api.data.ShowdownIdentifiable
import net.minecraft.text.Text
import net.minecraft.util.Identifier
/**
* The representation of the Pokémons Tera type.
*
* @see [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Terastal_phenomenon)
*
*/
interface TeraType : ShowdownIdentifiable {
/**
* The [Identifier] associated to this type.
*/
val id: Identifier
/**
* If this tera type can be selected naturally.
*/
val legalAsStatic: Boolean
/**
* The display name of this type.
*/
val displayName: Text
}
@@ -0,0 +1,128 @@
/*
* 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.types.tera
import com.cobblemon.mod.common.api.types.ElementalType
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.api.types.tera.elemental.ElementalTypeTeraType
import com.cobblemon.mod.common.api.types.tera.gimmick.StellarTeraType
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.util.Identifier
/**
* The registry of all [TeraType]s.
*/
@Suppress("unused")
object TeraTypes {
private val types = hashMapOf<Identifier, TeraType>()
@JvmStatic
val NORMAL = this.create(cobblemonResource("normal"), ElementalTypeTeraType(ElementalTypes.NORMAL))
@JvmStatic
val FIRE = this.create(cobblemonResource("fire"), ElementalTypeTeraType(ElementalTypes.FIRE))
@JvmStatic
val WATER = this.create(cobblemonResource("water"), ElementalTypeTeraType(ElementalTypes.WATER))
@JvmStatic
val GRASS = this.create(cobblemonResource("grass"), ElementalTypeTeraType(ElementalTypes.GRASS))
@JvmStatic
val ELECTRIC = this.create(cobblemonResource("electric"), ElementalTypeTeraType(ElementalTypes.ELECTRIC))
@JvmStatic
val ICE = this.create(cobblemonResource("ice"), ElementalTypeTeraType(ElementalTypes.ICE))
@JvmStatic
val FIGHTING = this.create(cobblemonResource("fighting"), ElementalTypeTeraType(ElementalTypes.FIGHTING))
@JvmStatic
val POISON = this.create(cobblemonResource("poison"), ElementalTypeTeraType(ElementalTypes.POISON))
@JvmStatic
val GROUND = this.create(cobblemonResource("ground"), ElementalTypeTeraType(ElementalTypes.GROUND))
@JvmStatic
val FLYING = this.create(cobblemonResource("flying"), ElementalTypeTeraType(ElementalTypes.FLYING))
@JvmStatic
val PSYCHIC = this.create(cobblemonResource("psychic"), ElementalTypeTeraType(ElementalTypes.PSYCHIC))
@JvmStatic
val BUG = this.create(cobblemonResource("bug"), ElementalTypeTeraType(ElementalTypes.BUG))
@JvmStatic
val ROCK = this.create(cobblemonResource("rock"), ElementalTypeTeraType(ElementalTypes.ROCK))
@JvmStatic
val GHOST = this.create(cobblemonResource("ghost"), ElementalTypeTeraType(ElementalTypes.GHOST))
@JvmStatic
val DRAGON = this.create(cobblemonResource("dragon"), ElementalTypeTeraType(ElementalTypes.DRAGON))
@JvmStatic
val DARK = this.create(cobblemonResource("dark"), ElementalTypeTeraType(ElementalTypes.DARK))
@JvmStatic
val STEEL = this.create(cobblemonResource("steel"), ElementalTypeTeraType(ElementalTypes.STEEL))
@JvmStatic
val FAIRY = this.create(cobblemonResource("fairy"), ElementalTypeTeraType(ElementalTypes.FAIRY))
@JvmStatic
val STELLAR = this.create(StellarTeraType.ID, StellarTeraType())
/**
* Pick a random [TeraType].
*
* @param legalOnly If [TeraType.legalAsStatic] should be respected.
* @return The selected [TeraType].
*/
@JvmStatic
fun random(legalOnly: Boolean): TeraType {
val possible = this.types.values
if (legalOnly) {
return possible.filter(TeraType::legalAsStatic).random()
}
return possible.random()
}
/**
* Gets a [TeraType] by its [id].
*
* @param id The [Identifier] expected to match against a [TeraType.id].
* @return The found [TeraType] or null.
*/
@JvmStatic
fun get(id: Identifier): TeraType? = this.types[id]
/**
* Gets a [TeraType] by its [id].
*
* @param id The string representation of a [Identifier] if no namespace is present assumes Cobblemon' instead of Minecraft'.
* @return The found [TeraType] or null.
*/
@JvmStatic
fun get(id: String): TeraType? = this.get(cobblemonResource(id))
/**
* Gets the corresponding tera type for a [ElementalType].
*
* @param type The [ElementalType] being checked.
* @return The associated [TeraType].
*/
@JvmStatic
fun forElementalType(type: ElementalType): TeraType = this.get(cobblemonResource(type.name))!! // it's safe to do
private fun create(id: Identifier, type: TeraType): TeraType {
this.types[id] = type
return type
}
}
@@ -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.types.tera.elemental
import com.cobblemon.mod.common.api.types.ElementalType
import com.cobblemon.mod.common.api.types.tera.TeraType
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.text.Text
import net.minecraft.util.Identifier
class ElementalTypeTeraType(val type: ElementalType) : TeraType {
override val legalAsStatic: Boolean = true
override val id: Identifier = cobblemonResource(this.type.name)
override val displayName: Text = this.type.displayName
override fun showdownId(): String = this.type.name
}
@@ -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.types.tera.gimmick
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.types.tera.TeraType
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.text.Text
import net.minecraft.util.Identifier
class StellarTeraType : TeraType {
override val id: Identifier = ID
override val legalAsStatic: Boolean = false
override val displayName: Text = LANG
override fun showdownId(): String = ID.path
companion object {
val ID = cobblemonResource("stellar")
private val LANG = Text.translatable("${Cobblemon.MODID}.terra_type.stellar")
}
}
@@ -22,7 +22,6 @@ import com.cobblemon.mod.common.net.messages.client.battle.BattleChallengeExpire
import com.cobblemon.mod.common.util.getPlayer
import com.google.gson.GsonBuilder
import java.time.Instant
import java.util.Optional
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
import net.minecraft.server.network.ServerPlayerEntity
@@ -139,7 +138,7 @@ object BattleRegistry {
// 0 - 9, empty == 10
packedTeamBuilder.append("${if (pk.dmaxLevel < 10) pk.dmaxLevel else ""},")
// Teratype
packedTeamBuilder.append("${pokemon.effectedPokemon.teraType.name},")
packedTeamBuilder.append("${pokemon.effectedPokemon.teraType.showdownId()},")
team.add(packedTeamBuilder.toString())
}
@@ -1,128 +0,0 @@
package com.cobblemon.mod.common.block
import net.minecraft.block.AbstractBlock.Settings
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.Blocks
import net.minecraft.block.HorizontalFacingBlock
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.ai.pathing.NavigationType
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.fluid.Fluids
import net.minecraft.item.ItemPlacementContext
import net.minecraft.item.ItemStack
import net.minecraft.screen.NamedScreenHandlerFactory
import net.minecraft.state.StateManager
import net.minecraft.state.property.EnumProperty
import net.minecraft.util.*
import net.minecraft.util.hit.BlockHitResult
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.world.BlockView
import net.minecraft.world.World
import net.minecraft.world.WorldAccess
import net.minecraft.world.WorldView
class ModStationBlock(settings: Settings) : Block(settings) {
companion object {
val PART = EnumProperty.of("part", ModStationPart::class.java)
}
enum class ModStationPart(private val label: String) : StringIdentifiable {
TOP("top"),
BOTTOM("bottom");
override fun asString() = label
}
init {
defaultState = this.stateManager.defaultState.with(
HorizontalFacingBlock.FACING, Direction.SOUTH
).with(PART, ModStationPart.BOTTOM)
}
override fun onPlaced(
world: World,
pos: BlockPos,
state: BlockState,
placer: LivingEntity?,
itemStack: ItemStack
) {
world.setBlockState(pos.up(), state
.with(PART, ModStationPart.TOP)
)
world.updateNeighbors(pos, Blocks.AIR)
state.updateNeighbors(world, pos, 3)
}
override fun getPlacementState(blockPlaceContext: ItemPlacementContext): BlockState? {
val abovePosition = blockPlaceContext.blockPos.up()
val world = blockPlaceContext.world
if (world.getBlockState(abovePosition).canReplace(blockPlaceContext) && !world.isOutOfHeightLimit(abovePosition)) {
return defaultState
.with(HorizontalFacingBlock.FACING, blockPlaceContext.horizontalPlayerFacing)
.with(PART, ModStationPart.BOTTOM)
}
return null
}
override fun canPlaceAt(state: BlockState, world: WorldView, pos: BlockPos): Boolean {
val blockPos = pos.down()
val blockState = world.getBlockState(blockPos)
return if (state.get(PART) == ModStationPart.BOTTOM) blockState.isSideSolidFullSquare(world, blockPos, Direction.UP) else blockState.isOf(this)
}
override fun canPathfindThrough(
state: BlockState?,
world: BlockView?,
pos: BlockPos?,
type: NavigationType?
) = false
override fun appendProperties(builder: StateManager.Builder<Block, BlockState>) {
builder.add(HorizontalFacingBlock.FACING)
builder.add(PART)
}
override fun rotate(blockState: BlockState, rotation: BlockRotation) = blockState.with(HorizontalFacingBlock.FACING, rotation.rotate(blockState.get(HorizontalFacingBlock.FACING)))
override fun mirror(blockState: BlockState, mirror: BlockMirror): BlockState {
return blockState.rotate(mirror.getRotation(blockState.get(HorizontalFacingBlock.FACING)))
}
override fun onStateReplaced(state: BlockState, world: World, pos: BlockPos?, newState: BlockState, moved: Boolean) {
if (!state.isOf(newState.block)) super.onStateReplaced(state, world, pos, newState, moved)
}
override fun getStateForNeighborUpdate(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: WorldAccess,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
val isStation = neighborState.isOf(this)
val part = state.get(PART)
if (!isStation && part == ModStationPart.TOP && neighborPos == pos.down()) {
return Blocks.AIR.defaultState
} else if (!isStation && part == ModStationPart.BOTTOM && neighborPos == pos.up()) {
return Blocks.AIR.defaultState
}
return state
}
override fun onUse(
state: BlockState,
world: World,
pos: BlockPos,
player: PlayerEntity,
hand: Hand,
hit: BlockHitResult
): ActionResult {
player.openHandledScreen(state.createScreenHandlerFactory(world, pos))
return ActionResult.CONSUME
}
}
@@ -62,8 +62,8 @@ class MonitorBlock(properties: Settings) : MultiblockBlock(properties) {
if(world == null || pos == null) {
return 0
}
val monitorEntity = world.getBlockEntity(pos) as MultiblockEntity
val multiBlockEntity = monitorEntity.multiblockStructure
val monitorEntity = world.getBlockEntity(pos) as? MultiblockEntity
val multiBlockEntity = monitorEntity?.multiblockStructure
if(multiBlockEntity != null) {
return multiBlockEntity.getComparatorOutput(state, world, pos)
}
@@ -149,8 +149,8 @@ class RestorationTankBlock(properties: Settings) : MultiblockBlock(properties),
if(world == null || pos == null) {
return 0
}
val tankEntity = world.getBlockEntity(pos) as MultiblockEntity
val multiBlockEntity = tankEntity.multiblockStructure
val tankEntity = world.getBlockEntity(pos) as? MultiblockEntity
val multiBlockEntity = tankEntity?.multiblockStructure
if(multiBlockEntity != null) {
return multiBlockEntity.getComparatorOutput(state, world, pos)
}
@@ -180,7 +180,7 @@ class RestorationTankBlock(properties: Settings) : MultiblockBlock(properties),
return
}
val tankEntity = world.getBlockEntity(pos) as? MultiblockEntity
tankEntity?.multiblockStructure!!.onTriggerEvent(state, world, pos, random)
tankEntity?.multiblockStructure?.onTriggerEvent(state, world, pos, random)
}
override fun getOutlineShape(
@@ -1,547 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.tms.TechnicalMachine
import com.cobblemon.mod.common.api.tms.TechnicalMachines
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.block.entity.TMBlockEntity
import com.cobblemon.mod.common.gui.TMMScreenHandler
import com.cobblemon.mod.common.util.playSoundServer
import com.cobblemon.mod.common.util.toVec3d
import net.minecraft.block.*
import net.minecraft.block.entity.BlockEntity
import net.minecraft.block.entity.BrewingStandBlockEntity
import net.minecraft.entity.ItemEntity
import net.minecraft.entity.ai.pathing.NavigationType
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.fluid.FluidState
import net.minecraft.fluid.Fluids
import net.minecraft.inventory.SidedInventory
import net.minecraft.item.ItemPlacementContext
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.registry.Registries
import net.minecraft.screen.NamedScreenHandlerFactory
import net.minecraft.screen.SimpleNamedScreenHandlerFactory
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.server.world.ServerWorld
import net.minecraft.sound.SoundCategory
import net.minecraft.stat.Stats
import net.minecraft.state.StateManager
import net.minecraft.state.property.BooleanProperty
import net.minecraft.state.property.Properties
import net.minecraft.text.Text
import net.minecraft.util.ActionResult
import net.minecraft.util.BlockMirror
import net.minecraft.util.BlockRotation
import net.minecraft.util.Hand
import net.minecraft.util.hit.BlockHitResult
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.util.shape.VoxelShape
import net.minecraft.util.shape.VoxelShapes
import net.minecraft.world.BlockView
import net.minecraft.world.World
import net.minecraft.world.WorldAccess
class TMBlock(properties: Settings): BlockWithEntity(properties), Waterloggable, InventoryProvider {
/*val FACING = Properties.FACING
val TRIGGERED = Properties.TRIGGERED
val WATERLOGGED = Properties.WATERLOGGED*/
//var filterTM: TechnicalMachine? = null
//var previousFilterTM: TechnicalMachine? = null
var loadedMaterials: MutableList<ItemStack> = mutableListOf()
//val inv = TMBlockInventory(this)
/*class TMBlockInventory(val tmBlock: TMBlock) : SidedInventory {
override fun clear() {
TODO("Not yet implemented")
}
override fun size(): Int {
TODO("Not yet implemented")
}
override fun isEmpty(): Boolean {
return false
}
override fun getStack(slot: Int): ItemStack {
return ItemStack.EMPTY
}
override fun removeStack(slot: Int, amount: Int): ItemStack {
return ItemStack.EMPTY
}
override fun removeStack(slot: Int): ItemStack {
TODO("Not yet implemented")
}
override fun setStack(slot: Int, stack: ItemStack?) {
TODO("Not yet implemented")
}
override fun markDirty() {
TODO("Not yet implemented")
}
override fun canPlayerUse(player: PlayerEntity?): Boolean {
return false
}
override fun getAvailableSlots(side: Direction?): IntArray {
return IntArray(1)
}
override fun canInsert(slot: Int, stack: ItemStack?, dir: Direction?): Boolean {
// todo only allow for hopper to insert materials if it has a filterTM in it
if (tmBlock.filterTM != null && stack != null) {
// if material is needed then load it
if (tmBlock.materialNeeded(tmBlock.filterTM!!, stack)) {
tmBlock.loadMaterial(stack)
return true
}
else
return false
}
return false
}
override fun canExtract(slot: Int, stack: ItemStack?, dir: Direction?): Boolean {
return false
}
}*/
companion object {
//val WATERLOGGED = BooleanProperty.of("waterlogged")
val ON = BooleanProperty.of("on")
val FACING = Properties.FACING
val TRIGGERED = Properties.TRIGGERED
val WATERLOGGED = Properties.WATERLOGGED
private var NORTH_OUTLINE = VoxelShapes.union(
VoxelShapes.cuboid(0.0, 0.0, 0.0, 1.0, 0.3125, 0.9375),
VoxelShapes.cuboid(0.0, 0.3125, 0.75, 1.0, 0.9375, 0.9375),
VoxelShapes.cuboid(0.0625, 0.3125, 0.0625, 0.9375, 0.875, 0.9375)
)
private var SOUTH_OUTLINE = VoxelShapes.union(
VoxelShapes.cuboid(0.0, 0.0, 0.0625, 1.0, 0.3125, 1.0),
VoxelShapes.cuboid(0.0, 0.3125, 0.0625, 1.0, 0.9375, 0.25),
VoxelShapes.cuboid(0.0625, 0.3125, 0.0625, 0.9375, 0.875, 0.9375)
)
private var WEST_OUTLINE = VoxelShapes.union(
VoxelShapes.cuboid(0.0, 0.0, 0.0, 0.9375, 0.3125, 1.0),
VoxelShapes.cuboid(0.75, 0.3125, 0.0, 0.9375, 0.9375, 1.0),
VoxelShapes.cuboid(0.0625, 0.3125, 0.0625, 0.9375, 0.875, 0.9375)
)
private var EAST_OUTLINE = VoxelShapes.union(
VoxelShapes.cuboid(0.0625, 0.0, 0.0, 1.0, 0.3125, 1.0),
VoxelShapes.cuboid(0.0625, 0.3125, 0.0, 0.25, 0.9375, 1.0),
VoxelShapes.cuboid(0.0625, 0.3125, 0.0625, 0.9375, 0.875, 0.9375)
)
}
init {
defaultState = this.stateManager.defaultState.with(FACING, Direction.NORTH)
.with(WATERLOGGED, false)
.with(ON, false)
.with(TRIGGERED, false)
}
override fun getPlacementState(blockPlaceContext: ItemPlacementContext): BlockState? {
return defaultState
.with(FACING, blockPlaceContext.horizontalPlayerFacing)
.with(WATERLOGGED, blockPlaceContext.world.getFluidState(blockPlaceContext.blockPos).fluid == Fluids.WATER)
.with(ON, false)
}
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
super.onBreak(world, pos, state, player)
// todo dump materials and filterTM on the ground
}
@Deprecated("Deprecated in Java")
override fun neighborUpdate(state: BlockState, world: World, pos: BlockPos, sourceBlock: Block?, sourcePos: BlockPos?, notify: Boolean) {
val bl = world.isReceivingRedstonePower(pos) || world.isReceivingRedstonePower(pos.up())
val bl2 = state.get(TRIGGERED)
if (bl && !bl2) {
world.scheduleBlockTick(pos, this, 4)
world.setBlockState(pos, state.with(TRIGGERED, true) as BlockState, NO_REDRAW)
} else if (!bl && bl2) {
world.setBlockState(pos, state.with(TRIGGERED, false) as BlockState, NO_REDRAW)
}
}
@Deprecated("Deprecated in Java")
override fun scheduledTick(state: BlockState?, world: ServerWorld?, pos: BlockPos?, random: net.minecraft.util.math.random.Random?) {
val inventory = (world!!.getBlockEntity(pos) as TMBlockEntity).tmmInventory
val tmEntity = (world.getBlockEntity(pos) as TMBlockEntity)
if(world == null || pos == null) {
return
}
//val tankEntity = world.getBlockEntity(pos) as MultiblockEntity
if (tmEntity.blockState.get(ON)) {
//print("TMM is in use so scheduled Tick is disabled")
return
}
//this.onTriggerEvent(state, world, pos, random)
// todo if the output slot is empty then try to craft a TM to that slot
if (ItemStack.areItemsEqual(inventory.items!!.get(3), ItemStack.EMPTY)) {
if (state?.let { getInventory(it, world, pos) } != null) {
val itemStack: ItemStack
itemStack = if (inventory.filterTM != null)
inventory.filterTM!!.copy()
else
ItemStack(CobblemonItems.BLANK_TM, 1)
val tm = TechnicalMachines.getTechnicalMachineFromStack(itemStack)
// todo use isReadyToCraftTM to finalize the creation
if (((inventory.filterTM != null && tm != null) && isReadyToCraftTM(state, world, pos, tm)) || isReadyToCraftBlankTM(state, world, pos)) {
// create TM item to the output slot
inventory.items!!.set(3, itemStack)
tmEntity.markDirty()
// Play sound for TM creation
world.playSoundServer(tmEntity.blockPos.toVec3d(), CobblemonSounds.TMM_CRAFT, SoundCategory.BLOCKS)
}
}
}
// todo if there is an item in the output slot then spit it out
else {
if (state?.let { getInventory(it, world, pos) } != null) {
val itemStack = inventory.items!!.get(3)
// Get the direction the block is facing
val facingDirection = state.get(Properties.FACING)?.opposite ?: return
// Calculate the center position of the block
val frontOffset = 0.5 // Half block offset to the front
val spawnX = pos.x + 0.5 + facingDirection.offsetX * frontOffset
val spawnY = pos.y + 0.3 + facingDirection.offsetY * frontOffset
val spawnZ = pos.z + 0.5 + facingDirection.offsetZ * frontOffset
// Create the ItemEntity at the center of the block
val itemEntity = ItemEntity(world, spawnX, spawnY, spawnZ, itemStack).copy()
// Create the ItemEntity
itemEntity.setVelocity(0.0, 0.0, 0.0)
// Add the ItemEntity to the world
world.spawnEntity(itemEntity)
//clear inventory of SidedInventory
inventory.items?.clear()
tmEntity.markDirty()
//getInventory(state, world, pos).clear()
}
}
/*if (state?.let { getInventory(it, world, pos) } != null) {
val itemStack: ItemStack
itemStack = if (inventory.filterTM != null)
inventory.filterTM!!
else
ItemStack(CobblemonItems.BLANK_TM, 1)
val tm = TechnicalMachines.getTechnicalMachineFromStack(itemStack)
// todo use isReadyToCraftTM to finalize the creation
if ((inventory.filterTM != null && isReadyToCraftTM(state, world, pos, tm!!)) || isReadyToCraftBlankTM(state, world, pos)) {
// Get the direction the block is facing
val facingDirection = state.get(Properties.FACING)?.opposite ?: return
// Calculate the center position of the block
val frontOffset = 0.5 // Half block offset to the front
val spawnX = pos.x + 0.5 + facingDirection.offsetX * frontOffset
val spawnY = pos.y + 0.3 + facingDirection.offsetY * frontOffset
val spawnZ = pos.z + 0.5 + facingDirection.offsetZ * frontOffset
// Create the ItemEntity at the center of the block
val itemEntity = ItemEntity(world, spawnX, spawnY, spawnZ, itemStack).copy()
// Create the ItemEntity
itemEntity.setVelocity(0.0, 0.0, 0.0)
// Add the ItemEntity to the world
world.spawnEntity(itemEntity)
//clear inventory of SidedInventory
inventory.items?.clear()
//getInventory(state, world, pos).clear()
}
}*/
}
/*val currentTm = filterTM ?: return sendPacketToServer(CraftBlankTMPacket(handler.input.getStack(2)))
sendPacketToServer(
CraftTMPacket(
currentTm,
handler.input.getStack(0),
handler.input.getStack(1),
handler.input.getStack(2)
)
)*/
@Deprecated("Deprecated in Java")
override fun canPathfindThrough(blockState: BlockState, blockGetter: BlockView, blockPos: BlockPos, pathComputationType: NavigationType) = false
@Deprecated("Deprecated in Java")
override fun hasComparatorOutput(state: BlockState?): Boolean {
return true
}
@Deprecated("Deprecated in Java")
override fun getComparatorOutput(state: BlockState, world: World?, pos: BlockPos?): Int {
if(world == null || pos == null) {
return 0
}
val tmBlockEntity = world.getBlockEntity(pos) as TMBlockEntity
val tm = TechnicalMachines.getTechnicalMachineFromStack(tmBlockEntity.tmmInventory.filterTM)
// if TMM has already crafted something and something is in the output slot do not send signal out
if (!ItemStack.areItemsEqual(tmBlockEntity.tmmInventory.items?.get(3), ItemStack.EMPTY))
return 0
// if the TMM is ready to craft send signal of 15 out
if ((tm != null && isReadyToCraftTM(state, world, pos, tm)) || isReadyToCraftBlankTM(state, world, pos))
return 15
/*if (tmBlockEntity.automationDelay > 0)
tmBlockEntity.automationDelay--
if ((tmBlockEntity.tmmInventory.filterTM != null && isReadyToCraftTM(state, world, pos, tmBlockEntity.tmmInventory.filterTM!!)) || isReadyToCraftBlankTM(state, world, pos)) {
if (tmBlockEntity.automationDelay == 0) {
tmBlockEntity.resetAutomationDelay()
return 15
}
else
return 0
}*/
return 0
}
override fun getInventory(
state: BlockState,
world: WorldAccess,
pos: BlockPos
): SidedInventory {
val tmBlockEntity = world.getBlockEntity(pos) as TMBlockEntity
return tmBlockEntity.tmmInventory
}
override fun appendProperties(builder: StateManager.Builder<Block, BlockState>) {
builder.add(FACING)
builder.add(WATERLOGGED)
builder.add(ON)
builder.add(TRIGGERED)
}
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity {
return TMBlockEntity(pos, state)
}
@Deprecated("Deprecated in Java")
override fun rotate(blockState: BlockState, rotation: BlockRotation) =
blockState.with(FACING, rotation.rotate(blockState.get(FACING)))
@Deprecated("Deprecated in Java")
override fun mirror(blockState: BlockState, mirror: BlockMirror): BlockState {
return blockState.rotate(mirror.getRotation(blockState.get(FACING)))
}
@Deprecated("Deprecated in Java")
override fun onStateReplaced(state: BlockState, world: World, pos: BlockPos?, newState: BlockState, moved: Boolean) {
if (!state.isOf(newState.block)) super.onStateReplaced(state, world, pos, newState, moved)
}
@Deprecated("Deprecated in Java")
override fun onUse(
blockState: BlockState,
world: World,
pos: BlockPos,
player: PlayerEntity,
interactionHand: Hand,
blockHitResult: BlockHitResult
): ActionResult {
// clear filter TM on client
if (world.isClient) {
val tmBlockEntity = world.getBlockEntity(pos)
val inventory = (tmBlockEntity as TMBlockEntity).tmmInventory
inventory.filterTM = null
return ActionResult.SUCCESS
}
val tmBlockEntity = world.getBlockEntity(pos)
if (tmBlockEntity is TMBlockEntity) {
// Set the block state to ON when the block is used
tmBlockEntity.stateManager.openContainer(player, world, pos, blockState)
player.openHandledScreen(tmBlockEntity as TMBlockEntity?)
}
val inventory = (tmBlockEntity as TMBlockEntity).tmmInventory // (world.getBlockEntity(pos) as TMBlockEntity).tmmInventory
// remove all machine from machine upon use
// inventory.items?.forEach {
// // Get the direction the block is facing
// val facingDirection = blockState.get(Properties.FACING).opposite
//
// // Calculate the center position of the block
// val frontOffset = 0.5 // Half block offset to the front
// val spawnX = pos.x + 0.5 + facingDirection.offsetX * frontOffset
// val spawnY = pos.y + 0.3 + facingDirection.offsetY * frontOffset
// val spawnZ = pos.z + 0.5 + facingDirection.offsetZ * frontOffset
//
// // Create the ItemEntity at the center of the block
// val itemEntity = ItemEntity(world, spawnX, spawnY, spawnZ, it)
//
// // Create the ItemEntity
// itemEntity.setVelocity(0.0, 0.0, 0.0)
//
// // Add the ItemEntity to the world
// world.spawnEntity(itemEntity)
// }
//
// inventory.items?.clear()
// spit out any disc filters
if (inventory.filterTM != null) {
// spit out the filter TM and set filterTM to null
val filterTMStack = inventory.filterTM!!
// Get the direction the block is facing
val facingDirection = blockState.get(Properties.FACING).opposite
// Calculate the center position of the block
val frontOffset = 0.5 // Half block offset to the front
val spawnX = pos.x + 0.5 + facingDirection.offsetX * frontOffset
val spawnY = pos.y + 0.3 + facingDirection.offsetY * frontOffset
val spawnZ = pos.z + 0.5 + facingDirection.offsetZ * frontOffset
// Create the ItemEntity at the center of the block
val itemEntity = ItemEntity(world, spawnX, spawnY, spawnZ, filterTMStack).copy()
// Create the ItemEntity
itemEntity.setVelocity(0.0, 0.0, 0.0)
// Add the ItemEntity to the world
world.spawnEntity(itemEntity)
inventory.filterTM = null
}
val blockEntity = world.getBlockEntity(pos)
if (blockEntity is TMBlockEntity) {
//player.openHandledScreen(blockEntity as TMBlockEntity?)
player.playSound(CobblemonSounds.TMM_ON, SoundCategory.BLOCKS, 1.0f, 1.0f)
// todo maybe uncomment this
//val serverPlayer = player as ServerPlayerEntity
//serverPlayer.openHandledScreen(blockState.createScreenHandlerFactory(world, pos))
}
return ActionResult.CONSUME
}
// override fun createScreenHandlerFactory(
// state: BlockState?,
// world: World?,
// pos: BlockPos?
// ): NamedScreenHandlerFactory {
// return SimpleNamedScreenHandlerFactory(::TMMScreenHandler, Text.of("TM Machine"))
// }
/*fun loadMaterial(itemStack: ItemStack) {
loadedMaterials.add(itemStack)
}*/
fun isReadyToCraftTM(state: BlockState?, world: WorldAccess, pos: BlockPos, tm: TechnicalMachine): Boolean {
val typeGem = Registries.ITEM.get(tm.let { ElementalTypes.get(it.type)?.typeGem }).defaultStack
val recipeItem = Registries.ITEM.get(tm.recipe?.item)
val inventory = state?.let { getInventory(it, world, pos) }
return (inventory!!.count(CobblemonItems.BLANK_TM) == 1
&& inventory.count(typeGem.item) == 1
&& ((inventory.count(recipeItem) == tm.recipe?.count) || (ItemStack.areItemsEqual(recipeItem.defaultStack, ItemStack.EMPTY))))
}
fun isReadyToCraftBlankTM(state: BlockState?, world: WorldAccess, pos: BlockPos): Boolean {
val inventory = state?.let { getInventory(it, world, pos) }
return (inventory!!.count(Items.AMETHYST_SHARD) == 1)
}
/*fun materialNeeded(tm: TechnicalMachine, itemStack: ItemStack): Boolean {
val typeGem = Registries.ITEM.get(ElementalTypes.get(tm.type)?.typeGem).defaultStack
val recipeItem = Registries.ITEM.get(tm.recipe?.item)
// if blank TM is needed still
if ((itemStack !in loadedMaterials && itemStack == CobblemonItems.BLANK_TM.defaultStack))
return true // load in blank TM
// if type gem is needed still
else if ((itemStack !in loadedMaterials && itemStack == typeGem))
return true // load in Type Gem
// if the itemStack is listed as needed in the recipe and the count is not currently met
else if (itemStack.item == recipeItem && loadedMaterials.count { it == itemStack } < tm.recipe?.count!!)
return true
else
return false
}*/
/*fun clearLoadedMaterials() {
loadedMaterials.clear()
}*/
@Deprecated("Deprecated in Java")
override fun getRenderType(blockState: BlockState): BlockRenderType {
return BlockRenderType.MODEL
}
override fun getFluidState(state: BlockState): FluidState? {
return if (state.get(WATERLOGGED)) {
Fluids.WATER.getStill(false)
} else super.getFluidState(state)
}
override fun getOutlineShape(
state: BlockState,
world: BlockView,
pos: BlockPos,
context: ShapeContext
): VoxelShape {
return when (state.get(FACING)) {
Direction.NORTH -> NORTH_OUTLINE
Direction.SOUTH -> SOUTH_OUTLINE
Direction.WEST -> WEST_OUTLINE
else -> EAST_OUTLINE
}
}
}
@@ -1,20 +0,0 @@
package com.cobblemon.mod.common.block
import net.minecraft.block.*
import net.minecraft.util.math.BlockPos
import net.minecraft.world.BlockView
class TypeGemBlock(
settings: Settings,
stage: Int,
height: Int,
xzOffset: Int,
nextStage: Block?,
val baseBlock: Block
) : GrowableStoneBlock(settings, stage, height, xzOffset, nextStage) {
override fun canGrow(pos: BlockPos, world: BlockView): Boolean {
val state = world.getBlockState(pos)
val dir = state.get(FACING).opposite
return (world.getBlockState(pos.offset(dir)).block == baseBlock)
}
}
@@ -23,13 +23,18 @@ import net.minecraft.block.BlockWithEntity
import net.minecraft.block.Blocks
import net.minecraft.block.HorizontalFacingBlock
import net.minecraft.block.ShapeContext
import net.minecraft.block.Waterloggable
import net.minecraft.entity.ai.pathing.NavigationType
import net.minecraft.entity.mob.PiglinBrain
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.fluid.FluidState
import net.minecraft.fluid.Fluids
import net.minecraft.item.ItemPlacementContext
import net.minecraft.screen.ScreenHandler
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.sound.SoundCategory
import net.minecraft.state.StateManager
import net.minecraft.state.property.BooleanProperty
import net.minecraft.state.property.Properties
import net.minecraft.text.MutableText
import net.minecraft.text.Text
@@ -46,17 +51,21 @@ import net.minecraft.util.shape.VoxelShape
import net.minecraft.util.shape.VoxelShapes
import net.minecraft.world.BlockView
import net.minecraft.world.World
import net.minecraft.world.WorldAccess
@Suppress("OVERRIDE_DEPRECATION")
class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWithEntity(settings) {
class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWithEntity(settings), Waterloggable {
init {
defaultState = defaultState.with(Properties.HORIZONTAL_FACING, Direction.SOUTH)
defaultState = defaultState
.with(Properties.HORIZONTAL_FACING, Direction.SOUTH)
.with(WATERLOGGED, false)
}
companion object {
val POKEMON_ARGS = "gimmighoul"
val LEVEL_RANGE = 5..30
val WATERLOGGED = BooleanProperty.of("waterlogged")
val SOUTH_OUTLINE = VoxelShapes.union(
VoxelShapes.cuboid(0.0, 0.0, 0.25, 1.0, 1.0, 0.9375)
@@ -88,9 +97,28 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
}
}
override fun getStateForNeighborUpdate(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: WorldAccess,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
if (state.get(WATERLOGGED)) world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world))
return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos)
}
override fun getFluidState(state: BlockState): FluidState {
return if (state.get(WATERLOGGED)) {
Fluids.WATER.getStill(false)
} else super.getFluidState(state)
}
override fun appendProperties(builder: StateManager.Builder<Block, BlockState>) {
super.appendProperties(builder)
builder.add(Properties.HORIZONTAL_FACING)
builder.add(WATERLOGGED)
}
private val facingToYaw: HashMap<Direction, Float> = hashMapOf(
@@ -111,7 +139,7 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
if (player is ServerPlayerEntity) {
spawnPokemon(world, pos, state, player)
}
world.setBlockState(pos, Blocks.AIR.defaultState)
world.setBlockState(pos, if (state.fluidState.isOf(Fluids.WATER)) Blocks.WATER.defaultState else Blocks.AIR.defaultState)
} else super.onBreak(world, pos, state, player)
}
@@ -188,12 +216,9 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
override fun getRenderType(state: BlockState?) = BlockRenderType.ENTITYBLOCK_ANIMATED
override fun getPlacementState(blockPlaceContext: ItemPlacementContext): BlockState? {
// val abovePosition = blockPlaceContext.blockPos.up()
// val world = blockPlaceContext.world
// if (world.getBlockState(abovePosition).canReplace(blockPlaceContext) && !world.isOutOfHeightLimit(abovePosition)) {
return defaultState.with(HorizontalFacingBlock.FACING, blockPlaceContext.horizontalPlayerFacing.opposite)
// }
// return null
return defaultState
.with(HorizontalFacingBlock.FACING, blockPlaceContext.horizontalPlayerFacing.opposite)
.with(WATERLOGGED, blockPlaceContext.world.getFluidState(blockPlaceContext.blockPos).fluid == Fluids.WATER)
}
@Deprecated("Deprecated in Java")
@@ -205,6 +230,14 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
) as BlockState
}
override fun hasComparatorOutput(state: BlockState?): Boolean {
return true
}
override fun getComparatorOutput(state: BlockState?, world: World, pos: BlockPos?): Int {
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos))
}
override fun mirror(state: BlockState, mirror: BlockMirror): BlockState {
return state.rotate(mirror.getRotation(state.get(Properties.HORIZONTAL_FACING) as Direction))
}
@@ -19,6 +19,7 @@ import net.minecraft.block.entity.BlockEntityType
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtHelper
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.ChunkPos
open class FossilMultiblockEntity(
pos: BlockPos,
@@ -39,8 +40,12 @@ open class FossilMultiblockEntity(
get() {
return if (field != null) {
field
} else if (masterBlockPos != null && masterBlockPos != pos && world?.getBlockEntity(masterBlockPos) != null) {
field = (world?.getBlockEntity(masterBlockPos) as FossilMultiblockEntity).multiblockStructure
} else if (masterBlockPos != null && masterBlockPos != pos) {
val chunkPos = ChunkPos(masterBlockPos)
if (world?.chunkManager?.isChunkLoaded(chunkPos.x, chunkPos.z) == true) {
val entity: FossilMultiblockEntity? = world?.getBlockEntity(masterBlockPos) as FossilMultiblockEntity?
field = entity?.multiblockStructure
}
field
} else {
null
@@ -20,6 +20,7 @@ import net.minecraft.entity.player.PlayerEntity
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.inventory.DoubleInventory
import net.minecraft.inventory.Inventories
import net.minecraft.inventory.SidedInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtCompound
import net.minecraft.screen.GenericContainerScreenHandler
@@ -28,9 +29,10 @@ import net.minecraft.state.property.Properties
import net.minecraft.text.Text
import net.minecraft.util.collection.DefaultedList
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.world.World
class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type = Type.RED) : LootableContainerBlockEntity(CobblemonBlockEntities.GILDED_CHEST, pos, state) {
class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type = Type.RED) : LootableContainerBlockEntity(CobblemonBlockEntities.GILDED_CHEST, pos, state), SidedInventory {
var inventoryContents: DefaultedList<ItemStack> = DefaultedList.ofSize(NUM_SLOTS, ItemStack.EMPTY)
val poseableState: GildedState = GildedState()
@@ -69,7 +71,7 @@ class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type =
override fun getContainerName() = Text.translatable("block.cobblemon.gilded_chest")
override fun createScreenHandler(syncId: Int, playerInventory: PlayerInventory?) =
GenericContainerScreenHandler.createGeneric9x3(syncId, playerInventory, this);
GenericContainerScreenHandler.createGeneric9x3(syncId, playerInventory, this)
override fun onOpen(player: PlayerEntity) {
if (!this.removed && !player.isSpectator && type != Type.FAKE) {
@@ -83,6 +85,22 @@ class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type =
}
}
override fun getAvailableSlots(side: Direction): IntArray {
return if (type == Type.FAKE) IntArray(0) else IntArray(NUM_SLOTS)
}
override fun canInsert(slot: Int, stack: ItemStack?, dir: Direction?): Boolean {
if (type == Type.FAKE) return false
return dir != Direction.DOWN
}
override fun canExtract(slot: Int, stack: ItemStack?, dir: Direction?): Boolean {
if (type == Type.FAKE) return false
return dir == Direction.DOWN
}
override fun canPlayerUse(player: PlayerEntity) = !player.isSpectator
override fun getInvStackList(): DefaultedList<ItemStack> = inventoryContents
override fun setInvStackList(list: DefaultedList<ItemStack>) {
@@ -1,349 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.entity
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.api.tms.TechnicalMachine
import com.cobblemon.mod.common.api.tms.TechnicalMachines
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.block.TMBlock
import com.cobblemon.mod.common.gui.TMMScreenHandler
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.entity.LockableContainerBlockEntity
import net.minecraft.block.entity.ViewerCountManager
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.inventory.Inventories
import net.minecraft.inventory.Inventory
import net.minecraft.inventory.SidedInventory
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.nbt.NbtCompound
import net.minecraft.network.listener.ClientPlayPacketListener
import net.minecraft.network.packet.Packet
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket
import net.minecraft.registry.Registries
import net.minecraft.screen.ScreenHandler
import net.minecraft.text.Text
import net.minecraft.util.collection.DefaultedList
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.world.World
class TMBlockEntity(
val blockPos: BlockPos,
val blockState: BlockState
) : LockableContainerBlockEntity(CobblemonBlockEntities.TM_BLOCK, blockPos, blockState) {
var tmmInventory = TMBlockInventory(this)
var automationDelay: Int = AUTOMATION_DELAY
var partialTicks = 0.0f
val stateManager: ViewerCountManager = object : ViewerCountManager() {
override fun onContainerOpen(world: World, pos: BlockPos, state: BlockState) {
this@TMBlockEntity.setOpen(state, true)
}
override fun onContainerClose(world: World, pos: BlockPos, state: BlockState) {
this@TMBlockEntity.setOpen(state, false)
}
override fun onViewerCountUpdate(world: World, pos: BlockPos, state: BlockState, oldViewerCount: Int, newViewerCount: Int) {}
override fun isPlayerViewing(player: PlayerEntity): Boolean {
if (player.currentScreenHandler is TMMScreenHandler) {
val inventory = (player.currentScreenHandler as TMMScreenHandler).inventory
return inventory === this@TMBlockEntity
}
return false
}
}
companion object {
const val AUTOMATION_DELAY = 4
const val FILTER_TM_NBT = "FilterTM"
}
fun setOpen(state: BlockState, open: Boolean) {
world!!.setBlockState(getPos(), state.with(TMBlock.ON, open), Block.NOTIFY_ALL)
}
fun tick() {
if (!removed) {
stateManager.updateViewerCount(getWorld(), getPos(), cachedState)
}
}
//var filterTM: TechnicalMachine? = null
//private var inventory: DefaultedList<ItemStack> = DefaultedList.ofSize(size(), ItemStack.EMPTY)
/*override fun size(): Int { return 3 }
override fun getContainerName(): Text {
return Text.translatable("container.tmblock")
}
override fun getInvStackList(): DefaultedList<ItemStack> {
return inventory
}
override fun setInvStackList(list: DefaultedList<ItemStack>?) {
if (list != null) {
this.inventory = list
}
}*/
fun resetAutomationDelay() {
automationDelay = AUTOMATION_DELAY
}
fun materialNeeded(tm: TechnicalMachine?, slot: Int, itemStack: ItemStack): Boolean {
val typeGem = Registries.ITEM.get(tm?.type?.let { ElementalTypes.get(it)?.typeGem }).defaultStack
val recipeItem = Registries.ITEM.get(tm?.recipe?.item)
//val inventory = tmmInventory.inventory
val inventory = tmmInventory.items
//inventory.count { it.value == CobblemonItems.BLANK_TM.defaultStack }
//ItemStack.areEqual()
if (inventory != null) {
if (tmmInventory.filterTM != null) {
// if blank TM is needed still
if (slot == 0 && (inventory.none { it?.count == 1 && it.item == CobblemonItems.BLANK_TM }) && ItemStack.areEqual(itemStack, ItemStack(CobblemonItems.BLANK_TM, 1)))
return true // load in blank TM
// if type gem is needed still
else if (slot == 1 && inventory.none { ItemStack.areEqual(it, typeGem) } && ItemStack.areEqual(itemStack, typeGem))
return true // load in Type Gem
// if the itemStack is listed as needed in the recipe and the count is not currently met
else if (slot == 2 && inventory.none { it?.count == tm?.recipe?.count && ItemStack.areItemsEqual(it, ItemStack(recipeItem, 1)) } && ItemStack.areEqual(itemStack, ItemStack(recipeItem, 1)))
return true
else
return false
}
else if (tmmInventory.filterTM == null && ItemStack.areItemsEqual(itemStack,Items.AMETHYST_SHARD.defaultStack)) {
return (slot == 2 && inventory.none { it?.count == 1 && ItemStack.areItemsEqual(it, Items.AMETHYST_SHARD.defaultStack) })
}
}
return false
}
override fun toInitialChunkDataNbt(): NbtCompound {
val res = NbtCompound()
writeNbt(res)
return res
}
override fun clear() {
tmmInventory.clear()
}
override fun size(): Int {
return this.tmmInventory.size()
}
override fun isEmpty(): Boolean {
return this.tmmInventory.isEmpty()
}
override fun getStack(slot: Int): ItemStack {
return this.tmmInventory.getStack(slot)
}
override fun removeStack(slot: Int, amount: Int): ItemStack {
return this.tmmInventory.removeStack(slot, amount)
}
override fun removeStack(slot: Int): ItemStack {
return this.tmmInventory.removeStack(slot)
}
override fun setStack(slot: Int, stack: ItemStack?) {
return this.tmmInventory.setStack(slot, stack)
}
override fun canPlayerUse(player: PlayerEntity?): Boolean {
return this.tmmInventory.canPlayerUse(player)
}
override fun getContainerName(): Text {
return Text.translatable("container.brewing")
}
override fun createScreenHandler(syncId: Int, playerInventory: PlayerInventory?): ScreenHandler {
return TMMScreenHandler(syncId, playerInventory!!, this.tmmInventory, this)
}
override fun toUpdatePacket(): Packet<ClientPlayPacketListener>? {
return BlockEntityUpdateS2CPacket.create(this)
}
override fun writeNbt(nbt: NbtCompound) {
super.writeNbt(nbt)
Inventories.writeNbt(nbt, tmmInventory.items)
val filterTmCompound = tmmInventory.filterTM?.writeNbt(NbtCompound())
if (filterTmCompound != null)
nbt.put(FILTER_TM_NBT, filterTmCompound)
}
override fun readNbt(nbt: NbtCompound) {
super.readNbt(nbt)
Inventories.readNbt(nbt, tmmInventory.items)
if (nbt.contains(FILTER_TM_NBT)) {
val itemStack = CobblemonItems.TECHNICAL_MACHINE.defaultStack
tmmInventory.filterTM = ItemStack.fromNbt(nbt.getCompound(FILTER_TM_NBT))
val test = 2
}
}
override fun markDirty() {
super.markDirty()
if (this.world != null && !this.world!!.isClient) {
val currentState = world!!.getBlockState(pos)
world!!.setBlockState(pos, currentState, 3) // Flags: 2 | 1 = Block update | Render update
this.world!!.updateNeighborsAlways(this.pos, this.cachedState.block)
}
}
class TMBlockInventory(val tmBlockEntity: TMBlockEntity) : SidedInventory {
private val BLANK_DISC_SLOT_INDEX = 0
private val GEM_SLOT_INDEX = 1
private val MISC_SLOT_INDEX = 2
private val OUTPUT_SLOT_INDEX = 3
private val INPUT_SLOTS = intArrayOf(0, 1, 2, 3)
val entityPos = this.tmBlockEntity.blockPos
val entityState = this.tmBlockEntity.blockState
val entityWorld = this.tmBlockEntity.world
var filterTM: ItemStack? = null
//var inventory: MutableMap<Int, ItemStack?> = mutableMapOf(0 to ItemStack.EMPTY, 1 to ItemStack.EMPTY, 2 to ItemStack.EMPTY)
var items: DefaultedList<ItemStack?>? = DefaultedList.ofSize(4, ItemStack.EMPTY)
fun hasFilterTM(): Boolean {
return filterTM != null
}
override fun clear() {
tmBlockEntity.markDirty()
this.items?.clear()
}
override fun size(): Int {
return this.items?.size ?: 0;
}
/*fun getInvSize(): Int {
return size()
}*/
fun getInvStack(slot: Int): ItemStack {
return items?.get(slot) ?: ItemStack.EMPTY
}
override fun isEmpty(): Boolean {
for (i in 0 until size()) {
val stack: ItemStack = getInvStack(i)
if (!stack.isEmpty) {
return false
}
}
return true
}
/*override fun isEmpty(): Boolean {
return !inventory.any { it.value != ItemStack.EMPTY }
}*/
override fun getStack(slot: Int): ItemStack {
return items?.get(slot) ?: ItemStack.EMPTY
}
override fun getAvailableSlots(side: Direction?): IntArray? {
return if (side == Direction.DOWN) {
return listOf(this.OUTPUT_SLOT_INDEX).toIntArray()
}
else this.INPUT_SLOTS
// val result = this.items?.size?.let { IntArray(it) }
// if (result != null) {
// for (i in result.indices) {
// result[i] = i
// }
// }
// return result
}
override fun removeStack(slot: Int, amount: Int): ItemStack {
tmBlockEntity.markDirty()
return Inventories.splitStack(items, slot, amount)
}
override fun removeStack(slot: Int): ItemStack {
val slotStack = items?.get(slot)
items?.set(slot, ItemStack.EMPTY)
tmBlockEntity.markDirty()
return slotStack ?: ItemStack.EMPTY
}
override fun setStack(slot: Int, stack: ItemStack?) {
items?.set(slot, stack)
tmBlockEntity.markDirty()
}
override fun markDirty() {
if (tmBlockEntity.world != null)
tmBlockEntity.markDirty()
}
override fun canPlayerUse(player: PlayerEntity?): Boolean {
return Inventory.canPlayerUse(this.tmBlockEntity, player)
}
/*override fun getAvailableSlots(side: Direction?): IntArray {
return IntArray(3)
}*/
override fun canInsert(slot: Int, stack: ItemStack?, dir: Direction?): Boolean {
if (this.entityState.get(TMBlock.ON)) {
// print("TMM is in use so canInsert is disabled")
return false
}
if (stack != null && slot < this.INPUT_SLOTS.size) {
val tm = TechnicalMachines.getTechnicalMachineFromStack(tmBlockEntity.tmmInventory.filterTM)
// if material is needed then load it
if (tmBlockEntity.materialNeeded(tm, slot, stack) && (ItemStack.areEqual(items?.get(slot) ?: ItemStack.EMPTY, ItemStack.EMPTY) || ItemStack.areItemsEqual(items?.get(slot) ?: ItemStack.EMPTY, stack))) {
//tmBlockEntity.loadMaterial(stack)
return true
}
else
return false
}
return false
}
override fun canExtract(slot: Int, stack: ItemStack?, dir: Direction?): Boolean {
if (this.entityState.get(TMBlock.ON)) {
//print("TMM is in use so canExtract is disabled")
return false
}
return dir == Direction.DOWN && slot == this.OUTPUT_SLOT_INDEX
}
}
}
@@ -117,10 +117,10 @@ class FossilMultiblockBuilder(val centerPos: BlockPos) : MultiblockStructureBuil
val monitorPos = monitorPositions[fossilTankIndex]
val fossilAnalyzerPos = fossilAnalyzerPositions[fossilTankIndex]!!
val restorationTankPos = restorationTankPositions[fossilTankIndex]!!
val monitorEntity = world.getBlockEntity(monitorPos) as MultiblockEntity
val analyzerEntity = world.getBlockEntity(fossilAnalyzerPos) as MultiblockEntity
val tankBaseEntity = world.getBlockEntity(restorationTankPos) as MultiblockEntity
val tankTopEntity = world.getBlockEntity(restorationTankPos.up()) as MultiblockEntity
val monitorEntity = world.getBlockEntity(monitorPos) as? MultiblockEntity
val analyzerEntity = world.getBlockEntity(fossilAnalyzerPos) as? MultiblockEntity
val tankBaseEntity = world.getBlockEntity(restorationTankPos) as? MultiblockEntity
val tankTopEntity = world.getBlockEntity(restorationTankPos.up()) as? MultiblockEntity
val structure = FossilMultiblockStructure(monitorPos, fossilAnalyzerPos, restorationTankPos)
structure.tankConnectorDirection = dirsToCheck.filter {
@@ -128,20 +128,20 @@ class FossilMultiblockBuilder(val centerPos: BlockPos) : MultiblockStructureBuil
return@filter adjPos == fossilAnalyzerPos
}.first()
analyzerEntity.multiblockStructure = structure
tankBaseEntity.multiblockStructure = structure
tankTopEntity.multiblockStructure = structure
monitorEntity.multiblockStructure = structure
analyzerEntity?.multiblockStructure = structure
tankBaseEntity?.multiblockStructure = structure
tankTopEntity?.multiblockStructure = structure
monitorEntity?.multiblockStructure = structure
structure.syncToClient(world)
structure.markDirty(world)
world.playSound(null, centerPos, CobblemonSounds.FOSSIL_MACHINE_ASSEMBLE, SoundCategory.BLOCKS)
//Set these to null so the builders can be freed
analyzerEntity.multiblockBuilder = null
tankBaseEntity.multiblockBuilder = null
tankTopEntity.multiblockBuilder = null
monitorEntity.multiblockBuilder = null
analyzerEntity?.multiblockBuilder = null
tankBaseEntity?.multiblockBuilder = null
tankTopEntity?.multiblockBuilder = null
monitorEntity?.multiblockBuilder = null
}
companion object {
@@ -98,101 +98,97 @@ class FossilMultiblockStructure (
): ActionResult {
val stack = player.getStackInHand(interactionHand)
if (this.createdPokemon != null) {
if (!stack.isIn(CobblemonItemTags.POKE_BALLS) || stack.item !is PokeBallItem) {
return ActionResult.PASS
}
if(stack.isIn(CobblemonItemTags.POKE_BALLS) || stack.item is PokeBallItem) {
if (player !is ServerPlayerEntity) {
return ActionResult.CONSUME
return ActionResult.SUCCESS
}
if (this.createdPokemon != null) {
if (this.fossilOwnerUUID != null && player.uuid != this.fossilOwnerUUID) {
var ownerName : String = "UNKNOWN_USER" // TODO: lang agnostic fallback
server()?.userCache?.getByUuid(this.fossilOwnerUUID)?.orElse(null)?.name?.let {
ownerName = it
if (this.fossilOwnerUUID != null && player.uuid != this.fossilOwnerUUID) {
var ownerName : String = "UNKNOWN_USER" // TODO: lang agnostic fallback
server()?.userCache?.getByUuid(this.fossilOwnerUUID)?.orElse(null)?.name?.let {
ownerName = it
}
player.sendMessage(lang("fossilmachine.protected", ownerName), true)
return ActionResult.FAIL
}
player.sendMessage(lang("fossilmachine.protected", ownerName), true)
return ActionResult.FAIL
val ballType = (stack.item as PokeBallItem).pokeBall
if (!player.isCreative) {
stack?.decrement(1)
}
this.createdPokemon!!.caughtBall = ballType
player.party().add(this.createdPokemon!!)
this.fossilState.growthState = "Taken"
player.playSound(CobblemonSounds.FOSSIL_MACHINE_RETRIEVE_POKEMON, SoundCategory.BLOCKS, 1.0F, 1.0F)
CobblemonCriteria.RESURRECT_POKEMON.trigger(player, createdPokemon!!)
// Turn the monitor off
val monitorState = world.getBlockState(monitorPos)
if(!monitorState.equals(MonitorBlock.MonitorScreen.OFF)) {
world.setBlockState(monitorPos, monitorState.with(MonitorBlock.SCREEN, MonitorBlock.MonitorScreen.OFF))
}
this.createdPokemon = null
this.fossilOwnerUUID = null
this.protectionTime = -1
this.updateFossilType(world)
this.syncToClient(world)
this.markDirty(world)
return ActionResult.SUCCESS
}
val ballType = (stack.item as PokeBallItem).pokeBall
if (!player.isCreative) {
stack?.decrement(1)
}
this.createdPokemon!!.caughtBall = ballType
player.party().add(this.createdPokemon!!)
this.fossilState.growthState = "Taken"
player.playSound(CobblemonSounds.FOSSIL_MACHINE_RETRIEVE_POKEMON, SoundCategory.BLOCKS, 1.0F, 1.0F)
CobblemonCriteria.RESURRECT_POKEMON.trigger(player, createdPokemon!!)
// Turn the monitor off
val monitorState = world.getBlockState(monitorPos)
if(!monitorState.equals(MonitorBlock.MonitorScreen.OFF)) {
world.setBlockState(monitorPos, monitorState.with(MonitorBlock.SCREEN, MonitorBlock.MonitorScreen.OFF))
}
this.createdPokemon = null
this.fossilOwnerUUID = null
this.protectionTime = -1
this.updateFossilType(world)
this.syncToClient(world)
this.markDirty(world)
return ActionResult.SUCCESS
}
if (this.isRunning()) {
return ActionResult.PASS
}
// Reclaim the last fossil from the machine if their hand is empty
if (player.getStackInHand(interactionHand).isEmpty) {
if (fossilInventory.isEmpty()) {
return ActionResult.CONSUME
}
if(!this.isRunning() && this.createdPokemon == null) {
if (fossilInventory.isEmpty()) {
return ActionResult.CONSUME
}
player.setStackInHand(interactionHand, fossilInventory.last())
player.setStackInHand(interactionHand, fossilInventory.last())
// remove last fossil in the fossil machine stack when grabbed out of the machine
this.fossilInventory.removeAt(fossilInventory.size - 1)
if(!world.isClient) {
world.playSound(null, analyzerPos, CobblemonSounds.FOSSIL_MACHINE_RETRIEVE_FOSSIL, SoundCategory.BLOCKS)
this.updateFossilType(world)
this.syncToClient(world)
this.markDirty(world)
// remove last fossil in the fossil machine stack when grabbed out of the machine
this.fossilInventory.removeAt(fossilInventory.size - 1)
if(!world.isClient) {
world.playSound(null, analyzerPos, CobblemonSounds.FOSSIL_MACHINE_RETRIEVE_FOSSIL, SoundCategory.BLOCKS)
this.updateFossilType(world)
this.syncToClient(world)
this.markDirty(world)
}
}
return ActionResult.CONSUME
}
// Check if the player is holding a fossil and if so insert it into the machine.
if (Fossils.isFossilIngredient(stack)) {
if (fossilInventory.size > Cobblemon.config.maxInsertedFossilItems) {
return ActionResult.FAIL
}
if(!this.isRunning() && this.createdPokemon == null) {
if (fossilInventory.size > Cobblemon.config.maxInsertedFossilItems) {
return ActionResult.FAIL
}
val copyFossilStack = stack.copyWithCount(1)
if (!player.isCreative) {
stack?.decrement(1)
}
val copyFossilStack = stack.copyWithCount(1)
if (!player.isCreative) {
stack?.decrement(1)
}
fossilOwnerUUID = player.uuid
fossilInventory.add(copyFossilStack)
if(!world.isClient) {
this.updateFossilType(world)
world.playSound(null, analyzerPos, CobblemonSounds.FOSSIL_MACHINE_INSERT_FOSSIL, SoundCategory.BLOCKS)
this.syncToClient(world)
this.markDirty(world)
fossilOwnerUUID = player.uuid
fossilInventory.add(copyFossilStack)
if(!world.isClient) {
this.updateFossilType(world)
world.playSound(null, analyzerPos, CobblemonSounds.FOSSIL_MACHINE_INSERT_FOSSIL, SoundCategory.BLOCKS)
this.syncToClient(world)
this.markDirty(world)
}
}
return ActionResult.SUCCESS
}
// Check if the player is holding a natural material and if so, feed it to the machine.
if (NaturalMaterials.isNaturalMaterial(stack) && this.organicMaterialInside < MATERIAL_TO_START) {
if (insertOrganicMaterial(stack, world)) {
if (NaturalMaterials.isNaturalMaterial(stack)) {
if (!this.isRunning() && this.createdPokemon == null && this.organicMaterialInside < MATERIAL_TO_START && insertOrganicMaterial(stack, world)) {
this.lastInteraction = world.time
if (!player.isCreative) {
val returnItem = NaturalMaterials.getReturnItem(stack)
@@ -200,7 +196,6 @@ class FossilMultiblockStructure (
player.giveOrDropItemStack(ItemStack(Registries.ITEM.get(returnItem)), false)
}
}
return ActionResult.success(world.isClient)
}
@@ -311,22 +306,22 @@ class FossilMultiblockStructure (
}
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
val monitorEntity = world.getBlockEntity(monitorPos) as MultiblockEntity
val analyzerEntity = world.getBlockEntity(analyzerPos) as MultiblockEntity
val tankBaseEntity = world.getBlockEntity(tankBasePos) as MultiblockEntity
val tankTopEntity = world.getBlockEntity(tankBasePos.up()) as MultiblockEntity
val state = world.getBlockState(tankBaseEntity.pos)
val monitorEntity = world.getBlockEntity(monitorPos) as? MultiblockEntity
val analyzerEntity = world.getBlockEntity(analyzerPos) as? MultiblockEntity
val tankBaseEntity = world.getBlockEntity(tankBasePos) as? MultiblockEntity
val tankTopEntity = world.getBlockEntity(tankBasePos.up()) as? MultiblockEntity
val state = world.getBlockState(tankBaseEntity?.pos)
val direction = state.get(HorizontalFacingBlock.FACING).getOpposite()
val wildPokemon: Pokemon? = this.createdPokemon
monitorEntity.multiblockStructure = null
analyzerEntity.multiblockStructure = null
tankBaseEntity.multiblockStructure = null
tankTopEntity.multiblockStructure = null
monitorEntity.masterBlockPos = null
analyzerEntity.masterBlockPos = null
tankBaseEntity.masterBlockPos = null
tankTopEntity.masterBlockPos = null
monitorEntity?.multiblockStructure = null
analyzerEntity?.multiblockStructure = null
tankBaseEntity?.multiblockStructure = null
tankTopEntity?.multiblockStructure = null
monitorEntity?.masterBlockPos = null
analyzerEntity?.masterBlockPos = null
tankBaseEntity?.masterBlockPos = null
tankTopEntity?.masterBlockPos = null
// Drop fossils from machine as long as the machine is not started or near completion
if (this.timeRemaining == -1 || this.timeRemaining >= 20) {
@@ -544,7 +539,7 @@ class FossilMultiblockStructure (
}
if (natureValue < 0 && organicMaterialInside == 0) return false
val oldFillStage = organicMaterialInside / 8
val oldFillStage = organicMaterialInside * 8 / MATERIAL_TO_START
// to prevent over/under filling the tank causing a crash
if ((organicMaterialInside + natureValue) > MATERIAL_TO_START) {
@@ -562,7 +557,7 @@ class FossilMultiblockStructure (
world.playSound(null, this.tankBasePos, CobblemonSounds.FOSSIL_MACHINE_INSERT_DNA, SoundCategory.BLOCKS, 1.0F, 1.0F)
}
this.markDirty(world)
if (oldFillStage != (organicMaterialInside / 8)) {
if (oldFillStage != (organicMaterialInside * 8 / MATERIAL_TO_START)) {
this.syncToClient(world)
}
return true
@@ -624,10 +619,10 @@ class FossilMultiblockStructure (
}
const val TICKS_PER_MINUTE = 1200
const val MATERIAL_TO_START = 64
const val TIME_TO_TAKE = TICKS_PER_MINUTE * 1
const val MATERIAL_TO_START = 128
const val TIME_TO_TAKE = TICKS_PER_MINUTE * 12
const val TIME_PER_STAGE = TIME_TO_TAKE / 8
const val PROTECTION_TIME = 6000
const val PROTECTION_TIME = TICKS_PER_MINUTE * 5
fun fromNbt(nbt: NbtCompound, animAge: Int = -1, partialTicks: Float = 0f): FossilMultiblockStructure {
val monitorPos = NbtHelper.toBlockPos(nbt.getCompound(DataKeys.MONITOR_POS))
@@ -662,7 +657,7 @@ class FossilMultiblockStructure (
if (nbt.contains(DataKeys.CREATED_POKEMON)) {
result.createdPokemon = Pokemon.loadFromNBT(nbt.getCompound(DataKeys.CREATED_POKEMON))
}
result.fillLevel = result.organicMaterialInside / 8
result.fillLevel = result.organicMaterialInside * 8 / MATERIAL_TO_START
return result
}
@@ -62,7 +62,6 @@ object CobblemonBakingOverrides {
cobblemonModel("restoration_tank_connector", "none")
)
fun registerOverride(modelLocation: Identifier, modelIdentifier: ModelIdentifier): BakingOverride {
val result = BakingOverride(modelLocation, modelIdentifier)
models.add(result)
@@ -18,12 +18,9 @@ import com.cobblemon.mod.common.CobblemonEntities
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.api.scheduling.ClientTaskTracker
import com.cobblemon.mod.common.api.text.gray
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.client.battle.ClientBattle
import com.cobblemon.mod.common.client.gui.PartyOverlay
import com.cobblemon.mod.common.client.gui.battle.BattleOverlay
import com.cobblemon.mod.common.client.gui.modstation.ModStationHandledScreen
import com.cobblemon.mod.common.client.gui.tm.TMMHandledScreen
import com.cobblemon.mod.common.client.particle.BedrockParticleEffectRepository
import com.cobblemon.mod.common.client.render.block.BerryBlockRenderer
import com.cobblemon.mod.common.client.render.block.FossilAnalyzerRenderer
@@ -31,7 +28,6 @@ import com.cobblemon.mod.common.client.render.block.RestorationTankRenderer
import com.cobblemon.mod.common.client.render.block.GildedChestBlockRenderer
import com.cobblemon.mod.common.client.render.block.HealingMachineRenderer
import com.cobblemon.mod.common.client.render.block.*
import com.cobblemon.mod.common.client.render.block.TMBlockRenderer
import com.cobblemon.mod.common.client.render.boat.CobblemonBoatRenderer
import com.cobblemon.mod.common.client.render.generic.GenericBedrockRenderer
import com.cobblemon.mod.common.client.render.item.CobblemonBuiltinItemRendererRegistry
@@ -50,19 +46,14 @@ import com.cobblemon.mod.common.client.storage.ClientStorageManager
import com.cobblemon.mod.common.client.trade.ClientTrade
import com.cobblemon.mod.common.data.CobblemonDataProvider
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.gui.CobblemonScreenHandlers
import com.cobblemon.mod.common.item.PokeBallItem
import com.cobblemon.mod.common.item.TechnicalMachineItem
import com.cobblemon.mod.common.client.render.models.blockbench.repository.FossilModelRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.GenericBedrockEntityModelRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.MiscModelRepository
import com.cobblemon.mod.common.platform.events.PlatformEvents
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.asTranslated
import net.minecraft.client.color.block.BlockColorProvider
import net.minecraft.client.color.item.ItemColorProvider
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.ingame.HandledScreens
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.block.entity.HangingSignBlockEntityRenderer
import net.minecraft.client.render.block.entity.SignBlockEntityRenderer
@@ -116,10 +107,9 @@ object CobblemonClient {
this.registerBlockEntityRenderers()
registerBlockRenderTypes()
registerColors()
//registerColors()
registerFlywheelRenderers()
this.registerEntityRenderers()
registerHandledScreens()
Berries.observable.subscribe {
BerryModelRepository.patchModels()
}
@@ -159,24 +149,21 @@ object CobblemonClient {
// .apply()
}
/*
fun registerColors() {
this.implementation.registerBlockColors(BlockColorProvider { _, _, _, _ ->
return@BlockColorProvider 0xE0A33A
}, CobblemonBlocks.APRICORN_LEAVES)
this.implementation.registerItemColors(ItemColorProvider { stack, tint ->
this.implementation.registerItemColors(ItemColorProvider { _, _ ->
return@ItemColorProvider 0xE0A33A
}, CobblemonItems.TECHNICAL_MACHINE)
this.implementation.registerItemColors(TechnicalMachineItem::getItemColor, CobblemonItems.TECHNICAL_MACHINE)
}, CobblemonItems.APRICORN_LEAVES)
}
*/
private fun registerBlockRenderTypes() {
this.implementation.registerBlockRenderType(RenderLayer.getCutoutMipped(), CobblemonBlocks.APRICORN_LEAVES)
this.implementation.registerBlockRenderType(RenderLayer.getTranslucent(), CobblemonBlocks.TM_MACHINE)
this.implementation.registerBlockRenderType(
RenderLayer.getCutout(),
CobblemonBlocks.GILDED_CHEST,
@@ -264,7 +251,6 @@ object CobblemonClient {
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.HANGING_SIGN, ::HangingSignBlockEntityRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.FOSSIL_ANALYZER, ::FossilAnalyzerRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.RESTORATION_TANK, ::RestorationTankRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.TM_BLOCK, ::TMBlockRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.GILDED_CHEST, ::GildedChestBlockRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.DISPLAY_CASE, ::DisplayCaseRenderer)
}
@@ -320,15 +306,4 @@ object CobblemonClient {
}
}
private fun registerHandledScreens() {
HandledScreens.register(
CobblemonScreenHandlers.TMM_SCREEN,
::TMMHandledScreen
)
HandledScreens.register(
CobblemonScreenHandlers.MOD_STATION_SCREEN,
::ModStationHandledScreen
)
}
}
@@ -59,7 +59,7 @@ class PartyOverlay : InGameHud(MinecraftClient.getInstance(), MinecraftClient.ge
BattleGUI::class.java
)
private val starterToast = CobblemonToast(
val starterToast = CobblemonToast(
MathHelper.randomUuid(),
CobblemonItems.POKE_BALL.defaultStack,
lang("ui.starter.choose_starter_title", SummaryBinding.boundKey().localizedText).red(),
@@ -104,24 +104,12 @@ class PartyOverlay : InGameHud(MinecraftClient.getInstance(), MinecraftClient.ge
!CobblemonClient.checkedStarterScreen
) {
if (!this.attachedToast) {
// Adding starter toast on start and connect of client to server.
minecraft.toastManager.add(this.starterToast)
this.attachedToast = true
}
/*
drawScaledText(
context = context,
text = lang("ui.starter.chooseyourstarter", SummaryBinding.boundKey().localizedText),
x = minecraft.window.scaledWidth / 2,
y = 70,
centered = true,
shadow = true
)
*/
}
return
}
if (this.starterToast.nextVisibility != Toast.Visibility.HIDE) {
this.starterToast.nextVisibility = Toast.Visibility.HIDE
return // Don't render the stuff below if no Pokémon in party
}
val totalHeight = party.slots.size * SLOT_HEIGHT
@@ -1,48 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.gui
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.types.ElementalType
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.util.math.MatrixStack
class TypeReturnIcon(
val x: Number,
val y: Number,
val centeredX: Boolean = false,
val small: Boolean = false,
val secondaryOffset: Float = 15F,
val doubleCenteredOffset: Float = 7.5F,
val opacity: Float = 1F
) {
companion object {
private const val TYPE_ICON_DIAMETER = 36
private const val SCALE = 0.5F
private val typeReturnResource = cobblemonResource("textures/gui/type_return.png")
private val smallTypeReturnResource = cobblemonResource("textures/gui/type_return_small.png")
}
fun render(context: DrawContext) {
val diameter = if (small) (TYPE_ICON_DIAMETER / 2) else TYPE_ICON_DIAMETER
blitk(
matrixStack = context.matrices,
texture = if (small) smallTypeReturnResource else typeReturnResource,
x = (x.toFloat()) / SCALE - 9,
y = y.toFloat() / SCALE,
height = diameter,
width = diameter,
alpha = opacity,
scale = SCALE
)
}
}
@@ -62,8 +62,9 @@ class BattleGeneralActionSelection(
}
addOption(rank++, battleLang("ui.run"), BattleGUI.runResource) {
MinecraftClient.getInstance().player?.sendMessage(battleLang("flee"))
CobblemonClient.battle?.minimised = true
MinecraftClient.getInstance().player?.sendMessage(battleLang("run_prompt"), false)
playDownSound(MinecraftClient.getInstance().soundManager)
}
}
}
@@ -1,28 +0,0 @@
package com.cobblemon.mod.common.client.gui.modstation
import com.cobblemon.mod.common.gui.ModStationScreenHandler
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.ingame.HandledScreen
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.item.ItemStack
import net.minecraft.screen.ScreenHandler
import net.minecraft.screen.ScreenHandlerListener
import net.minecraft.text.Text
class ModStationHandledScreen(
val handler: ModStationScreenHandler,
val inventory: PlayerInventory,
title: Text?
) : HandledScreen<ModStationScreenHandler>(handler, inventory, title), ScreenHandlerListener {
override fun drawBackground(context: DrawContext?, delta: Float, mouseX: Int, mouseY: Int) {
}
override fun onSlotUpdate(handler: ScreenHandler?, slotId: Int, stack: ItemStack?) {
}
override fun onPropertyUpdate(handler: ScreenHandler?, property: Int, value: Int) {
}
}
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.api.gui.ColourLibrary
import com.cobblemon.mod.common.api.gui.MultiLineLabelK
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.text.bold
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.CobblemonResources
import com.cobblemon.mod.common.client.gui.startselection.widgets.CategoryList
import com.cobblemon.mod.common.client.gui.startselection.widgets.ExitButton
@@ -37,7 +38,7 @@ import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.sound.PositionedSoundInstance
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.client.toast.Toast
import net.minecraft.text.Text
/**
@@ -74,6 +75,12 @@ class StarterSelectionScreen(private val categories: List<RenderableStarterCateg
override fun init() {
super.init()
// Hide toast once checkedStarterScreen was set, which happens during the opening of the starter screen.
if (CobblemonClient.checkedStarterScreen) {
if (CobblemonClient.overlay.starterToast.nextVisibility != Toast.Visibility.HIDE) {
CobblemonClient.overlay.starterToast.nextVisibility = Toast.Visibility.HIDE
}
}
val x = (width - BASE_WIDTH) / 2
val y = (height - BASE_HEIGHT) / 2
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.moves.Move
import com.cobblemon.mod.common.api.moves.MoveSet
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies.species
import com.cobblemon.mod.common.api.reactive.Observable.Companion.emitWhile
import com.cobblemon.mod.common.api.reactive.ObservableSubscription
import com.cobblemon.mod.common.api.scheduling.Schedulable
@@ -34,6 +35,7 @@ import com.cobblemon.mod.common.client.gui.summary.widgets.screens.moves.MoveSwa
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.moves.MovesWidget
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.stats.StatWidget
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokemonModelRepository
import com.cobblemon.mod.common.net.messages.server.storage.party.MovePartyPokemonPacket
import com.cobblemon.mod.common.net.messages.server.storage.party.SwapPartyPokemonPacket
import com.cobblemon.mod.common.pokemon.Gender
@@ -613,6 +615,27 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
) {
this.focused = null
}
if (Cobblemon.config.enableDebugKeys) {
val model = PokemonModelRepository.getPoser(selectedPokemon.species.resourceIdentifier, selectedPokemon.aspects)
if (keyCode == InputUtil.GLFW_KEY_UP) {
model.profileTranslation = model.profileTranslation.add(0.0, -0.01, 0.0)
}
if (keyCode == InputUtil.GLFW_KEY_DOWN) {
model.profileTranslation = model.profileTranslation.add(0.0, 0.01, 0.0)
}
if (keyCode == InputUtil.GLFW_KEY_LEFT) {
model.profileTranslation = model.profileTranslation.add(-0.01, 0.0, 0.0)
}
if (keyCode == InputUtil.GLFW_KEY_RIGHT) {
model.profileTranslation = model.profileTranslation.add(0.01, 0.0, 0.0)
}
if (keyCode == InputUtil.GLFW_KEY_EQUAL) {
model.profileScale += 0.01F
}
if (keyCode == InputUtil.GLFW_KEY_MINUS) {
model.profileScale -= 0.01F
}
}
return super.keyPressed(keyCode, scanCode, modifiers)
}
@@ -620,4 +643,14 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
MinecraftClient.getInstance().soundManager.play(PositionedSoundInstance.master(soundEvent, 1.0F))
}
override fun close() {
if (Cobblemon.config.enableDebugKeys) {
val model = PokemonModelRepository.getPoser(selectedPokemon.species.resourceIdentifier, selectedPokemon.aspects)
MinecraftClient.getInstance().player?.sendMessage(Text.of("Profile Translation: ${model.profileTranslation}"))
MinecraftClient.getInstance().player?.sendMessage(Text.of("Profile Scale: ${model.profileScale}"))
Cobblemon.LOGGER.info("override var profileTranslation = Vec3d(${model.profileTranslation.x}, ${model.profileTranslation.y}, ${model.profileTranslation.z})")
Cobblemon.LOGGER.info("override var profileScale = ${model.profileScale}F")
}
super.close()
}
}
@@ -1,37 +0,0 @@
package com.cobblemon.mod.common.client.gui.tm
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.sound.SoundManager
import net.minecraft.text.Text
class DiscButton(
pX: Int, pY: Int,
onPress: PressAction,
): ButtonWidget(pX, pY, WIDTH.toInt(), HEIGHT.toInt(), Text.literal("All Types"), onPress, DEFAULT_NARRATION_SUPPLIER) {
companion object {
private const val WIDTH = 53F
private const val HEIGHT = 53F
val DISC_BUTTON = cobblemonResource("textures/gui/tm/disc_button.png")
}
override fun renderButton(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
blitk(
matrixStack = context.matrices,
texture = DISC_BUTTON,
x = x,
y = y,
width = WIDTH,
height = HEIGHT,
vOffset = if (isHovered(pMouseX.toDouble(), pMouseY.toDouble())) HEIGHT else 0,
textureHeight = HEIGHT * 2
)
}
override fun playDownSound(soundManager: SoundManager) {}
fun isHovered(mouseX: Double, mouseY: Double) = mouseX.toFloat() in (x.toFloat()..(x.toFloat() + WIDTH)) && mouseY.toFloat() in (y.toFloat()..(y.toFloat() + HEIGHT))
}
@@ -1,54 +0,0 @@
package com.cobblemon.mod.common.client.gui.tm
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.sound.SoundManager
import net.minecraft.text.Text
class EjectButton(
pX: Int, pY: Int,
val small: Boolean = false,
onPress: PressAction
): ButtonWidget(
pX,
pY,
if (small) SMALL_WIDTH.toInt() else LARGE_WIDTH.toInt(),
if (small) SMALL_HEIGHT.toInt() else LARGE_HEIGHT.toInt(),
Text.literal("Eject"),
onPress,
DEFAULT_NARRATION_SUPPLIER
) {
companion object {
private const val LARGE_WIDTH = 54F
private const val LARGE_HEIGHT = 14F
private const val SMALL_WIDTH = 14F
private const val SMALL_HEIGHT = 14F
val SMALL_BUTTON = cobblemonResource("textures/gui/tm/eject_button_small.png")
val LARGE_BUTTON = cobblemonResource("textures/gui/tm/eject_button_large.png")
}
val height = if (small) SMALL_HEIGHT else LARGE_HEIGHT
val width = if (small) SMALL_WIDTH else LARGE_WIDTH
val texture = if (small) SMALL_BUTTON else LARGE_BUTTON
override fun renderButton(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
blitk(
matrixStack = context.matrices,
texture = texture,
x = x,
y = y,
width = width,
height = height,
vOffset = if (isHovered(pMouseX.toDouble(), pMouseY.toDouble())) height else 0,
textureHeight = height * 2
)
}
override fun playDownSound(soundManager: SoundManager) {}
fun isHovered(mouseX: Double, mouseY: Double) = mouseX.toFloat() in (x.toFloat()..(x.toFloat() + width)) && mouseY.toFloat() in (y.toFloat()..(y.toFloat() + height))
}
@@ -1,59 +0,0 @@
package com.cobblemon.mod.common.client.gui.tm
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.tms.TechnicalMachine
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.client.render.renderScaledGuiItemIcon
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.sound.SoundManager
import net.minecraft.text.Text
class TMListingButton(
pX: Int, pY: Int,
onPress: PressAction,
val tm: TechnicalMachine
): ButtonWidget(pX, pY, WIDTH.toInt(), HEIGHT.toInt(), Text.literal("All Types"), onPress, DEFAULT_NARRATION_SUPPLIER) {
companion object {
private const val HEIGHT = 20F
private const val WIDTH = 140F
val TM_LISTING_BUTTON = cobblemonResource("textures/gui/tm/tm_selection_listing.png")
}
override fun renderButton(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
blitk(
matrixStack = context.matrices,
texture = TM_LISTING_BUTTON,
x = x,
y = y,
width = WIDTH,
height = HEIGHT,
vOffset = if (isHovered(pMouseX.toDouble(), pMouseY.toDouble())) HEIGHT else 0,
textureHeight = HEIGHT * 2
)
val item = CobblemonItems.TECHNICAL_MACHINE
renderScaledGuiItemIcon(
itemStack = item.setNbt(item.defaultStack, tm.id().toString()),
x = x.toDouble() + 2,
y = y.toDouble() + 2
)
drawScaledText(
context = context,
text = tm.translatedMoveName(),
x = x + 25,
y = y + 7.5,
scale = 0.75f
)
}
override fun playDownSound(soundManager: SoundManager) {}
fun isHovered(mouseX: Double, mouseY: Double) = mouseX.toFloat() in (x.toFloat()..(x.toFloat() + WIDTH)) && mouseY.toFloat() in (y.toFloat()..(y.toFloat() + HEIGHT))
}
@@ -1,611 +0,0 @@
package com.cobblemon.mod.common.client.gui.tm
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.CobblemonNetwork.sendPacketToServer
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.gui.ColourLibrary
import com.cobblemon.mod.common.api.gui.MultiLineLabelK
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.moves.Moves
import com.cobblemon.mod.common.api.reactive.SettableObservable
import com.cobblemon.mod.common.api.text.bold
import com.cobblemon.mod.common.api.tms.TechnicalMachine
import com.cobblemon.mod.common.api.tms.TechnicalMachineRecipe
import com.cobblemon.mod.common.api.types.ElementalType
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.block.TMBlock
import com.cobblemon.mod.common.block.entity.TMBlockEntity
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.gui.ExitButton
import com.cobblemon.mod.common.client.gui.MoveCategoryIcon
import com.cobblemon.mod.common.client.gui.TypeIcon
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.client.render.renderScaledGuiItemIcon
import com.cobblemon.mod.common.gui.TMMScreenHandler
import com.cobblemon.mod.common.net.messages.client.ui.CraftBlankTMPacket
import com.cobblemon.mod.common.net.messages.client.ui.CraftTMPacket
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.activestate.PokemonState
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.lang
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.Drawable
import net.minecraft.client.gui.Element
import net.minecraft.client.gui.Selectable
import net.minecraft.client.gui.screen.ingame.HandledScreen
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.registry.Registries
import net.minecraft.screen.ScreenHandler
import net.minecraft.screen.ScreenHandlerListener
import net.minecraft.text.Text
import net.minecraft.util.Identifier
class TMMHandledScreen(
val handler: TMMScreenHandler,
val inventory: PlayerInventory,
title: Text?
) : HandledScreen<TMMScreenHandler>(handler, inventory, title), ScreenHandlerListener {
companion object {
val TEXTURE_HEIGHT = 222
val TEXTURE_WIDTH = 254
val TYPE_MENU_MODE = 1
val TM_BROWSING_MODE = 2
val TYPE_SELECTION_BASE = cobblemonResource("textures/gui/tm/type_selection_base.png")
val TM_SELECTION_BASE = cobblemonResource("textures/gui/tm/tm_selection_base.png")
val TM_SELECTION_BORDER = cobblemonResource("textures/gui/tm/tm_selection_border.png")
val TM_SELECTION_LISTING = cobblemonResource("textures/gui/tm/tm_selection_listing.png")
val EJECT_BUTTON_SMALL = cobblemonResource("textures/gui/tm/eject_button_small.png")
val EJECT_BUTTON_LARGE = cobblemonResource("textures/gui/tm/eject_button_large.png")
val PARTY_SLOT = cobblemonResource("textures/gui/tm/party_slot.png")
val TEACH_BUTTON = cobblemonResource("textures/gui/tm/teach_button.png")
}
// val selectedTM: TechnicalMachine? = TechnicalMachines.tmMap[cobblemonResource("thunderbolt")]!!
var selectedTM: TechnicalMachine? = null
var tmList: SettableObservable<MutableList<TechnicalMachine>> = SettableObservable(mutableListOf())
var output: ItemStack? = null
val children: MutableMap<String, Element> = mutableMapOf()
var mode: Int = TYPE_MENU_MODE
var sortType: ElementalType? = null
var selectedPokemon: Pokemon? = null
var scroll: TMScrollingList? = null
init {
scroll = TMScrollingList(
x = x + 132,
y = y + 45,
parent = this
)
}
// val selectedTM = TechnicalMachine("stompingtantrum", null, emptyList(), "ground", null, null)
/**
* Used instead of `addDrawableChild()` to avoid re-drawing children.
*/
private fun <T> addChild(drawableElement: T, identifier: String) where T : Element, T : Drawable, T : Selectable {
if (children.contains(identifier)) return
addDrawableChild(drawableElement)
children[identifier] = drawableElement
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
if (scroll?.isHovered(mouseX, mouseY) == true) {
scroll!!.mouseClicked(mouseX, mouseY, button)
}
return super.mouseClicked(mouseX, mouseY, button)
}
override fun mouseScrolled(mouseX: Double, mouseY: Double, amount: Double): Boolean {
if (scroll?.isHovered(mouseX, mouseY) == true) {
scroll!!.mouseScrolled(mouseX, mouseY, amount)
return true
}
return false
}
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
if (mode != TYPE_MENU_MODE) scroll?.mouseDragged(
mouseX,
mouseY,
button,
deltaX,
deltaY
)
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
}
fun drawBlankCraftingRecipe(context: DrawContext) {
val x = (width - TEXTURE_WIDTH) / 2
val y = (height - TEXTURE_HEIGHT) / 2
// ingredient
renderScaledGuiItemIcon(
itemStack = Items.AMETHYST_SHARD.defaultStack,
x = (x + 197 + 36).toDouble(),
y = (y + 127).toDouble(),
zTranslation = 1f
)
drawScaledText(
context = context,
text = lang("ui.tms.material_cost"),
x = (x + 223),
y = (y + 117.5),
scale = 0.5f,
centered = true
)
drawScaledText(
context = context,
text = Text.translatable(CobblemonItems.BLANK_TM.translationKey).bold(),
x = (x + 223),
y = (y + 12),
scale = 0.5f,
centered = true
)
drawScaledText(
context = context,
text = lang("ui.power"),
x = (x + 199),
y = (y + 25),
scale = 0.5f
)
drawScaledText(
context = context,
text = Text.literal("-"),
x = (x + 241),
y = (y + 25),
scale = 0.5f,
centered = true
)
drawScaledText(
context = context,
text = lang("ui.accuracy_short"),
x = (x + 199),
y = (y + 35),
scale = 0.5f
)
drawScaledText(
context = context,
text = Text.literal("-"),
x = (x + 241),
y = (y + 35),
scale = 0.5f,
centered = true
)
drawScaledText(
context = context,
text = lang("ui.pp"),
x = (x + 199),
y = (y + 45),
scale = 0.5f
)
drawScaledText(
context = context,
text = Text.literal("-"),
x = (x + 241),
y = (y + 45),
scale = 0.5f,
centered = true
)
drawScaledText(
context = context,
text = lang("ui.summary.title"),
x = (x + 199),
y = (y + 54.5),
scale = 0.5f
)
val scale = 0.5f
context.matrices.push()
context.matrices.scale(scale, scale, 1f)
MultiLineLabelK.create(
component = lang("ui.tms.blank_tm_desc"),
width = 49 / scale,
maxLines = 7
).renderLeftAligned(
context = context,
x = (x + 199) / scale,
y = (y + 62) / scale,
ySpacing = 5.5 / scale,
colour = ColourLibrary.WHITE,
shadow = true
)
context.matrices.pop()
}
fun drawMoveInfo(context: DrawContext, delta: Float, mouseX: Int, mouseY: Int) {
val currentTm = selectedTM
if (currentTm == null) {
return drawBlankCraftingRecipe(context)
}
val x = (width - TEXTURE_WIDTH) / 2
val y = (height - TEXTURE_HEIGHT) / 2
val move = Moves.getByNameOrDummy(currentTm.moveName)
// blank tm
renderScaledGuiItemIcon(
itemStack = CobblemonItems.BLANK_TM.defaultStack,
x = (x + 197).toDouble(),
y = (y + 127).toDouble(),
)
val typeGem = Registries.ITEM.get(ElementalTypes.get(currentTm.type)?.typeGem).defaultStack
// type gem
renderScaledGuiItemIcon(
itemStack = typeGem ?: ItemStack.EMPTY,
x = (x + 197 + 18).toDouble(),
y = (y + 127).toDouble(),
)
val recipe = currentTm.recipe ?: TechnicalMachineRecipe(Identifier.of("minecraft", "air")!!, 1)
// ingredient
renderScaledGuiItemIcon(
itemStack = Registries.ITEM.get(recipe.item).defaultStack,
x = (x + 197 + 36).toDouble(),
y = (y + 127).toDouble(),
zTranslation = 1f
)
context.matrices.push()
context.matrices.translate(0f, 0f, 2f)
if (recipe.count > 1) {
val xIncrease = if (recipe.count < 10) 47 else 41
drawScaledText(
context = context,
text = Text.literal(recipe.count.toString()),
x = (x + 197 + xIncrease).toDouble(),
y = (y + 136).toDouble(),
shadow = true
)
}
context.matrices.pop()
drawScaledText(
context = context,
text = lang("ui.tms.material_cost"),
x = (x + 223),
y = (y + 117.5),
scale = 0.5f,
centered = true
)
drawScaledText(
context = context,
text = currentTm.translatedMoveName().bold(),
x = (x + 223),
y = (y + 12),
scale = 0.5f,
centered = true
)
MoveCategoryIcon(
x = (x + 237.5),
y = (y + 52.5),
category = Moves.getByNameOrDummy(currentTm.moveName).damageCategory
).render(context)
drawScaledText(
context = context,
text = lang("ui.power"),
x = (x + 199),
y = (y + 25),
scale = 0.5f
)
drawScaledText(
context = context,
text = Text.literal(move.power.toInt().toString()),
x = (x + 241),
y = (y + 25),
scale = 0.5f,
centered = true
)
drawScaledText(
context = context,
text = lang("ui.accuracy_short"),
x = (x + 199),
y = (y + 35),
scale = 0.5f
)
drawScaledText(
context = context,
text = Text.literal(move.accuracy.toInt().toString() + "%"),
x = (x + 241),
y = (y + 35),
scale = 0.5f,
centered = true
)
drawScaledText(
context = context,
text = lang("ui.pp"),
x = (x + 199),
y = (y + 45),
scale = 0.5f
)
drawScaledText(
context = context,
text = Text.literal(move.pp.toString()),
x = (x + 241),
y = (y + 45),
scale = 0.5f,
centered = true
)
drawScaledText(
context = context,
text = lang("ui.summary.title"),
x = (x + 199),
y = (y + 54.5),
scale = 0.5f
)
val scale = 0.5f
context.matrices.push()
context.matrices.scale(scale, scale, 1f)
MultiLineLabelK.create(
component = lang("move.${currentTm.moveName}.desc"),
width = 49 / scale,
maxLines = 7
).renderLeftAligned(
context = context,
x = (x + 199) / scale,
y = (y + 62) / scale,
ySpacing = 5.5 / scale,
colour = ColourLibrary.WHITE,
shadow = true
)
context.matrices.pop()
}
fun drawTypeMenu(context: DrawContext, delta: Float, mouseX: Int, mouseY: Int) {
val x = (width - TEXTURE_WIDTH) / 2
val y = (height - TEXTURE_HEIGHT) / 2
blitk(
matrixStack = context.matrices,
texture = TYPE_SELECTION_BASE,
x = x, // horizontal placement of GUI
y = y, // vertical placement of GUI
width = TEXTURE_WIDTH, // scale of the GUI width
height = TEXTURE_HEIGHT // scale of the GUI height
)
fun drawTypeRow(drawX: Int, drawY: Int, types: List<ElementalType>) {
var xOffset = 0
for (type in types) {
addChild(TypeButton(
pX = drawX + 32 + xOffset,
pY = drawY + 16,
type = type,
onPress = {
inventory.player.playSound(CobblemonSounds.GUI_CLICK, 1f, 1f)
tmList.set(TechnicalMachine.filterTms(null, type, null).toMutableList())
sortType = type
mode = TM_BROWSING_MODE
clearGUI()
scroll?.scrollAmount = 0.0
}
), "${type.name}type")
xOffset += 24
}
}
drawTypeRow(x, y, listOf(
ElementalTypes.NORMAL,
ElementalTypes.FIRE,
ElementalTypes.WATER,
ElementalTypes.GRASS,
ElementalTypes.ELECTRIC,
ElementalTypes.ICE
))
drawTypeRow(x + 12, y + 24, listOf(
ElementalTypes.FIGHTING,
ElementalTypes.POISON,
ElementalTypes.GROUND,
ElementalTypes.FLYING,
))
drawTypeRow(x, y + 48, listOf(
ElementalTypes.PSYCHIC,
ElementalTypes.BUG,
ElementalTypes.ROCK,
ElementalTypes.GHOST,
))
drawTypeRow(x + 12, y + 72, listOf(
ElementalTypes.DRAGON,
ElementalTypes.DARK,
ElementalTypes.STEEL,
ElementalTypes.FAIRY,
))
addChild(
DiscButton(
pX = x + 134,
pY = y + 50,
onPress = {
inventory.player.playSound(CobblemonSounds.GUI_CLICK, 1f, 1f)
tmList.set(TechnicalMachine.filterTms(null, null, null).toMutableList())
mode = TM_BROWSING_MODE
sortType = null
scroll?.scrollAmount = 0.0
clearGUI()
}
), "disc"
)
}
fun drawTmSelectMenu(context: DrawContext, delta: Float, mouseX: Int, mouseY: Int) {
val x = (width - TEXTURE_WIDTH) / 2
val y = (height - TEXTURE_HEIGHT) / 2
blitk(
matrixStack = context.matrices,
texture = TM_SELECTION_BASE,
x = x, // horizontal placement of GUI
y = y, // vertical placement of GUI
width = TEXTURE_WIDTH, // scale of the GUI width
height = TEXTURE_HEIGHT // scale of the GUI height
)
blitk(
matrixStack = context.matrices,
texture = TM_SELECTION_BORDER,
x = x + 31, // horizontal placement of GUI
y = y + 14, // vertical placement of GUI
width = 157,
height = 101
)
val displayType = sortType
addChild(
TypeButton(
pX = x + 31,
pY = y + 16,
type = displayType,
onPress = {
mode = TYPE_MENU_MODE
inventory.player.playSound(CobblemonSounds.GUI_CLICK, 1f, 1f)
clearGUI()
}
), "returnTypeMenu"
)
scroll?.render(context, mouseX, mouseY, delta)
}
fun clearGUI() {
val iterator = children.iterator()
while (iterator.hasNext()) {
val (id, _) = iterator.next()
iterator.remove()
children.remove(id)
}
clearChildren()
}
override fun drawBackground(context: DrawContext, delta: Float, mouseX: Int, mouseY: Int) {
super.renderBackground(context)
val x = (width - TEXTURE_WIDTH) / 2
val y = (height - TEXTURE_HEIGHT) / 2
blitk(
matrixStack = context.matrices,
texture = TYPE_SELECTION_BASE,
x = x, // horizontal placement of GUI
y = y, // vertical placement of GUI
width = TEXTURE_WIDTH, // scale of the GUI width
height = TEXTURE_HEIGHT // scale of the GUI height
)
when (mode) {
TYPE_MENU_MODE -> drawTypeMenu(context, delta, mouseX, mouseY)
else -> drawTmSelectMenu(context, delta, mouseX, mouseY)
}
drawMoveInfo(context, delta, mouseX, mouseY)
inventory.markDirty()
addChild(
EjectButton(
pX = x + 196,
pY = y + 168,
small = false,
onPress = {
inventory.player.playSound(CobblemonSounds.GUI_CLICK, 1f, 1f)
val currentTm = selectedTM ?: return@EjectButton sendPacketToServer(CraftBlankTMPacket(handler.input.getStack(2)))
sendPacketToServer(
CraftTMPacket(
currentTm,
handler.input.getStack(0),
handler.input.getStack(1),
handler.input.getStack(2)
)
)
this.handler.syncState()
}
), "eject"
)
addChild(
ExitButton(
pX = x + 228,
pY = y + 185,
onPress = {
this.close()
}
), "exit"
)
val startY = y + 13
val offset = 28
var iterations = 0
CobblemonClient.storage.myParty.forEach { pokemon ->
if (pokemon != null) {
addChild(TMPartySlotWidget(
pX = x - 23,
pY = startY + (offset * iterations),
pokemon = pokemon,
onPress = {
selectedPokemon = if (selectedPokemon == pokemon) null else pokemon
}
), "partyslot_${pokemon.uuid}")
}
iterations++
}
}
override fun drawForeground(context: DrawContext?, mouseX: Int, mouseY: Int) {
//Text is usually drawn here, we dont want that
this.drawMouseoverTooltip(context, mouseX - 158, mouseY - 28)
//this.renderWithTooltip(context, mouseX, mouseY, 1F)
}
override fun onSlotUpdate(handler: ScreenHandler?, slotId: Int, stack: ItemStack?) {
}
override fun close() {
super.close()
val inventory = handler.inventory
if (inventory is TMBlockEntity.TMBlockInventory) {
inventory.tmBlockEntity.blockState.with(TMBlock.ON,false)
}
}
override fun onPropertyUpdate(handler: ScreenHandler?, property: Int, value: Int) {
}
}
@@ -1,20 +0,0 @@
package com.cobblemon.mod.common.client.gui.tm
import com.cobblemon.mod.common.gui.TMMScreenHandler
import com.cobblemon.mod.common.util.giveOrDropItemStack
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.inventory.Inventory
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.screen.slot.Slot
class TMMOutputSlot(val screen: TMMScreenHandler, index: Int, x: Int, y: Int) : Slot(screen.playerInventory, index, x, y) {
override fun canInsert(stack: ItemStack?) = false
override fun onTakeItem(player: PlayerEntity, stack: ItemStack) {
player.giveOrDropItemStack(stack, false)
this.stack = Items.AIR.defaultStack
}
}
@@ -1,106 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.gui.tm
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.text.Text
import org.joml.Quaternionf
import org.joml.Vector3f
class TMPartySlotWidget(
pX: Number,
pY: Number,
val pokemon: Pokemon?,
onPress: PressAction
) : ButtonWidget(pX.toInt(), pY.toInt(), WIDTH, HEIGHT, Text.literal("PartyMember"), onPress, NarrationSupplier { "".text() }) {
companion object {
const val WIDTH = 46
const val HEIGHT = 27
private const val PORTRAIT_DIAMETER = 25
private val slotResource = cobblemonResource("textures/gui/tm/party_slot.png")
val genderIconMale = cobblemonResource("textures/gui/party/party_gender_male.png")
val genderIconFemale = cobblemonResource("textures/gui/party/party_gender_female.png")
}
private fun getSlotVOffset(pokemon: Pokemon?, isHovered: Boolean, isSelected: Boolean): Int {
if (isHovered || isSelected) {
if (pokemon == null) {
return 0
}
return height
}
return 0
}
override fun renderButton(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
hovered = mouseX >= x && mouseY >= y && mouseX < x + width && mouseY < y + height;
val matrices = context.matrices
blitk(
matrixStack = matrices,
texture = slotResource,
x = x,
y = y,
width = width,
height = height,
vOffset = getSlotVOffset(pokemon, isHovered, isSelected),
textureHeight = height * 2,
)
if (pokemon != null) {
val halfScale = 0.5F
// Render Pokémon
matrices.push()
matrices.translate(x + (PORTRAIT_DIAMETER / 2.0) + 10, y - 1.0, 0.0)
matrices.scale(2.5F, 2.5F, 1F)
drawProfilePokemon(
species = pokemon.species.resourceIdentifier,
aspects = pokemon.aspects.toSet(),
matrixStack = matrices,
rotation = Quaternionf().fromEulerXYZDegrees(Vector3f(13F, 35F, 0F)),
state = null,
scale = 4.5F,
partialTicks = delta
)
matrices.pop()
// Draw Name
drawScaledText(
context = context,
text = pokemon.getDisplayName(),
x = x + 16,
y = y + 21.5,
scale = halfScale
)
val ballIcon = cobblemonResource("textures/gui/ball/" + pokemon.caughtBall.name.path + ".png")
val ballHeight = 22
blitk(
matrixStack = matrices,
texture = ballIcon,
x = (x - 2) / halfScale,
y = (y - 3) / halfScale,
height = ballHeight,
width = 18,
textureHeight = ballHeight * 2,
scale = halfScale
)
}
}
}
@@ -1,158 +0,0 @@
package com.cobblemon.mod.common.client.gui.tm
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.tms.TechnicalMachine
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget
import net.minecraft.text.Text
class TMScrollingList(
val x: Int,
val y: Int,
val parent: TMMHandledScreen
) : AlwaysSelectedEntryListWidget<TMScrollingList.TMScrollingListEntry> (
MinecraftClient.getInstance(),
WIDTH, // width
HEIGHT, // height
0, // top
HEIGHT, // bottom
SLOT_HEIGHT// + SLOT_SPACING
) {
companion object {
const val WIDTH = 140
const val HEIGHT = 78
const val SLOT_WIDTH = 140
const val SLOT_HEIGHT = 20
const val SLOT_SPACING = 3
const val SCALE = 0.5f
}
private var scrolling = false
override fun getRowWidth() = SLOT_WIDTH
init {
correctSize()
setRenderHorizontalShadows(false)
setRenderBackground(false)
setRenderSelection(false)
parent.tmList.subscribeIncludingCurrent { tmList ->
val currentEntries = children()
val newTMs = tmList.filter { tm -> currentEntries.none { it.tm.id() == tm.id() } }
val removedTMs = currentEntries.filter { entry -> tmList.none { it.id() == entry.tm.id() } }
removedTMs.forEach(this::removeEntry)
newTMs.forEach { tm -> addEntry(TMScrollingListEntry(tm, parent)) }
}
}
override fun getScrollbarPositionX() = left + width - 3
private fun correctSize() {
updateSize(
WIDTH,
HEIGHT, y - 2, (y + 2) + (HEIGHT - 2))
setLeftPos(x)
}
public override fun addEntry(entry: TMScrollingListEntry) = super.addEntry(entry)
public override fun removeEntry(entry: TMScrollingListEntry) = super.removeEntry(entry)
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
correctSize()
context.enableScissor(
left,
top + 5,
left + width,
top + 1 + height
)
super.render(context, mouseX, mouseY, delta)
context.disableScissor()
}
fun isHovered(mouseX: Double, mouseY: Double): Boolean {
println(mouseX.toFloat() in (x.toFloat()..(x.toFloat() + WIDTH)) && mouseY.toFloat() in (y.toFloat()..(y.toFloat() + HEIGHT)))
return mouseX.toFloat() in (x.toFloat()..(x.toFloat() + WIDTH)) && mouseY.toFloat() in (y.toFloat()..(y.toFloat() + HEIGHT))
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
updateScrollingState(mouseX, mouseY)
if (scrolling) {
focused = getEntryAtPosition(mouseX, mouseY)
isDragging = true
}
return super.mouseClicked(mouseX, mouseY, button)
}
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
if (scrolling) {
if (mouseY < top) {
scrollAmount = 0.0
} else if (mouseY > bottom) {
scrollAmount = maxScroll.toDouble()
} else {
scrollAmount += deltaY
}
}
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
}
private fun updateScrollingState(mouseX: Double, mouseY: Double) {
scrolling = mouseX >= this.scrollbarPositionX.toDouble()
&& mouseX < (this.scrollbarPositionX + 3).toDouble()
&& mouseY >= top
&& mouseY < bottom
}
class TMScrollingListEntry(val tm: TechnicalMachine, private val parent: TMMHandledScreen) : Entry<TMScrollingListEntry>() {
private val tmButton: TMListingButton = TMListingButton(
pX = 0,
pY = 0,
onPress = {
parent.selectedTM = tm
parent.inventory.player.playSound(CobblemonSounds.GUI_CLICK, 1f, 1f)
},
tm = tm
)
override fun render(
context: DrawContext,
index: Int,
rowTop: Int,
rowLeft: Int,
rowWidth: Int,
rowHeight: Int,
mouseX: Int,
mouseY: Int,
isHovered: Boolean,
tickDelta: Float
) {
val x = rowLeft
val y = rowTop
val matrixStack = context.matrices
// Render just this TMListingButton
tmButton.setPosition(x + 1, y)
tmButton.render(context, mouseX, mouseY, tickDelta)
}
override fun mouseClicked(mouseX: Double, mouseY: Double, delta: Int): Boolean {
if (tmButton.isHovered(mouseX, mouseY)) {
tmButton.onPress()
return true
}
return false
}
override fun getNarration(): Text {
TODO("Not yet implemented")
}
}
}
@@ -1,69 +0,0 @@
package com.cobblemon.mod.common.client.gui.tm
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.types.ElementalType
import com.cobblemon.mod.common.client.gui.TypeIcon
import com.cobblemon.mod.common.client.gui.TypeReturnIcon
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.sound.SoundInstance
import net.minecraft.client.sound.SoundManager
class TypeButton(
pX: Int, pY: Int,
onPress: PressAction,
val type: ElementalType?
): ButtonWidget(pX, pY, WIDTH.toInt(), HEIGHT.toInt(), type?.displayName, onPress, DEFAULT_NARRATION_SUPPLIER) {
companion object {
private const val WIDTH = 24F
private const val HEIGHT = 24F
val TYPE_BUTTON = cobblemonResource("textures/gui/tm/type_button.png")
}
override fun renderButton(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
blitk(
matrixStack = context.matrices,
texture = TYPE_BUTTON,
x = x,
y = y,
width = WIDTH,
height = HEIGHT,
vOffset = if (isHovered(pMouseX.toDouble(), pMouseY.toDouble())) HEIGHT else 0,
textureHeight = HEIGHT * 2
)
context.matrices.push()
context.matrices.scale(2f, 2f, 2f)
if (type != null) {
TypeIcon(
x = (x + 12.125) / 2,
y = (y + 3) / 2,
type = type,
centeredX = true,
small = true
).render(context)
}
else {
TypeReturnIcon(
x = (x + 12.125) / 2,
y = (y + 3) / 2,
centeredX = true,
small = true
).render(context)
}
context.matrices.pop()
}
override fun playDownSound(soundManager: SoundManager) {
}
fun isHovered(mouseX: Double, mouseY: Double) = mouseX.toFloat() in (x.toFloat()..(x.toFloat() + WIDTH)) && mouseY.toFloat() in (y.toFloat()..(y.toFloat() + HEIGHT))
}
@@ -8,11 +8,14 @@
package com.cobblemon.mod.common.client.keybind
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.client.keybind.keybinds.DebugKeybindings
import com.cobblemon.mod.common.client.keybind.keybinds.DownShiftPartyBinding
import com.cobblemon.mod.common.client.keybind.keybinds.HidePartyBinding
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding
import com.cobblemon.mod.common.client.keybind.keybinds.SummaryBinding
import com.cobblemon.mod.common.client.keybind.keybinds.UpShiftPartyBinding
import com.cobblemon.mod.common.config.CobblemonConfig
import com.cobblemon.mod.common.platform.events.PlatformEvents
import net.minecraft.client.option.KeyBinding
@@ -23,13 +26,17 @@ import net.minecraft.client.option.KeyBinding
* @since 2022-02-17
*/
object CobblemonKeyBinds {
private val keyBinds = arrayListOf<CobblemonKeyBinding>()
init {
PlatformEvents.CLIENT_TICK_POST.subscribe { this.onTick() }
if (Cobblemon.config.enableDebugKeys) {
DebugKeybindings.keybindings.forEach {
this.queue(it)
}
}
}
private val keyBinds = arrayListOf<CobblemonKeyBinding>()
val HIDE_PARTY = this.queue(HidePartyBinding)
// ToDo enable again down the line
//val POKENAV = this.queue(PokeNavigatorBinding)
@@ -9,7 +9,9 @@
package com.cobblemon.mod.common.client.keybind
import com.cobblemon.mod.common.api.text.red
import com.cobblemon.mod.common.api.text.yellow
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.keybind.keybinds.SummaryBinding
import com.cobblemon.mod.common.net.messages.server.starter.RequestStarterScreenPacket
import com.cobblemon.mod.common.util.lang
import net.minecraft.client.MinecraftClient
@@ -25,12 +27,20 @@ abstract class CobblemonPartyLockedKeyBinding(
category: String
) : CobblemonKeyBinding(name, type, key, category) {
private var skippedStarterSelectionMessageShown = false
override fun onTick() {
if (this.wasPressed() && this.hasPartyMembers()) {
this.onPress()
}
}
/**
* Checks if the player has any party members, and
*
* - Handles the starter selection if the player doesn't have any party members.
* - Shows a message if the player initially skipped the starter selection.
*/
private fun hasPartyMembers(): Boolean {
val havePokemon = CobblemonClient.storage.myParty.slots.any { it != null }
val starterSelected = CobblemonClient.clientPlayerData.starterSelected
@@ -42,6 +52,18 @@ abstract class CobblemonPartyLockedKeyBinding(
RequestStarterScreenPacket().sendToServer()
}
return false
} else if (!startersLocked && !starterSelected && havePokemon) {
if (!skippedStarterSelectionMessageShown) {
MinecraftClient.getInstance().player?.sendMessage(
lang(
"ui.starter.skippedchoosing",
SummaryBinding.boundKey().localizedText
).yellow(), false
)
/** Only show the info message about skipping the selection once per MC instance */
skippedStarterSelectionMessageShown = true
}
return true
}
return true
}
@@ -10,4 +10,5 @@ package com.cobblemon.mod.common.client.keybind
object KeybindCategories {
const val COBBLEMON_CATEGORY = "key.cobblemon.categories.cobblemon"
const val COBBLEMON_DEBUG_CATEGORY = "key.cobblemon.categories.cobblemon.debug"
}
@@ -0,0 +1,140 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.keybind.keybinds
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.keybind.CobblemonKeyBinding
import com.cobblemon.mod.common.client.keybind.KeybindCategories
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokemonModelRepository
import net.minecraft.client.MinecraftClient
import net.minecraft.client.util.InputUtil
import net.minecraft.text.Text
object DebugKeybindings {
val keybindings = listOf(
ScaleUpKeybinding(),
ScaleDownKeybinding(),
TranslateLeftKeybinding(),
TranslateRightKeybinding(),
TranslateUpKeybinding(),
TranslateDownKeybinding(),
PrintModelSettingsKeybinding()
)
class ScaleUpKeybinding(): CobblemonKeyBinding(
"key.cobblemon.scaleportraitup",
InputUtil.Type.KEYSYM,
InputUtil.GLFW_KEY_EQUAL,
KeybindCategories.COBBLEMON_DEBUG_CATEGORY
) {
override fun onPress() {
val currentlySelectedPokemon = CobblemonClient.storage.myParty.get(CobblemonClient.storage.selectedSlot)
if (currentlySelectedPokemon != null) {
val model = PokemonModelRepository.getPoser(currentlySelectedPokemon.species.resourceIdentifier, currentlySelectedPokemon.aspects)
model.portraitScale += 0.01F
}
}
}
class ScaleDownKeybinding(): CobblemonKeyBinding(
"key.cobblemon.scaleportraitdown",
InputUtil.Type.KEYSYM,
InputUtil.GLFW_KEY_MINUS,
KeybindCategories.COBBLEMON_DEBUG_CATEGORY
) {
override fun onPress() {
val currentlySelectedPokemon = CobblemonClient.storage.myParty.get(CobblemonClient.storage.selectedSlot)
if (currentlySelectedPokemon != null) {
val model = PokemonModelRepository.getPoser(currentlySelectedPokemon.species.resourceIdentifier, currentlySelectedPokemon.aspects)
model.portraitScale -= 0.01F
}
}
}
class TranslateUpKeybinding: CobblemonKeyBinding(
"key.cobblemon.translateportraitup",
InputUtil.Type.KEYSYM,
InputUtil.GLFW_KEY_I,
KeybindCategories.COBBLEMON_DEBUG_CATEGORY
) {
override fun onPress() {
val currentlySelectedPokemon = CobblemonClient.storage.myParty.get(CobblemonClient.storage.selectedSlot)
if (currentlySelectedPokemon != null) {
val model = PokemonModelRepository.getPoser(currentlySelectedPokemon.species.resourceIdentifier, currentlySelectedPokemon.aspects)
model.portraitTranslation = model.portraitTranslation.add(0.0, -0.01, 0.0)
}
}
}
class TranslateDownKeybinding(): CobblemonKeyBinding(
"key.cobblemon.translateportraitdown",
InputUtil.Type.KEYSYM,
InputUtil.GLFW_KEY_K,
KeybindCategories.COBBLEMON_DEBUG_CATEGORY
) {
override fun onPress() {
val currentlySelectedPokemon = CobblemonClient.storage.myParty.get(CobblemonClient.storage.selectedSlot)
if (currentlySelectedPokemon != null) {
val model = PokemonModelRepository.getPoser(currentlySelectedPokemon.species.resourceIdentifier, currentlySelectedPokemon.aspects)
model.portraitTranslation = model.portraitTranslation.add(0.0, 0.01, 0.0)
}
}
}
class TranslateLeftKeybinding(): CobblemonKeyBinding(
"key.cobblemon.translateportraitleft",
InputUtil.Type.KEYSYM,
InputUtil.GLFW_KEY_J,
KeybindCategories.COBBLEMON_DEBUG_CATEGORY
) {
override fun onPress() {
val currentlySelectedPokemon = CobblemonClient.storage.myParty.get(CobblemonClient.storage.selectedSlot)
if (currentlySelectedPokemon != null) {
val model = PokemonModelRepository.getPoser(currentlySelectedPokemon.species.resourceIdentifier, currentlySelectedPokemon.aspects)
model.portraitTranslation = model.portraitTranslation.add(-0.01, 0.0, 0.0)
}
}
}
class TranslateRightKeybinding(): CobblemonKeyBinding(
"key.cobblemon.translateportraitright",
InputUtil.Type.KEYSYM,
InputUtil.GLFW_KEY_L,
KeybindCategories.COBBLEMON_DEBUG_CATEGORY
) {
override fun onPress() {
val currentlySelectedPokemon = CobblemonClient.storage.myParty.get(CobblemonClient.storage.selectedSlot)
if (currentlySelectedPokemon != null) {
val model = PokemonModelRepository.getPoser(currentlySelectedPokemon.species.resourceIdentifier, currentlySelectedPokemon.aspects)
model.portraitTranslation = model.portraitTranslation.add(0.01, 0.0, 0.0)
}
}
}
class PrintModelSettingsKeybinding() : CobblemonKeyBinding(
"key.cobblemon.printmodelsettings",
InputUtil.Type.KEYSYM,
InputUtil.GLFW_KEY_PERIOD,
KeybindCategories.COBBLEMON_DEBUG_CATEGORY
) {
override fun onPress() {
val currentlySelectedPokemon = CobblemonClient.storage.myParty.get(CobblemonClient.storage.selectedSlot)
if (currentlySelectedPokemon != null) {
val model = PokemonModelRepository.getPoser(currentlySelectedPokemon.species.resourceIdentifier, currentlySelectedPokemon.aspects)
MinecraftClient.getInstance().player?.sendMessage(Text.of("Portrait Translation: ${model.portraitTranslation}"))
MinecraftClient.getInstance().player?.sendMessage(Text.of("Portrait Scale: ${model.portraitScale}"))
Cobblemon.LOGGER.info("override var portraitTranslation = Vec3d(${model.portraitTranslation.x}, ${model.portraitTranslation.y}, ${model.portraitTranslation.z})")
Cobblemon.LOGGER.info("override var portraitScale = ${model.portraitScale}F")
}
}
}
}
@@ -1,30 +0,0 @@
package com.cobblemon.mod.common.client.net.gui
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.gui.TMMScreenHandler
import com.cobblemon.mod.common.net.messages.client.ui.CraftBlankTMPacket
import com.cobblemon.mod.common.util.playSoundServer
import net.minecraft.item.Items
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.sound.SoundCategory
object CraftBlankTMPacketHandler : ServerNetworkPacketHandler<CraftBlankTMPacket> {
override fun handle(packet: CraftBlankTMPacket, server: MinecraftServer, player: ServerPlayerEntity) {
val screen = player.currentScreenHandler as TMMScreenHandler
val ingredientSlot = screen.input.getStack(2)
if (ingredientSlot.isOf(Items.AMETHYST_SHARD) && ingredientSlot.count >= 1) {
screen.input.removeStack(2, 1)
screen.result.setStack(0, CobblemonItems.BLANK_TM.defaultStack)
screen.input.markDirty()
screen.result.markDirty()
player.currentScreenHandler.syncState()
player.world.playSoundServer(player.pos, CobblemonSounds.TMM_CRAFT_BLANK, SoundCategory.BLOCKS)
}
}
}
@@ -1,60 +0,0 @@
package com.cobblemon.mod.common.client.net.gui
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.gui.TMMScreenHandler
import com.cobblemon.mod.common.item.TechnicalMachineItem
import com.cobblemon.mod.common.net.messages.client.ui.CraftTMPacket
import com.cobblemon.mod.common.util.playSoundServer
import net.minecraft.item.Items
import net.minecraft.registry.Registries
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.sound.SoundCategory
object CraftTMPacketHandler : ServerNetworkPacketHandler<CraftTMPacket> {
override fun handle(packet: CraftTMPacket, server: MinecraftServer, player: ServerPlayerEntity) {
val screen = player.currentScreenHandler as TMMScreenHandler
val discSlot = screen.inventory?.getStack(0)
val gemSlot = screen.inventory?.getStack(1)
val ingredientSlot = screen.inventory?.getStack(2)
val outputSlot = screen.result.getStack(0)
val typeGem = Registries.ITEM.get(ElementalTypes.get(packet.tm.type)?.typeGem)
print("test")
if (!outputSlot.isEmpty) return
if (discSlot != null) {
if (!discSlot.isOf(CobblemonItems.BLANK_TM)) return
}
if (gemSlot != null) {
if (!gemSlot.isOf(typeGem)) return
}
if (packet.tm.recipe != null) {
if (ingredientSlot != null) {
if (!ingredientSlot.isOf(Registries.ITEM.get(packet.tm.recipe.item))) return
}
if (ingredientSlot != null) {
if (ingredientSlot.count < packet.tm.recipe.count) return
}
}
val item = CobblemonItems.TECHNICAL_MACHINE.defaultStack
item.getOrCreateNbt().putString(TechnicalMachineItem.STORED_MOVE_KEY, packet.tm.id().toString())
screen.result.setStack(0, item)
screen.inventory?.removeStack(0, 1)
screen.inventory?.removeStack(1, 1)
if (packet.tm.recipe != null) {
screen.inventory?.removeStack(2, packet.tm.recipe.count)
}
screen.input.markDirty()
screen.result.markDirty()
player.currentScreenHandler.syncState()
player.world.playSoundServer(player.pos, CobblemonSounds.TMM_CRAFT, SoundCategory.BLOCKS)
}
}
@@ -1,13 +0,0 @@
package com.cobblemon.mod.common.client.net.gui
import com.cobblemon.mod.common.api.net.ClientNetworkPacketHandler
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
import com.cobblemon.mod.common.net.messages.client.ui.OpenTMMPacket
import net.minecraft.client.MinecraftClient
object OpenTMMPacketHandler : ClientNetworkPacketHandler<OpenTMMPacket>
{
override fun handle(packet: OpenTMMPacket, client: MinecraftClient) {
//client.setScreen()
}
}
@@ -189,8 +189,8 @@ class SnowstormParticle(
viewDirection = viewDirection
)
val xSize = storm.runtime.resolveDouble(storm.effect.particle.sizeX).toFloat()
val ySize = storm.runtime.resolveDouble(storm.effect.particle.sizeY).toFloat()
val xSize = storm.runtime.resolveDouble(storm.effect.particle.sizeX).toFloat() / 1.5.toFloat()
val ySize = storm.runtime.resolveDouble(storm.effect.particle.sizeY).toFloat() / 1.5.toFloat()
val particleVertices = arrayOf(
Vector3f(-xSize, -ySize, 0.0f),
@@ -72,7 +72,7 @@ class RestorationTankRenderer(ctx: BlockEntityRendererFactory.Context) : BlockEn
val fluidModel = if (struct.isRunning()) FLUID_MODELS[8]
else if (struct.createdPokemon != null) FLUID_MODELS[7]
else FLUID_MODELS[fillLevel-1]
else FLUID_MODELS[fillLevel.coerceAtMost(FLUID_MODELS.size - 1) - 1]
fluidModel.getQuads(entity.cachedState, null, entity.world?.random).forEach { quad ->
transparentBuffer?.quad(matrices.peek(), quad, 0.75f, 0.75f, 0.75f, light, OverlayTexture.DEFAULT_UV)
}
@@ -1,78 +0,0 @@
package com.cobblemon.mod.common.client.render.block
import com.cobblemon.mod.common.api.text.blue
import com.cobblemon.mod.common.api.text.green
import com.cobblemon.mod.common.api.text.red
import com.cobblemon.mod.common.api.tms.TechnicalMachines
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.block.TMBlock
import com.cobblemon.mod.common.block.entity.TMBlockEntity
import com.cobblemon.mod.common.client.CobblemonBakingOverrides
import com.cobblemon.mod.common.client.render.layer.CobblemonRenderLayers
import com.cobblemon.mod.common.client.render.models.blockbench.repository.MiscModelRepository
import com.cobblemon.mod.common.client.render.models.blockbench.setRotation
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.math.geometry.Axis
import net.minecraft.client.MinecraftClient
import net.minecraft.client.render.LightmapTextureManager
import net.minecraft.client.render.OverlayTexture
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.VertexConsumerProvider
import net.minecraft.client.render.block.entity.BlockEntityRenderer
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.util.math.Direction
import net.minecraft.util.math.RotationAxis
import java.awt.Color
import kotlin.math.sin
class TMBlockRenderer(context: BlockEntityRendererFactory.Context) : BlockEntityRenderer<TMBlockEntity> {
//TODO Do the render optimizations that we do for berries and fossils
override fun render(
entity: TMBlockEntity,
tickDelta: Float,
matrices: MatrixStack,
vertexConsumers: VertexConsumerProvider,
light: Int,
overlay: Int
) {
val diskModel = MiscModelRepository.modelOf(MODEL_ID)
matrices.push()
val tm = entity.tmmInventory.filterTM?.let {
TechnicalMachines.getTechnicalMachineFromStack(
it
)
}
entity.partialTicks += tickDelta
val color = tm?.let { Color(ElementalTypes.get(it.type)!!.hue) } ?: Color.WHITE
when (entity.cachedState.get(TMBlock.FACING)) {
Direction.SOUTH -> matrices.translate(15F / 16F, 5.5F / 16F, 1F / 16F)
Direction.WEST -> matrices.translate(14F / 16F, 5.5F / 16F, 0F)
Direction.EAST -> matrices.translate(1F, 5.5F / 16F, 0F)
else -> matrices.translate(15F / 16F, 5.5F / 16F, -1F / 16F)
}
matrices.translate(-7.0/16f, 0.0, 8.0/16f)
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees( entity.partialTicks / 0.5f))
matrices.translate(7.0/16f, 0.0, -8.0/16f)
val renderLayer = RenderLayer.getEntityCutout(cobblemonResource("textures/block/tm_machine.png"))
diskModel?.render(
matrices,
vertexConsumers.getBuffer(renderLayer),
light,
overlay,
color.red.toFloat() / 255F,
color.green.toFloat() / 255F,
color.blue.toFloat() / 255F,
1.0F
)
matrices.pop()
}
companion object {
val MODEL_ID = cobblemonResource("tm_disk.geo")
}
}
@@ -40,27 +40,6 @@ object CobblemonRenderLayers {
multiPhaseParameters
)
}
val TM_BLOCK_LAYER = run {
val multiPhaseParameters = RenderLayer.MultiPhaseParameters.builder()
.lightmap(ENABLE_LIGHTMAP)
.program(CUTOUT_PROGRAM)
.texture(Texture(
cobblemonResource("textures/misc/tm_machine"),
false,
true
))
.cull(DISABLE_CULLING)
.build(true)
RenderLayer.of(
"tm_block",
VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL,
VertexFormat.DrawMode.QUADS,
512,
true,
false,
multiPhaseParameters
)
}
val ENTITY_TRANSLUCENT: BiFunction<Identifier, Boolean, RenderLayer> = Util.memoize { texture: Identifier, affectsOutline: kotlin.Boolean ->
var multiPhaseParameters: RenderLayer.MultiPhaseParameters =
@@ -18,7 +18,6 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.addFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.getQueryStruct
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.scheduling.afterOnClient
import com.cobblemon.mod.common.client.ClientMoLangFunctions.setupClient
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.MatrixWrapper
@@ -46,6 +45,7 @@ import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.getDoubleOrNull
import com.cobblemon.mod.common.util.getStringOrNull
import com.cobblemon.mod.common.util.plus
import net.minecraft.client.model.ModelPart
import net.minecraft.client.render.OverlayTexture
import net.minecraft.client.render.RenderLayer
@@ -697,6 +697,7 @@ abstract class PoseableEntityModel<T : Entity>(
val portion = (state.animationSeconds - primaryAnimation.started) / primaryAnimation.duration
state.primaryOverridePortion = 1 - primaryAnimation.curve(portion)
if (!primaryAnimation.run(entity, this, state, limbSwing, limbSwingAmount, ageInTicks, headYaw, headPitch, 1 - state.primaryOverridePortion)) {
primaryAnimation.afterAction.accept(Unit)
state.primaryAnimation = null
state.primaryOverridePortion = 1F
}
@@ -715,6 +716,7 @@ abstract class PoseableEntityModel<T : Entity>(
//This is used to set additional entity type specific context
open fun setupEntityTypeContext(entity: T?) {}
//Called by LivingEntityRenderer's render method before calling model.render (which is this.render in this case)
override fun setAngles(
entity: T,
limbSwing: Float,
@@ -745,19 +747,16 @@ abstract class PoseableEntityModel<T : Entity>(
curve = { 1F }
)
state.addPrimaryAnimation(primaryAnimation)
afterOnClient(seconds = primaryAnimation.duration) {
primaryAnimation.afterAction += {
state.setPose(desirablePose.poseName)
if (state.primaryAnimation == primaryAnimation) {
state.primaryAnimation = null
}
}
} else if (transition != null) {
val animation = transition(previousPose, desirablePose)
val primaryAnimation = if (animation is PrimaryAnimation) animation else PrimaryAnimation(animation, curve = { 1F })
state.addPrimaryAnimation(primaryAnimation)
afterOnClient(seconds = primaryAnimation.duration) {
primaryAnimation.afterAction += {
state.setPose(desirablePose.poseName)
}
state.addPrimaryAnimation(primaryAnimation)
} else {
state.setPose(poses.values.first { desirablePoseType in it.poseTypes && (it.condition == null || (entity != null && it.condition.invoke(entity))) }.poseName)
}
@@ -56,6 +56,8 @@ import net.minecraft.util.math.Vec3d
* handling all the state for an entity's model, and needs to be conscious of the fact that the
* model may change without this state changing.
*
* This also handles setting up the molang runtime that animations have access to
*
* @author Hiroku
* @since December 5th, 2021
*/
@@ -164,6 +166,11 @@ abstract class PoseableEntityState<T : Entity> : Schedulable {
val previousAge = age
updateAge(age + 1)
runEffects(entity, previousAge, age)
val primaryAnimation = primaryAnimation ?: return
if (primaryAnimation.started + primaryAnimation.duration <= animationSeconds) {
this.primaryAnimation = null
primaryAnimation.afterAction.accept(Unit)
}
}
abstract fun updatePartialTicks(partialTicks: Float)
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityMo
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityState
import com.cobblemon.mod.common.client.render.models.blockbench.frame.ModelFrame
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunction
import java.util.function.Consumer
import net.minecraft.entity.Entity
/**
@@ -39,6 +40,7 @@ class PrimaryAnimation<T : Entity>(
): StatefulAnimation<T, ModelFrame> {
var started = -1F
override val duration: Float = animation.duration
var afterAction: Consumer<Unit> = Consumer { }
override fun run(
entity: T?,
@@ -15,7 +15,7 @@ import net.minecraft.entity.Entity
/**
* An animation that can run without an entity associated. These are
* locked to a specific frame, and CAN be given an entity along with
* locked to a specific [ModelFrame], and CAN be given an entity along with
* limb swing and age information, but might not.
*
* @author Hiroku
@@ -32,11 +32,11 @@ class BlockEntityModel(val root: Bone) : PoseableEntityModel<Entity>() {
)
closedPose.transitions[openPose.poseName] = { _, _ ->
bedrockStateful("gilded_chest", "opening").andThen { _, state -> state.setPose(openPose.poseName) }
bedrockStateful("gilded_chest", "opening")
}
openPose.transitions[closedPose.poseName] = { _, _ ->
bedrockStateful("gilded_chest", "closing").andThen { _, state -> state.setPose(closedPose.poseName) }
bedrockStateful("gilded_chest", "closing")
}
}
@@ -51,8 +51,8 @@ class AncientPokeBallModel(root: ModelPart) : PokeBallModel(root), PokeBallFrame
transformTicks = 0
)
shut.transitions[open.poseName] = { _, _ -> bedrockStateful("ancient_poke_ball", "open").andThen { entity, state -> state.setPose(open.poseName) } }
open.transitions[shut.poseName] = { _, _ -> bedrockStateful("ancient_poke_ball", "shut").andThen { entity, state -> state.setPose(shut.poseName) } }
shut.transitions[open.poseName] = { _, _ -> bedrockStateful("ancient_poke_ball", "open") }
open.transitions[shut.poseName] = { _, _ -> bedrockStateful("ancient_poke_ball", "shut") }
midair.transitions[open.poseName] = shut.transitions[open.poseName]!!
}
}
@@ -91,14 +91,18 @@ class JsonPokemonPoseableModel(override val rootPart: Bone) : PokemonPoseableMod
@SerializedName("profileTranslation")
private val _profileTranslation: Vec3d? = null
override val portraitScale
//Some weirdness going on here, vars have to be initialized, gson doesn't like multiple fields with the same name
@Transient
override var portraitScale = 1F
get() = _portraitScale ?: 1F
override val portraitTranslation
@Transient
override var portraitTranslation = Vec3d.ZERO
get() = _portraitTranslation ?: Vec3d(0.0, 0.0, 0.0)
override val profileScale
@Transient
override var profileScale = 1F
get() = _profileScale ?: 1F
override val profileTranslation
@Transient
override var profileTranslation = Vec3d.ZERO
get() = _profileTranslation ?: Vec3d(0.0, 0.0, 0.0)
@@ -56,14 +56,14 @@ abstract class PokemonPoseableModel : PoseableEntityModel<PokemonEntity>() {
}
@Transient
open val portraitScale: Float = 1F
open var portraitScale: Float = 1F
@Transient
open val portraitTranslation: Vec3d = Vec3d.ZERO
open var portraitTranslation: Vec3d = Vec3d.ZERO
@Transient
open val profileScale: Float = 1F
open var profileScale: Float = 1F
@Transient
open val profileTranslation: Vec3d = Vec3d.ZERO
open var profileTranslation: Vec3d = Vec3d.ZERO
open fun getFaintAnimation(
pokemonEntity: PokemonEntity,
@@ -24,11 +24,11 @@ class AbraModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("abra")
override val head = getPart("head")
override val portraitScale = 1.8F
override val portraitTranslation = Vec3d(0.0, 0.2, 0.0)
override var portraitScale = 1.8F
override var portraitTranslation = Vec3d(0.0, 0.2, 0.0)
override val profileScale = 0.85F
override val profileTranslation = Vec3d(0.0, 0.7, 0.0)
override var profileScale = 0.85F
override var profileTranslation = Vec3d(0.0, 0.7, 0.0)
lateinit var standing: PokemonPose
lateinit var walking: PokemonPose
@@ -20,11 +20,11 @@ class AerodactylModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("aerodactyl")
override val head = getPart("head")
override val portraitScale = 1.9F
override val portraitTranslation = Vec3d(-1.0, -0.65, 0.0)
override var portraitScale = 1.9F
override var portraitTranslation = Vec3d(-1.0, -0.65, 0.0)
override val profileScale = 0.55F
override val profileTranslation = Vec3d(0.0, 0.55, 0.0)
override var profileScale = 0.55F
override var profileTranslation = Vec3d(0.0, 0.55, 0.0)
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
@@ -30,11 +30,11 @@ class AlakazamModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Bipe
override val leftLeg = getPart("left_upper_leg")
override val rightLeg = getPart("right_upper_leg")
override val portraitScale = 1.75F
override val portraitTranslation = Vec3d(-0.25, 0.85, 0.0)
override var portraitScale = 1.75F
override var portraitTranslation = Vec3d(-0.25, 0.85, 0.0)
override val profileScale = 0.73F
override val profileTranslation = Vec3d(0.0, 0.65, 0.0)
override var profileScale = 0.73F
override var profileTranslation = Vec3d(0.0, 0.65, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
@@ -29,11 +29,11 @@ class ArbokModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("arbok")
override val head = getPart("head_ai")
override val portraitScale = 1.5F
override val portraitTranslation = Vec3d(-0.4, 1.0, 0.0)
override var portraitScale = 1.5F
override var portraitTranslation = Vec3d(-0.4, 1.0, 0.0)
override val profileScale = 0.67F
override val profileTranslation = Vec3d(0.0, 0.7, 0.0)
override var profileScale = 0.67F
override var profileTranslation = Vec3d(0.0, 0.7, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
@@ -27,11 +27,11 @@ class ArcanineModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Quad
override val hindLeftLeg = getPart("leg_back_left")
override val hindRightLeg = getPart("leg_back_right")
override val portraitScale = 1.5F
override val portraitTranslation = Vec3d(-0.4, 0.7, 0.0)
override var portraitScale = 1.5F
override var portraitTranslation = Vec3d(-0.4, 0.7, 0.0)
override val profileScale = 0.76F
override val profileTranslation = Vec3d(0.0, 0.57, 0.0)
override var profileScale = 0.76F
override var profileTranslation = Vec3d(0.0, 0.57, 0.0)
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
@@ -31,11 +31,11 @@ class ArticunoModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Bipe
override val leftWing = getPart("leftwing")
override val rightWing = getPart("rightwing")
override val portraitScale = 2.8F
override val portraitTranslation = Vec3d(-0.35, 0.6, 0.0)
override var portraitScale = 2.8F
override var portraitTranslation = Vec3d(-0.35, 0.6, 0.0)
override val profileScale = 0.85F
override val profileTranslation = Vec3d(0.0, 0.5, 0.0)
override var profileScale = 0.85F
override var profileTranslation = Vec3d(0.0, 0.5, 0.0)
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
@@ -28,11 +28,11 @@ class BeedrillModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, BiWi
override val leftWing = getPart("wing_left")
override val rightWing = getPart("wing_right")
override val portraitScale = 1.9F
override val portraitTranslation = Vec3d(0.05, 0.9, 0.0)
override var portraitScale = 1.9F
override var portraitTranslation = Vec3d(0.05, 0.9, 0.0)
override val profileScale = 0.8F
override val profileTranslation = Vec3d(-0.1, 0.9, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3d(-0.1, 0.9, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
@@ -21,11 +21,11 @@ class BellsproutModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("bellsprout")
override val head = getPart("head")
override val portraitScale = 2.0F
override val portraitTranslation = Vec3d(-0.1, 0.41, 0.0)
override var portraitScale = 2.0F
override var portraitTranslation = Vec3d(-0.1, 0.41, 0.0)
override val profileScale = 0.75F
override val profileTranslation = Vec3d(0.0, 0.64, 0.0)
override var profileScale = 0.75F
override var profileTranslation = Vec3d(0.0, 0.64, 0.0)
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
@@ -27,10 +27,10 @@ class BulbasaurModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Qua
override val hindLeftLeg = getPart("leg_back_left")
override val hindRightLeg = getPart("leg_back_right")
override val portraitScale = 2.0F
override val portraitTranslation = Vec3d(-0.26, -1.20, 0.0)
override val profileScale = 0.9F
override val profileTranslation = Vec3d(0.0, 0.4, 0.0)
override var portraitScale = 2.0F
override var portraitTranslation = Vec3d(-0.26, -1.20, 0.0)
override var profileScale = 0.9F
override var profileTranslation = Vec3d(0.0, 0.4, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
@@ -27,11 +27,11 @@ class ButterfreeModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Bi
val leftWingBack = getPart("wing_left2")
val rightWingBack = getPart("wing_right2")
override val portraitScale = 2.4F
override val portraitTranslation = Vec3d(-0.1, 0.2, 0.0)
override var portraitScale = 2.4F
override var portraitTranslation = Vec3d(-0.1, 0.2, 0.0)
override val profileScale = 0.7F
override val profileTranslation = Vec3d(0.1, 0.8, 0.0)
override var profileScale = 0.7F
override var profileTranslation = Vec3d(0.1, 0.8, 0.0)
lateinit var sleep: PokemonPose
@@ -25,10 +25,10 @@ class CaterpieModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("caterpie")
override val head = getPart("head")
override val portraitScale = 2.1F
override val portraitTranslation = Vec3d(-0.55, -1.55, 0.0)
override val profileScale = 0.8F
override val profileTranslation = Vec3d(0.0, 0.55, 0.0)
override var portraitScale = 2.1F
override var portraitTranslation = Vec3d(-0.55, -1.55, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3d(0.0, 0.55, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
@@ -8,13 +8,16 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityState
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
@@ -23,17 +26,27 @@ class ChanseyModel(root: ModelPart) : PokemonPoseableModel(), BipedFrame {
override val leftLeg = getPart("left_foot")
override val rightLeg = getPart("right_foot")
override val portraitScale = 1.5F
override val portraitTranslation = Vec3d(-0.35, 0.3, 0.0)
override var portraitScale = 1.5F
override var portraitTranslation = Vec3d(-0.35, 0.3, 0.0)
override val profileScale = 0.8F
override val profileTranslation = Vec3d(0.0, 0.55, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3d(0.0, 0.55, 0.0)
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
lateinit var sleep: PokemonPose
override fun registerPoses() {
val blink = quirk { bedrockStateful("chansey", "blink")}
val blink = quirk { bedrockStateful("chansey", "blink") }
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
idleAnimations = arrayOf(
bedrock("chansey", "ground_sleep")
)
)
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
@@ -49,15 +62,13 @@ class ChanseyModel(root: ModelPart) : PokemonPoseableModel(), BipedFrame {
transformTicks = 10,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
bedrock("chansey", "ground_idle"),
BipedWalkAnimation(this),
//bedrock("chansey", "ground_walk")
bedrock("chansey", "ground_walk")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PoseableEntityState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("chansey", "faint") else null
override fun getFaintAnimation(
pokemonEntity: PokemonEntity,
state: PoseableEntityState<PokemonEntity>
) = bedrockStateful("chansey", "faint")
}
@@ -34,11 +34,11 @@ class CharizardModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Bip
override val leftWing = getPart("wing_left")
override val rightWing = getPart("wing_right")
override val portraitScale = 1.9F
override val portraitTranslation = Vec3d(-0.5, 1.4, 0.0)
override var portraitScale = 1.9F
override var portraitTranslation = Vec3d(-0.5, 1.4, 0.0)
override val profileScale = 0.55F
override val profileTranslation = Vec3d(0.05, 0.93, 0.0)
override var profileScale = 0.55F
override var profileTranslation = Vec3d(0.05, 0.93, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose

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