Compare commits

...
Author SHA1 Message Date
dhi_holo ada7f0faf8 Missed some
should be all clean now
2025-06-07 16:11:43 +10:00
dhi_holo e1eff89259 Update en_us.json 2025-06-07 15:36:24 +10:00
dhi_holo cc149a0ff2 They're made of Copper!
We decided that the set name should be copper, so I renamed it all.
2025-06-07 15:35:10 +10:00
dhi_holo 3fea718766 Merge branch 'main' into mechanical-hands 2025-06-07 14:10:34 +10:00
Polymeta c99bf99052 correct pokemon model item offset and GUI lighting
Closes #1597

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-07 00:40:52 +01:00
Polymeta e8019a0623 make model loading not crash the game if a non-cobblemon model gets caught up in the parsing
Closes #1593

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-06 17:05:29 +01:00
Polymeta 4c95cfc1b3 some neoforge fixes
Closes #1437

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-06 16:19:54 +01:00
Polymeta 51a096913d simplify HeartyGrainsItem logic and update survival conditions for HeartyGrainsBlock to use tags
Closes #1591

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-06 11:58:23 +01:00
Polymeta 980d95819e make DrowsySensor consider sleep status to allow it to wake/sleep during battles no matter the time
Closes #1554
Closes #1596

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-06 01:19:34 +01:00
Polymeta 24aa65b2f1 Merge branch 'POLISH-POLISH' into 'main'
Little bit of refactoring

See merge request cable-mc/cobblemon!1699
2025-06-05 15:45:40 +00:00
Polymeta 19f33fe530 small cleanup and move component to correct place
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-05 16:02:32 +01:00
Polymeta bbe8a6948a fix license, refactor saplingblock and make falldamagemultiplier configurable
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-05 14:32:52 +01:00
Hiroku e46aaa5725 Merge branch 'party-select-tooltips' into 'main'
Adds a hoverText option to Party Select Callbacks.

See merge request cable-mc/cobblemon!1700
2025-06-05 11:08:34 +00:00
DeltricandHiroku fc6c302c71 Adds a hoverText option to Party Select Callbacks. 2025-06-05 11:08:34 +00:00
dhi_holo 76cf856907 Update CobblemonBlocks.kt
Didn't work properly, damn private classes
2025-06-05 20:46:43 +10:00
dhi_holo 145d56e205 Resolves Threads
I'm not done though, reverting the bale to a separate class makes me want to try learning something, if I can't work it out then no more commits
2025-06-05 20:10:20 +10:00
dhi_holo 969b070300 Very minor fix to kings rock model 2025-06-05 20:02:51 +10:00
Polymeta e474ef607c Ignore vitalspirit activation message
Closes #1595

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-04 14:29:24 +01:00
Polymeta a2ecccfac4 Merge branch 'Saccharine-Tree-Bee-Nest-Orientation-Fix' into 'main'
Saccharine tree bee nest orientation fix

See merge request cable-mc/cobblemon!1695
2025-06-04 13:15:39 +00:00
Polymeta 1a475bff87 fix two mons using old behaviour keys
Closes #1598

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-04 13:43:43 +01:00
Polymeta 8b6f5f55e6 Merge branch 'RaftsAndFlyingForSmartererPokemon' into 'main'
Battle flight migrated to brains, fixed illusion mobility for brains, fixed...

Closes #1496

See merge request cable-mc/cobblemon!1696
2025-06-04 10:43:47 +00:00
Polymeta 39ed65e8ca Merge branch 'main' into 'RaftsAndFlyingForSmartererPokemon'
# Conflicts:
#   common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
2025-06-04 10:43:06 +00:00
dhi_holo 35dab86ef4 Kings Rock Model Switch
Changing to the original model, rather than the newer one that causes more problems
2025-06-04 20:27:14 +10:00
dhi_holo 2cc14d26b1 leftover files
damn refactors missed a bit
2025-06-04 18:31:31 +10:00
dhi_holo c29da11541 Modern Major General
I prefer `general` as a term for block classes that exist to be a baseline for many blocks (in theory) to `varied`, so swapping that over
2025-06-04 18:29:08 +10:00
dhi_holo 8188ce0ed2 The Beningging
Refactoring some stuff to simplify down
2025-06-04 18:22:28 +10:00
JazzMcNade 301de140e3 canStandOnFluid now looks at the exposed form of the pokemon 2025-06-03 23:26:32 -05:00
dhi_holo 4a41060533 Merge branch 'main' into mechanical-hands 2025-06-04 09:36:07 +10:00
Polymeta ac55636c51 small recipe fix for loaded dice
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-03 23:31:49 +01:00
Polymeta 18eb50d4d2 Merge branch 'data-driven-brewing' into 'main'
Wrapped the Brewing Stand to allow Data Driven Recipes

See merge request cable-mc/cobblemon!1667
2025-06-03 13:22:44 +00:00
Aram 87276de14d Update CHANGELOG.md 2025-06-03 14:42:22 +02:00
Aram b7dc9ea6f6 Removed Unneccerry files 2025-06-03 14:30:34 +02:00
Aram ff59604526 Merge branch 'main' into data-driven-brewing 2025-06-03 14:27:40 +02:00
Polymeta b620ad27b6 rename OmniPathingEntity#isOnGround > entityOnGround to get around yarn mapping conflict
Fixes #1590

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-03 11:32:28 +01:00
dhi_holo 78daec9c7b Merge branch 'main' into mechanical-hands 2025-06-03 17:50:15 +10:00
Polymeta 5565f22610 Merge branch 'hyper_trained_ivs' into 'main'
Hyper Training Event and MoLang Functions

See merge request cable-mc/cobblemon!1689
2025-06-03 06:22:07 +00:00
Konoha DandPolymeta 7582b08d56 Hyper Training Event and MoLang Functions 2025-06-03 06:22:07 +00:00
Polymeta 2e101f023f Merge branch 'cleanup' into 'main'
Crash Fix

See merge request cable-mc/cobblemon!1697
2025-06-03 06:19:26 +00:00
dhi_holo d98cccfc0f Edit evolution_items.json 2025-06-03 16:12:46 +10:00
dhi_holo 07f087c35c Merge branch 'cleanup' into mechanical-hands 2025-06-03 14:39:02 +10:00
dhi_holo f83bde399c no crash
Removed some duplicates
2025-06-03 14:20:32 +10:00
dhi_holo 19f0bc29f4 Merge branch 'main' into mechanical-hands 2025-06-03 11:38:31 +10:00
dhi_holo 531f64394a Name Change Part 1
We know what they are now, what the series is called is still to be determined
2025-06-03 11:38:13 +10:00
JazzMcNade af77534b96 Removed escaped quotation marks 2025-06-02 20:01:30 -05:00
Karl Martin fa5193a3db Fix for bee nest entrances being blocked on saccharine trees 2025-06-02 22:06:10 +01:00
Polymeta e3c95aa4a5 Merge branch 'cooking-redstone' into 'main'
A ton of Redstone Compatibility inside the Cooking System

See merge request cable-mc/cobblemon!1640
2025-06-02 13:57:10 +00:00
AramandPolymeta 72740fb418 A ton of Redstone Compatibility inside the Cooking System 2025-06-02 13:57:10 +00:00
Paul 250f9e3cec Cleanup 2025-06-02 20:15:03 +10:00
Paul 26078ec29d Merge remote-tracking branch 'origin/main' 2025-06-02 20:09:11 +10:00
Paul 5b68889689 Fixed non-walking fliers not being able to wander 2025-06-02 20:09:00 +10:00
Paul bb3e86ac02 Fixed wander not being added to flying non-walkers 2025-06-02 20:08:21 +10:00
Polymeta b96a6282d8 Merge branch 'implement_pokemon' into 'main'
Fruity Implementation Merge to Main

See merge request cable-mc/cobblemon!1691
2025-06-02 08:18:00 +00:00
Frank The FarmerandPolymeta 14ee3cd754 Fruity Implementation Merge to Main 2025-06-02 08:17:59 +00:00
Paul 9c66c65b9e Merge remote-tracking branch 'origin/main' 2025-06-02 16:06:13 +10:00
Paul 9ffbd14a81 The wiki says it's called "artificial" 2025-06-02 16:06:03 +10:00
dhi_holo 7044cb35b2 jsons go grrr 2025-06-02 14:08:29 +10:00
dhi_holo e258d6439f Tops and Recipes 2025-06-02 13:53:06 +10:00
dhi_holo 221e51b023 Drops and Spin
Containers drop, fridge faces properly, new fridge texture
2025-06-02 12:20:29 +10:00
JazzMcNade 5053c765fb Merge branch 'main' into RaftsAndFlyingForSmartererPokemon 2025-06-01 17:20:39 -05:00
JazzMcNade bfe8d41102 Refactored BattleFlight as a OneShot Task, removed unnecessary memory flag. 2025-06-01 17:20:28 -05:00
dhi_holo c9fe117916 Cool
Fridge pseudo-working (visually, not functionally)
2025-06-01 21:13:20 +10:00
dhi_holo af3b6e3f2a Goes Brrr 2025-06-01 16:57:52 +10:00
dhi_holo 1b7759b77d Tweaks and fix ups 2025-06-01 13:05:09 +10:00
dhi_holo 698c07f0b8 Oven and Washer Work!
Yippee!!

They have the wrong behaviours, but it's still a major step towards these blocks being functional
2025-06-01 12:29:26 +10:00
JazzMcNade a4a094a624 spawnallpokemon no longer calls sendOut() 2025-05-31 21:29:13 -05:00
dhi_holo b0d2df2917 This was a Triumph
I'm making a note here, thank you landon.
2025-05-31 19:18:02 +10:00
dhi_holo f6ad1ab7aa what if i
blam
2025-05-31 17:50:09 +10:00
dhi_holo 3f85ce0c81 Merge branch 'main' into mechanical-hands 2025-05-30 17:13:03 +10:00
dhi_holo e25c3c3d7c Learning
Slowly trying stuff, mmmmm
2025-05-30 17:12:44 +10:00
JazzMcNade 0215a30c8d Battle flight migrated to brains, fixed illusion mobility for brains, fixed pokemon spawning with rafts outside of battle, 2025-05-30 01:17:56 -05:00
dhi_holo f16ec1d6d3 Backup
Is this me backing up my work or calling for backup? You'll never know, busy-body
2025-05-30 15:34:11 +10:00
dhi_holo 73e59159a0 Testable State again 2025-05-30 14:11:46 +10:00
dhi_holo 5b7b430e5f Data Start 2025-05-30 13:29:40 +10:00
dhi_holo 4e6f2973c2 Assets
Temporarily changed the mechanical oven to just be a regular block so that testing can be done, and added theoretically all needed assets for the appliances
2025-05-30 12:58:02 +10:00
dhi_holo 822794230d Help - Kobo Kanaeru
Major Struggles, so it's time to make this not local
2025-05-30 09:26:07 +10:00
dhi_holo d58603ff33 Mower
No functions at all, just a model with all the needed rotation behavior and nice decoration. No data, no lang.
2025-05-29 17:01:38 +10:00
dhi_holo 157532f372 Merge branch 'main' into mechanical-hands 2025-05-29 11:26:05 +10:00
dhi_holo 3a1c3fc934 Mechanical Fan (Simple)
Implemented a Mechanical Fan. No data files, no lang translation, no bonus functions beyond being able to turn it on and off. Still needs sound events.
2025-05-28 18:26:19 +10:00
Polymeta 43aa0ec04a oop this is not needed anymore
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-05-27 00:54:28 +01:00
Polymeta b4bf044f76 small refactors in mixins and JEI integration
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-05-27 00:49:26 +01:00
Aram 2e615800ae Update RecipeAwareSlot.java 2025-05-23 20:48:33 +02:00
Polymeta 4a4aaf3a94 fix mixin target for menu
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-05-23 17:03:33 +01:00
Aram 53ca8f009d Tried to Resolve getting the Level, sadly it checks twice, Server and Client, and Server is Null 2025-05-23 17:20:52 +02:00
Aram 5b5c756d3c Merge branch 'main' into data-driven-brewing 2025-05-23 14:24:38 +02:00
Aram 75410c3a72 Update BrewingStandBlockEntityMixin.java 2025-05-23 12:48:03 +02:00
Aram 87d001da80 Removed Client stuff from the server 2025-05-23 12:37:29 +02:00
Aram be466ad252 Oops 2025-05-21 12:23:13 +02:00
Aram d37d95ee70 Fixed the Build Error 2025-05-19 19:32:52 +02:00
Plastered_Crab 36cd5f3894 Merge remote-tracking branch 'origin/data-driven-brewing' into data-driven-brewing 2025-05-16 10:05:17 -07:00
Plastered_Crab b86f08b069 Merge branch 'main' into data-driven-brewing
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonRecipeCategories.kt
2025-05-16 10:04:03 -07:00
plastered_crab 75927fc1a9 licenses 2025-05-16 06:34:03 -07:00
Aram 628db514b3 Fixed JEI With Data Driven Brewing Stand Recipe 2025-05-16 03:29:44 +02:00
Aram 9046217867 Fixed the Recipe + Shift Clicking Items 2025-05-16 02:07:44 +02:00
Aram 09c7bd8e61 Added Last Recipe 2025-05-15 23:43:26 +02:00
Aram 8df8cb9cfe Added All Recipe 2025-05-15 23:38:52 +02:00
Aram c048e5752b Updated Recipes to allow Tags AND Item IDs 2025-05-15 23:33:57 +02:00
Aram e8aa06d633 Update super_potion_brewing_stand.json 2025-05-15 22:16:23 +02:00
Aram 64979ff742 Merge branch 'main' into data-driven-brewing 2025-05-15 22:14:55 +02:00
Aram 0163619e87 Made Potion Brewing Recipes, gotta get the Tags from Main 2025-05-15 22:14:48 +02:00
Aram 258ffd25ea Nuked the old Brewing Stand code, time to Refactor 2025-05-15 21:47:52 +02:00
Aram b7de250457 Merge branch 'data-mixin-brewing' into 'data-driven-brewing'
Rewrote Data Driven to Mixin

See merge request cable-mc/cobblemon!1666
2025-05-15 21:12:46 +02:00
Aram 8d0c5bc05c Rewrote Data Driven to Mixin 2025-05-15 21:12:45 +02:00
Aram 1ed4d9ff9a Shift Clicking items into the brewing stand is almost perfect! 2025-05-13 21:07:24 +02:00
Aram 8d0fc77be2 Update BrewingStandBlockMixin.java 2025-05-13 20:42:59 +02:00
Aram c45ef65645 Hard Coded Recipes still work to remain compatible with mods 2025-05-13 20:30:40 +02:00
Aram 0adfc64e35 DATAPACK BREWING STAND RECIPE HERE WE GO 2025-05-13 19:56:12 +02:00
Aram 80b4238c7e DATA DRIVEN RECIPE IN BREWING STAND 2025-05-13 19:55:55 +02:00
Aram f182cf4335 Update CobblemonRecipeCategories.kt 2025-05-13 17:38:51 +02:00
Aram f5840c4794 Nuked the Recipe Book 2025-05-13 17:38:45 +02:00
Aram 10e7962d85 Merge branch 'main' into data-driven-brewing 2025-05-13 14:39:59 +02:00
Aram c3d482c78f Recipe Book is workingggg!!!!!!!!! 2025-05-08 17:47:43 +02:00
Aram 7effc4c853 NON FUNCTIONAL: Finally added the Recipe Book, 2025-05-07 20:17:41 +02:00
Aram 4cd504126b BROKEN: Started adding the Recipe Book 2025-05-07 17:18:30 +02:00
Aram 60ee7b819c Created the Recipe 2025-05-07 12:48:06 +02:00
Aram 28548d5b19 Small rename? 2025-05-07 12:47:46 +02:00
Aram e6ec690811 Wrapped the Brewing Stand to allow Data Driven Recipes Soon!!!
Check previous commit
2025-05-07 01:42:51 +02:00
Aram dac49c2f42 Wrapped the Brewing Stand to allow Data Driven Recipes Soon!!!
Some small issues
* Right clicking Brewing stand first time converts it and wont open gui, so fix that
* The entire code is a Copy Paste of Vanilla ATM, need to start modifying the shit out of it
2025-05-07 01:41:30 +02:00
plastered_crab 07497d653e More data, models, etc for Ponigiri 2025-04-30 19:08:44 -07:00
plastered_crab dfb28ed185 langs for Base, Frosted, Fancy, and Deluxe Poke Puffs 2025-04-30 14:54:08 -07:00
plastered_crab 0cc9a75255 Rough draft on Poke Puff tooltips 2025-04-30 12:59:14 -07:00
plastered_crab abfd718681 Poke Puffs are starting to work great now (visually) 2025-04-30 12:00:32 -07:00
plastered_crab 8271b7a979 I am so close but I must sleep 2025-04-30 01:42:12 -07:00
plastered_crab 251c2df78e tweak parent of first predicate 2025-04-29 23:03:38 -07:00
plastered_crab c03e30bd9c Test poke puff predicate stuff 2025-04-29 21:32:24 -07:00
Plastered_Crab ecc793350a New experimental food stuff 2025-04-29 16:33:50 -07:00
998 changed files with 75436 additions and 15527 deletions
+3 -2
View File
@@ -2,8 +2,9 @@
- Rebuilt Pokémon AI to use Minecraft's Brain system, allowing for more complex behaviours and interactions.
- As an early pass of this, pastured Pokémon will now sleep when appropriate, and may come up to you when they see you.
- Probably also added a whole bunch of bugs.
- Growlithe and Arcanine intimidate Skeletons.
- Meowth intimidate Creepers and Phantoms.
- Dog Pokémon (Growlithe, Arcanine, etc.) intimidate Skeletons.
- Cat Pokémon (Meowth, Persian, etc.) intimidate Creepers and Phantoms.
- Sleep-related Pokémon (Munsharna, Komala, etc.) intimidate Phantoms.
- Added a Behaviour Editor to the NPC editing screen.
- Added /behaviouredit command for opening the Behaviour Editor on Pokémon and NPCs.
- Editing variables for Pokémon is not yet supported.
+23
View File
@@ -4,6 +4,29 @@
- There is a different pot for each apricorn colour because at this point I think we may have an addiction.
- Added Aprijuice, made from the Campfire Pot using apricorns with seasoning to give flavours.
- Aprijuice can be fed to ride-able Pokémon to improve their riding characteristics, depending on the flavour and the Pokémon's nature.
- Added Lure Cakes, made from the Campfire Pot using honey and berries.
- Lure Cakes can be used to modify the spawn rate of Pokémon in the wild.
- Added the Saccharine Tree, which can be found in the wild and is used to obtain Honey Bottles.
- The leaves of the tree can be harvested to obtain honey, which can be used in the Campfire Pot to make Lure Cakes.
- The Log of the tree can be clicked on with honey to create a Honey Log, which increases the change of spawning a Pokemon with an Hidden Ability.
- Clicking on the Progress Arrow will show the JEI Recipe Book for the Campfire Pot, which will show all recipes that can be made with it.
- Added a Ton of Redstone Compatibility.
- Dispenser can now Honey and Unhoney:
- Saccharine Log
- Saccharine Leaves
- Redstone can Close and Open the Lid of a Cooking Pot
- Powered = Closed
- Unpowered = Open
- Hoppers can be used to insert items into a Cooking pot
- Top = Seasonals
- All Sides = Crafting
- Bottom = Extract the Result
- Observer will recognise when a Cooking pot is Closed or Opened
- Comparator Calculates a Signal Strength depending on the items inside the cooking pot
- Sculk Sensor
- Saccharine Leaves
- Opening and Closing the Cooking Pot
- Saccharine Log
### Datapack and Addon Changes
- Renamed the fishing_baits datapack folder to spawn_bait_effects.
+72 -2
View File
@@ -41,12 +41,17 @@
- Grumpig
- Snorunt
- Glalie
- Latias
- Latios
#### Gen 4
- Bronzor
- Bronzong
- Croagunk
- Toxicroak
- Froslass
- Glameow
- Purugly
#### Gen 5
- Pansage
@@ -59,10 +64,22 @@
- Musharna
- Blitzle
- Zebstrika
- Drilbur
- Excadrill
- Trubbish
- Garbodor
- Gothita
- Gothorita
- Gothitelle
- Solosis
- Duosion
- Reuniclus
#### Gen 6
- Inkay
- Malamar
- Hawlucha
- Dedenne
- Noibat
- Noivern
@@ -72,13 +89,20 @@
#### Gen 8
- Silicobra
- Sandaconda
- Sinistea
- Polteageist
#### Gen 9
- Smoliv
- Dolliv
- Arboliva
- Tarountula
- Spidops
- Orthworm
- Dudunsparce
- Cyclizar
- Poltchageist
- Sinistcha
### Animation updates for the following Pokémon
- Garchomp
@@ -91,6 +115,15 @@
- Delphox
- Cinderace
- Kangaskhan
- Gossifleur
- Eldegoss
- Stonjourner
- Wailmer
- Lechonk
- Oinkologne
- Dratini
- Dragonair
- Dragonite
### Model updates for the following Pokémon
- Gyarados
@@ -108,15 +141,39 @@
- Grovyle
- Sceptile
- Honchkrow
- Gible
- Gabite
- Garchomp
- Pidgeot
- Nosepass
- Probopass
- Kangaskhan
- Cinderace
- Magnemite
- Magneton
- Magnezone
- Beldum
- Metang
- Metagross
- Hoothoot
- Noctowl
- Teddiursa
- Ursaring
- Ursaluna
- Heatmor
- Bouffalant
- Sigilyph
- Sharpedo
- Maractus
- Clodsire
- Scyther
- Scizor
- Cacturne
- Taillow
- Swellow
- Added Syrupy Apples.
- Seel
- Dewgong
### Changes
- Renamed `chargeGainedPerTick` config to `secondsToChargeHealingMachine`.
@@ -153,6 +210,9 @@
- Added all Potted Apricorn Sprouts, Potted Saccharine Saplings, and Potted Pep-Up Flowers to the `#minecraft:flower_pots` block tag
- Corrected the healing values of the remedies and energy root, and reintroduced the friendship lowering mechanics for them, revivl herb, and heal powder
- Updated battle language keys for side effects to use position-specific formats, improving grammatical consistency
- Saccharine Leaves are now Collectable
- Saccharine Leaves Age 1 or higher will now show Yellow particles when broken
- Destroying a Saccharine Honey Log will now drop a Saccharine Log in stead of nothing
### Fixes
- Fixed Particles sometimes facing the wrong direction (looking at you, Swords Dance)
@@ -193,10 +253,16 @@
- Fixed the `dimensions` spawning condition using the incorrect ResourceLocation, causing it to not function properly.
- Fix issue where locator X axis was not aligned with blockbench.
- Fix issue where particle effects that play on frame 1 on sendout would never play (Gastly)
- The Wiglett line will now sink in water again.
- Fixed the Sprigatito line's portraits being zoomed in too far.
- Fixed Floragato's battle cry animation from breaking.
- Fixed the block texture name for the Pep-Up Flower being inaccurate
- Fixed issue where the restoration tank would not accept valid items from a hopper.
- Fixed energy root not being shearable
- Fixed energy root always spreading into more energy roots instead of by chance (same as big root)
- Fixed issue where Pokémon spawned by the "spawnallpokemon" command potentially receiving a raft.
- Fixed logspam on NeoForge when adorn is not installed
- Fixed Cobblemon crashing if it tries to load a bedrock model not meant for cobblemon (example: Qlipoth Awakening)
### Developer
- A finished battle now has winners and losers set inside of `PokemonBattle` instead of them always being empty.
@@ -224,7 +290,9 @@
}
`
- The IVs class has now been extended to include Hyper Trained values.
- Added `Pokemon#hyperTrainIV()` and `IVs#setHyperTrainedIV(Stat, Int)`
- Added `Pokemon#hyperTrainIV()` and `IVs#setHyperTrainedIV(Stat, Int)`.
- Added `HyperTrainedIvEvent.Pre` and `HyperTrainedIvEvent.Post`.
- Added a `hoverText` option to PartySelectCallback, to display a tooltip on hovering over a Pokémon in the selection screen.
### MoLang & Datapacks
- The following usages for item predicates can now use item conditions like advancements do, you can learn about them in the [Minecraft wiki](https://minecraft.wiki/w/Advancement_definition#minecraft:filled_bucket)
@@ -252,6 +320,7 @@
- The format of the `remedies.json` file has changed to allow for individual friendshipDrop amounts per remedy
- Fixed `entity.find_nearby_block` causing crashes when attempting to use a block tag
- Spawn Filters can now access `v.spawn.class` to get the identifier of an NPC class for when trying to influence NPC spawns
- Added `pokemon.hyper_train_iv` as an available Molang function.
## [1.6.1 (January 26th, 2025)](#1-6-1)
@@ -1066,6 +1135,7 @@
}
`
- Added support for custom stashes, similar to Gimmighoul's coin and scrap stashes.
- Added the ability to create custom brewing stand recipes.
### Localization
- Updated translations for:
@@ -2373,4 +2443,4 @@ Thank you so much to all of our community translators that bring the mod to the
- Added species, ability, and move translations for `ko_ko`, `jp_jp`, `fr_fr`, `es_es`, `it_it`, and `zh_cn`.
## [1.0.0 (November 12th, 2022)](#1-0-0)
- Initial release.
- Initial release.
@@ -6,9 +6,10 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
package com.cobblemon.mod.common.duck;
import com.cobblemon.mod.common.block.grower.SaccharineTreeGrower
import net.minecraft.world.level.block.SaplingBlock
import net.minecraft.world.item.crafting.RecipeManager;
class SaccharineSaplingBlock(properties : Properties) : SaplingBlock(SaccharineTreeGrower(), properties)
public interface RecipeAwareSlot {
void setRecipeManager(RecipeManager recipeManager);
}
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.brewing;
import com.cobblemon.mod.common.CobblemonRecipeTypes;
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandInput;
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.world.Containers;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.alchemy.PotionBrewing;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.LevelEvent;
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import java.util.List;
import java.util.Optional;
@Mixin(BrewingStandBlockEntity.class)
public class BrewingStandBlockEntityMixin {
@WrapOperation(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/BrewingStandBlockEntity;doBrew(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/NonNullList;)V"))
private static void cobblemon$doBrew(Level level, BlockPos pos, NonNullList<ItemStack> slots, Operation<Void> original) {
var recipe = cobblemon$fetchBrewingRecipe(slots, level);
if(recipe == null) {
original.call(level, pos, slots);
return;
}
//copied from vanilla doBrew logic, but slightly tweaked to work for cobblemon, this was needed as replacing the loop was not quite possible inside doBrew
ItemStack itemStack = slots.get(3);
for(int i = 0; i < 3; ++i) {
slots.set(i, recipe.getResult().copy());
}
itemStack.shrink(1);
if (itemStack.getItem().hasCraftingRemainingItem()) {
ItemStack itemStack2 = new ItemStack(itemStack.getItem().getCraftingRemainingItem());
if (itemStack.isEmpty()) {
itemStack = itemStack2;
} else {
Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), itemStack2);
}
}
slots.set(3, itemStack);
level.levelEvent(LevelEvent.SOUND_BREWING_STAND_BREW, pos, 0);
}
@WrapOperation(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/BrewingStandBlockEntity;isBrewable(Lnet/minecraft/world/item/alchemy/PotionBrewing;Lnet/minecraft/core/NonNullList;)Z"))
private static boolean cobblemon$isBrewable(PotionBrewing potionBrewing, NonNullList<ItemStack> items, Operation<Boolean> original,
@Local(argsOnly = true) Level level) {
return cobblemon$fetchBrewingRecipe(items, level) != null || original.call(potionBrewing, items);
}
@Unique
private static BrewingStandRecipe cobblemon$fetchBrewingRecipe(NonNullList<ItemStack> items, Level level) {
ItemStack ingredient = items.get(3);
List<ItemStack> bottles = items.subList(0, 3);
boolean allBottlesEmpty = true;
for (ItemStack bottle : bottles) {
if (!bottle.isEmpty()) {
allBottlesEmpty = false;
break;
}
}
if (ingredient.isEmpty() || allBottlesEmpty) {
return null;
}
BrewingStandInput input = new BrewingStandInput(ingredient, bottles);
RecipeManager recipeManager = level.getRecipeManager();
Optional<RecipeHolder<BrewingStandRecipe>> recipeHolder =
recipeManager.getRecipeFor(CobblemonRecipeTypes.INSTANCE.getBREWING_STAND(), input, level);
return recipeHolder.map(RecipeHolder::value).orElse(null);
}
}
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.brewing;
import com.cobblemon.mod.common.duck.RecipeAwareSlot;
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.BrewingStandMenu;
import net.minecraft.world.inventory.ContainerData;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(BrewingStandMenu.class)
public abstract class BrewingStandMenuMixin {
@Inject(method = "<init>(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/Container;Lnet/minecraft/world/inventory/ContainerData;)V", at = @At("TAIL"))
private void captureLevel(int containerId, Inventory playerInventory, Container brewingStandContainer, ContainerData brewingStandData, CallbackInfo ci) {
var recipeManager = playerInventory.player.level().getRecipeManager();
for (Slot slot : ((BrewingStandMenu) (Object) this).slots) {
if (slot instanceof RecipeAwareSlot awareSlot) {
awareSlot.setRecipeManager(recipeManager);
}
}
}
@WrapOperation(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/BrewingStandMenu$PotionSlot;mayPlaceItem(Lnet/minecraft/world/item/ItemStack;)Z"))
private boolean cobblemon$isPotionBottle(ItemStack stack, Operation<Boolean> original, @Local(argsOnly = true) Player player) {
return BrewingStandRecipe.Companion.isBottle(stack, player.level().getRecipeManager()) || original.call(stack);
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.brewing;
import com.cobblemon.mod.common.duck.RecipeAwareSlot;
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
import net.minecraft.world.inventory.BrewingStandMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.Level;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BrewingStandMenu.IngredientsSlot.class)
public class IngredientSlotMixin implements RecipeAwareSlot {
@Unique
private RecipeManager cobblemon$recipeManager;
@Override
public void setRecipeManager(RecipeManager recipeManager) {
this.cobblemon$recipeManager = recipeManager;
}
@Inject(
method = "mayPlace",
at = @At("HEAD"),
cancellable = true
)
private void cobblemon$mayPlace(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
if (BrewingStandRecipe.Companion.isInput(stack, cobblemon$recipeManager)) {
cir.setReturnValue(true);
}
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.brewing;
import com.cobblemon.mod.common.duck.RecipeAwareSlot;
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
import net.minecraft.world.inventory.BrewingStandMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.Level;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BrewingStandMenu.PotionSlot.class)
public class PotionSlotMixin implements RecipeAwareSlot {
@Unique
private RecipeManager cobblemon$recipeManager;
@Override
public void setRecipeManager(RecipeManager recipeManager) {
this.cobblemon$recipeManager = recipeManager;
}
@Inject(
method = "mayPlace",
at = @At("HEAD"),
cancellable = true
)
private void cobblemon$mayPlace(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
if (BrewingStandRecipe.Companion.isBottle(stack, cobblemon$recipeManager)) {
cir.setReturnValue(true);
}
}
}
@@ -19,7 +19,6 @@ import net.minecraft.client.ClientRecipeBook;
import net.minecraft.client.RecipeBookCategories;
import net.minecraft.client.gui.screens.recipebook.RecipeCollection;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import org.spongepowered.asm.mixin.Mixin;
@@ -40,9 +39,11 @@ public abstract class ClientRecipeBookMixin {
return null;
}
@Shadow private Map<RecipeBookCategories, List<RecipeCollection>> collectionsByTab;
@Shadow
private Map<RecipeBookCategories, List<RecipeCollection>> collectionsByTab;
@Shadow private List<RecipeCollection> allCollections;
@Shadow
private List<RecipeCollection> allCollections;
@Inject(method = "getCategory", at = @At(value = "HEAD"), cancellable = true)
private static void addCustomCategory(RecipeHolder<?> recipe, CallbackInfoReturnable<RecipeBookCategories> cir) {
@@ -76,8 +77,8 @@ public abstract class ClientRecipeBookMixin {
.collect(ImmutableList.toImmutableList());
map2.put(recipeBookCategories, collections);
});
RecipeBookCategories.AGGREGATE_CATEGORIES.forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List)list.stream().flatMap((recipeBookCategoriesx) -> ((List)map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
CobblemonRecipeCategories.Companion.getCustomAggregateCategories().forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List)list.stream().flatMap((recipeBookCategoriesx) -> ((List)map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
RecipeBookCategories.AGGREGATE_CATEGORIES.forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List) list.stream().flatMap((recipeBookCategoriesx) -> ((List) map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
CobblemonRecipeCategories.Companion.getCustomAggregateCategories().forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List) list.stream().flatMap((recipeBookCategoriesx) -> ((List) map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
this.collectionsByTab = ImmutableMap.copyOf(map2);
this.allCollections = builder.build();
@@ -63,13 +63,10 @@ import com.cobblemon.mod.common.api.storage.player.adapter.PlayerDataMongoBacken
import com.cobblemon.mod.common.api.storage.player.factory.CachedPlayerDataStoreFactory
import com.cobblemon.mod.common.api.tags.CobblemonEntityTypeTags
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.battles.BagItems
import com.cobblemon.mod.common.battles.BattleFormat
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.battles.BattleSide
import com.cobblemon.mod.common.battles.ShowdownThread
import com.cobblemon.mod.common.battles.*
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.block.DispenserBehaviorRegistry
import com.cobblemon.mod.common.client.CobblemonPack
import com.cobblemon.mod.common.command.argument.*
import com.cobblemon.mod.common.config.CobblemonConfig
@@ -91,23 +88,11 @@ import com.cobblemon.mod.common.pokemon.aspects.SHINY_ASPECT
import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
import com.cobblemon.mod.common.pokemon.properties.AspectPropertyType
import com.cobblemon.mod.common.pokemon.properties.BattleCloneProperty
import com.cobblemon.mod.common.pokemon.properties.FreezeFrameProperty
import com.cobblemon.mod.common.pokemon.properties.HiddenAbilityPropertyType
import com.cobblemon.mod.common.pokemon.properties.NoAIProperty
import com.cobblemon.mod.common.pokemon.properties.UnaspectPropertyType
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
import com.cobblemon.mod.common.pokemon.properties.*
import com.cobblemon.mod.common.pokemon.properties.tags.PokemonFlagProperty
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.ifDedicatedServer
import com.cobblemon.mod.common.util.isLaterVersion
import com.cobblemon.mod.common.util.party
import com.cobblemon.mod.common.util.requestWallpapers
import com.cobblemon.mod.common.util.server
import com.cobblemon.mod.common.util.*
import com.cobblemon.mod.common.world.feature.CobblemonPlacedFeatures
import com.cobblemon.mod.common.world.feature.ore.CobblemonOrePlacedFeatures
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
@@ -115,20 +100,8 @@ 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 java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
import kotlin.properties.Delegates
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaField
import net.minecraft.client.Minecraft
import net.minecraft.commands.synchronization.SingletonArgumentInfo
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
@@ -139,6 +112,17 @@ import net.minecraft.world.level.Level
import net.minecraft.world.level.storage.LevelResource
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import java.io.File
import java.io.FileReader
import java.io.FileWriter
import java.io.PrintWriter
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
import kotlin.properties.Delegates
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaField
object Cobblemon {
const val MODID = CobblemonBuildDetails.MOD_ID
@@ -213,6 +197,7 @@ object Cobblemon {
implementation.registerEntityDataSerializers()
implementation.registerCriteria()
implementation.registerEntitySubPredicates()
DispenserBehaviorRegistry.registerDispenserBehaviors()
DropEntry.register("command", CommandDropEntry::class.java)
DropEntry.register("item", ItemDropEntry::class.java, isDefault = true)
@@ -97,6 +97,18 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
val CAMPFIRE: BlockEntityType<CampfireBlockEntity> = this.create("campfire_pot",
BlockEntityType.Builder.of(::CampfireBlockEntity, CobblemonBlocks.CAMPFIRE).build(null)
)
@JvmField
val COPPER_OVEN: BlockEntityType<CopperOvenBlockEntity> = this.create("copper_oven",
BlockEntityType.Builder.of(::CopperOvenBlockEntity, CobblemonBlocks.COPPER_OVEN).build(null)
)
@JvmField
val COPPER_WASHER: BlockEntityType<CopperWasherBlockEntity> = this.create("copper_washer",
BlockEntityType.Builder.of(::CopperWasherBlockEntity, CobblemonBlocks.COPPER_WASHER).build(null)
)
@JvmField
val COPPER_FRIDGE: BlockEntityType<CopperFridgeBlockEntity> = this.create("copper_fridge",
BlockEntityType.Builder.of(::CopperFridgeBlockEntity, CobblemonBlocks.COPPER_FRIDGE).build(null)
)
/*@JvmField
val LURE_CAKE: BlockEntityType<LureCakeBlockEntity> =
@@ -15,10 +15,14 @@ import com.cobblemon.mod.common.block.LecternBlock
import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.block.campfirepot.CampfirePotBlock
import com.cobblemon.mod.common.block.chest.GildedChestBlock
import com.cobblemon.mod.common.block.general.BaleBlock
import com.cobblemon.mod.common.block.grower.SaccharineTreeGrower
import com.cobblemon.mod.common.block.sign.CobblemonHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
import com.cobblemon.mod.common.block.general.HorizontalRotationCarpetBlock
import com.cobblemon.mod.common.block.general.HorizontalRotationalBlock
import com.cobblemon.mod.common.mixin.invoker.*
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.cobblemon.mod.common.util.cobblemonResource
@@ -175,11 +179,11 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val SACCHARINE_HONEY_LOG = this.create("saccharine_honey_log", SaccharineHoneyLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava()))
@JvmField
val STRIPPED_SACCHARINE_LOG = this.create("stripped_saccharine_log", SaccharineStrippedLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
val STRIPPED_SACCHARINE_LOG = this.create("stripped_saccharine_log", RotatedPillarBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
@JvmField
val SACCHARINE_WOOD = log("saccharine_wood")
@JvmField
val STRIPPED_SACCHARINE_WOOD = this.create("stripped_saccharine_wood", SaccharineStrippedLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
val STRIPPED_SACCHARINE_WOOD = this.create("stripped_saccharine_wood", RotatedPillarBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
@JvmField
val SACCHARINE_PLANKS = this.create("saccharine_planks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
@JvmField
@@ -222,7 +226,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val SACCHARINE_TRAPDOOR = this.create("saccharine_trapdoor", TrapdoorBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(3.0F).sound(SoundType.WOOD).noOcclusion()))
@JvmField
val SACCHARINE_SAPLING = this.create("saccharine_sapling", SaccharineSaplingBlock(PLANT_PROPERTIES))
val SACCHARINE_SAPLING = this.create("saccharine_sapling", SaplingBlock(SaccharineTreeGrower(), PLANT_PROPERTIES))
@JvmField
val MEDICINAL_LEEK = this.create("medicinal_leek", MedicinalLeekBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.CRIMSON_NYLIUM).noCollission().randomTicks().instabreak().sound(CobblemonSounds.MEDICINAL_LEEK_SOUNDS)))
@@ -446,7 +450,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val CAMPFIRE = create("campfire", CampfireBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOD).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.PODZOL).strength(2.0F).lightLevel { if ((it.getValue(CampfireBlock.SOUL) as Boolean)) 9 else 14 }))
@JvmField
val RELIC_COIN_POUCH = create("relic_coin_pouch", CoinPouchBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.RELIC_COIN_POUCH_SOUNDS).pushReaction(PushReaction.DESTROY).noOcclusion(), true))
@JvmField
@@ -488,6 +492,17 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val DISPLAY_CASE = create("display_case", DisplayCaseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3F)))
@JvmField
val COPPER_FAN = create("copper_fan", CopperFanBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
@JvmField
val COPPER_MOWER = create("copper_mower", CopperMowerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
@JvmField
val COPPER_OVEN = create("copper_oven", CopperOvenBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
@JvmField
val COPPER_WASHER = this.create("copper_washer", CopperWasherBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
@JvmField
val COPPER_FRIDGE = this.create("copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
@JvmField
val INCENSE_SWEET = create("incense_sweet", SweetIncenseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3f)))
@@ -533,11 +548,11 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val POTTED_SACCHARINE_SAPLING = this.create("potted_saccharine_sapling", BlocksInvoker.createFlowerPotBlock(SACCHARINE_SAPLING))
@JvmField
val HEARTY_GRAIN_BALE = this.create("hearty_grain_bale", HeartyGrainBaleBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).instrument(NoteBlockInstrument.BANJO).strength(0.5F).sound(SoundType.GRASS)))
val HEARTY_GRAIN_BALE = this.create("hearty_grain_bale", BaleBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).instrument(NoteBlockInstrument.BANJO).strength(0.5F).sound(SoundType.GRASS)))
@JvmField
val TATAMI_BLOCK = this.create("tatami_block", TatamiBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).sound(SoundType.GRASS)))
val TATAMI_BLOCK = this.create("tatami_block", HorizontalRotationalBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).sound(SoundType.GRASS)))
@JvmField
val TATAMI_MAT = this.create("tatami_mat", TatamiMatBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).sound(SoundType.GRASS)))
val TATAMI_MAT = this.create("tatami_mat", HorizontalRotationCarpetBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).sound(SoundType.GRASS)))
/**
* Returns a map of all the blocks that can be stripped with an axe in the format of input - output.
@@ -8,7 +8,6 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.block.PotComponent
import com.cobblemon.mod.common.item.components.*
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.mojang.serialization.Codec
@@ -58,6 +58,7 @@ import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.HangingSignItem
import net.minecraft.world.item.Item
import net.minecraft.world.item.Item.Properties
import net.minecraft.world.item.ItemNameBlockItem
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.item.Rarity
@@ -191,22 +192,22 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
val campfire_pots = mutableListOf<CampfirePotItem>()
@JvmField
val CAMPFIRE_POT_BLACK = campfirePotItem(CobblemonBlocks.BLACK_CAMPFIRE_POT, "black")
val CAMPFIRE_POT_RED = campfirePotItem(CobblemonBlocks.RED_CAMPFIRE_POT, "red")
@JvmField
val CAMPFIRE_POT_BLUE = campfirePotItem(CobblemonBlocks.BLUE_CAMPFIRE_POT, "blue")
val CAMPFIRE_POT_YELLOW = campfirePotItem(CobblemonBlocks.YELLOW_CAMPFIRE_POT, "yellow")
@JvmField
val CAMPFIRE_POT_GREEN = campfirePotItem(CobblemonBlocks.GREEN_CAMPFIRE_POT, "green")
@JvmField
val CAMPFIRE_POT_BLUE = campfirePotItem(CobblemonBlocks.BLUE_CAMPFIRE_POT, "blue")
@JvmField
val CAMPFIRE_POT_PINK = campfirePotItem(CobblemonBlocks.PINK_CAMPFIRE_POT, "pink")
@JvmField
val CAMPFIRE_POT_RED = campfirePotItem(CobblemonBlocks.RED_CAMPFIRE_POT, "red")
val CAMPFIRE_POT_BLACK = campfirePotItem(CobblemonBlocks.BLACK_CAMPFIRE_POT, "black")
@JvmField
val CAMPFIRE_POT_WHITE = campfirePotItem(CobblemonBlocks.WHITE_CAMPFIRE_POT, "white")
@JvmField
val CAMPFIRE_POT_YELLOW = campfirePotItem(CobblemonBlocks.YELLOW_CAMPFIRE_POT, "yellow")
@JvmField
val HEARTY_GRAINS = compostableItem("hearty_grains", HeartyGrainsItem(CobblemonBlocks.HEARTY_GRAINS))
val HEARTY_GRAINS = compostableItem("hearty_grains", ItemNameBlockItem(CobblemonBlocks.HEARTY_GRAINS, Properties().rarity(Rarity.COMMON)))
@JvmField
val HEARTY_GRAIN_BALE = compostableBlockItem("hearty_grain_bale", CobblemonBlocks.HEARTY_GRAIN_BALE, 0.85f)
@@ -346,10 +347,10 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", HangingSignItem(CobblemonBlocks.SACCHARINE_HANGING_SIGN, CobblemonBlocks.SACCHARINE_WALL_HANGING_SIGN, Item.Properties().stacksTo(16)))
@JvmField
val SACCHARINE_SAPLING = saccharineSaplingItem("saccharine_sapling", SaccharineSaplingItem(CobblemonBlocks.SACCHARINE_SAPLING))
val SACCHARINE_SAPLING = compostableBlockItem("saccharine_sapling", CobblemonBlocks.SACCHARINE_SAPLING)
@JvmField
val BUGWORT = bugwortItem("bugwort", BugwortItem(CobblemonBlocks.BUGWORT))
val BUGWORT = compostableBlockItem("bugwort", CobblemonBlocks.BUGWORT)
@JvmField
val POKE_BAIT = noSettingsItem("poke_bait")
@@ -432,33 +433,33 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
val TWICE_SPICED_BEETROOT = noSettingsItem("twice_spiced_beetroot") // todo make a TwiceSpiceBeetrootItem class for battle purposes
*/
@JvmField
val POTATO_MOCHI = create("potato_mochi", object : Item(Properties().stacksTo(16)
val POTATO_MOCHI = create("potato_mochi", CobblemonItem(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10) // todo get final values for this from vera
.saturationModifier(1.2F) // todo get final values for this from vera
.alwaysEdible()
.build())) {})
.build())))
@JvmField
val FRIED_RICE = create("fried_rice", object : Item(Properties().stacksTo(16)
val FRIED_RICE = create("fried_rice", CobblemonItem(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10) // todo get final values for this from vera
.saturationModifier(1.2F) // todo get final values for this from vera
.alwaysEdible()
.build())) {})
.build())))
@JvmField
val CANDIED_APPLE = create("candied_apple", object : Item(Properties().stacksTo(16)
val CANDIED_APPLE = create("candied_apple", CobblemonItem(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10) // todo get final values for this from vera
.saturationModifier(1.2F) // todo get final values for this from vera
.alwaysEdible()
.build())) {})
.build())))
@JvmField
val CANDIED_BERRY = create("candied_berry", object : Item(Properties().stacksTo(16)
val CANDIED_BERRY = create("candied_berry", CobblemonItem(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10) // todo get final values for this from vera
.saturationModifier(1.2F) // todo get final values for this from vera
.alwaysEdible()
.build())) {})
.build())))
//@JvmField
//val SCATTER_BANG = this.create("scatter_bang", ScatterBangItem(Item.Settings()))
@@ -482,6 +483,17 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val INCENSE_SWEET = blockItem("incense_sweet", CobblemonBlocks.INCENSE_SWEET)
@JvmField
val COPPER_FAN = blockItem("copper_fan", CobblemonBlocks.COPPER_FAN)
@JvmField
val COPPER_MOWER = blockItem("copper_mower", CobblemonBlocks.COPPER_MOWER)
@JvmField
val COPPER_OVEN = blockItem("copper_oven", CobblemonBlocks.COPPER_OVEN)
@JvmField
val COPPER_WASHER = blockItem("copper_washer", CobblemonBlocks.COPPER_WASHER)
@JvmField
val COPPER_FRIDGE = blockItem("copper_fridge", CobblemonBlocks.COPPER_FRIDGE)
// Evolution items
@JvmField val LINK_CABLE = create("link_cable", LinkCableItem())
@@ -684,11 +696,11 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val MEDICINAL_LEEK = heldItem("medicinal_leek", MedicinalLeekItem(CobblemonBlocks.MEDICINAL_LEEK, Item.Properties().food(FoodProperties.Builder().fast().nutrition(1).saturationModifier(0.2f).build())), "leek")
@JvmField
val ROASTED_LEEK = create("roasted_leek", Item(Item.Properties().food(FoodProperties.Builder().fast().nutrition(3).saturationModifier(0.3f).build())))
val ROASTED_LEEK = create("roasted_leek", CobblemonItem(Item.Properties().food(FoodProperties.Builder().fast().nutrition(3).saturationModifier(0.3f).build())))
@JvmField
val BRAISED_VIVICHOKE = create("braised_vivichoke", Item(Item.Properties().food(FoodProperties.Builder().nutrition(6).saturationModifier(0.6f).build())))
val BRAISED_VIVICHOKE = create("braised_vivichoke", foodItem(6, 0.6F))
@JvmField
val VIVICHOKE_DIP = create("vivichoke_dip", object : Item(Properties().stacksTo(1)
val VIVICHOKE_DIP = create("vivichoke_dip", object : CobblemonItem(Properties().stacksTo(1)
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
@@ -708,7 +720,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val PEP_UP_FLOWER = compostableBlockItem("pep_up_flower", CobblemonBlocks.PEP_UP_FLOWER)
@JvmField
val MEDICINAL_BREW = create("medicinal_brew", Item(Item.Properties()))
val MEDICINAL_BREW = noSettingsItem("medicinal_brew")
@JvmField
val REMEDY = create("remedy", RemedyItem(RemedyItem.NORMAL))
@JvmField
@@ -716,7 +728,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val SUPERB_REMEDY = create("superb_remedy", RemedyItem(RemedyItem.SUPERB))
@JvmField
val MOOMOO_MILK = create("moomoo_milk", Item(Item.Properties()))
val MOOMOO_MILK = noSettingsItem("moomoo_milk")
@JvmField
val POTION = create("potion", PotionItem(PotionType.POTION))
@@ -732,7 +744,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val HEAL_POWDER = create("heal_powder", HealPowderItem())
@JvmField
val LEEK_AND_POTATO_STEW = create("leek_and_potato_stew", Item(Item.Properties().food(FoodProperties.Builder().nutrition(8).saturationModifier(0.6f).usingConvertsTo(Items.BOWL).build()).stacksTo(1)))
val LEEK_AND_POTATO_STEW = create("leek_and_potato_stew", CobblemonItem(Item.Properties().food(FoodProperties.Builder().nutrition(8).saturationModifier(0.6f).usingConvertsTo(Items.BOWL).build()).stacksTo(1)))
@JvmField
val REVIVE = create("revive", ReviveItem(max = false))
@JvmField
@@ -1580,11 +1592,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
private fun heldItem(name: String, item: Item, remappedName: String? = null) = create(
name = name,
entry = item.also {
if (remappedName != null) {
remappedName?.let { remappedName ->
CobblemonHeldItemManager.registerRemap(it, remappedName)
CobblemonHeldItemManager.registerRemap(Items.BONE, "thickclub")
CobblemonHeldItemManager.registerRemap(Items.SNOWBALL, "snowball")
CobblemonHeldItemManager.registerRemap(Items.GOLD_BLOCK, "bignugget")
}
}
)
@@ -1634,20 +1643,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
return item
}
private fun saccharineSaplingItem(name: String, saccharineSaplingItem: SaccharineSaplingItem): SaccharineSaplingItem {
val finalName = "saccharine_sapling"
val item = this.create(finalName, saccharineSaplingItem)
compostable(item, .65f)
return item
}
private fun bugwortItem(name: String, bugwortItem: BugwortItem): BugwortItem {
val finalName = "bugwort"
val item = this.create(finalName, bugwortItem)
compostable(item, .65f)
return item
}
private fun mintSeed(name: String, mintBlock: MintBlock): Item {
val finalName = "${name}_mint_seeds"
@@ -1664,7 +1659,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
}
private fun compostableItem(name: String, item: Item? = null, increaseLevelChance: Float = .65f): Item {
val createdItem = this.create(name, item ?: Item(Item.Properties()))
val createdItem = this.create(name, item ?: CobblemonItem(Item.Properties()))
compostable(createdItem, increaseLevelChance)
return createdItem
}
@@ -1682,6 +1677,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
}
private fun foodItem(nutrition: Int, saturationModifier: Float): Item {
return Item(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
return CobblemonItem(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
}
}
@@ -10,9 +10,7 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.block.campfirepot.CookingPotMenu
import com.cobblemon.mod.common.client.gui.cookingpot.CookingPotScreen
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.client.gui.screens.MenuScreens
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
@@ -24,6 +25,8 @@ object CobblemonRecipeSerializers : PlatformRegistry<Registry<RecipeSerializer<*
val COOKING_POT_COOKING: RecipeSerializer<*> = register("cobblemon:cooking_pot", CookingPotRecipe.Serializer())
val COOKING_POT_SHAPELESS: RecipeSerializer<*> = register("cobblemon:cooking_pot_shapeless", CookingPotShapelessRecipe.Serializer())
val BREWING_STAND: RecipeSerializer<*> = register("cobblemon:brewing_stand", BrewingStandRecipe.Serializer())
override val registry: Registry<RecipeSerializer<*>>
get() = BuiltInRegistries.RECIPE_SERIALIZER
override val resourceKey: ResourceKey<Registry<RecipeSerializer<*>>>
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
@@ -24,6 +25,8 @@ object CobblemonRecipeTypes : PlatformRegistry<Registry<RecipeType<*>>, Resource
val COOKING_POT_COOKING: RecipeType<CookingPotRecipe> = register("cobblemon:cooking_pot")
val COOKING_POT_SHAPELESS: RecipeType<CookingPotShapelessRecipe> = register("cobblemon:cooking_pot_shapeless")
val BREWING_STAND: RecipeType<BrewingStandRecipe> = register("cobblemon:brewing_stand")
override val registry: Registry<RecipeType<*>>
get() = BuiltInRegistries.RECIPE_TYPE
override val resourceKey: ResourceKey<Registry<RecipeType<*>>>
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.npc.ai.MeleeAttackTask
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.BattleFlightTask
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class BattleFlightTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
return BattleFlightTask.create()
}
}
@@ -94,7 +94,8 @@ interface TaskConfig {
cobblemonResource("point_to_spawn") to PointToSpawnTaskConfig::class.java,
cobblemonResource("eat_grass") to EatGrassTaskConfig::class.java,
cobblemonResource("find_air") to FindAirTaskConfig::class.java,
cobblemonResource("go_to_land") to GoToLandTaskConfig::class.java
cobblemonResource("go_to_land") to GoToLandTaskConfig::class.java,
cobblemonResource("battle_flight_task") to BattleFlightTaskConfig::class.java
)
val runtime = MoLangRuntime().setup()
@@ -125,10 +125,11 @@ open class PartySelectPokemonDTO(
val heldItem: ItemStack = ItemStack.EMPTY,
var currentHealth: Int,
var maxHealth: Int,
var enabled: Boolean
var enabled: Boolean,
var hoverText: List<Component> = emptyList()
) {
@JvmOverloads
constructor(pokemon: Pokemon, enabled: Boolean = true): this(
constructor(pokemon: Pokemon, enabled: Boolean = true, hoverText: List<Component> = emptyList()): this(
pokemonProperties = pokemon.createPokemonProperties(
PokemonPropertyExtractor.SPECIES,
PokemonPropertyExtractor.LEVEL,
@@ -140,7 +141,8 @@ open class PartySelectPokemonDTO(
heldItem = pokemon.heldItemNoCopy(),
currentHealth = pokemon.currentHealth,
maxHealth = pokemon.maxHealth,
enabled = enabled
enabled = enabled,
hoverText = hoverText
)
constructor(buffer: RegistryFriendlyByteBuf): this(
@@ -149,7 +151,8 @@ open class PartySelectPokemonDTO(
heldItem = buffer.readItemStack(),
currentHealth = buffer.readInt(),
maxHealth = buffer.readInt(),
enabled = buffer.readBoolean()
enabled = buffer.readBoolean(),
hoverText = buffer.readList { buffer.readText() }
)
fun writeToBuffer(buffer: RegistryFriendlyByteBuf) {
@@ -159,6 +162,6 @@ open class PartySelectPokemonDTO(
buffer.writeInt(currentHealth)
buffer.writeInt(maxHealth)
buffer.writeBoolean(enabled)
buffer.writeCollection(hoverText) { _, text -> buffer.writeText(text) }
}
}
}
@@ -24,6 +24,7 @@ sealed interface DialogueFaceProvider {
companion object {
val types = mutableMapOf(
"artificial" to ArtificialDialogueFaceProvider::class.java,
"player" to PlayerDialogueFaceProvider::class.java,
"standard" to ArtificialDialogueFaceProvider::class.java,
"expression" to ExpressionLikeDialogueFaceProvider::class.java
@@ -171,6 +171,11 @@ object CobblemonEvents {
@JvmField
val EV_GAINED_EVENT_POST = EventObservable<EvGainedEvent.Post>()
@JvmField
val HYPER_TRAINED_IV_PRE = CancelableObservable<HyperTrainedIvEvent.Pre>()
@JvmField
val HYPER_TRAINED_IV_POST = EventObservable<HyperTrainedIvEvent.Post>()
@JvmField
val POKEMON_RELEASED_EVENT_PRE = CancelableObservable<ReleasePokemonEvent.Pre>()
@JvmField
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.events.pokemon
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
import com.cobblemon.mod.common.api.pokemon.stats.Stat
import com.cobblemon.mod.common.pokemon.Pokemon
/**
* Fired during a Hyper Training mutation.
*
* @see [Pre]
* @see [Post]
*/
interface HyperTrainedIvEvent {
/**
* The [Stat] having whose IV is being hyper-trained.
*/
val stat: Stat
/**
* The [Pokemon] being hyper-trained.
*/
val pokemon: Pokemon
/**
* Fired before Hyper Training occurs, cancelling will cause the mutation to be flagged as not successful.
*/
class Pre(override val pokemon: Pokemon, override val stat: Stat, var value: Int) : HyperTrainedIvEvent, Cancelable() {
val context = mutableMapOf(
"pokemon" to pokemon.struct,
"stat" to StringValue(stat.toString()),
"value" to DoubleValue(value)
)
val functions = moLangFunctionMap(cancelFunc)
}
/**
* Fired after Hyper Training occurs, this is purely for notification purposes.
*/
class Post(override val pokemon: Pokemon, override val stat: Stat, val value: Int) : HyperTrainedIvEvent {
val context = mutableMapOf(
"pokemon" to pokemon.struct,
"stat" to StringValue(stat.toString()),
"value" to DoubleValue(value)
)
}
}
@@ -75,6 +75,7 @@ import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityP
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
import com.cobblemon.mod.common.pokemon.Gender
import com.cobblemon.mod.common.pokemon.IVs
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.Species
import com.cobblemon.mod.common.pokemon.evolution.variants.ItemInteractionEvolution
@@ -1103,6 +1104,19 @@ object MoLangFunctions {
map.put("apply_potential_marks") {
return@put DoubleValue(pokemon.applyPotentialMarks())
}
map.put("hyper_train_iv") { params ->
val statId = params.getString(0)
val stat = Stats.getStat(statId)
val value = params.getIntOrNull(1) ?: IVs.MAX_VALUE
if (Stats.PERMANENT.contains(stat)) {
pokemon.hyperTrainIV(stat, value)
return@put DoubleValue.ONE
} else {
Cobblemon.LOGGER.error("Unknown or non-permanent stat: ${stat.toString()}")
return@put DoubleValue.ZERO
}
}
map
}
)
@@ -16,7 +16,6 @@ import com.cobblemon.mod.common.api.moves.animations.UsersProvider
import com.cobblemon.mod.common.api.scheduling.after
import com.cobblemon.mod.common.entity.ai.OmniPathNavigation.NavigationContext
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.PokemonNavigation
import com.cobblemon.mod.common.util.asExpressionLike
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.phys.Vec3
@@ -57,7 +57,8 @@ object CobblemonBlockTags {
@JvmField val MACHINES = createTag("machines")
@JvmField val MANSION_BLOCKS = createTag("mansion_blocks")
@JvmField val MEDICINAL_LEEK_PLANTABLE = createTag("medicinal_leek_plantable")
@JvmField val HEARTY_GRAINS_PLANTABLE = createTag("hearty_grains_plantable")
@JvmField val HEARTY_GRAINS_LAND_PLANTABLE = createTag("hearty_grains_land_plantable")
@JvmField val HEARTY_GRAINS_WATER_PLANTABLE = createTag("hearty_grains_water_plantable")
@JvmField val MINTS = createTag("mints")
@JvmField val MOON_STONE_ORES = createTag("moon_stone_ores")
@JvmField val NATURAL = createTag("natural")
@@ -89,6 +89,7 @@ object CobblemonItemTags {
@JvmField val SKY_TUMBLESTONES = create("sky_tumblestones")
@JvmField val SUN_STONE_ORES = create("sun_stone_ores")
@JvmField val SUPER_POTION_INGREDIENTS = create("super_potion_ingredients")
@JvmField val FULL_HEAL_BOTTLES = create("full_heal_bottles")
@JvmField val SWEETS = create("sweets")
@JvmField val TEACUPS = create("teacups")
@JvmField val TEAPOTS = create("teapots")
@@ -100,7 +100,7 @@ class ActivateInstruction(val instructionSet: InstructionSet, val message: Battl
// Includes spited move and the PP it was reduced by
"spite", "eeriespell" -> battleLang("activate.spite", pokemonName, extraEffect, message.argumentAt(3)!!)
// Don't need additional lang, announced elsewhere
"toxicdebris", "shedskin", "iceface", "owntempo" -> return@dispatch GO
"toxicdebris", "shedskin", "iceface", "owntempo", "vitalspirit" -> return@dispatch GO
// Add activation to each Pokemon's history
"destinybond" -> {
battle.activePokemon.mapNotNull { it.battlePokemon?.uuid }.forEach { battle.minorBattleActions[it] = message }
@@ -0,0 +1,190 @@
/*
* 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.CobblemonSounds
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.block.state.properties.BooleanProperty
import net.minecraft.world.level.gameevent.GameEvent
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class CopperFanBlock(settings: Properties) : Block(settings), SimpleWaterloggedBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH)
.setValue(ACTIVE, false)
.setValue(WATERLOGGED, false)
)
}
override fun getStateForPlacement(ctx: BlockPlaceContext): BlockState? {
var blockState = defaultBlockState().setValue(ACTIVE, false)
.setValue(WATERLOGGED, ctx.level.getFluidState(ctx.clickedPos).type == Fluids.WATER)
val worldView = ctx.level
val blockPos = ctx.clickedPos
ctx.nearestLookingDirections.forEach { direction ->
if (direction.axis.isHorizontal) {
blockState = blockState.setValue(FACING, direction.opposite) as BlockState
if (blockState.canSurvive(worldView, blockPos)) {
return blockState
}
}
}
return null
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HORIZONTAL_FACING)
builder.add(ACTIVE)
builder.add(WATERLOGGED)
}
override fun getShape(
state: BlockState,
blockGetter: BlockGetter,
pos: BlockPos,
collisionContext: CollisionContext
): VoxelShape {
return when (state.getValue(HorizontalDirectionalBlock.FACING)) {
Direction.SOUTH -> NS_AABB
Direction.WEST -> EW_AABB
Direction.EAST -> EW_AABB
else -> NS_AABB
}
}
override fun useWithoutItem(
state: BlockState,
level: Level,
pos: BlockPos,
player: Player,
hitResult: BlockHitResult
): InteractionResult {
if (level.isClientSide) {
level.setBlockAndUpdate(pos, state.cycle(ACTIVE))
return InteractionResult.SUCCESS
} else {
this.push(state, level, pos, null as Player?)
return InteractionResult.CONSUME
}
}
fun push(state: BlockState, level: Level, pos: BlockPos?, player: Player?) {
var state = state
state = state.cycle(ACTIVE)
level.setBlock(pos!!, state, 3)
level.gameEvent(player, if (state.getValue(ACTIVE)) GameEvent.BLOCK_ACTIVATE else GameEvent.BLOCK_DEACTIVATE, pos)
playSound(level, pos, state, CobblemonSounds.DISPLAY_CASE_PLACE)
}
override fun getFluidState(blockState: BlockState): FluidState? {
return if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState);
}
@Deprecated("Deprecated in Java")
override fun rotate(state: BlockState, rotation: Rotation): BlockState {
return state.setValue(HORIZONTAL_FACING, rotation.rotate(state.getValue(HORIZONTAL_FACING)))
}
@Deprecated("Deprecated in Java")
override fun isPathfindable(state: BlockState, type: PathComputationType): Boolean {
return false
}
@Deprecated("Deprecated in Java")
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
if (state.getValue(WATERLOGGED)) {
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
}
return if (direction == state.getValue(FACING) && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
companion object {
val CODEC = simpleCodec(::CopperFanBlock)
val ACTIVE = BooleanProperty.create("active")
private val NS_AABB = Shapes.or(
Shapes.box(0.125, 0.25, 0.4375, 0.875, 1.0, 0.5625),
Shapes.box(0.4375, 0.125, 0.4375, 0.5625, 0.25, 0.5625),
Shapes.box(0.3125, 0.0, 0.3125, 0.6875, 0.125, 0.6875)
)
private val EW_AABB = Shapes.or(
Shapes.box(0.4375, 0.25, 0.125, 0.5625, 1.0, 0.875),
Shapes.box(0.4375, 0.125, 0.4375, 0.5625, 0.25, 0.5625),
Shapes.box(0.3125, 0.0, 0.3125, 0.6875, 0.125, 0.6875)
)
fun playSound(world: Level, pos: BlockPos, state: BlockState, sound: SoundEvent) {
var d = pos.x.toDouble() + 0.5
val e = pos.y.toDouble() + 0.5
var f = pos.z.toDouble() + 0.5
val direction = state.getValue(BlockStateProperties.HORIZONTAL_FACING)
d += direction.stepX.toDouble() * 0.5
f += direction.stepZ.toDouble() * 0.5
world.playSound(
null,
d,
e,
f,
sound,
SoundSource.BLOCKS,
0.5f,
world.random.nextFloat() * 0.1f + 0.9f
)
}
}
//TODO Get it to be a cleanly looping sound, and get Sterr to make a proper sound for it
/* override fun animateTick(state: BlockState, level: Level, pos: BlockPos, random: RandomSource) {
if ((state.getValue(ACTIVE))) {
if (random.nextInt(6) == 0) {
level.playLocalSound(
pos.x.toDouble() + 0.5,
pos.y.toDouble() + 0.5,
pos.z.toDouble() + 0.5,
CobblemonSounds.EVOLUTION_NOTIFICATION,
SoundSource.BLOCKS,
1f,
1f,
false
)
}
}
}*/
}
@@ -0,0 +1,306 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.block.entity.CopperFridgeBlockEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.util.StringRepresentable
import net.minecraft.world.Containers
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.monster.piglin.PiglinAi
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.LevelReader
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.block.state.properties.EnumProperty
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class CopperFridgeBlock(properties: Properties): BaseEntityBlock(properties), SimpleWaterloggedBlock {
companion object {
val CODEC = simpleCodec(::CopperFridgeBlock)
val PART = EnumProperty.create("part", CopperFridgePart::class.java)
private val NORTH_AABB_TOP = Shapes.or(
Shapes.box(0.0, 0.0, 0.0625, 1.0, 1.0, 1.0),
Shapes.box(0.25, 0.125, 0.0, 0.375, 0.3125, 0.0625),
Shapes.box(0.625, 0.125, 0.0, 0.75, 0.3125, 0.0625)
)
private val SOUTH_AABB_TOP = Shapes.or(
Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.9375),
Shapes.box(0.625, 0.125, 0.9375, 0.75, 0.3125, 1.0),
Shapes.box(0.25, 0.125, 0.9375, 0.375, 0.3125, 1.0)
)
private val WEST_AABB_TOP = Shapes.or(
Shapes.box(0.0625, 0.0, 0.0, 1.0, 1.0, 1.0),
Shapes.box(0.0, 0.125, 0.625, 0.0625, 0.3125, 0.75),
Shapes.box(0.0, 0.125, 0.25, 0.0625, 0.3125, 0.375)
)
private val EAST_AABB_TOP = Shapes.or(
Shapes.box(0.0, 0.0, 0.0, 0.9375, 1.0, 1.0),
Shapes.box(0.9375, 0.125, 0.25, 1.0, 0.3125, 0.375),
Shapes.box(0.9375, 0.125, 0.625, 1.0, 0.3125, 0.75)
)
private val NORTH_AABB_BOTTOM = Shapes.or(
Shapes.box(0.0, 0.0625, 0.0625, 1.0, 1.0, 1.0),
Shapes.box(0.0625, 0.0, 0.125, 0.9375, 0.0625, 0.9375)
)
private val SOUTH_AABB_BOTTOM = Shapes.or(
Shapes.box(0.0, 0.0625, 0.0, 1.0, 1.0, 0.9375),
Shapes.box(0.0625, 0.0, 0.0625, 0.9375, 0.0625, 0.875)
)
private val WEST_AABB_BOTTOM = Shapes.or(
Shapes.box(0.0625, 0.0625, 0.0, 1.0, 1.0, 1.0),
Shapes.box(0.125, 0.0, 0.0625, 0.9375, 0.0625, 0.9375)
)
private val EAST_AABB_BOTTOM = Shapes.or(
Shapes.box(0.0, 0.0625, 0.0, 0.9375, 1.0, 1.0),
Shapes.box(0.0625, 0.0, 0.0625, 0.875, 0.0625, 0.9375)
)
}
enum class CopperFridgePart(private val label: String) : StringRepresentable {
TOP("top"),
BOTTOM("bottom");
override fun getSerializedName(): String = label
}
init {
registerDefaultState(stateDefinition.any()
.setValue(HorizontalDirectionalBlock.FACING, Direction.NORTH)
.setValue(PART, CopperFridgePart.BOTTOM)
.setValue(WATERLOGGED, false)
)
}
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState) = if (blockState.getValue(PART) == CopperFridgePart.BOTTOM) CopperFridgeBlockEntity(blockPos, blockState) else null
override fun getName(): MutableComponent {
return Component.translatable("block.cobblemon.copper_fridge")
}
override fun getShape(
blockState: BlockState,
blockGetter: BlockGetter,
blockPos: BlockPos,
collisionContext: CollisionContext
): VoxelShape {
return if (blockState.getValue(PART) == CopperFridgePart.TOP) {
when (blockState.getValue(HorizontalDirectionalBlock.FACING)) {
Direction.SOUTH -> SOUTH_AABB_TOP
Direction.WEST -> WEST_AABB_TOP
Direction.EAST -> EAST_AABB_TOP
else -> NORTH_AABB_TOP
}
} else {
when (blockState.getValue(HorizontalDirectionalBlock.FACING)) {
Direction.SOUTH -> SOUTH_AABB_BOTTOM
Direction.WEST -> WEST_AABB_BOTTOM
Direction.EAST -> EAST_AABB_BOTTOM
else -> NORTH_AABB_BOTTOM
}
}
}
fun getPositionOfOtherPart(state: BlockState, pos: BlockPos): BlockPos {
return if (state.getValue(PART) == CopperFridgePart.BOTTOM) {
pos.above()
} else {
pos.below()
}
}
fun getBasePosition(state: BlockState, pos: BlockPos): BlockPos {
return if (isBase(state)) {
pos
} else {
pos.below()
}
}
private fun isBase(state: BlockState): Boolean = state.getValue(PART) == CopperFridgePart.BOTTOM
override fun setPlacedBy(
world: Level,
pos: BlockPos,
state: BlockState,
placer: LivingEntity?,
itemStack: ItemStack
) {
world.setBlock(pos.above(),
state
.setValue(PART, CopperFridgePart.TOP)
.setValue(WATERLOGGED, world.getFluidState((pos.above())).type == Fluids.WATER)
, 3)
world.blockUpdated(pos, Blocks.AIR)
state.updateNeighbourShapes(world, pos, 3)
}
override fun getStateForPlacement(blockPlaceContext: BlockPlaceContext): BlockState? {
val abovePosition = blockPlaceContext.clickedPos.above()
val world = blockPlaceContext.level
if (world.getBlockState(abovePosition).canBeReplaced(blockPlaceContext) && !world.isOutsideBuildHeight(abovePosition)) {
return defaultBlockState()
.setValue(HorizontalDirectionalBlock.FACING, blockPlaceContext.horizontalDirection.opposite)
.setValue(PART, CopperFridgePart.BOTTOM)
.setValue(WATERLOGGED, blockPlaceContext.level.getFluidState(blockPlaceContext.clickedPos).type == Fluids.WATER)
}
return null
}
override fun canSurvive(state: BlockState, world: LevelReader, pos: BlockPos): Boolean {
val blockPos = pos.below()
val blockState = world.getBlockState(blockPos)
return if (state.getValue(PART) == CopperFridgePart.BOTTOM) blockState.isFaceSturdy(world, blockPos, Direction.UP) else blockState.`is`(this)// todo (techdaan): ensure this is the right mapping
}
override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
if (!world.isClientSide && player?.isCreative == true) {
var blockPos: BlockPos = BlockPos.ZERO
var blockState: BlockState = state
val part = state.getValue(PART)
if (part == CopperFridgePart.TOP && world.getBlockState(pos.below().also { blockPos = it }).also { blockState = it }.`is`(state.block) && blockState.getValue(PART) == CopperFridgePart.BOTTOM) {
val blockState2 = if (blockState.fluidState.`is`(Fluids.WATER)) Blocks.WATER.defaultBlockState() else Blocks.AIR.defaultBlockState()
world.setBlock(blockPos, blockState2, UPDATE_ALL or UPDATE_SUPPRESS_DROPS)
world.levelEvent(player, LevelEvent.PARTICLES_DESTROY_BLOCK, blockPos, getId(blockState))
}
}
return super.playerWillDestroy(world, pos, state, player)
}
override fun codec() = CODEC
@Deprecated("Deprecated in Java")
override fun isPathfindable(
blockState: BlockState,
pathComputationType: PathComputationType
): Boolean = false
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HorizontalDirectionalBlock.FACING)
builder.add(PART)
builder.add(WATERLOGGED)
}
@Deprecated("Deprecated in Java")
override fun rotate(blockState: BlockState, rotation: Rotation) =
blockState.setValue(
HorizontalDirectionalBlock.FACING, rotation.rotate(blockState.getValue(
HorizontalDirectionalBlock.FACING)))
override fun onRemove(state: BlockState, world: Level, pos: BlockPos, newState: BlockState, moved: Boolean) {
if (!state.`is`(newState.block)) {
Containers.dropContentsOnDestroy(state, newState, world, pos)
super.onRemove(state, world, pos, newState, moved)
}
}
override fun hasAnalogOutputSignal(state: BlockState): Boolean {
return true
}
override fun getAnalogOutputSignal(state: BlockState, world: Level, pos: BlockPos): Int {
return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos))
}
override fun useWithoutItem(
state: BlockState,
world: Level,
pos: BlockPos,
player: Player,
hit: BlockHitResult
): InteractionResult {
val basePos = getBasePosition(state, pos)
// Remove any duplicate block entities that may exist
world.getBlockEntity(basePos.above())?.setRemoved()
val baseEntity = world.getBlockEntity(basePos)
if (baseEntity !is CopperFridgeBlockEntity) return InteractionResult.SUCCESS
player.openMenu(baseEntity)
if (!player.level().isClientSide) {
PiglinAi.angerNearbyPiglins(player, true)
}
return InteractionResult.SUCCESS
}
override fun getRenderShape(state: BlockState) = RenderShape.ENTITYBLOCK_ANIMATED
override fun getFluidState(state: BlockState): FluidState? {
return if (state.getValue(WATERLOGGED)) {
Fluids.WATER.getSource(false)
} else super.getFluidState(state)
}
enum class Type(val poserId: ResourceLocation) : StringRepresentable {
RED(cobblemonResource("copper_fridge"));
override fun getSerializedName(): String = name.lowercase()
companion object {
val CODEC = StringRepresentable.fromValues(::values)
}
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
if (state.getValue(WATERLOGGED)) {
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
}
val isFridge = neighborState.`is`(this)
val part = state.getValue(PART)
if (!isFridge && part == CopperFridgePart.TOP && neighborPos == pos.below()) {
return Blocks.AIR.defaultBlockState()
} else if (!isFridge && part == CopperFridgePart.BOTTOM && neighborPos == pos.above()) {
return Blocks.AIR.defaultBlockState()
}
return state
}
override fun tick(state: BlockState, world: ServerLevel, pos: BlockPos, random: RandomSource) {
val blockEntity = world.getBlockEntity(pos) as? CopperFridgeBlockEntity ?: return
blockEntity.tick()
}
}
@@ -0,0 +1,133 @@
/*
* 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 net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING
import net.minecraft.world.level.block.Rotation
import net.minecraft.world.level.block.SimpleWaterloggedBlock
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class CopperMowerBlock(settings: Properties) : Block(settings), SimpleWaterloggedBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH)
.setValue(WATERLOGGED, false)
)
}
override fun getStateForPlacement(ctx: BlockPlaceContext): BlockState? {
var blockState = defaultBlockState()
.setValue(WATERLOGGED, ctx.level.getFluidState(ctx.clickedPos).type == Fluids.WATER)
val worldView = ctx.level
val blockPos = ctx.clickedPos
ctx.nearestLookingDirections.forEach { direction ->
if (direction.axis.isHorizontal) {
blockState = blockState.setValue(FACING, direction.opposite) as BlockState
if (blockState.canSurvive(worldView, blockPos)) {
return blockState
}
}
}
return null
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HORIZONTAL_FACING)
builder.add(WATERLOGGED)
}
override fun getShape(
state: BlockState,
blockGetter: BlockGetter,
pos: BlockPos,
collisionContext: CollisionContext
): VoxelShape {
return when (state.getValue(FACING)) {
Direction.EAST -> EAST_OUTLINE
Direction.SOUTH -> SOUTH_OUTLINE
Direction.WEST -> WEST_OUTLINE
else -> NORTH_OUTLINE
}
}
override fun getFluidState(blockState: BlockState): FluidState? {
return if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState);
}
@Deprecated("Deprecated in Java")
override fun rotate(state: BlockState, rotation: Rotation): BlockState {
return state.setValue(HORIZONTAL_FACING, rotation.rotate(state.getValue(HORIZONTAL_FACING)))
}
@Deprecated("Deprecated in Java")
override fun isPathfindable(state: BlockState, type: PathComputationType): Boolean {
return false
}
@Deprecated("Deprecated in Java")
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
if (state.getValue(WATERLOGGED)) {
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
}
return if (direction == state.getValue(FACING) && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
companion object {
val CODEC = simpleCodec(::CopperMowerBlock)
val SOUTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.0, 0.9375, 0.625, 0.375),
Shapes.box(0.1875, 0.0, 0.375, 0.8125, 0.375, 1.0),
Shapes.box(0.8125, 0.0, 0.5, 0.875, 0.3125, 0.8125),
Shapes.box(0.125, 0.0, 0.5, 0.1875, 0.3125, 0.8125)
)
val NORTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.625, 0.9375, 0.625, 1.0),
Shapes.box(0.1875, 0.0, 0.0, 0.8125, 0.375, 0.625),
Shapes.box(0.125, 0.0, 0.1875, 0.1875, 0.3125, 0.5),
Shapes.box(0.8125, 0.0, 0.1875, 0.875, 0.3125, 0.5)
)
val WEST_OUTLINE = Shapes.or(
Shapes.box(0.625, 0.0, 0.0625, 1.0, 0.625, 0.9375),
Shapes.box(0.0, 0.0, 0.1875, 0.625, 0.375, 0.8125),
Shapes.box(0.1875, 0.0, 0.8125, 0.5, 0.3125, 0.875),
Shapes.box(0.1875, 0.0, 0.125, 0.5, 0.3125, 0.1875),
)
val EAST_OUTLINE = Shapes.or(
Shapes.box(0.0, 0.0, 0.0625, 0.375, 0.625, 0.9375),
Shapes.box(0.375, 0.0, 0.1875, 1.0, 0.375, 0.8125),
Shapes.box(0.5, 0.0, 0.125, 0.8125, 0.3125, 0.1875),
Shapes.box(0.5, 0.0, 0.8125, 0.8125, 0.3125, 0.875)
)
}
}
@@ -0,0 +1,227 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.block.entity.CopperOvenBlockEntity
import com.cobblemon.mod.common.util.cobblemonResource
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.util.StringRepresentable
import net.minecraft.world.Containers
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.monster.piglin.PiglinAi
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
@Suppress("OVERRIDE_DEPRECATION")
class CopperOvenBlock(settings: Properties) : BaseEntityBlock(settings),
SimpleWaterloggedBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.SOUTH)
.setValue(WATERLOGGED, false))
}
companion object {
val CODEC: MapCodec<CopperOvenBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::CopperOvenBlock)
}
val SOUTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.125, 0.9375, 0.625, 0.8125)
)
val NORTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.1875, 0.9375, 0.625, 0.875)
)
val WEST_OUTLINE = Shapes.or(
Shapes.box(0.1875, 0.0, 0.0625, 0.875, 0.625, 0.9375)
)
val EAST_OUTLINE = Shapes.or(
Shapes.box(0.125, 0.0, 0.0625, 0.8125, 0.625, 0.9375)
)
}
override fun getShape(
state: BlockState,
world: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
return when (state.getValue(HorizontalDirectionalBlock.FACING)) {
Direction.NORTH -> NORTH_OUTLINE
Direction.EAST -> EAST_OUTLINE
Direction.WEST -> WEST_OUTLINE
else -> SOUTH_OUTLINE
}
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
if (state.getValue(WATERLOGGED)) world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
return super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
override fun getFluidState(state: BlockState): FluidState {
return if (state.getValue(WATERLOGGED)) {
Fluids.WATER.getSource(false)
} else super.getFluidState(state)
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
super.createBlockStateDefinition(builder)
builder.add(HORIZONTAL_FACING)
builder.add(WATERLOGGED)
}
override fun newBlockEntity(pos: BlockPos, state: BlockState) = CopperOvenBlockEntity(pos, state)
private val facingToYaw: HashMap<Direction, Float> = hashMapOf(
Direction.NORTH to -179.0F,
Direction.WEST to 90.0F,
Direction.SOUTH to 0.0F,
Direction.EAST to -90.0F
)
override fun getName(): MutableComponent {
return Component.translatable("block.cobblemon.copper_oven")
}
override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
if (!world.isClientSide) {}
return super.playerWillDestroy(world, pos, state, player)
}
override fun onRemove(
state: BlockState,
world: Level,
pos: BlockPos,
newState: BlockState,
moved: Boolean
) {
Containers.dropContentsOnDestroy(state, newState, world, pos)
super.onRemove(state, world, pos, newState, moved)
}
override fun useWithoutItem(
state: BlockState,
world: Level,
pos: BlockPos,
player: Player,
hit: BlockHitResult
): InteractionResult {
val entity = world.getBlockEntity(pos) as? CopperOvenBlockEntity ?: return InteractionResult.FAIL
player.openMenu(entity)
if (!player.level().isClientSide) {
PiglinAi.angerNearbyPiglins(player, true)
}
return InteractionResult.SUCCESS
}
override fun getRenderShape(state: BlockState) = RenderShape.ENTITYBLOCK_ANIMATED
override fun getStateForPlacement(blockPlaceContext: BlockPlaceContext): BlockState {
return defaultBlockState()
.setValue(HorizontalDirectionalBlock.FACING, blockPlaceContext.horizontalDirection.opposite)
.setValue(WATERLOGGED, blockPlaceContext.level.getFluidState(blockPlaceContext.clickedPos).type == Fluids.WATER)
}
@Deprecated("Deprecated in Java")
override fun rotate(state: BlockState, rotation: Rotation): BlockState {
return state.setValue(
HORIZONTAL_FACING, rotation.rotate(
state.getValue(HORIZONTAL_FACING) as Direction
)
) as BlockState
}
override fun hasAnalogOutputSignal(state: BlockState): Boolean {
return true
}
override fun getAnalogOutputSignal(state: BlockState, world: Level, pos: BlockPos): Int {
return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos))
}
override fun mirror(state: BlockState, mirror: Mirror): BlockState {
return state.rotate(mirror.getRotation(state.getValue(HORIZONTAL_FACING) as Direction))
}
enum class Type(val poserId: ResourceLocation) : StringRepresentable {
RED(cobblemonResource("copper_oven"));
override fun getSerializedName(): String = name.lowercase()
companion object {
val CODEC = StringRepresentable.fromValues(::values)
}
}
@Deprecated("Deprecated in Java")
override fun isPathfindable(state: BlockState, type: PathComputationType): Boolean {
return false
}
override fun codec(): MapCodec<out BaseEntityBlock> {
return CODEC
}
override fun setPlacedBy(
world: Level,
pos: BlockPos,
state: BlockState,
placer: LivingEntity?,
itemStack: ItemStack
) {
//Theoretically this is no longer needed according to https://fabricmc.net/2024/04/19/1205.html
/*
val blockEntity = world.getBlockEntity(pos)
if (itemStack.get(DataComponentTypes.CUSTOM_NAME) != && blockEntity is GildedChestBlockEntity) {
blockEntity.customName = itemStack.name
}
*/
}
override fun tick(state: BlockState, world: ServerLevel, pos: BlockPos, random: RandomSource) {
val blockEntity = world.getBlockEntity(pos) as? CopperOvenBlockEntity ?: return
blockEntity.tick()
}
}
@@ -0,0 +1,235 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.block.entity.CopperWasherBlockEntity
import com.cobblemon.mod.common.util.cobblemonResource
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.util.StringRepresentable
import net.minecraft.world.Containers
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.monster.piglin.PiglinAi
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
@Suppress("OVERRIDE_DEPRECATION")
class CopperWasherBlock(settings: Properties) : BaseEntityBlock(settings),
SimpleWaterloggedBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.SOUTH)
.setValue(WATERLOGGED, false))
}
companion object {
val CODEC: MapCodec<CopperWasherBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::CopperWasherBlock)
}
private val NORTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.125, 0.9375, 0.875, 1.0),
Shapes.box(0.25, 0.125, 0.0625, 0.75, 0.625, 0.125),
Shapes.box(0.9375, 0.125, 0.6875, 1.0, 0.375, 0.9375)
)
private val SOUTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.0, 0.9375, 0.875, 0.875),
Shapes.box(0.25, 0.125, 0.875, 0.75, 0.625, 0.9375),
Shapes.box(0.0, 0.125, 0.0625, 0.0625, 0.375, 0.3125)
)
private val WEST_OUTLINE = Shapes.or(
Shapes.box(0.125, 0.0, 0.0625, 1.0, 0.875, 0.9375),
Shapes.box(0.0625, 0.125, 0.25, 0.125, 0.625, 0.75),
Shapes.box(0.6875, 0.125, 0.0, 0.9375, 0.375, 0.0625)
)
private val EAST_OUTLINE = Shapes.or(
Shapes.box(0.0, 0.0, 0.0625, 0.875, 0.875, 0.9375),
Shapes.box(0.875, 0.125, 0.25, 0.9375, 0.625, 0.75),
Shapes.box(0.0625, 0.125, 0.9375, 0.3125, 0.375, 1.0)
)
}
override fun getShape(
state: BlockState,
world: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
return when (state.getValue(HorizontalDirectionalBlock.FACING)) {
Direction.NORTH -> NORTH_OUTLINE
Direction.EAST -> EAST_OUTLINE
Direction.WEST -> WEST_OUTLINE
else -> SOUTH_OUTLINE
}
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
if (state.getValue(WATERLOGGED)) world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
return super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
override fun getFluidState(state: BlockState): FluidState {
return if (state.getValue(WATERLOGGED)) {
Fluids.WATER.getSource(false)
} else super.getFluidState(state)
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
super.createBlockStateDefinition(builder)
builder.add(HORIZONTAL_FACING)
builder.add(WATERLOGGED)
}
override fun newBlockEntity(pos: BlockPos, state: BlockState) = CopperWasherBlockEntity(pos, state)
private val facingToYaw: HashMap<Direction, Float> = hashMapOf(
Direction.NORTH to -179.0F,
Direction.WEST to 90.0F,
Direction.SOUTH to 0.0F,
Direction.EAST to -90.0F
)
override fun getName(): MutableComponent {
return Component.translatable("block.cobblemon.copper_washer")
}
override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
if (!world.isClientSide) {}
return super.playerWillDestroy(world, pos, state, player)
}
override fun onRemove(
state: BlockState,
world: Level,
pos: BlockPos,
newState: BlockState,
moved: Boolean
) {
Containers.dropContentsOnDestroy(state, newState, world, pos)
super.onRemove(state, world, pos, newState, moved)
}
override fun useWithoutItem(
state: BlockState,
world: Level,
pos: BlockPos,
player: Player,
hit: BlockHitResult
): InteractionResult {
val entity = world.getBlockEntity(pos) as? CopperWasherBlockEntity ?: return InteractionResult.FAIL
player.openMenu(entity)
if (!player.level().isClientSide) {
PiglinAi.angerNearbyPiglins(player, true)
}
return InteractionResult.SUCCESS
}
override fun getRenderShape(state: BlockState) = RenderShape.ENTITYBLOCK_ANIMATED
override fun getStateForPlacement(blockPlaceContext: BlockPlaceContext): BlockState {
return defaultBlockState()
.setValue(HorizontalDirectionalBlock.FACING, blockPlaceContext.horizontalDirection.opposite)
.setValue(WATERLOGGED, blockPlaceContext.level.getFluidState(blockPlaceContext.clickedPos).type == Fluids.WATER)
}
@Deprecated("Deprecated in Java")
override fun rotate(state: BlockState, rotation: Rotation): BlockState {
return state.setValue(
HORIZONTAL_FACING, rotation.rotate(
state.getValue(HORIZONTAL_FACING) as Direction
)
) as BlockState
}
override fun hasAnalogOutputSignal(state: BlockState): Boolean {
return true
}
override fun getAnalogOutputSignal(state: BlockState, world: Level, pos: BlockPos): Int {
return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos))
}
override fun mirror(state: BlockState, mirror: Mirror): BlockState {
return state.rotate(mirror.getRotation(state.getValue(HORIZONTAL_FACING) as Direction))
}
enum class Type(val poserId: ResourceLocation) : StringRepresentable {
RED(cobblemonResource("copper_washer"));
override fun getSerializedName(): String = name.lowercase()
companion object {
val CODEC = StringRepresentable.fromValues(::values)
}
}
@Deprecated("Deprecated in Java")
override fun isPathfindable(state: BlockState, type: PathComputationType): Boolean {
return false
}
override fun codec(): MapCodec<out BaseEntityBlock> {
return CODEC
}
override fun setPlacedBy(
world: Level,
pos: BlockPos,
state: BlockState,
placer: LivingEntity?,
itemStack: ItemStack
) {
//Theoretically this is no longer needed according to https://fabricmc.net/2024/04/19/1205.html
/*
val blockEntity = world.getBlockEntity(pos)
if (itemStack.get(DataComponentTypes.CUSTOM_NAME) != && blockEntity is GildedChestBlockEntity) {
blockEntity.customName = itemStack.name
}
*/
}
override fun tick(state: BlockState, world: ServerLevel, pos: BlockPos, random: RandomSource) {
val blockEntity = world.getBlockEntity(pos) as? CopperWasherBlockEntity ?: return
blockEntity.tick()
}
}
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
import net.minecraft.world.item.Item
import net.minecraft.core.dispenser.DispenseItemBehavior
import net.minecraft.world.item.Items
import net.minecraft.world.level.block.DispenserBlock
object DispenserBehaviorRegistry {
private val behaviors = mutableMapOf<Item, DispenseItemBehavior>()
fun register(items: List<Item>, behaviorProvider: (Item) -> DispenseItemBehavior) {
for (item in items) {
behaviors[item] = behaviorProvider(item)
}
}
fun applyBehaviors() {
behaviors.forEach { (item, behavior) ->
DispenserBlock.registerBehavior(item, behavior)
}
}
fun registerDispenserBehaviors() {
register(listOf(Items.GLASS_BOTTLE)) { SaccharineHoneyLogBlock.createBehavior() }
register(listOf(Items.HONEY_BOTTLE)) { SaccharineLogBlock.createBehavior() }
register(listOf(Items.HONEY_BOTTLE, Items.GLASS_BOTTLE)) { item -> SaccharineLeafBlock.createBehavior(item)}
applyBehaviors()
}
}
@@ -1,104 +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 net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.RotatedPillarBlock
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.EnumProperty
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class HeartyGrainBaleBlock(properties: Properties) : RotatedPillarBlock(properties) {
private var owner: LivingEntity? = null
init {
this.registerDefaultState(
this.stateDefinition.any()
.setValue(AXIS, Direction.Axis.Y)
)
}
override fun setPlacedBy(
level: Level,
pos: BlockPos,
state: BlockState,
placer: LivingEntity?,
itemStack: ItemStack
) {
owner = placer
super.setPlacedBy(level, pos, state, placer, itemStack)
}
override fun getShape(
state: BlockState,
level: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
return SHAPE
}
override fun getCollisionShape(
state: BlockState,
level: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
return super.getCollisionShape(state, level, pos, context)
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
level: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
return if (!state.canSurvive(level, pos)) {
Blocks.AIR.defaultBlockState()
} else {
super.updateShape(state, direction, neighborState, level, pos, neighborPos)
}
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(AXIS)
}
override fun isPathfindable(
state: BlockState,
type: PathComputationType
): Boolean = false
companion object {
val AXIS: EnumProperty<Direction.Axis> = BlockStateProperties.AXIS
private val SHAPE: VoxelShape = Shapes.block()
}
override fun fallOn(level: Level, state: BlockState, pos: BlockPos, entity: Entity, fallDistance: Float) {
entity.causeFallDamage(fallDistance, 0.3f, level.damageSources().fall())
}
}
@@ -18,6 +18,7 @@ import net.minecraft.server.level.ServerLevel
import net.minecraft.tags.FluidTags
import net.minecraft.util.RandomSource
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.ItemLike
import net.minecraft.world.level.Level
@@ -69,8 +70,17 @@ class HeartyGrainsBlock(settings: Properties) : CropBlock(settings), SimpleWater
}
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
val fluidState = context.level.getFluidState(context.clickedPos)
return this.defaultBlockState()
.setValue(
WATERLOGGED,
fluidState.type === Fluids.WATER
)
}
private fun canGrow(world: LevelReader, pos: BlockPos, state: BlockState): Boolean {
return !this.isMaxAge(state) && canSurvive(state, world, pos) && (state.getValue(HALF) == DoubleBlockHalf.UPPER || canGrowInto(world, pos.above()))
return !this.isMaxAge(state) && canSurvive(state, world, pos)
}
private fun canGrowInto(world: LevelReader, pos: BlockPos): Boolean {
@@ -111,14 +121,15 @@ class HeartyGrainsBlock(settings: Properties) : CropBlock(settings), SimpleWater
if (state.getValue(WATERLOGGED)) {
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
}
return if (!canSurvive(state, world, pos)) Blocks.AIR.defaultBlockState() else super.updateShape(
state,
direction,
neighborState,
world,
pos,
neighborPos
)
val doubleBlockHalf = state.getValue(HALF)
return if (direction.axis !== Direction.Axis.Y || doubleBlockHalf == DoubleBlockHalf.LOWER != (direction == Direction.UP) ||
neighborState.`is`(this) && neighborState.getValue(HALF) != doubleBlockHalf) {
if (doubleBlockHalf == DoubleBlockHalf.LOWER && direction == Direction.DOWN && !state.canSurvive(world, pos))
Blocks.AIR.defaultBlockState()
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
} else {
Blocks.AIR.defaultBlockState()
}
}
override fun isValidBonemealTarget(level: LevelReader, pos: BlockPos, state: BlockState): Boolean {
@@ -168,21 +179,27 @@ class HeartyGrainsBlock(settings: Properties) : CropBlock(settings), SimpleWater
override fun canSurvive(state: BlockState, world: LevelReader, pos: BlockPos): Boolean {
return when (state.getValue(HALF)) {
DoubleBlockHalf.LOWER -> {
val floor = world.getBlockState(pos.below())
val fluidState = world.getFluidState(pos)
val floorBlock = pos.below()
val floor = world.getBlockState(floorBlock)
// Check if bottom part is submerged in water
val isSubmergedInWater = fluidState.`is`(FluidTags.WATER) && fluidState.isSource
val fluidState = world.getFluidState(pos)
if (fluidState.`is`(FluidTags.WATER) && fluidState.isSource)
return floor.`is`(CobblemonBlockTags.HEARTY_GRAINS_WATER_PLANTABLE) && canGrowInto(world, pos.above())
// Check for adjacency to water
val isNearWater = BlockPos.betweenClosed(pos.offset(-1, 0, -1), pos.offset(1, 0, 1))
.any { world.getFluidState(it).`is`(FluidTags.WATER) }
// check if water is adjacent
var waterNearby = false
for (i in -1..1) {
for (j in -1..1) {
val fluidState = world.getFluidState(floorBlock.offset(i, 0, j))
if (fluidState.`is`(FluidTags.WATER) && fluidState.isSource) {
waterNearby = true
break
}
}
}
// Check waterlogging state
val isWaterlogged = state.getValue(WATERLOGGED)
// Check for valid soil or survival conditions
isSubmergedInWater || isWaterlogged || isNearWater || floor.`is`(CobblemonBlockTags.HEARTY_GRAINS_PLANTABLE) || floor.`is`(Blocks.MUD) || floor.`is`(Blocks.FARMLAND)
waterNearby && floor.`is`(CobblemonBlockTags.HEARTY_GRAINS_LAND_PLANTABLE) && canGrowInto(world, pos.above())
}
DoubleBlockHalf.UPPER -> {
getLowerHalf(world, pos, state) != null
@@ -8,84 +8,120 @@
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.dispenser.DispenseItemBehavior
import net.minecraft.world.Containers
import net.minecraft.world.InteractionHand
import net.minecraft.world.ItemInteractionResult
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.DispenserBlock
import net.minecraft.world.level.block.RotatedPillarBlock
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.EnumProperty
import net.minecraft.world.level.material.PushReaction
import net.minecraft.world.level.gameevent.GameEvent
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.level.storage.loot.LootParams
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.EntityCollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class SaccharineHoneyLogBlock(properties: Properties) : RotatedPillarBlock(properties) {
init {
this.registerDefaultState(
this.stateDefinition.any()
.setValue(AXIS, Direction.Axis.Y)
)
}
override fun getShape(
override fun useItemOn(
stack: ItemStack,
state: BlockState,
level: BlockGetter,
level: Level,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
return SHAPE
}
player: Player,
hand: InteractionHand,
hitResult: BlockHitResult
): ItemInteractionResult? {
val itemStack = player.getItemInHand(hand)
if (itemStack.`is`(Items.GLASS_BOTTLE)) {
if (!level.isClientSide) {
// Replace the honey with the block variant
val newState = CobblemonBlocks.SACCHARINE_LOG.defaultBlockState()
.setValue(RotatedPillarBlock.AXIS, state.getValue(RotatedPillarBlock.AXIS))
level.setBlock(pos, newState, 3)
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
override fun getCollisionShape(
state: BlockState,
level: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
if (context is EntityCollisionContext && (context.entity as? ItemEntity)?.item?.`is`(CobblemonItemTags.APRICORNS) == true) {
return Shapes.empty()
// Consume glass bottle
if (!player.isCreative) {
itemStack.shrink(1)
// Give Honey bottle
val honeyBottle = ItemStack(Items.HONEY_BOTTLE)
if (!player.addItem(honeyBottle)) {
player.drop(honeyBottle, false)
}
}
}
return ItemInteractionResult.SUCCESS
}
return super.getCollisionShape(state, level, pos, context)
return super.useItemOn(stack, state, level, pos, player, hand, hitResult)
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
level: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
return if (!state.canSurvive(level, pos)) {
Blocks.AIR.defaultBlockState()
} else {
super.updateShape(state, direction, neighborState, level, pos, neighborPos)
}
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(AXIS)
}
override fun isPathfindable(
state: BlockState,
type: PathComputationType
): Boolean = false
companion object {
val AXIS: EnumProperty<Direction.Axis> = BlockStateProperties.AXIS
private val SHAPE: VoxelShape = Shapes.block()
fun createBehavior(): DispenseItemBehavior {
return DispenseItemBehavior { source, stack ->
val level = source.level
val pos = source.pos.relative(source.state.getValue(DispenserBlock.FACING))
val blockState = level.getBlockState(pos)
if (blockState.block is SaccharineHoneyLogBlock) {
val newState = CobblemonBlocks.SACCHARINE_LOG.defaultBlockState()
.setValue(AXIS, blockState.getValue(AXIS))
level.setBlock(pos, newState, 3)
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
stack.shrink(1)
val dispenserEntity = source.blockEntity
if (dispenserEntity != null) {
val honeyBottle = ItemStack(Items.HONEY_BOTTLE)
var added = false
for (i in 0 until dispenserEntity.containerSize) {
val slotStack = dispenserEntity.getItem(i)
if (slotStack.isEmpty) {
dispenserEntity.setItem(i, honeyBottle.copy())
added = true
break
} else if (slotStack.`is`(Items.HONEY_BOTTLE) && slotStack.count < slotStack.maxStackSize) {
slotStack.grow(1)
added = true
break
}
}
if (!added) {
Containers.dropItemStack(
level,
source.pos.x.toDouble(), source.pos.y.toDouble(), source.pos.z.toDouble(), honeyBottle
)
}
}
}
stack
}
}
}
}
@@ -11,31 +11,31 @@ package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.dispenser.DispenseItemBehavior
import net.minecraft.core.particles.ParticleTypes
import net.minecraft.server.level.ServerLevel
import net.minecraft.tags.BlockTags
import net.minecraft.util.Mth
import net.minecraft.util.RandomSource
import net.minecraft.world.Containers
import net.minecraft.world.InteractionHand
import net.minecraft.world.ItemInteractionResult
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.LevelReader
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.BonemealableBlock
import net.minecraft.world.level.block.LeavesBlock
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.BooleanProperty
import net.minecraft.world.level.block.state.properties.IntegerProperty
import net.minecraft.world.level.gameevent.GameEvent
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
@@ -84,7 +84,7 @@ class SaccharineLeafBlock(settings: Properties) : LeavesBlock(settings), Bonemea
if (belowAge < MAX_AGE) {
changeAge(state, -1)
changeAge(belowState, 1)
}
}
break
} else {
break
@@ -130,7 +130,7 @@ class SaccharineLeafBlock(settings: Properties) : LeavesBlock(settings), Bonemea
override fun animateTick(state: BlockState, level: Level, pos: BlockPos, random: RandomSource) {
val particleCount = random.nextInt(3)
if (state.getValue(AGE) == 2) {
repeat(particleCount) {
spawnHoneyParticles(level, pos, state, 0.75f)
@@ -218,12 +218,14 @@ class SaccharineLeafBlock(settings: Properties) : LeavesBlock(settings), Bonemea
// give player honey bottle for now
player.addItem(Items.HONEY_BOTTLE.defaultInstance)
level.setBlock(pos, state.setValue(AGE, 0), 2)
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
} else if (isHoneyBottle && !isAtMaxAge(state)) {
// decrement stack if not in creative mode
if (!player.isCreative)
itemStack.shrink(1)
level.setBlock(pos, state.setValue(AGE, 2), 2)
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
}
if (state.getValue(AGE) != MAX_AGE) {
@@ -235,13 +237,28 @@ class SaccharineLeafBlock(settings: Properties) : LeavesBlock(settings), Bonemea
}
private fun isAtMaxAge(state: BlockState) = state.getValue(AGE) == MAX_AGE
private fun isAtMinAge(state: BlockState) = state.getValue(AGE) >= MIN_AGE
private fun isAtMinAge(state: BlockState) = state.getValue(AGE) == MIN_AGE
private fun changeAge(state: BlockState, value: Int): BlockState {
val newAge = (state.getValue(AGE) + value).coerceIn(MIN_AGE, MAX_AGE)
return state.setValue(AGE, newAge)
}
override fun spawnDestroyParticles(level: Level, player: Player, pos: BlockPos, state: BlockState) {
if (isAtMinAge(state)) {
super.spawnDestroyParticles(level, player, pos, state)
return
} else {
// TODO: Change to Yellow Leaves in stead of concrete
val particle = Blocks.YELLOW_CONCRETE_POWDER.defaultBlockState()
level.levelEvent(
LevelEvent.PARTICLES_DESTROY_BLOCK,
pos,
Block.getId(particle)
)
}
}
/*override fun onBlockBreakStart(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity) {
if (state.get(AGE) != MAX_AGE) {
return super.onBlockBreakStart(state, world, pos, player)
@@ -260,6 +277,63 @@ class SaccharineLeafBlock(settings: Properties) : LeavesBlock(settings), Bonemea
const val DISTANCE_MAX = 7
private val SHAPE: VoxelShape = box(0.0, 0.0, 0.0, 16.0, 16.0, 16.0)
fun createBehavior(item: Item): DispenseItemBehavior {
return DispenseItemBehavior { source, stack ->
val level = source.level
val facing = source.state.getValue(DispenserBlock.FACING)
val pos = source.pos.relative(facing)
val blockState = level.getBlockState(pos)
if (blockState.block is SaccharineLeafBlock) {
val currentAge = blockState.getValue(AGE)
val newAge = when {
item == Items.HONEY_BOTTLE && currentAge < MAX_AGE -> (currentAge + 2).coerceAtMost(MAX_AGE)
item == Items.GLASS_BOTTLE && currentAge > MIN_AGE -> (currentAge - 2).coerceAtLeast(MIN_AGE)
else -> currentAge
}
if (newAge != currentAge) {
level.setBlock(pos, blockState.setValue(AGE, newAge), 3)
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
stack.shrink(1)
val dispenserEntity = source.blockEntity
if (dispenserEntity != null) {
val outputItem = if (item == Items.HONEY_BOTTLE) Items.GLASS_BOTTLE else Items.HONEY_BOTTLE
val outputStack = ItemStack(outputItem)
var added = false
for (i in 0 until dispenserEntity.containerSize) {
val slotStack = dispenserEntity.getItem(i)
if (slotStack.isEmpty) {
dispenserEntity.setItem(i, outputStack.copy())
added = true
break
} else if (slotStack.`is`(outputItem) && slotStack.count < slotStack.maxStackSize) {
slotStack.grow(1)
added = true
break
}
}
if (!added) {
Containers.dropItemStack(
level,
source.pos.x.toDouble(),
source.pos.y.toDouble(),
source.pos.z.toDouble(),
outputStack
)
}
}
}
}
stack
}
}
}
}
@@ -9,16 +9,13 @@
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.core.dispenser.DispenseItemBehavior
import net.minecraft.world.Containers
import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult
import net.minecraft.world.ItemInteractionResult
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
@@ -26,14 +23,16 @@ import net.minecraft.world.item.Items
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.DispenserBlock
import net.minecraft.world.level.block.RotatedPillarBlock
import net.minecraft.world.level.block.entity.DispenserBlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.EnumProperty
import net.minecraft.world.level.block.state.properties.IntegerProperty
import net.minecraft.world.level.material.PushReaction
import net.minecraft.world.level.gameevent.GameEvent
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
@@ -43,53 +42,6 @@ import net.minecraft.world.phys.shapes.VoxelShape
class SaccharineLogBlock(properties: Properties) : RotatedPillarBlock(properties) {
init {
this.registerDefaultState(
this.stateDefinition.any()
.setValue(AXIS, Direction.Axis.Y)
)
}
override fun getShape(
state: BlockState,
level: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
return SHAPE
}
override fun getCollisionShape(
state: BlockState,
level: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
if (context is EntityCollisionContext && (context.entity as? ItemEntity)?.item?.`is`(CobblemonItemTags.APRICORNS) == true) {
return Shapes.empty()
}
return super.getCollisionShape(state, level, pos, context)
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
level: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
return if (!state.canSurvive(level, pos)) {
Blocks.AIR.defaultBlockState()
} else {
super.updateShape(state, direction, neighborState, level, pos, neighborPos)
}
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(AXIS)
}
override fun useItemOn(
stack: ItemStack,
state: BlockState,
@@ -106,6 +58,7 @@ class SaccharineLogBlock(properties: Properties) : RotatedPillarBlock(properties
val newState = CobblemonBlocks.SACCHARINE_HONEY_LOG.defaultBlockState()
.setValue(RotatedPillarBlock.AXIS, state.getValue(RotatedPillarBlock.AXIS))
level.setBlock(pos, newState, 3)
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
// Consume honey bottle
if (!player.isCreative) {
@@ -123,15 +76,57 @@ class SaccharineLogBlock(properties: Properties) : RotatedPillarBlock(properties
return super.useItemOn(stack, state, level, pos, player, hand, hitResult)
}
override fun isPathfindable(
state: BlockState,
type: PathComputationType
): Boolean = false
companion object {
val AXIS: EnumProperty<Direction.Axis> = BlockStateProperties.AXIS
private val SHAPE: VoxelShape = Shapes.block()
fun createBehavior(): DispenseItemBehavior {
return DispenseItemBehavior { source, stack ->
val level = source.level
val facing = source.state.getValue(DispenserBlock.FACING)
val pos = source.pos.relative(facing)
val blockState = level.getBlockState(pos)
if (blockState.block is SaccharineLogBlock) {
val newState = CobblemonBlocks.SACCHARINE_HONEY_LOG.defaultBlockState()
.setValue(AXIS, blockState.getValue(AXIS))
level.setBlock(pos, newState, 3)
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
stack.shrink(1)
val dispenserEntity = source.blockEntity
if (dispenserEntity != null) {
val glassBottle = ItemStack(Items.GLASS_BOTTLE)
var added = false
for (i in 0 until dispenserEntity.containerSize) {
val slotStack = dispenserEntity.getItem(i)
if (slotStack.isEmpty) {
dispenserEntity.setItem(i, glassBottle.copy())
added = true
break
} else if (slotStack.`is`(Items.GLASS_BOTTLE) && slotStack.count < slotStack.maxStackSize) {
slotStack.grow(1)
added = true
break
}
}
if (!added) {
Containers.dropItemStack(
level,
source.pos.x.toDouble(), source.pos.y.toDouble(), source.pos.z.toDouble(), glassBottle
)
}
}
}
stack
}
}
}
}
@@ -1,115 +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.api.tags.CobblemonItemTags
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult
import net.minecraft.world.ItemInteractionResult
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.RotatedPillarBlock
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.EnumProperty
import net.minecraft.world.level.block.state.properties.IntegerProperty
import net.minecraft.world.level.material.PushReaction
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.EntityCollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class SaccharineStrippedLogBlock(properties: Properties) : RotatedPillarBlock(properties) {
private var owner: LivingEntity? = null
init {
this.registerDefaultState(
this.stateDefinition.any()
.setValue(AXIS, Direction.Axis.Y)
)
}
override fun setPlacedBy(
level: Level,
pos: BlockPos,
state: BlockState,
placer: LivingEntity?,
itemStack: ItemStack
) {
owner = placer
super.setPlacedBy(level, pos, state, placer, itemStack)
}
override fun getShape(
state: BlockState,
level: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
return SHAPE
}
override fun getCollisionShape(
state: BlockState,
level: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
if (context is EntityCollisionContext && (context.entity as? ItemEntity)?.item?.`is`(CobblemonItemTags.APRICORNS) == true) {
return Shapes.empty()
}
return super.getCollisionShape(state, level, pos, context)
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
level: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
return if (!state.canSurvive(level, pos)) {
Blocks.AIR.defaultBlockState()
} else {
super.updateShape(state, direction, neighborState, level, pos, neighborPos)
}
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(AXIS)
}
override fun isPathfindable(
state: BlockState,
type: PathComputationType
): Boolean = false
companion object {
val AXIS: EnumProperty<Direction.Axis> = BlockStateProperties.AXIS
private val SHAPE: VoxelShape = Shapes.block()
}
}
@@ -12,9 +12,7 @@ import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.block.entity.CampfireBlockEntity
import com.cobblemon.mod.common.block.entity.CampfireBlockEntity.Companion.PREVIEW_ITEM_SLOT
import com.cobblemon.mod.common.block.entity.DisplayCaseBlockEntity
import com.cobblemon.mod.common.item.CampfirePotItem
import com.cobblemon.mod.common.item.PokeBallItem
import com.cobblemon.mod.common.util.playSoundServer
import com.cobblemon.mod.common.util.toVec3d
import com.mojang.serialization.MapCodec
@@ -28,7 +26,7 @@ import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.BlockItem
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
@@ -62,6 +60,7 @@ class CampfireBlock(settings: Properties) : BaseEntityBlock(settings), SimpleWat
val ITEM_DIRECTION = DirectionProperty.create("item_facing")
val LIT = BlockStateProperties.LIT
var SOUL = BooleanProperty.create("soul")
val POWERED = BlockStateProperties.POWERED
private val campfireAABB = Shapes.box(0.0, 0.0, 0.0, 1.0, 0.4375, 1.0)
private val AABB = Shapes.or(
@@ -79,7 +78,8 @@ class CampfireBlock(settings: Properties) : BaseEntityBlock(settings), SimpleWat
.setValue(FACING, Direction.NORTH)
.setValue(LIT, true)
.setValue(SOUL, false)
.setValue(ITEM_DIRECTION, Direction.NORTH))
.setValue(ITEM_DIRECTION, Direction.NORTH)
.setValue(POWERED, false))
}
override fun getStateForPlacement(ctx: BlockPlaceContext): BlockState? {
@@ -198,7 +198,7 @@ class CampfireBlock(settings: Properties) : BaseEntityBlock(settings), SimpleWat
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(FACING, ITEM_DIRECTION, LIT, SOUL)
builder.add(FACING, ITEM_DIRECTION, LIT, SOUL, POWERED)
}
override fun updateShape(
@@ -215,13 +215,8 @@ class CampfireBlock(settings: Properties) : BaseEntityBlock(settings), SimpleWat
override fun getRenderShape(state: BlockState) = RenderShape.MODEL
override fun getAnalogOutputSignal(state: BlockState, world: Level, pos: BlockPos): Int {
val stack = (world.getBlockEntity(pos) as DisplayCaseBlockEntity).getStack()
if (stack.isEmpty) return 0
if (stack.item is PokeBallItem) return 3
if (stack.item is BlockItem) return 2
return 1
override fun getAnalogOutputSignal(state: BlockState, level: Level, pos: BlockPos): Int {
return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(level.getBlockEntity(pos))
}
override fun hasAnalogOutputSignal(state: BlockState): Boolean = true
@@ -304,4 +299,26 @@ class CampfireBlock(settings: Properties) : BaseEntityBlock(settings), SimpleWat
override fun getCloneItemStack(level: LevelReader, pos: BlockPos, state: BlockState): ItemStack {
return if (state.getValue(SOUL)) ItemStack(Blocks.SOUL_CAMPFIRE) else ItemStack(Blocks.CAMPFIRE)
}
override fun neighborChanged(
state: BlockState,
level: Level,
pos: BlockPos,
neighborBlock: Block,
neighborPos: BlockPos,
movedByPiston: Boolean
) {
super.neighborChanged(state, level, pos, neighborBlock, neighborPos, movedByPiston)
val isPowered = level.hasNeighborSignal(pos)
val blockEntity = level.getBlockEntity(pos) as? CampfireBlockEntity ?: return
if (isPowered != state.getValue(POWERED)) {
level.setBlock(pos, state.setValue(POWERED, isPowered), UPDATE_ALL)
blockEntity.toggleLid(!isPowered, pos)
}
}
override fun isSignalSource(state: BlockState): Boolean {
return true
}
}
@@ -12,7 +12,7 @@ import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonRecipeTypes
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.cooking.getColourMixFromSeasonings
import com.cobblemon.mod.common.block.PotComponent
import com.cobblemon.mod.common.item.components.PotComponent
import com.cobblemon.mod.common.block.campfirepot.CookingPotMenu
import com.cobblemon.mod.common.client.particle.BedrockParticleOptionsRepository
import com.cobblemon.mod.common.client.particle.ParticleStorm
@@ -20,10 +20,10 @@ import com.cobblemon.mod.common.client.render.MatrixWrapper
import com.cobblemon.mod.common.client.sound.BlockEntitySoundTracker
import com.cobblemon.mod.common.client.sound.instances.CancellableSoundInstance
import com.cobblemon.mod.common.item.crafting.CookingPotRecipeBase
import com.cobblemon.mod.common.util.activateNearbyObservers
import com.cobblemon.mod.common.util.playSoundServer
import com.mojang.blaze3d.vertex.PoseStack
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
import java.util.Optional
import net.minecraft.client.multiplayer.ClientLevel
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
@@ -41,11 +41,7 @@ import net.minecraft.world.ContainerHelper
import net.minecraft.world.WorldlyContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.StackedContents
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.ContainerData
import net.minecraft.world.inventory.CraftingContainer
import net.minecraft.world.inventory.RecipeCraftingHolder
import net.minecraft.world.inventory.StackedContentsCompatible
import net.minecraft.world.inventory.*
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.item.crafting.CraftingInput
@@ -56,9 +52,10 @@ import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.gameevent.GameEvent
import net.minecraft.world.phys.Vec3
import org.joml.Vector4f
import kotlin.compareTo
import java.util.*
class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlockEntity(
CobblemonBlockEntities.CAMPFIRE,
@@ -95,14 +92,17 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
val isSoundActive = BlockEntitySoundTracker.isActive(pos, campfireBlockEntity.runningSound.location)
if (isLit && !isSoundActive) {
BlockEntitySoundTracker.play(pos, CancellableSoundInstance(campfireBlockEntity.runningSound, pos, true, 0.8f, 1.0f))
BlockEntitySoundTracker.play(
pos,
CancellableSoundInstance(campfireBlockEntity.runningSound, pos, true, 0.8f, 1.0f)
)
} else if (!isLit && isSoundActive) {
BlockEntitySoundTracker.stop(pos, campfireBlockEntity.runningSound.location)
}
campfireBlockEntity.brothColor =
getColourMixFromSeasonings(campfireBlockEntity.getSeasonings())
?: BASE_BROTH_COLOR
?: BASE_BROTH_COLOR
campfireBlockEntity.bubbleColor =
getColourMixFromSeasonings(campfireBlockEntity.getSeasonings(), true)
@@ -111,15 +111,20 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
if (campfireBlockEntity.particleCooldown > 0) {
campfireBlockEntity.particleCooldown--
} else {
if (isLit) {
if (isLit) {
val position = Vec3(pos.x + 0.5, pos.y + 0.5375, pos.z + 0.5)
campfireBlockEntity.particleEntityHandler(
position = position,
level = level,
particle = ResourceLocation("cobblemon", if (campfireBlockEntity.getSeasonings().isEmpty()) "broth_bubbles_basic" else "broth_bubbles")
particle = ResourceLocation(
"cobblemon",
if (campfireBlockEntity.getSeasonings()
.isEmpty()
) "broth_bubbles_basic" else "broth_bubbles"
)
)
}
}
campfireBlockEntity.particleCooldown = 20
}
@@ -163,7 +168,11 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
}
if (!resultSlotItem.isEmpty) {
if (!ItemStack.isSameItemSameComponents(resultSlotItem, cookedItem) || resultSlotItem.count >= resultSlotItem.maxStackSize) {
if (!ItemStack.isSameItemSameComponents(
resultSlotItem,
cookedItem
) || resultSlotItem.count >= resultSlotItem.maxStackSize
) {
campfireBlockEntity.cookingProgress = 0
return
}
@@ -196,18 +205,19 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
}
private val runningSound = CobblemonSounds.CAMPFIRE_POT_COOK
private var cookingProgress : Int = 0
private var cookingTotalTime : Int = COOKING_TOTAL_TIME
private var isLidOpen : Boolean = true
private var items : NonNullList<ItemStack> = NonNullList.withSize(ITEMS_SIZE, ItemStack.EMPTY)
private var cookingProgress: Int = 0
private var cookingTotalTime: Int = COOKING_TOTAL_TIME
private var isLidOpen: Boolean = true
private var items: NonNullList<ItemStack> = NonNullList.withSize(ITEMS_SIZE, ItemStack.EMPTY)
private val recipesUsed: Object2IntOpenHashMap<ResourceLocation> = Object2IntOpenHashMap()
private val quickCheck: RecipeManager.CachedCheck<CraftingInput, *> = RecipeManager.createCheck(CobblemonRecipeTypes.COOKING_POT_COOKING)
private val quickCheck: RecipeManager.CachedCheck<CraftingInput, *> =
RecipeManager.createCheck(CobblemonRecipeTypes.COOKING_POT_COOKING)
private var potComponent: PotComponent? = null
private var particleCooldown: Int = 0
var brothColor: Int = BASE_BROTH_COLOR
var bubbleColor: Int = 0xFFFFFF
var dataAccess : ContainerData = object : ContainerData {
var dataAccess: ContainerData = object : ContainerData {
override fun get(index: Int): Int {
return when (index) {
COOKING_PROGRESS_INDEX -> this@CampfireBlockEntity.cookingProgress
@@ -235,15 +245,16 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
val matrix = PoseStack()
wrapper.updateMatrix(matrix.last().pose())
wrapper.updatePosition(position)
val effect = BedrockParticleOptionsRepository.getEffect(particle) ?: throw IllegalStateException("Particle with resource location $particle not found")
val effect = BedrockParticleOptionsRepository.getEffect(particle)
?: throw IllegalStateException("Particle with resource location $particle not found")
val particleStorm = ParticleStorm(
effect,
wrapper,
wrapper,
level as ClientLevel,
sourceAlive = { cookingProgress > 0 },
sourceVisible = { cookingProgress > 0 },
sourceAlive = { cookingProgress > 0 },
sourceVisible = { cookingProgress > 0 },
getParticleColor = {
val red = FastColor.ARGB32.red(bubbleColor) / 255F
val green = FastColor.ARGB32.green(bubbleColor) / 255F
@@ -268,6 +279,7 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
// Replace with empty bucket
setItem(i, ItemStack(Items.BUCKET))
}
Items.HONEY_BOTTLE -> {
// TODO: Currently eats the empty bottles until the honey bottle stack is empty, replace with better system later.
itemInSlot.shrink(1)
@@ -275,6 +287,7 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
setItem(i, ItemStack.EMPTY)
}
}
else -> {
// Decrease the stack size by 1
itemInSlot.shrink(1)
@@ -323,9 +336,7 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
}
override fun getContainerSize() = this.items.size
override fun getSlotsForFace(side: Direction) = intArrayOf(0, 1, 2)
override fun canPlaceItemThroughFace(index: Int, itemStack: ItemStack, direction: Direction?) = false
override fun canTakeItemThroughFace(index: Int, stack: ItemStack, direction: Direction) = false
override fun getSlotsForFace(side: Direction) = (0..12).toList().toIntArray()
override fun setRecipeUsed(recipe: RecipeHolder<*>?) {
if (recipe != null) {
@@ -413,4 +424,34 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
BlockEntitySoundTracker.stop(blockPos, runningSound.location)
}
}
fun toggleLid(isOpen: Boolean, blockPos: BlockPos) {
this.isLidOpen = isOpen
level?.let { lvl ->
lvl.activateNearbyObservers(blockPos)
lvl.playSoundServer(
position = blockPos.center,
sound = if (isOpen) CobblemonSounds.CAMPFIRE_POT_OPEN else CobblemonSounds.CAMPFIRE_POT_CLOSE
)
lvl.gameEvent(
null,
if (isOpen) GameEvent.BLOCK_OPEN else GameEvent.BLOCK_CLOSE,
blockPos
)
}
setChanged()
}
override fun canTakeItemThroughFace(index: Int, stack: ItemStack, direction: Direction): Boolean {
return index == RESULT_SLOT
}
override fun canPlaceItemThroughFace(index: Int, itemStack: ItemStack, direction: Direction?): Boolean {
return when (direction) {
Direction.UP -> SEASONING_SLOTS.contains(index)
else -> CRAFTING_GRID_SLOTS.contains(index)
}
}
}
@@ -0,0 +1,168 @@
/*
* 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.CobblemonSounds
import com.cobblemon.mod.common.block.chest.GildedState
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup
import net.minecraft.core.NonNullList
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
import net.minecraft.world.ContainerHelper
import net.minecraft.world.WorldlyContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.ChestMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.ContainerOpenersCounter
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperFridgeBlockEntity(pos: BlockPos, state: BlockState) : RandomizableContainerBlockEntity(CobblemonBlockEntities.COPPER_FRIDGE, pos, state), WorldlyContainer {
var inventoryContents: NonNullList<ItemStack> = NonNullList.withSize(NUM_SLOTS, ItemStack.EMPTY)
val posableState: GildedState = GildedState()
private val stateManager: ContainerOpenersCounter = object : ContainerOpenersCounter() {
override fun onOpen(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_OPEN)
}
override fun onClose(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_CLOSE)
}
override fun openerCountChanged(
world: Level,
pos: BlockPos,
state: BlockState,
oldViewerCount: Int,
newViewerCount: Int
) {
this@CopperFridgeBlockEntity.onViewerCountUpdate(world, pos, state, oldViewerCount, newViewerCount)
}
override fun isOwnContainer(player: Player): Boolean {
if (player.containerMenu is ChestMenu) {
val inventory = (player.containerMenu as ChestMenu).container
return inventory === this@CopperFridgeBlockEntity
}
return false
}
}
override fun getContainerSize() = NUM_SLOTS
override fun getDefaultName() = Component.translatable("block.cobblemon.copper_fridge")
override fun createMenu(syncId: Int, playerInventory: Inventory): AbstractContainerMenu =
ChestMenu.sixRows(syncId, playerInventory, this)
override fun getItems() = inventoryContents
override fun startOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.incrementOpeners(player, level, blockPos, blockState)
}
}
override fun stopOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.decrementOpeners(player, level, blockPos, blockState)
}
}
override fun getSlotsForFace(side: Direction): IntArray {
return IntArray(NUM_SLOTS) { it }
}
override fun canPlaceItemThroughFace(slot: Int, stack: ItemStack, dir: Direction?): Boolean {
return dir != Direction.DOWN
}
override fun canTakeItemThroughFace(slot: Int, stack: ItemStack, dir: Direction): Boolean {
return dir == Direction.DOWN
}
override fun stillValid(player: Player) = !player.isSpectator
override fun setItems(inventory: NonNullList<ItemStack>) {
inventoryContents = inventory
}
companion object {
val NUM_SLOTS = 54
fun playSound(world: Level, pos: BlockPos, state: BlockState, sound: SoundEvent) {
var d = pos.x.toDouble() + 0.5
val e = pos.y.toDouble() + 0.5
var f = pos.z.toDouble() + 0.5
val direction = state.getValue(BlockStateProperties.HORIZONTAL_FACING)
d += direction.stepX.toDouble() * 0.5
f += direction.stepZ.toDouble() * 0.5
world.playSound(
null,
d,
e,
f,
sound,
SoundSource.BLOCKS,
0.5f,
world.random.nextFloat() * 0.1f + 0.9f
)
}
}
override fun triggerEvent(type: Int, data: Int): Boolean {
if (type == 1) {
val isNowOpen = data > 0
val wasOpen = posableState.currentPose == "open"
val model = posableState.currentModel ?: return true
if (isNowOpen && !wasOpen) {
model.moveToPose(posableState, model.poses["open"]!!)
} else if (!isNowOpen && wasOpen) {
model.moveToPose(posableState, model.poses["closed"]!!)
}
return true
}
return super.triggerEvent(type, data)
}
fun onViewerCountUpdate(world: Level, pos: BlockPos, state: BlockState, oldViewerCount: Int, newViewerCount: Int) {
val block = state.block
world.blockEvent(pos, block, 1, newViewerCount)
}
override fun saveAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.saveAdditional(nbt, registryLookup)
if (!trySaveLootTable(nbt)) {
ContainerHelper.saveAllItems(nbt, inventoryContents, registryLookup)
}
}
override fun loadAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.loadAdditional(nbt, registryLookup)
inventoryContents= NonNullList.withSize(containerSize, ItemStack.EMPTY)
if (!tryLoadLootTable(nbt)) {
ContainerHelper.loadAllItems(nbt, inventoryContents, registryLookup)
}
}
fun tick() {
if (!this.remove) {
stateManager.recheckOpeners(level, blockPos, this.blockState)
}
}
}
@@ -0,0 +1,168 @@
/*
* 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.CobblemonSounds
import com.cobblemon.mod.common.block.chest.GildedState
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup
import net.minecraft.core.NonNullList
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
import net.minecraft.world.ContainerHelper
import net.minecraft.world.WorldlyContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.ChestMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.ContainerOpenersCounter
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperOvenBlockEntity(pos: BlockPos, state: BlockState) : RandomizableContainerBlockEntity(CobblemonBlockEntities.COPPER_OVEN, pos, state), WorldlyContainer {
var inventoryContents: NonNullList<ItemStack> = NonNullList.withSize(NUM_SLOTS, ItemStack.EMPTY)
val posableState: GildedState = GildedState()
private val stateManager: ContainerOpenersCounter = object : ContainerOpenersCounter() {
override fun onOpen(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_OPEN)
}
override fun onClose(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_CLOSE)
}
override fun openerCountChanged(
world: Level,
pos: BlockPos,
state: BlockState,
oldViewerCount: Int,
newViewerCount: Int
) {
this@CopperOvenBlockEntity.onViewerCountUpdate(world, pos, state, oldViewerCount, newViewerCount)
}
override fun isOwnContainer(player: Player): Boolean {
if (player.containerMenu is ChestMenu) {
val inventory = (player.containerMenu as ChestMenu).container
return inventory === this@CopperOvenBlockEntity
}
return false
}
}
override fun getContainerSize() = NUM_SLOTS
override fun getDefaultName() = Component.translatable("block.cobblemon.copper_oven")
override fun createMenu(syncId: Int, playerInventory: Inventory): AbstractContainerMenu =
ChestMenu.threeRows(syncId, playerInventory, this)
override fun getItems() = inventoryContents
override fun startOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.incrementOpeners(player, level, blockPos, blockState)
}
}
override fun stopOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.decrementOpeners(player, level, blockPos, blockState)
}
}
override fun getSlotsForFace(side: Direction): IntArray {
return IntArray(NUM_SLOTS) { it }
}
override fun canPlaceItemThroughFace(slot: Int, stack: ItemStack, dir: Direction?): Boolean {
return dir != Direction.DOWN
}
override fun canTakeItemThroughFace(slot: Int, stack: ItemStack, dir: Direction): Boolean {
return dir == Direction.DOWN
}
override fun stillValid(player: Player) = !player.isSpectator
override fun setItems(inventory: NonNullList<ItemStack>) {
inventoryContents = inventory
}
companion object {
val NUM_SLOTS = 27
fun playSound(world: Level, pos: BlockPos, state: BlockState, sound: SoundEvent) {
var d = pos.x.toDouble() + 0.5
val e = pos.y.toDouble() + 0.5
var f = pos.z.toDouble() + 0.5
val direction = state.getValue(BlockStateProperties.HORIZONTAL_FACING)
d += direction.stepX.toDouble() * 0.5
f += direction.stepZ.toDouble() * 0.5
world.playSound(
null,
d,
e,
f,
sound,
SoundSource.BLOCKS,
0.5f,
world.random.nextFloat() * 0.1f + 0.9f
)
}
}
override fun triggerEvent(type: Int, data: Int): Boolean {
if (type == 1) {
val isNowOpen = data > 0
val wasOpen = posableState.currentPose == "open"
val model = posableState.currentModel ?: return true
if (isNowOpen && !wasOpen) {
model.moveToPose(posableState, model.poses["open"]!!)
} else if (!isNowOpen && wasOpen) {
model.moveToPose(posableState, model.poses["closed"]!!)
}
return true
}
return super.triggerEvent(type, data)
}
fun onViewerCountUpdate(world: Level, pos: BlockPos, state: BlockState, oldViewerCount: Int, newViewerCount: Int) {
val block = state.block
world.blockEvent(pos, block, 1, newViewerCount)
}
override fun saveAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.saveAdditional(nbt, registryLookup)
if (!trySaveLootTable(nbt)) {
ContainerHelper.saveAllItems(nbt, inventoryContents, registryLookup)
}
}
override fun loadAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.loadAdditional(nbt, registryLookup)
inventoryContents= NonNullList.withSize(containerSize, ItemStack.EMPTY)
if (!tryLoadLootTable(nbt)) {
ContainerHelper.loadAllItems(nbt, inventoryContents, registryLookup)
}
}
fun tick() {
if (!this.remove) {
stateManager.recheckOpeners(level, blockPos, this.blockState)
}
}
}
@@ -0,0 +1,168 @@
/*
* 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.CobblemonSounds
import com.cobblemon.mod.common.block.chest.GildedState
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup
import net.minecraft.core.NonNullList
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
import net.minecraft.world.ContainerHelper
import net.minecraft.world.WorldlyContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.ChestMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.ContainerOpenersCounter
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperWasherBlockEntity(pos: BlockPos, state: BlockState) : RandomizableContainerBlockEntity(CobblemonBlockEntities.COPPER_WASHER, pos, state), WorldlyContainer {
var inventoryContents: NonNullList<ItemStack> = NonNullList.withSize(NUM_SLOTS, ItemStack.EMPTY)
val posableState: GildedState = GildedState()
private val stateManager: ContainerOpenersCounter = object : ContainerOpenersCounter() {
override fun onOpen(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_OPEN)
}
override fun onClose(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_CLOSE)
}
override fun openerCountChanged(
world: Level,
pos: BlockPos,
state: BlockState,
oldViewerCount: Int,
newViewerCount: Int
) {
this@CopperWasherBlockEntity.onViewerCountUpdate(world, pos, state, oldViewerCount, newViewerCount)
}
override fun isOwnContainer(player: Player): Boolean {
if (player.containerMenu is ChestMenu) {
val inventory = (player.containerMenu as ChestMenu).container
return inventory === this@CopperWasherBlockEntity
}
return false
}
}
override fun getContainerSize() = NUM_SLOTS
override fun getDefaultName() = Component.translatable("block.cobblemon.copper_washer")
override fun createMenu(syncId: Int, playerInventory: Inventory): AbstractContainerMenu =
ChestMenu.threeRows(syncId, playerInventory, this)
override fun getItems() = inventoryContents
override fun startOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.incrementOpeners(player, level, blockPos, blockState)
}
}
override fun stopOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.decrementOpeners(player, level, blockPos, blockState)
}
}
override fun getSlotsForFace(side: Direction): IntArray {
return IntArray(NUM_SLOTS) { it }
}
override fun canPlaceItemThroughFace(slot: Int, stack: ItemStack, dir: Direction?): Boolean {
return dir != Direction.DOWN
}
override fun canTakeItemThroughFace(slot: Int, stack: ItemStack, dir: Direction): Boolean {
return dir == Direction.DOWN
}
override fun stillValid(player: Player) = !player.isSpectator
override fun setItems(inventory: NonNullList<ItemStack>) {
inventoryContents = inventory
}
companion object {
val NUM_SLOTS = 27
fun playSound(world: Level, pos: BlockPos, state: BlockState, sound: SoundEvent) {
var d = pos.x.toDouble() + 0.5
val e = pos.y.toDouble() + 0.5
var f = pos.z.toDouble() + 0.5
val direction = state.getValue(BlockStateProperties.HORIZONTAL_FACING)
d += direction.stepX.toDouble() * 0.5
f += direction.stepZ.toDouble() * 0.5
world.playSound(
null,
d,
e,
f,
sound,
SoundSource.BLOCKS,
0.5f,
world.random.nextFloat() * 0.1f + 0.9f
)
}
}
override fun triggerEvent(type: Int, data: Int): Boolean {
if (type == 1) {
val isNowOpen = data > 0
val wasOpen = posableState.currentPose == "open"
val model = posableState.currentModel ?: return true
if (isNowOpen && !wasOpen) {
model.moveToPose(posableState, model.poses["open"]!!)
} else if (!isNowOpen && wasOpen) {
model.moveToPose(posableState, model.poses["closed"]!!)
}
return true
}
return super.triggerEvent(type, data)
}
fun onViewerCountUpdate(world: Level, pos: BlockPos, state: BlockState, oldViewerCount: Int, newViewerCount: Int) {
val block = state.block
world.blockEvent(pos, block, 1, newViewerCount)
}
override fun saveAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.saveAdditional(nbt, registryLookup)
if (!trySaveLootTable(nbt)) {
ContainerHelper.saveAllItems(nbt, inventoryContents, registryLookup)
}
}
override fun loadAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.loadAdditional(nbt, registryLookup)
inventoryContents= NonNullList.withSize(containerSize, ItemStack.EMPTY)
if (!tryLoadLootTable(nbt)) {
ContainerHelper.loadAllItems(nbt, inventoryContents, registryLookup)
}
}
fun tick() {
if (!this.remove) {
stateManager.recheckOpeners(level, blockPos, this.blockState)
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.general
import net.minecraft.core.BlockPos
import net.minecraft.world.entity.Entity
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.RotatedPillarBlock
import net.minecraft.world.level.block.state.BlockState
class BaleBlock(properties: Properties, val fallDamageMultiplier: Float = 0.3f) : RotatedPillarBlock(properties) {
override fun fallOn(level: Level, state: BlockState, pos: BlockPos, entity: Entity, fallDistance: Float) {
entity.causeFallDamage(fallDistance, fallDamageMultiplier, level.damageSources().fall())
}
}
@@ -6,9 +6,8 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
package com.cobblemon.mod.common.block.general
import com.mojang.serialization.MapCodec
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.world.item.context.BlockPlaceContext
@@ -24,7 +23,7 @@ import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
import net.minecraft.world.level.block.CarpetBlock
class TatamiMatBlock(settings: Properties) : CarpetBlock(settings) {
class HorizontalRotationCarpetBlock(settings: Properties) : CarpetBlock(settings) {
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH))
@@ -58,7 +57,7 @@ class TatamiMatBlock(settings: Properties) : CarpetBlock(settings) {
}
companion object {
val CODEC = simpleCodec(::TatamiMatBlock)
val CODEC = simpleCodec(::HorizontalRotationCarpetBlock)
val HITBOX = Shapes.box(0.0, 0.0, 0.0, 1.0, 0.0625, 1.0)
}
@@ -6,60 +6,29 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
package com.cobblemon.mod.common.block.general
import com.mojang.serialization.MapCodec
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Rotation
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
import net.minecraft.world.level.block.CarpetBlock
class TatamiBlock(settings: Properties) : Block(settings) {
class HorizontalRotationalBlock(settings: Properties) : Block(settings) {
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH))
}
override fun getStateForPlacement(blockPlaceContext: BlockPlaceContext): BlockState {
return defaultBlockState().setValue(HORIZONTAL_FACING, blockPlaceContext.horizontalDirection)
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HORIZONTAL_FACING)
}
override fun getShape(
state: BlockState,
blockGetter: BlockGetter,
pos: BlockPos,
collisionContext: CollisionContext
): VoxelShape {
return HITBOX
}
@Deprecated("Deprecated in Java")
override fun rotate(state: BlockState, rotation: Rotation): BlockState {
return state.setValue(HORIZONTAL_FACING, rotation.rotate(state.getValue(HORIZONTAL_FACING)))
}
@Deprecated("Deprecated in Java")
override fun isPathfindable(state: BlockState, type: PathComputationType): Boolean {
return false
}
companion object {
val CODEC = simpleCodec(::TatamiBlock)
val HITBOX = Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 1.0)
}
}
@@ -1,57 +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.brewing
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.brewing.ingredient.CobblemonIngredient
import com.cobblemon.mod.common.brewing.ingredient.CobblemonItemIngredient
import com.cobblemon.mod.common.brewing.ingredient.CobblemonPotionIngredient
import net.minecraft.world.item.Item
import net.minecraft.world.item.alchemy.Potions
object BrewingRecipes {
val recipes: List<Triple<CobblemonIngredient, Item, Item>> by lazy {
listOf(
Triple(CobblemonPotionIngredient(Potions.WATER), CobblemonItems.MEDICINAL_LEEK, CobblemonItems.MEDICINAL_BREW),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.LEPPA_BERRY, CobblemonItems.ETHER),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.HOPO_BERRY, CobblemonItems.ELIXIR),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.ORAN_BERRY, CobblemonItems.POTION),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.SITRUS_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.PECHA_BERRY, CobblemonItems.ANTIDOTE),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.CHESTO_BERRY, CobblemonItems.AWAKENING),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.RAWST_BERRY, CobblemonItems.BURN_HEAL),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.ASPEAR_BERRY, CobblemonItems.ICE_HEAL),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.CHERI_BERRY, CobblemonItems.PARALYZE_HEAL),
convert(CobblemonItems.BURN_HEAL, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.ANTIDOTE, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.AWAKENING, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.ICE_HEAL, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.PARALYZE_HEAL, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.ETHER, CobblemonItems.PEP_UP_FLOWER, CobblemonItems.MAX_ETHER),
convert(CobblemonItems.ELIXIR, CobblemonItems.PEP_UP_FLOWER, CobblemonItems.MAX_ELIXIR),
convert(CobblemonItems.POTION, CobblemonItems.ENERGY_ROOT, CobblemonItems.SUPER_POTION),
convert(CobblemonItems.SUPER_POTION, CobblemonItems.FIGY_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.SUPER_POTION, CobblemonItems.WIKI_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.SUPER_POTION, CobblemonItems.MAGO_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.SUPER_POTION, CobblemonItems.AGUAV_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.SUPER_POTION, CobblemonItems.IAPAPA_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.HYPER_POTION, CobblemonItems.VIVICHOKE, CobblemonItems.MAX_POTION),
convert(CobblemonItems.MAX_POTION, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_RESTORE),
convert(CobblemonItems.POTION, CobblemonItems.PETAYA_BERRY, CobblemonItems.THROAT_SPRAY)
)
}
private fun convert(input: Item, ingredient: Item, output: Item): Triple<CobblemonIngredient, Item, Item> {
return Triple(CobblemonItemIngredient(input), ingredient, output)
}
}
@@ -1,36 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.brewing.ingredient
import net.minecraft.world.item.ItemStack
import org.jetbrains.annotations.ApiStatus
/**
* The Cobblemon representation of a brewing ingredient.
* This is done to abstract platform specific requirements for a more custom solution to brewing.
*/
@ApiStatus.Internal
sealed interface CobblemonIngredient {
/**
* Tests if a given [stack] is valid for this ingredient.
*
* @param stack The [ItemStack] being tested.
* @return If the given [stack] is valid for this ingredient.
*/
fun matches(stack: ItemStack): Boolean
/**
* Resolves list of [ItemStack]s that is used by the vanilla Ingredient implementation when a platform requires wrapping.
*
* @return A list of [ItemStack]s
*/
fun matchingStacks(): List<ItemStack>
}
@@ -1,22 +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.brewing.ingredient
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
class CobblemonItemIngredient(val item: Item) : CobblemonIngredient {
override fun matches(stack: ItemStack): Boolean = stack.`is`(this.item)
override fun matchingStacks(): List<ItemStack> = listOf(this.item.defaultInstance)
}
@@ -1,34 +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.brewing.ingredient
import net.minecraft.core.Holder
import net.minecraft.core.component.DataComponents
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.item.alchemy.Potion
import net.minecraft.world.item.alchemy.PotionContents
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
class CobblemonPotionIngredient(val potion: Holder<Potion>) : CobblemonIngredient {
override fun matches(stack: ItemStack): Boolean {
return stack.get(DataComponents.POTION_CONTENTS)?.`is`(potion) ?: false
}
override fun matchingStacks(): List<ItemStack> {
val list = arrayListOf<ItemStack>()
list += PotionContents.createItemStack(Items.POTION, potion)
list += PotionContents.createItemStack(Items.SPLASH_POTION, potion)
list += PotionContents.createItemStack(Items.LINGERING_POTION, potion)
return list
}
}
@@ -14,7 +14,7 @@ import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonClientImplementation
import com.cobblemon.mod.common.CobblemonEntities
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.CobblemonMenuType.COOKING_POT
import com.cobblemon.mod.common.CobblemonMenuType
import com.cobblemon.mod.common.api.berry.Berries
import com.cobblemon.mod.common.api.scheduling.ClientTaskTracker
import com.cobblemon.mod.common.api.storage.player.client.ClientGeneralPlayerData
@@ -53,7 +53,6 @@ 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.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.item.food.SinisterTeaItem
import com.cobblemon.mod.common.platform.events.PlatformEvents
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext
import com.cobblemon.mod.common.util.isLookingAt
@@ -83,6 +82,7 @@ object CobblemonClient {
var battle: ClientBattle? = null
var clientPlayerData = ClientGeneralPlayerData()
var clientPokedexData = ClientPokedexManager(mutableMapOf())
/** If true then we won't bother them anymore about choosing a starter even if it's a thing they can do. */
var checkedStarterScreen = false
var requests = ClientPlayerActionRequests()
@@ -147,9 +147,9 @@ object CobblemonClient {
if (pokedexUsageContext.scanningGuiOpen &&
!(selectedItem.`is`(CobblemonItemTags.POKEDEX)) &&
!(player.offhandItem.`is`(CobblemonItemTags.POKEDEX) &&
player.isUsingItem == true &&
player.usedItemHand == InteractionHand.OFF_HAND
)
player.isUsingItem == true &&
player.usedItemHand == InteractionHand.OFF_HAND
)
) {
// Stop using Pokédex in main hand if player switches to a different slot in hotbar
pokedexUsageContext.stopUsing(PokedexUsageContext.OPEN_SCANNER_BUFFER_TICKS + 1)
@@ -157,7 +157,10 @@ object CobblemonClient {
if (event.client.isPaused) {
return@subscribe
}
val nearbyShinies = player.level().getEntities(player, AABB.ofSize(player.position(), 16.0, 16.0, 16.0)) { it is PokemonEntity && it.pokemon.shiny && !it.isSilent }
val nearbyShinies = player.level().getEntities(
player,
AABB.ofSize(player.position(), 16.0, 16.0, 16.0)
) { it is PokemonEntity && it.pokemon.shiny && !it.isSilent }
nearbyShinies?.firstOrNull { player.isLookingAt(it) && !player.isSpectator }.let {
if (it is PokemonEntity) {
it.delegate.spawnShinyParticle(player)
@@ -285,8 +288,8 @@ object CobblemonClient {
CobblemonBlocks.PINK_CAMPFIRE_POT,
CobblemonBlocks.RED_CAMPFIRE_POT,
CobblemonBlocks.WHITE_CAMPFIRE_POT,
CobblemonBlocks.YELLOW_CAMPFIRE_POT
CobblemonBlocks.YELLOW_CAMPFIRE_POT,
CobblemonBlocks.COPPER_FAN
)
this.createBoatModelLayers()
@@ -304,30 +307,46 @@ object CobblemonClient {
@Suppress("UNCHECKED_CAST")
fun onAddLayer(skinMap: Map<PlayerSkin.Model, EntityRenderer<out Player>>?) {
var renderer: LivingEntityRenderer<Player, PlayerModel<Player>>? = skinMap?.get(PlayerSkin.Model.WIDE) as LivingEntityRenderer<Player, PlayerModel<Player>>
var renderer: LivingEntityRenderer<Player, PlayerModel<Player>>? =
skinMap?.get(PlayerSkin.Model.WIDE) as LivingEntityRenderer<Player, PlayerModel<Player>>
renderer?.addLayer(PokemonOnShoulderRenderer(renderer))
renderer = skinMap[PlayerSkin.Model.SLIM] as LivingEntityRenderer<Player, PlayerModel<Player>>?
renderer?.addLayer(PokemonOnShoulderRenderer(renderer))
}
private fun registerMenuScreens() {
MenuScreens.register(COOKING_POT, ::CookingPotScreen)
MenuScreens.register(CobblemonMenuType.COOKING_POT, ::CookingPotScreen)
}
private fun registerBlockEntityRenderers() {
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.HEALING_MACHINE, ::HealingMachineRenderer)
this.implementation.registerBlockEntityRenderer(
CobblemonBlockEntities.HEALING_MACHINE,
::HealingMachineRenderer
)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.BERRY, ::BerryBlockRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.SIGN, ::SignRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.HANGING_SIGN, ::HangingSignRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.FOSSIL_ANALYZER, ::FossilAnalyzerRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.RESTORATION_TANK, ::RestorationTankRenderer)
this.implementation.registerBlockEntityRenderer(
CobblemonBlockEntities.FOSSIL_ANALYZER,
::FossilAnalyzerRenderer
)
this.implementation.registerBlockEntityRenderer(
CobblemonBlockEntities.RESTORATION_TANK,
::RestorationTankRenderer
)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.GILDED_CHEST, ::GildedChestBlockRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.DISPLAY_CASE, ::DisplayCaseRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.LECTERN, ::LecternBlockEntityRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.CAMPFIRE, ::CampfireBlockEntityRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.LURE_CAKE, ::CakeBlockEntityRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.POKE_CAKE, ::CakeBlockEntityRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.CANDLE_POKE_CAKE, ::CandlePokeCakeBlockEntityRenderer)
this.implementation.registerBlockEntityRenderer(
CobblemonBlockEntities.CANDLE_POKE_CAKE,
::CandlePokeCakeBlockEntityRenderer
)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.COPPER_OVEN, ::CopperOvenBlockRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.COPPER_WASHER, ::CopperWasherBlockRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.COPPER_FRIDGE, ::CopperFridgeBlockRenderer)
}
private fun registerEntityRenderers() {
@@ -338,7 +357,12 @@ object CobblemonClient {
LOGGER.info("Registering Boat renderer")
this.implementation.registerEntityRenderer(CobblemonEntities.BOAT) { ctx -> CobblemonBoatRenderer(ctx, false) }
LOGGER.info("Registering Boat with Chest renderer")
this.implementation.registerEntityRenderer(CobblemonEntities.CHEST_BOAT) { ctx -> CobblemonBoatRenderer(ctx, true) }
this.implementation.registerEntityRenderer(CobblemonEntities.CHEST_BOAT) { ctx ->
CobblemonBoatRenderer(
ctx,
true
)
}
LOGGER.info("Registering Generic Bedrock renderer")
this.implementation.registerEntityRenderer(CobblemonEntities.GENERIC_BEDROCK_ENTITY, ::GenericBedrockRenderer)
LOGGER.info("Registering Generic Bedrock Entity renderer")
@@ -382,8 +406,14 @@ object CobblemonClient {
private fun createBoatModelLayers() {
CobblemonBoatType.entries.forEach { type ->
this.implementation.registerLayer(CobblemonBoatRenderer.createBoatModelLayer(type, false), BoatModel::createBodyModel)
this.implementation.registerLayer(CobblemonBoatRenderer.createBoatModelLayer(type, true), ChestBoatModel::createBodyModel)
this.implementation.registerLayer(
CobblemonBoatRenderer.createBoatModelLayer(type, false),
BoatModel::createBodyModel
)
this.implementation.registerLayer(
CobblemonBoatRenderer.createBoatModelLayer(type, true),
ChestBoatModel::createBodyModel
)
}
}
@@ -13,6 +13,8 @@ import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.block.campfirepot.CookingPotMenu
import com.cobblemon.mod.common.block.entity.CampfireBlockEntity.Companion.IS_LID_OPEN_INDEX
import com.cobblemon.mod.common.block.entity.CampfireBlockEntity.Companion.PREVIEW_ITEM_SLOT
import com.cobblemon.mod.common.integration.jei.CobblemonJeiPlugin
import com.cobblemon.mod.common.integration.jei.cooking.CampfirePotRecipeCategory
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe
import com.cobblemon.mod.common.mixin.accessor.RecipeBookComponentAccessor
import com.cobblemon.mod.common.net.messages.client.cooking.ToggleCookingPotLidPacket
@@ -20,11 +22,13 @@ import com.cobblemon.mod.common.util.cobblemonResource
import com.mojang.blaze3d.systems.RenderSystem
import net.fabricmc.api.EnvType
import net.fabricmc.api.Environment
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.components.ImageButton
import net.minecraft.client.gui.components.StateSwitchingButton
import net.minecraft.client.gui.components.Tooltip
import net.minecraft.client.gui.components.WidgetSprites
import net.minecraft.client.gui.screens.Screen
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent
import net.minecraft.client.gui.screens.recipebook.RecipeUpdateListener
@@ -65,7 +69,7 @@ class CookingPotScreen(
}
private val recipeBookComponent: RecipeBookComponent = RecipeBookComponent()
private var widthTooNarrow : Boolean = false
private var widthTooNarrow: Boolean = false
private lateinit var cookButton: CookButton
@@ -82,7 +86,13 @@ class CookingPotScreen(
override fun init() {
super.init()
this.widthTooNarrow = this.width < 379
this.recipeBookComponent.init(this.width, this.height, this.minecraft!!, this.widthTooNarrow, this.menu as RecipeBookMenu<CraftingInput, CookingPotRecipe>)
this.recipeBookComponent.init(
this.width,
this.height,
this.minecraft!!,
this.widthTooNarrow,
this.menu as RecipeBookMenu<CraftingInput, CookingPotRecipe>
)
if (this.recipeBookComponent.isVisible) {
val recipeBookFilterButton = (this.recipeBookComponent as RecipeBookComponentAccessor).filterButton
@@ -190,20 +200,58 @@ class CookingPotScreen(
override fun getRecipeBookComponent(): RecipeBookComponent = this.recipeBookComponent
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
val progressX = leftPos + 96
val progressY = topPos + 39
if (mouseX >= progressX && mouseX < progressX + COOK_PROGRESS_WIDTH &&
mouseY >= progressY && mouseY < progressY + COOK_PROGRESS_HEIGHT
) {
CobblemonJeiPlugin.jeiRuntime?.recipesGui?.showTypes(
listOf(CampfirePotRecipeCategory.RECIPE_TYPE)
)
return true
}
if (this.recipeBookComponent.mouseClicked(mouseX, mouseY, button)) {
this.focused = this.recipeBookComponent
if (this.recipeBookComponent.isVisible) {
val recipeBookFilterButton = (this.recipeBookComponent as RecipeBookComponentAccessor).filterButton
if (recipeBookFilterButton.isMouseOver(mouseX, mouseY)) overrideRecipeBookFilterButton(recipeBookFilterButton)
if (recipeBookFilterButton.isMouseOver(mouseX, mouseY)) overrideRecipeBookFilterButton(
recipeBookFilterButton
)
}
return true
} else {
return if (this.widthTooNarrow && this.recipeBookComponent.isVisible) true else super.mouseClicked(mouseX, mouseY, button)
return if (this.widthTooNarrow && this.recipeBookComponent.isVisible) true else super.mouseClicked(
mouseX,
mouseY,
button
)
}
}
override fun renderTooltip(
guiGraphics: GuiGraphics,
mouseX: Int,
mouseY: Int
) {
val progressX = leftPos + 96
val progressY = topPos + 39
if (mouseX >= progressX && mouseX < progressX + COOK_PROGRESS_WIDTH &&
mouseY >= progressY && mouseY < progressY + COOK_PROGRESS_HEIGHT
) {
guiGraphics.renderTooltip(
this.font,
Component.translatable("jei.tooltip.show.recipes"),
mouseX,
mouseY
)
return
}
super.renderTooltip(guiGraphics, mouseX, mouseY)
}
private fun overrideRecipeBookFilterButton(filterButton: StateSwitchingButton) {
filterButton.initTextureValues(FILTER_BUTTON_SPRITES)
filterButton.setTooltip(
@@ -100,7 +100,8 @@ class PartySelectGUI(
heldItem = pokemon.heldItem,
currentHealth = pokemon.currentHealth,
maxHealth = pokemon.maxHealth,
enabled = pokemon.enabled
enabled = pokemon.enabled,
hoverText = pokemon.hoverText,
) { onPress(pokemon) }
)
}
@@ -24,11 +24,12 @@ import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.lang
import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
import com.google.common.collect.Lists
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.components.Button
import net.minecraft.client.gui.components.Button.CreateNarration
import net.minecraft.client.sounds.SoundManager
import net.minecraft.network.chat.Component
import net.minecraft.util.FormattedCharSequence
import net.minecraft.world.item.ItemStack
import org.joml.Quaternionf
import org.joml.Vector3f
@@ -41,6 +42,7 @@ class PartySlotButton(
val maxHealth: Int,
val heldItem: ItemStack,
val enabled: Boolean = true,
val hoverText: List<Component>,
val parent: PartySelectGUI,
onPress: OnPress
) : Button(x, y, WIDTH, HEIGHT, Component.literal("Pokemon"), onPress, CreateNarration { "".text() }), CobblemonRenderable {
@@ -198,6 +200,12 @@ class PartySlotButton(
matrixStack = matrices
)
}
// Hover Text
if (isHovered && hoverText.isNotEmpty()) {
this.parent.setTooltipForNextRenderPass(Lists.transform<Component, FormattedCharSequence>(hoverText) { it.visualOrderText })
}
matrices.popPose()
}
@@ -12,9 +12,11 @@ import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.block.campfirepot.CampfireBlock
import com.cobblemon.mod.common.block.entity.CampfireBlockEntity.Companion.IS_LID_OPEN_INDEX
import com.cobblemon.mod.common.block.campfirepot.CookingPotMenu
import com.cobblemon.mod.common.block.entity.CampfireBlockEntity
import com.cobblemon.mod.common.block.entity.CampfireBlockEntity.Companion.IS_LID_OPEN_INDEX
import com.cobblemon.mod.common.net.messages.client.cooking.ToggleCookingPotLidPacket
import com.cobblemon.mod.common.util.activateNearbyObservers
import com.cobblemon.mod.common.util.playSoundServer
import com.cobblemon.mod.common.util.raycast
import net.minecraft.server.MinecraftServer
@@ -36,12 +38,9 @@ object ToggleCookingPotLidHandler : ServerNetworkPacketHandler<ToggleCookingPotL
val isLidOpen = if (packet.value) 1 else 0
menu.containerData.set(IS_LID_OPEN_INDEX, isLidOpen)
val raycastBlockPos = player.raycast(player.blockInteractionRange().toFloat() + 1F, ClipContext.Fluid.ANY).blockPos
if (player.level().getBlockState(raycastBlockPos).block is CampfireBlock) {
player.level().playSoundServer(
position = raycastBlockPos.center,
sound = if (isLidOpen == 1) CobblemonSounds.CAMPFIRE_POT_OPEN else CobblemonSounds.CAMPFIRE_POT_CLOSE
)
}
val raycastBlockPos =
player.raycast(player.blockInteractionRange().toFloat() + 1F, ClipContext.Fluid.ANY).blockPos
val blockEntity = player.level().getBlockEntity(raycastBlockPos) as? CampfireBlockEntity ?: return
blockEntity.toggleLid(isLidOpen == 1, raycastBlockPos)
}
}
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.block
import com.cobblemon.mod.common.block.CopperFridgeBlock.Type
import com.cobblemon.mod.common.block.entity.CopperFridgeBlockEntity
import com.cobblemon.mod.common.client.render.models.blockbench.blockentity.BlockEntityModel
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperFridgeBlockRenderer(context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<CopperFridgeBlockEntity> {
val context = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.BLOCK)
it.put(RenderContext.DO_QUIRKS, true)
}
override fun render(
entity: CopperFridgeBlockEntity,
tickDelta: Float,
matrices: PoseStack,
vertexConsumers: MultiBufferSource,
light: Int,
overlay: Int
) {
val aspects = emptySet<String>()
val state = entity.posableState
state.currentAspects = aspects
state.updatePartialTicks(tickDelta)
val poserId = Type.RED.poserId
val model = VaryingModelRepository.getPoser(poserId, state) as BlockEntityModel
model.context = context
val texture = VaryingModelRepository.getTexture(poserId, state)
val vertexConsumer = vertexConsumers.getBuffer(RenderType.entityCutout(texture))
model.bufferProvider = vertexConsumers
state.currentModel = model
context.put(RenderContext.ASPECTS, aspects)
context.put(RenderContext.TEXTURE, texture)
context.put(RenderContext.SPECIES, poserId)
context.put(RenderContext.POSABLE_STATE, state)
matrices.pushPose()
matrices.mulPose(Axis.ZP.rotationDegrees(180f))
matrices.translate(-0.5, 0.0, 0.5)
matrices.mulPose(Axis.YP.rotationDegrees(entity.blockState.getValue(BlockStateProperties.HORIZONTAL_FACING).toYRot()))
matrices.mulPose(Axis.YP.rotationDegrees(180f))
model.applyAnimations(
entity = null,
state = state,
headYaw = 0F,
headPitch = 0F,
limbSwing = 0F,
limbSwingAmount = 0F,
ageInTicks = state.animationSeconds * 20
)
model.render(context, matrices, vertexConsumer, light, overlay, -0x1)
model.withLayerContext(vertexConsumers, state, VaryingModelRepository.getLayers(poserId, state)) {
model.render(context, matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, -0x1)
}
model.setDefault()
matrices.popPose()
}
}
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.block
import com.cobblemon.mod.common.block.entity.CopperOvenBlockEntity
import com.cobblemon.mod.common.block.CopperOvenBlock.Type
import com.cobblemon.mod.common.client.render.models.blockbench.blockentity.BlockEntityModel
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperOvenBlockRenderer(context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<CopperOvenBlockEntity> {
val context = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.BLOCK)
it.put(RenderContext.DO_QUIRKS, true)
}
override fun render(
entity: CopperOvenBlockEntity,
tickDelta: Float,
matrices: PoseStack,
vertexConsumers: MultiBufferSource,
light: Int,
overlay: Int
) {
val aspects = emptySet<String>()
val state = entity.posableState
state.currentAspects = aspects
state.updatePartialTicks(tickDelta)
val poserId = Type.RED.poserId
val model = VaryingModelRepository.getPoser(poserId, state) as BlockEntityModel
model.context = context
val texture = VaryingModelRepository.getTexture(poserId, state)
val vertexConsumer = vertexConsumers.getBuffer(RenderType.entityCutout(texture))
model.bufferProvider = vertexConsumers
state.currentModel = model
context.put(RenderContext.ASPECTS, aspects)
context.put(RenderContext.TEXTURE, texture)
context.put(RenderContext.SPECIES, poserId)
context.put(RenderContext.POSABLE_STATE, state)
matrices.pushPose()
matrices.mulPose(Axis.ZP.rotationDegrees(180f))
matrices.translate(-0.5, 0.0, 0.5)
matrices.mulPose(Axis.YP.rotationDegrees(entity.blockState.getValue(BlockStateProperties.HORIZONTAL_FACING).toYRot()))
matrices.mulPose(Axis.YP.rotationDegrees(180f))
model.applyAnimations(
entity = null,
state = state,
headYaw = 0F,
headPitch = 0F,
limbSwing = 0F,
limbSwingAmount = 0F,
ageInTicks = state.animationSeconds * 20
)
model.render(context, matrices, vertexConsumer, light, overlay, -0x1)
model.withLayerContext(vertexConsumers, state, VaryingModelRepository.getLayers(poserId, state)) {
model.render(context, matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, -0x1)
}
model.setDefault()
matrices.popPose()
}
}
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.block
import com.cobblemon.mod.common.block.CopperWasherBlock.Type
import com.cobblemon.mod.common.block.entity.CopperWasherBlockEntity
import com.cobblemon.mod.common.client.render.models.blockbench.blockentity.BlockEntityModel
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperWasherBlockRenderer(context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<CopperWasherBlockEntity> {
val context = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.BLOCK)
it.put(RenderContext.DO_QUIRKS, true)
}
override fun render(
entity: CopperWasherBlockEntity,
tickDelta: Float,
matrices: PoseStack,
vertexConsumers: MultiBufferSource,
light: Int,
overlay: Int
) {
val aspects = emptySet<String>()
val state = entity.posableState
state.currentAspects = aspects
state.updatePartialTicks(tickDelta)
val poserId = Type.RED.poserId
val model = VaryingModelRepository.getPoser(poserId, state) as BlockEntityModel
model.context = context
val texture = VaryingModelRepository.getTexture(poserId, state)
val vertexConsumer = vertexConsumers.getBuffer(RenderType.entityCutout(texture))
model.bufferProvider = vertexConsumers
state.currentModel = model
context.put(RenderContext.ASPECTS, aspects)
context.put(RenderContext.TEXTURE, texture)
context.put(RenderContext.SPECIES, poserId)
context.put(RenderContext.POSABLE_STATE, state)
matrices.pushPose()
matrices.mulPose(Axis.ZP.rotationDegrees(180f))
matrices.translate(-0.5, 0.0, 0.5)
matrices.mulPose(Axis.YP.rotationDegrees(entity.blockState.getValue(BlockStateProperties.HORIZONTAL_FACING).toYRot()))
matrices.mulPose(Axis.YP.rotationDegrees(180f))
model.applyAnimations(
entity = null,
state = state,
headYaw = 0F,
headPitch = 0F,
limbSwing = 0F,
limbSwingAmount = 0F,
ageInTicks = state.animationSeconds * 20
)
model.render(context, matrices, vertexConsumer, light, overlay, -0x1)
model.withLayerContext(vertexConsumers, state, VaryingModelRepository.getLayers(poserId, state)) {
model.render(context, matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, -0x1)
}
model.setDefault()
matrices.popPose()
}
}
@@ -59,7 +59,6 @@ class PokemonItemRenderer : CobblemonBuiltinItemRenderer {
state.setPoseToFirstSuitable(PoseType.PORTRAIT)
model.applyAnimations(null, state, 0F, 0F, 0F, 0F, 0F)
matrices.translate(model.profileTranslation.x, model.profileTranslation.y, -4.0)
matrices.scale(model.profileScale, model.profileScale, 0.15F)
val rotation = Quaternionf().fromEulerXYZDegrees(Vector3f(transformations.rotation.x, transformations.rotation.y, transformations.rotation.z))
@@ -98,37 +97,37 @@ class PokemonItemRenderer : CobblemonBuiltinItemRenderer {
init {
positions[ItemDisplayContext.GUI] = PokemonItemRenderer().Transformations(
PokemonItemRenderer().Transformation(1.0, -1.9, -0.5),
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
PokemonItemRenderer().Transformation(1.0, -0.2, -0.5),
PokemonItemRenderer().Transformation(0.5F, -0.5F, -3.5F),
PokemonItemRenderer().Transformation(0F, 35F, 0F)
)
positions[ItemDisplayContext.FIXED] = PokemonItemRenderer().Transformations(
PokemonItemRenderer().Transformation(1.0, -2.0, 3.0),
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
PokemonItemRenderer().Transformation(1.0, -0.5, -5.0),
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.1F),
PokemonItemRenderer().Transformation(0F, 35F - 180F, 0F)
)
positions[ItemDisplayContext.FIRST_PERSON_RIGHT_HAND] = PokemonItemRenderer().Transformations(
PokemonItemRenderer().Transformation(2.75, -1.2, 5.0),
PokemonItemRenderer().Transformation(2.75, 0.0, 1.0),
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
PokemonItemRenderer().Transformation(0F, 35F, 0F)
)
positions[ItemDisplayContext.FIRST_PERSON_LEFT_HAND] = PokemonItemRenderer().Transformations(
PokemonItemRenderer().Transformation(-0.75, -1.2, 5.0),
PokemonItemRenderer().Transformation(-0.75, 0.0, 1.0),
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
PokemonItemRenderer().Transformation(0F, -35F, 0F)
)
positions[ItemDisplayContext.THIRD_PERSON_RIGHT_HAND] = PokemonItemRenderer().Transformations(
PokemonItemRenderer().Transformation(1.0, -2.6, 2.75),
PokemonItemRenderer().Transformation(1.0, -1.0, -1.25),
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
PokemonItemRenderer().Transformation(0F, 35F, 0F)
)
positions[ItemDisplayContext.THIRD_PERSON_LEFT_HAND] = PokemonItemRenderer().Transformations(
PokemonItemRenderer().Transformation(1.0, -2.6, 2.75),
PokemonItemRenderer().Transformation(1.0, -1.0, -1.25),
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
PokemonItemRenderer().Transformation(0F, -35F, 0F)
)
positions[ItemDisplayContext.GROUND] = PokemonItemRenderer().Transformations(
PokemonItemRenderer().Transformation(1.0, -2.6, 3.0),
PokemonItemRenderer().Transformation(1.0, -0.5, -1.0),
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
PokemonItemRenderer().Transformation(0F, 35F, 0F)
)
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.client.render.models.blockbench
import com.cobblemon.mod.common.Cobblemon.LOGGER
import com.cobblemon.mod.common.client.util.adapters.LocatorBoneAdapter
import com.google.gson.GsonBuilder
import com.google.gson.annotations.SerializedName
@@ -293,11 +294,12 @@ class TexturedModel {
.registerTypeAdapter(LocatorBone::class.java, LocatorBoneAdapter)
.create()
fun from(json: String) : TexturedModel {
try {
return GSON.fromJson(json, TexturedModel::class.java)
fun from(json: String) : TexturedModel? {
return try {
GSON.fromJson(json, TexturedModel::class.java)
} catch (exception: Exception) {
throw IllegalStateException("Issue loading pokemon geo: $json", exception)
LOGGER.warn(exception)
null
}
}
}
@@ -1,70 +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.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.STANDING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class DewgongModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("dewgong")
override val head = getPart("head")
override var portraitScale = 2.5F
override var portraitTranslation = Vec3(-0.6, -2.0, 0.0)
override var profileScale = 1.1F
override var profileTranslation = Vec3(0.0, 0.0, 0.0)
lateinit var standing: CobblemonPose
lateinit var float: CobblemonPose
lateinit var swim: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("dewgong", "cry") }
override fun registerPoses() {
standing = registerPose(
poseName = "standing",
poseTypes = STANDING_POSES + UI_POSES,
animations = arrayOf(
singleBoneLook(),
bedrock("dewgong", "ground_idle")
)
)
float = registerPose(
poseName = "float",
poseType = PoseType.FLOAT,
animations = arrayOf(
singleBoneLook(),
bedrock("dewgong", "water_idle")
)
)
swim = registerPose(
poseName = "swim",
poseType = PoseType.SWIM,
animations = arrayOf(
singleBoneLook(),
bedrock("dewgong", "water_swim")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("dewgong", "faint") else null
}
@@ -1,179 +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.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
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.util.isBattling
import com.cobblemon.mod.common.util.isUnderWater
import com.cobblemon.mod.common.util.isInWater
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class DragonairModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("dragonair")
override val head = getPart("head")
override var portraitScale = 2.3F
override var portraitTranslation = Vec3(-0.02, 1.58, 0.0)
override var profileScale = 0.65F
override var profileTranslation = Vec3(0.1, 0.9, 0.0)
lateinit var standing: CobblemonPose
lateinit var walking: CobblemonPose
lateinit var water_idle: CobblemonPose
lateinit var water_swim: CobblemonPose
lateinit var sleep: CobblemonPose
lateinit var water_sleep: CobblemonPose
lateinit var surface_swim: CobblemonPose
lateinit var surface_float: CobblemonPose
lateinit var battle_idle: CobblemonPose
lateinit var hovering: CobblemonPose
lateinit var flying: CobblemonPose
val flyingoffset = -12
override fun registerPoses() {
val blink = quirk { bedrockStateful("dragonair", "blink") }
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
condition = { !it.isInWater },
animations = arrayOf(
bedrock("dragonair", "sleep")
)
)
water_sleep = registerPose(
poseName = "water_sleep",
poseType = PoseType.SLEEP,
condition = { it.isInWater },
animations = arrayOf(
bedrock("dragonair", "water_sleep")
)
)
standing = registerPose(
poseName = "standing",
poseTypes = setOf(PoseType.STAND) + UI_POSES,
quirks = arrayOf(blink),
condition = { !it.isBattling && !it.isInWater},
transformTicks = 10,
animations = arrayOf(
singleBoneLook(),
bedrock("dragonair", "ground_idle")
)
)
walking = registerPose(
poseName = "walking",
poseTypes = MOVING_POSES - PoseType.SWIM - PoseType.FLY,
quirks = arrayOf(blink),
condition = {!it.isInWater},
transformTicks = 10,
animations = arrayOf(
bedrock("dragonair", "ground_walk")
)
)
hovering = registerPose(
poseName = "hovering",
poseType = PoseType.HOVER,
quirks = arrayOf(blink),
condition = { !it.isBattling },
transformTicks = 10,
animations = arrayOf(
singleBoneLook(),
bedrock("dragonair", "water_idle")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.Y_AXIS, flyingoffset)
)
)
flying = registerPose(
poseName = "flying",
poseType = PoseType.FLY,
quirks = arrayOf(blink),
condition = { !it.isBattling },
transformTicks = 10,
animations = arrayOf(
singleBoneLook(),
bedrock("dragonair", "water_swim")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.Y_AXIS, flyingoffset)
)
)
water_idle = registerPose(
poseName = "water_idle",
poseType = PoseType.FLOAT,
condition = { it.isUnderWater},
transformTicks = 10,
animations = arrayOf(
bedrock("dragonair", "water_idle")
)
)
water_swim = registerPose(
poseName = "water_swim",
poseType = PoseType.SWIM,
condition = { it.isUnderWater},
transformTicks = 10,
animations = arrayOf(
bedrock("dragonair", "water_swim")
)
)
surface_float = registerPose(
poseName = "surface_float",
poseTypes = PoseType.STATIONARY_POSES,
condition = { !it.isUnderWater && it.isInWater},
transformTicks = 10,
animations = arrayOf(
bedrock("dragonair", "surfacewater_idle")
)
)
surface_swim = registerPose(
poseName = "surface_swim",
poseTypes = PoseType.MOVING_POSES,
condition = { !it.isUnderWater && it.isInWater},
transformTicks = 10,
animations = arrayOf(
bedrock("dragonair", "surfacewater_swim")
)
)
battle_idle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
condition = { it.isBattling },
animations = arrayOf(
bedrock("dragonair", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("dragonair", "faint") else null
}
@@ -1,154 +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.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import com.cobblemon.mod.common.util.isBattling
import com.cobblemon.mod.common.util.isUnderWater
import com.cobblemon.mod.common.util.isInWater
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class DragoniteModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("dragonite")
override val head = getPart("head")
override var portraitScale = 1.2F
override var portraitTranslation = Vec3(-0.2, 2.6, 0.0)
override var profileScale = 0.41F
override var profileTranslation = Vec3(0.0, 1.1, -6.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var wateridle: CobblemonPose
lateinit var waterswim: CobblemonPose
lateinit var surfacewateridle: CobblemonPose
lateinit var surfacewaterswim: CobblemonPose
lateinit var battleidle: CobblemonPose
lateinit var sleep: CobblemonPose
lateinit var hover: CobblemonPose
lateinit var fly: CobblemonPose
override fun registerPoses() {
val blink = quirk { bedrockStateful("dragonite", "blink")}
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
animations = arrayOf(
bedrock("dragonite", "sleep")
)
)
standing = registerPose(
poseName = "standing",
poseTypes = UI_POSES + PoseType.STAND,
condition = { !it.isBattling},
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(maxPitch = 15F),
bedrock("dragonite", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseType = PoseType.WALK,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(maxPitch = 15F),
bedrock("dragonite", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battleidle",
poseTypes = PoseType.STATIONARY_POSES,
condition = { it.isBattling},
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(maxPitch = 10F),
bedrock("dragonite", "battle_idle")
)
)
hover = registerPose(
poseName = "hover",
poseType = PoseType.HOVER,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(maxPitch = 15F),
bedrock("dragonite", "air_idle")
)
)
fly = registerPose(
poseName = "fly",
poseType = PoseType.FLY,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(maxPitch = 15F),
bedrock("dragonite", "air_fly")
)
)
wateridle = registerPose(
poseName = "wateridle",
poseType = PoseType.FLOAT,
condition = { it.isUnderWater },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(maxPitch = 15F),
bedrock("dragonite", "water_idle")
)
)
waterswim = registerPose(
poseName = "waterswim",
poseType = PoseType.SWIM,
condition = { it.isUnderWater },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(maxPitch = 15F),
bedrock("dragonite", "water_swim")
)
)
surfacewateridle = registerPose(
poseName = "surfacewateridle",
poseTypes = PoseType.STANDING_POSES,
condition = { !it.isUnderWater && it.isInWater },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(maxPitch = 15F),
bedrock("dragonite", "surfacewater_idle")
)
)
surfacewaterswim = registerPose(
poseName = "surfacewaterswim",
poseTypes = PoseType.MOVING_POSES,
condition = { !it.isUnderWater && it.isInWater },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(maxPitch = 15F),
bedrock("dragonite", "surfacewater_swim")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("dragonite", "faint") else null
}
@@ -1,116 +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.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
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.util.isUnderWater
import com.cobblemon.mod.common.util.isInWater
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class DratiniModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("dratini")
override val head = getPart("head")
override var portraitScale = 1.66F
override var portraitTranslation = Vec3(-0.48, 0.35, 0.0)
override var profileScale = 0.58F
override var profileTranslation = Vec3(0.14, 0.83, 0.0)
lateinit var standing: CobblemonPose
lateinit var walking: CobblemonPose
lateinit var water_idle: CobblemonPose
lateinit var water_swim: CobblemonPose
lateinit var sleep: CobblemonPose
lateinit var water_sleep: CobblemonPose
lateinit var surface_swim: CobblemonPose
override fun registerPoses() {
val blink = quirk { bedrockStateful("dratini", "blink") }
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
condition = { !it.isInWater },
animations = arrayOf(
bedrock("dratini", "sleep")
)
)
water_sleep = registerPose(
poseName = "water_sleep",
poseType = PoseType.SLEEP,
condition = { it.isInWater },
animations = arrayOf(
bedrock("dratini", "water_sleep")
)
)
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES - PoseType.FLOAT,
quirks = arrayOf(blink),
transformTicks = 10,
animations = arrayOf(
singleBoneLook(),
bedrock("dratini", "ground_idle")
)
)
walking = registerPose(
poseName = "walking",
poseTypes = MOVING_POSES - PoseType.SWIM,
quirks = arrayOf(blink),
transformTicks = 10,
animations = arrayOf(
bedrock("dratini", "ground_walk")
)
)
water_idle = registerPose(
poseName = "water_idle",
poseType = PoseType.FLOAT,
transformTicks = 10,
animations = arrayOf(
bedrock("dratini", "water_idle")
)
)
water_swim = registerPose(
poseName = "water_swim",
poseType = PoseType.SWIM,
transformTicks = 10,
animations = arrayOf(
bedrock("dratini", "water_swim")
)
)
surface_swim = registerPose(
poseName = "surface_swim",
poseTypes = PoseType.STATIONARY_POSES + PoseType.MOVING_POSES,
condition = { !it.isUnderWater && it.isInWater},
transformTicks = 10,
animations = arrayOf(
bedrock("dratini", "surfacewater_swim")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("dratini", "faint") else null
}
@@ -1,65 +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.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class MagnemiteModel(root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("magnemite")
override var portraitScale = 2.2F
override var portraitTranslation = Vec3(-0.1, -1.5, 0.0)
override var profileScale = 1.0F
override var profileTranslation = Vec3(0.0, 0.18, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var sleep: Pose
override val cryAnimation = CryProvider { bedrockStateful("magnemite", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("magnemite", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("magnemite", "sleep"))
)
registerPose(
poseName = "hover",
poseTypes = PoseType.ALL_POSES - PoseType.FLY - PoseType.SLEEP - PoseType.SWIM,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("magnemite", "air_idle")
)
)
registerPose(
poseName = "fly",
poseTypes = setOf(PoseType.FLY, PoseType.SWIM),
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("magnemite", "air_fly")
)
)
}
override fun getFaintAnimation(state: PosableState) = bedrockStateful("magnemite", "faint")
}
@@ -1,65 +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.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class MagnetonModel(root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("magneton")
override var portraitScale = 1.2F
override var portraitTranslation = Vec3(0.0, 0.2, 0.0)
override var profileScale = 0.84F
override var profileTranslation = Vec3(0.0, 0.5, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var sleep: Pose
override val cryAnimation = CryProvider { bedrockStateful("magneton", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("magneton", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("magneton", "sleep"))
)
registerPose(
poseName = "hover",
poseTypes = PoseType.ALL_POSES - PoseType.FLY - PoseType.SLEEP - PoseType.SWIM,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("magneton", "air_idle")
)
)
registerPose(
poseName = "fly",
poseTypes = setOf(PoseType.FLY, PoseType.SWIM),
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("magneton", "air_fly")
)
)
}
override fun getFaintAnimation(state: PosableState) = bedrockStateful("magneton", "faint")
}
@@ -1,107 +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.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WingFlapIdleAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.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.util.math.geometry.toRadians
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class ScytherModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BiWingedFrame {
override val rootPart = root.registerChildWithAllChildren("scyther")
override val head = getPart("head")
override val leftLeg = getPart("left_upper_leg")
override val rightLeg = getPart("right_upper_leg")
override val leftWing = getPart("left_wing")
override val rightWing = getPart("right_wing")
override var portraitScale = 2.2F
override var portraitTranslation = Vec3(-0.4, 1.4, 0.0)
override var profileScale = 0.64F
override var profileTranslation = Vec3(0.0, 0.7, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var hover: CobblemonPose
lateinit var fly: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("scyther", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("scyther", "blink")}
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES - PoseType.HOVER,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("scyther", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES - PoseType.FLY,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
BipedWalkAnimation(this, periodMultiplier = 0.7F, amplitudeMultiplier = 0.85F),
bedrock("scyther", "ground_idle")
//bedrock("scyther", "ground_walk")
)
)
hover = registerPose(
poseName = "hover",
poseType = PoseType.HOVER,
transformTicks = 10,
animations = arrayOf(
bedrock("scyther", "air_idle"),
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -10F.toRadians(), period = 0.9F, amplitude = 0.6F),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Y_AXIS
)
)
)
fly = registerPose(
poseName = "fly",
poseType = PoseType.FLY,
transformTicks = 10,
animations = arrayOf(
bedrock("scyther", "air_idle"),
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -14F.toRadians(), period = 0.9F, amplitude = 0.9F),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Y_AXIS
)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("scyther", "faint") else null
}
@@ -1,80 +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.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SeelModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("seel")
override val head = getPart("head")
override var portraitScale = 2.5F
override var portraitTranslation = Vec3(-0.4, -2.0, 0.0)
override var profileScale = 1.0F
override var profileTranslation = Vec3(0.0, 0.2, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var float: CobblemonPose
lateinit var swim: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("seel", "cry") }
override fun registerPoses() {
standing = registerPose(
poseName = "standing",
poseTypes = UI_POSES + PoseType.STAND,
animations = arrayOf(
singleBoneLook(),
bedrock("seel", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseType = PoseType.WALK,
animations = arrayOf(
singleBoneLook(),
bedrock("seel", "ground_idle")
//bedrock("seel", "ground_walk")
)
)
float = registerPose(
poseName = "float",
poseType = PoseType.FLOAT,
animations = arrayOf(
singleBoneLook(),
bedrock("seel", "water_idle")
)
)
swim = registerPose(
poseName = "swim",
poseType = PoseType.SWIM,
animations = arrayOf(
singleBoneLook(),
bedrock("seel", "water_swim")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("seel", "faint") else null
}
@@ -1,167 +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.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WingFlapIdleAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.parabolaFunction
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class NoctowlModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BiWingedFrame {
override val rootPart = root.registerChildWithAllChildren("noctowl")
override val leftWing = getPart("wing_left")
override val rightWing = getPart("wing_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override val head = getPart("head")
private val tail = getPart("tail")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.35, 1.0, 0.0)
override var profileScale = 0.7F
override var profileTranslation = Vec3(0.0, 0.68, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var hover: Pose
lateinit var fly: Pose
override val cryAnimation = CryProvider { bedrockStateful("noctowl", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("noctowl", "blink")}
standing = registerPose(
poseName = "stand",
poseTypes = PoseType.STATIONARY_POSES - PoseType.HOVER - PoseType.FLOAT + PoseType.UI_POSES,
transformTicks = 0,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("noctowl", "ground_idle")
)
)
hover = registerPose(
poseName = "hover",
poseTypes = setOf(PoseType.HOVER, PoseType.FLOAT),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -10F.toRadians(), period = 0.9F, amplitude = 0.8F),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Y_AXIS
)
)
)
fly = registerPose(
poseName = "fly",
poseTypes = setOf(PoseType.FLY, PoseType.SWIM),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -10F.toRadians(), period = 0.9F, amplitude = 0.8F),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Y_AXIS
)
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES - PoseType.FLY - PoseType.SWIM,
transformTicks = 5,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("noctowl", "ground_idle"),
rootPart.translation(
function = parabolaFunction(
peak = -4F,
period = 0.4F
),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Y_AXIS
),
head.translation(
function = sineFunction(
amplitude = (-20F).toRadians(),
period = 1F,
verticalShift = (-10F).toRadians()
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { state, _, _ -> state.animationSeconds }
),
leftLeg.rotation(
function = parabolaFunction(
tightness = -20F,
phaseShift = 0F,
verticalShift = (30F).toRadians()
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
rightLeg.rotation(
function = parabolaFunction(
tightness = -20F,
phaseShift = 0F,
verticalShift = (30F).toRadians()
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
tail.rotation(
function = sineFunction(
amplitude = (-5F).toRadians(),
period = 1F
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
wingFlap(
flapFunction = sineFunction(
amplitude = (-5F).toRadians(),
period = 0.4F,
phaseShift = 0.00F,
verticalShift = (-20F).toRadians()
),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Z_AXIS
),
rightWing.translation(
function = parabolaFunction(
tightness = -10F,
phaseShift = 30F,
verticalShift = (25F).toRadians()
),
axis = ModelPartTransformation.Y_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
leftWing.translation(
function = parabolaFunction(
tightness = -10F,
phaseShift = 30F,
verticalShift = (25F).toRadians()
),
axis = ModelPartTransformation.Y_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
)
)
}
}
@@ -1,109 +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.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WingFlapIdleAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class ScizorModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame, BiWingedFrame {
override val rootPart = root.registerChildWithAllChildren("scizor")
override val head = getPart("head_pivot")
override val leftWing = getPart("left_wing")
override val rightWing = getPart("right_wing")
override val leftArm = getPart("left_upper_arm")
override val rightArm = getPart("right_upper_arm")
override val leftLeg = getPart("left_leg_joint")
override val rightLeg = getPart("right_leg_joint")
override var portraitScale = 2.6F
override var portraitTranslation = Vec3(-0.28, 2.9, 0.0)
override var profileScale = 0.55F
override var profileTranslation = Vec3(0.0, 0.9, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var hover: Pose
lateinit var fly: Pose
override fun registerPoses() {
val blink = quirk { bedrockStateful("scizor", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = UI_POSES + PoseType.STAND,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("scizor", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseType = PoseType.WALK,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
BipedWalkAnimation(this, periodMultiplier = 0.7F, amplitudeMultiplier = 0.85F),
BimanualSwingAnimation (this, amplitudeMultiplier = 0.85F),
bedrock("scizor", "ground_idle")
)
)
hover = registerPose(
poseName = "hover",
poseTypes = setOf(PoseType.HOVER, PoseType.FLOAT),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("scizor", "air_idle"),
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -10F.toRadians(), period = 0.9F, amplitude = 0.6F),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Y_AXIS
)
)
)
fly = registerPose(
poseName = "fly",
poseTypes = setOf(PoseType.FLY, PoseType.SWIM),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("scizor", "air_idle"),
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -14F.toRadians(), period = 0.9F, amplitude = 0.6F),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Y_AXIS
)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("scizor", "faint") else null
}
@@ -1,71 +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.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class TeddiursaModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("teddiursa")
override val head = getPart("head")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.2, -0.7, 0.0)
override var profileScale = 0.7F
override var profileTranslation = Vec3(0.0, 0.7, 0.0)
lateinit var sleep: Pose
lateinit var standing: Pose
lateinit var walk: Pose
override val cryAnimation = CryProvider { bedrockStateful("teddiursa", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("teddiursa", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
transformTicks = 10,
animations = arrayOf(bedrock("teddiursa", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("teddiursa", "ground_idle")
)
)
walk = registerPose(
poseName = "walking",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("teddiursa", "ground_walk")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("teddiursa", "faint") else null
}
@@ -1,70 +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.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class UrsaringModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("ursaring")
override val head = getPart("head")
override val leftArm = getPart("left_arm")
override val rightArm = getPart("right_arm")
override val leftLeg = getPart("left_leg")
override val rightLeg = getPart("right_leg")
override var portraitScale = 2.1F
override var portraitTranslation = Vec3(-0.4, 1.4, 0.0)
override var profileScale = 0.65F
override var profileTranslation = Vec3(0.0, 0.76, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
override fun registerPoses() {
val blink = quirk { bedrockStateful("ursaring", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("ursaring", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("ursaring", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F),
BimanualSwingAnimation(this, swingPeriodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
//bedrock("ursaring", "ground_walk")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("ursaring", "faint") else null
}
@@ -1,124 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class BeldumModel (root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("beldum")
override var portraitScale = 2.3F
override var portraitTranslation = Vec3(-0.3, -1.2, 0.0)
override var profileScale = 0.9F
override var profileTranslation = Vec3(0.0, 0.5, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var hover: Pose
lateinit var fly: Pose
lateinit var sleep: Pose
lateinit var battleidle: Pose
lateinit var shoulderLeft: Pose
lateinit var shoulderRight: Pose
val shoulderOffset = 0.5
override val cryAnimation = CryProvider { bedrockStateful("beldum", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("beldum", "blink")}
val quirk = quirk { bedrockStateful("beldum", "quirk_spin")}
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("beldum", "sleep"))
)
standing = registerPose(
poseName = "stand",
poseTypes = PoseType.STATIONARY_POSES - PoseType.HOVER - PoseType.FLOAT + PoseType.UI_POSES,
condition = { !it.isBattling },
transformTicks = 10,
quirks = arrayOf(blink, quirk),
animations = arrayOf(
bedrock("beldum", "ground_idle")
)
)
hover = registerPose(
poseName = "hover",
poseTypes = setOf(PoseType.HOVER, PoseType.FLOAT),
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("beldum", "air_idle")
)
)
fly = registerPose(
poseName = "fly",
poseTypes = setOf(PoseType.FLY, PoseType.SWIM),
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("beldum", "air_fly")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES - PoseType.FLY - PoseType.SWIM,
transformTicks = 5,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("beldum", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink, quirk),
condition = { it.isBattling },
animations = arrayOf(
bedrock("beldum", "battle_idle")
)
)
shoulderLeft = registerPose(
poseType = PoseType.SHOULDER_LEFT,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("beldum", "ground_idle")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, shoulderOffset)
)
)
shoulderRight = registerPose(
poseType = PoseType.SHOULDER_RIGHT,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("beldum", "ground_idle")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, -shoulderOffset)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("beldum", "faint") else null
}
@@ -1,86 +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.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class CacneaModel (root: ModelPart) : PokemonPosableModel(root), BimanualFrame, BipedFrame {
override val rootPart = root.registerChildWithAllChildren("cacnea")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override val leftArm = getPart("arm_left")
override val rightArm = getPart("arm_right")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.2, -1.0, 0.0)
override var profileScale = 0.85F
override var profileTranslation = Vec3(0.0, 0.5, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var sleep: CobblemonPose
lateinit var battleidle: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("cacnea", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("cacnea", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("cacnea", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
condition = { !it.isBattling },
transformTicks = 10,
animations = arrayOf(
bedrock("cacnea", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
transformTicks = 10,
animations = arrayOf(
bedrock("cacnea", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
bedrock("cacnea", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("cacnea", "faint") else null
}
@@ -1,88 +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.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class CacturneModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BimanualFrame, BipedFrame {
override val rootPart = root.registerChildWithAllChildren("cacturne")
override val head = getPart("head")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override val leftArm = getPart("arm_left")
override val rightArm = getPart("arm_right")
override var portraitScale = 2.5F
override var portraitTranslation = Vec3(0.0, 0.5, 0.0)
override var profileScale = 0.75F
override var profileTranslation = Vec3(0.0, 0.6, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var sleep: CobblemonPose
lateinit var battleidle: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("cacturne", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("cacturne", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("cacturne", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
condition = { !it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("cacturne", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
animations = arrayOf(
singleBoneLook(),
bedrock("cacturne", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
bedrock("cacturne", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("cacturne", "faint") else null
}
@@ -1,95 +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.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class MetangModel (root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("metang")
override var portraitScale = 1.8F
override var portraitTranslation = Vec3(-0.35, 0.0, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3(0.0, 0.65, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var hover: Pose
lateinit var fly: Pose
lateinit var sleep: Pose
lateinit var battleidle: Pose
override val cryAnimation = CryProvider { bedrockStateful("metang", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("metang", "blink")}
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("metang", "sleep"))
)
standing = registerPose(
poseName = "stand",
poseTypes = PoseType.STATIONARY_POSES - PoseType.HOVER - PoseType.FLOAT + PoseType.UI_POSES,
condition = { !it.isBattling },
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metang", "ground_idle")
)
)
hover = registerPose(
poseName = "hover",
poseTypes = setOf(PoseType.HOVER, PoseType.FLOAT),
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metang", "air_idle")
)
)
fly = registerPose(
poseName = "fly",
poseTypes = setOf(PoseType.FLY, PoseType.SWIM),
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metang", "air_fly")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES - PoseType.FLY - PoseType.SWIM,
transformTicks = 5,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metang", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
bedrock("metang", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("metang", "faint") else null
}
@@ -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.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SharpedoModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("sharpedo")
override val head = getPart("body")
override var portraitScale = 1.5F
override var portraitTranslation = Vec3(-0.24, -0.9, 0.0)
override var profileScale = 0.6F
override var profileTranslation = Vec3(0.0, 0.61, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
override fun registerPoses() {
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
animations = arrayOf(
bedrock("sharpedo", "water_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
animations = arrayOf(
bedrock("sharpedo", "water_idle")
)
)
}
}
@@ -1,94 +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.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SwellowModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BiWingedFrame {
override val rootPart = root.registerChildWithAllChildren("swellow")
override val leftWing = getPart("wing_left")
override val rightWing = getPart("wing_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override val head = getPart("head")
override var portraitScale = 3.0F
override var portraitTranslation = Vec3(-0.8, -0.8, 0.0)
override var profileScale = 1.2F
override var profileTranslation = Vec3(0.0, -0.01, 0.0)
lateinit var sleep: Pose
lateinit var stand: Pose
lateinit var walk: Pose
lateinit var hover: Pose
lateinit var fly: Pose
override val cryAnimation = CryProvider { bedrockStateful("swellow", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("swellow", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("swellow", "sleep"))
)
stand = registerPose(
poseName = "standing",
poseTypes = PoseType.SHOULDER_POSES + PoseType.UI_POSES + PoseType.STAND,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("swellow", "ground_idle")
)
)
hover = registerPose(
poseName = "hover",
poseType = PoseType.HOVER,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("swellow", "air_idle")
)
)
fly = registerPose(
poseName = "fly",
poseType = PoseType.FLY,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("swellow", "air_fly")
)
)
walk = registerPose(
poseName = "walking",
poseType = PoseType.WALK,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("swellow", "ground_walk")
)
)
}
}
@@ -1,94 +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.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class TaillowModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BiWingedFrame {
override val rootPart = root.registerChildWithAllChildren("taillow")
override val leftWing = getPart("wing_left")
override val rightWing = getPart("wing_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override val head = getPart("head")
override var portraitScale = 3.5F
override var portraitTranslation = Vec3(-0.2, -2.5, 0.0)
override var profileScale = 1.2F
override var profileTranslation = Vec3(0.0, -0.01, 0.0)
lateinit var sleep: Pose
lateinit var stand: Pose
lateinit var walk: Pose
lateinit var hover: Pose
lateinit var fly: Pose
override val cryAnimation = CryProvider { bedrockStateful("taillow", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("taillow", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("taillow", "sleep"))
)
stand = registerPose(
poseName = "standing",
poseTypes = PoseType.SHOULDER_POSES + PoseType.UI_POSES + PoseType.STAND,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("taillow", "ground_idle")
)
)
hover = registerPose(
poseName = "hover",
poseType = PoseType.HOVER,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("taillow", "air_idle")
)
)
fly = registerPose(
poseName = "fly",
poseType = PoseType.FLY,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("taillow", "air_fly")
)
)
walk = registerPose(
poseName = "walking",
poseType = PoseType.WALK,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("taillow", "ground_walk")
)
)
}
}
@@ -1,61 +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.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation.Companion.X_AXIS
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation.Companion.Z_AXIS
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class WailmerModel(root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("wailmer")
val finLeft = getPart("fin_left")
val finRight = getPart("fin_right")
val jaw = getPart("jaw")
override var portraitScale = 1.2F
override var portraitTranslation = Vec3(-0.15, -0.3, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3(0.0, 0.3, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
override fun registerPoses() {
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 0,
animations = arrayOf(
finLeft.rotation(sineFunction(amplitude = 1F / 4, period = 4F), axis = Z_AXIS, timeVariable = { state, _, _ -> state.animationSeconds }),
finRight.rotation(sineFunction(amplitude = -1F / 4, period = 4F), axis = Z_AXIS, timeVariable = { state, _, _ -> state.animationSeconds }),
jaw.rotation(sineFunction(amplitude = 0.05F, period = 8F, verticalShift = 0.04F), axis = X_AXIS, timeVariable = { state, _, _ -> state.animationSeconds })
// bedrock("wailmer", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 0,
animations = arrayOf(
finLeft.rotation(sineFunction(amplitude = 1F / 3, period = 3F), axis = Z_AXIS, timeVariable = { state, _, _ -> state.animationSeconds }),
finRight.rotation(sineFunction(amplitude = -1F / 3, period = 3F), axis = Z_AXIS, timeVariable = { state, _, _ -> state.animationSeconds }),
jaw.rotation(sineFunction(amplitude = 0.05F, period = 8F, verticalShift = 0.04F), axis = X_AXIS, timeVariable = { state, _, _ -> state.animationSeconds }),
// bedrock("wailmer", "ground_walk")
)
)
}
}
@@ -1,66 +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.render.models.blockbench.pokemon.gen5
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class BouffalantModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("bouffalant")
override val head = getPart("head")
override var portraitScale = 1.9F
override var portraitTranslation = Vec3(-0.9, -0.7, 0.0)
override var profileScale = 0.75F
override var profileTranslation = Vec3(0.0, 0.6, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("bouffalant", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("bouffalant", "blink")}
// Forgive me. I have animated illegally yet again.
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("bouffalant", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("bouffalant", "ground_walk")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("bouffalant", "faint") else null
}
@@ -1,66 +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.render.models.blockbench.pokemon.gen5
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class HeatmorModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("heatmor")
override val head = getPart("head")
override val leftArm = getPart("arm_left")
override val rightArm = getPart("arm_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override var portraitScale = 3.5F
override var portraitTranslation = Vec3(-0.7, -0.5, 0.0)
override var profileScale = 0.9F
override var profileTranslation = Vec3(0.0, 0.4, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var sleep: Pose
override fun registerPoses() {
val blink = quirk { bedrockStateful("heatmor", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("heatmor", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("heatmor", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("heatmor", "ground_walk")
)
)
}
}
@@ -1,70 +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.render.models.blockbench.pokemon.gen5
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class MaractusModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("maractus")
override val head = getPart("head")
override val leftArm = getPart("arm_left1")
override val rightArm = getPart("arm_right1")
override var portraitScale = 2.4F
override var portraitTranslation = Vec3(-0.05, -0.7, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3(0.0, 0.55, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
override val cryAnimation = CryProvider { bedrockStateful("maractus", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("maractus", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("maractus", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("maractus", "ground_idle"),
BimanualSwingAnimation(this, swingPeriodMultiplier = 0.75F)
//bedrock("maractus", "ground_walk")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("maractus", "faint") else null
}
@@ -1,60 +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.render.models.blockbench.pokemon.gen5
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SigilyphModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("sigilyph")
override val head = getPart("head")
override var portraitScale = 4.0F
override var portraitTranslation = Vec3(-0.2, 1.9, 0.0)
override var profileScale = 0.65F
override var profileTranslation = Vec3(0.0, 0.85, 0.0)
lateinit var sleep: CobblemonPose
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("sigilyph", "cry") }
override fun registerPoses() {
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("sigilyph", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
animations = arrayOf(
singleBoneLook(),
bedrock("sigilyph", "air_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
animations = arrayOf(
bedrock("sigilyph", "air_fly")
)
)
}
override fun getFaintAnimation(state: PosableState) = if (state.isNotPosedIn(sleep)) bedrockStateful("sigilyph", "faint") else null
}
@@ -1,125 +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.render.models.blockbench.pokemon.gen8
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class CorviknightModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BiWingedFrame {
override val rootPart = root.registerChildWithAllChildren("corviknight")
override val leftWing = getPart("wing_left")
override val rightWing = getPart("wing_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override val head = getPart("head")
val openWingLeft = getPart("wing_open_left")
val openWingRight = getPart("wing_open_right")
val closedWingLeft = getPart("wing_closed_left")
val closedWingRight = getPart("wing_closed_right")
override var portraitScale = 1.0F
override var portraitTranslation = Vec3(-0.45, 3.0, 0.0)
override var profileScale = 0.36F
override var profileTranslation = Vec3(0.0, 1.2, 0.0)
lateinit var stand: Pose
lateinit var walk: Pose
lateinit var hover: Pose
lateinit var fly: Pose
lateinit var sleep: Pose
override val cryAnimation = CryProvider { bedrockStateful("corviknight", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("corviknight", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("corviknight", "sleep"))
)
stand = registerPose(
poseName = "standing",
poseTypes = PoseType.UI_POSES + PoseType.STATIONARY_POSES - PoseType.HOVER,
transformTicks = 10,
transformedParts = arrayOf(
openWingLeft.createTransformation().withVisibility(visibility = false),
openWingRight.createTransformation().withVisibility(visibility = false),
closedWingLeft.createTransformation().withVisibility(visibility = true),
closedWingRight.createTransformation().withVisibility(visibility = true)
),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("corviknight", "ground_idle")
)
)
hover = registerPose(
poseName = "hover",
poseType = PoseType.HOVER,
transformTicks = 10,
transformedParts = arrayOf(
openWingLeft.createTransformation().withVisibility(visibility = true),
openWingRight.createTransformation().withVisibility(visibility = true),
closedWingLeft.createTransformation().withVisibility(visibility = false),
closedWingRight.createTransformation().withVisibility(visibility = false)
),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("corviknight", "air_idle")
)
)
fly = registerPose(
poseName = "fly",
poseType = PoseType.FLY,
transformTicks = 10,
transformedParts = arrayOf(
openWingLeft.createTransformation().withVisibility(visibility = true),
openWingRight.createTransformation().withVisibility(visibility = true),
closedWingLeft.createTransformation().withVisibility(visibility = false),
closedWingRight.createTransformation().withVisibility(visibility = false)
),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("corviknight", "air_fly")
)
)
walk = registerPose(
poseName = "walking",
poseTypes = PoseType.MOVING_POSES - PoseType.FLY,
transformTicks = 10,
transformedParts = arrayOf(
openWingLeft.createTransformation().withVisibility(visibility = false),
openWingRight.createTransformation().withVisibility(visibility = false),
closedWingLeft.createTransformation().withVisibility(visibility = true),
closedWingRight.createTransformation().withVisibility(visibility = true)
),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("corviknight", "ground_walk")
)
)
}
}
@@ -1,60 +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.render.models.blockbench.pokemon.gen8
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class EldegossModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("eldegoss")
override val head = getPart("head")
override var portraitScale = 2.6F
override var portraitTranslation = Vec3(-0.25, -1.41, 0.0)
override var profileScale = 0.62F
override var profileTranslation = Vec3(0.07, 0.85, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("eldegoss", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("eldegoss", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.UI_POSES + PoseType.STATIONARY_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("eldegoss", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("eldegoss", "ground_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("eldegoss", "faint") else null
}
@@ -1,60 +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.render.models.blockbench.pokemon.gen8
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class GossifleurModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("gossifleur")
override val head = getPart("head")
override var portraitScale = 1.7F
override var portraitTranslation = Vec3(-0.22, 0.13, 0.0)
override var profileScale = 0.52F
override var profileTranslation = Vec3(0.0, 1.04, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("gossifleur", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("gossifleur", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.UI_POSES + PoseType.STATIONARY_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("gossifleur", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("gossifleur", "ground_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("gossifleur", "faint") else null
}
@@ -1,64 +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.render.models.blockbench.pokemon.gen8
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class StonjournerModel (root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("stonjourner")
override var portraitScale = 1.83F
override var portraitTranslation = Vec3(-0.46, 3.17, 0.0)
override var profileScale = 0.38F
override var profileTranslation = Vec3(0.0, 1.16, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var sleep: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("stonjourner", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("stonjourner", "blink") }
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
animations = arrayOf(
bedrock("stonjourner", "sleep")
)
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("stonjourner", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("stonjourner", "ground_walk")
)
)
}
override fun getFaintAnimation(state: PosableState) = bedrockStateful("stonjourner", "faint")
}
@@ -1,78 +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.render.models.blockbench.pokemon.gen8
import com.cobblemon.mod.common.client.render.models.blockbench.animation.QuadrupedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class UrsalunaModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, QuadrupedFrame {
override val rootPart = root.registerChildWithAllChildren("ursaluna")
override val head = getPart("head")
override val foreLeftLeg = getPart("shoulder_left")
override val foreRightLeg = getPart("shoulder_right")
override val hindLeftLeg = getPart("thigh_left")
override val hindRightLeg = getPart("thigh_right")
override var portraitScale = 1.2F
override var portraitTranslation = Vec3(-1.1, 0.4, 0.0)
override var profileScale = 0.45F
override var profileTranslation = Vec3(0.0, 0.9, 0.0)
// lateinit var sleep: Pose
lateinit var standing: Pose
lateinit var walk: Pose
override val cryAnimation = CryProvider { bedrockStateful("ursaluna", "cry") }
override fun registerPoses() {
// sleep = registerPose(
// poseType = PoseType.SLEEP,
// animations = arrayOf(bedrock("ursaluna", "sleep"))
// )
val blink = quirk { bedrockStateful("ursaluna", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("ursaluna", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 5,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("ursaluna", "ground_idle"),
QuadrupedWalkAnimation(this, periodMultiplier = 0.75F, amplitudeMultiplier = 1F)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isNotPosedIn(sleep)) bedrockStateful("ursaluna", "faint") else null
}
@@ -1,83 +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.render.models.blockbench.pokemon.gen9
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class FloragatoModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("floragato")
override val head = getPart("head")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(0.0, 1.1, 0.0)
override var profileScale = 0.65F
override var profileTranslation = Vec3(0.0, 0.8, 0.0)
lateinit var standing: Pose
lateinit var walking: Pose
lateinit var sleep: Pose
lateinit var battleidle: Pose
override val cryAnimation = CryProvider { if (it.isBattling) bedrockStateful("floragato", "battle_cry") else bedrockStateful("floragato", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("floragato", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("floragato", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
condition = { !it.isBattling },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("floragato", "ground_idle")
)
)
walking = registerPose(
poseName = "walking",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("floragato", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("floragato", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walking, battleidle, sleep)) bedrockStateful("floragato", "faint") else null
}
@@ -1,79 +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.render.models.blockbench.pokemon.gen9
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class LechonkModel (root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("lechonk")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(0.0, -1.35, 0.0)
override var profileScale = 1.0F
override var profileTranslation = Vec3(0.0, 0.25, 0.0)
lateinit var sleep: CobblemonPose
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var battle_idle: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("lechonk", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("lechonk", "blink") }
val snort = quirk { bedrockStateful("lechonk", "snort_quirk") }
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("lechonk", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
condition = { !it.isBattling },
transformTicks = 10,
quirks = arrayOf(blink, snort),
animations = arrayOf(
bedrock("lechonk", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 5,
quirks = arrayOf(blink, snort),
animations = arrayOf(
bedrock("lechonk", "ground_walk")
)
)
battle_idle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
quirks = arrayOf(blink, snort),
condition = { it.isBattling },
animations = arrayOf(
bedrock("lechonk", "battle_idle")
)
)
}
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(battle_idle)) bedrockStateful("lechonk", "battle_faint") else bedrockStateful("lechonk", "faint")
}
@@ -1,89 +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.render.models.blockbench.pokemon.gen9
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class MeowscaradaModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("meowscarada")
override val head = getPart("head")
override var portraitScale = 1.9F
override var portraitTranslation = Vec3(-0.3, 3.0, 0.0)
override var profileScale = 0.46F
override var profileTranslation = Vec3(0.0, 1.1, 0.0)
lateinit var standing: Pose
lateinit var walking: Pose
lateinit var sleep: Pose
lateinit var battleidle: Pose
override val cryAnimation = CryProvider { bedrockStateful("meowscarada", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("meowscarada", "blink") }
val sleep1 = quirk(secondsBetweenOccurrences = 60F to 120F) { bedrockStateful("meowscarada", "sleep_quirk") }
val sleep2 = quirk(secondsBetweenOccurrences = 30F to 120F) { bedrockStateful("meowscarada", "sleep_quirk2") }
val sleep3 = quirk(secondsBetweenOccurrences = 20F to 60F) { bedrockStateful("meowscarada", "sleep_quirk3") }
val sleep4 = quirk(secondsBetweenOccurrences = 60F to 120F) { bedrockStateful("meowscarada", "sleep_quirk4") }
sleep = registerPose(
poseType = PoseType.SLEEP,
quirks = arrayOf(blink, sleep1, sleep2, sleep3, sleep4),
animations = arrayOf(bedrock("meowscarada", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
condition = { !it.isBattling },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("meowscarada", "ground_idle")
)
)
walking = registerPose(
poseName = "walking",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("meowscarada", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("meowscarada", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walking, battleidle, sleep)) bedrockStateful("meowscarada", "faint") else null
}
@@ -1,78 +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.render.models.blockbench.pokemon.gen9
import com.cobblemon.mod.common.client.render.models.blockbench.animation.QuadrupedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class OinkologneFemaleModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, QuadrupedFrame {
override val rootPart = root.registerChildWithAllChildren("oinkologne_female")
override val head = getPart("head")
override val foreLeftLeg = getPart("leg_front_left")
override val foreRightLeg = getPart("leg_front_right")
override val hindLeftLeg = getPart("leg_back_left")
override val hindRightLeg = getPart("leg_back_right")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.65, -0.5, 0.0)
override var profileScale = 0.9F
override var profileTranslation = Vec3(0.0, 0.35, 0.0)
// lateinit var sleep: CobblemonPose
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("oinkologne_female", "cry") }
override fun registerPoses() {
// sleep = registerPose(
// poseType = PoseType.SLEEP,
// animations = arrayOf(bedrock("oinkologne_female", "sleep"))
// )
val blink = quirk { bedrockStateful("oinkologne_female", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("oinkologne_female", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 5,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("oinkologne_female", "ground_idle"),
QuadrupedWalkAnimation(this, periodMultiplier = 0.75F, amplitudeMultiplier = 1F)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isNotPosedIn(sleep)) bedrockStateful("oinkologne_female", "faint") else null
}
@@ -1,78 +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.render.models.blockbench.pokemon.gen9
import com.cobblemon.mod.common.client.render.models.blockbench.animation.QuadrupedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class OinkologneMaleModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, QuadrupedFrame {
override val rootPart = root.registerChildWithAllChildren("oinkologne_male")
override val head = getPart("head")
override val foreLeftLeg = getPart("leg_front_left")
override val foreRightLeg = getPart("leg_front_right")
override val hindLeftLeg = getPart("leg_back_left")
override val hindRightLeg = getPart("leg_back_right")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.65, -0.5, 0.0)
override var profileScale = 0.9F
override var profileTranslation = Vec3(0.0, 0.35, 0.0)
// lateinit var sleep: CobblemonPose
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("oinkologne_male", "cry") }
override fun registerPoses() {
// sleep = registerPose(
// poseType = PoseType.SLEEP,
// animations = arrayOf(bedrock("oinkologne_male", "sleep"))
// )
val blink = quirk { bedrockStateful("oinkologne_male", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("oinkologne_male", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 5,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("oinkologne_male", "ground_idle"),
QuadrupedWalkAnimation(this, periodMultiplier = 0.75F, amplitudeMultiplier = 1F)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isNotPosedIn(sleep)) bedrockStateful("oinkologne_male", "faint") else null
}
@@ -1,200 +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.render.models.blockbench.pokemon.gen9
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import com.cobblemon.mod.common.util.isUnderWater
import com.cobblemon.mod.common.util.isInWater
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class QuaxlyModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame {
override val rootPart = root.registerChildWithAllChildren("quaxly")
override val head = getPart("head")
private val messyHair = getPart("hair_messy")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.1, -0.5, 0.0)
override var profileScale = 0.7F
override var profileTranslation = Vec3(0.0, 0.71, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var floating: Pose
lateinit var swimming: Pose
lateinit var sleep: Pose
lateinit var watersleep: Pose
lateinit var battleidle: Pose
lateinit var waterbattleidle: Pose
lateinit var water_surface_idle: Pose
lateinit var water_surface_swim: Pose
val wateroffset = -10
override val cryAnimation = CryProvider { bedrockStateful("quaxly", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("quaxly", "blink")}
sleep = registerPose(
poseName = "sleeping",
poseType = PoseType.SLEEP,
transformedParts = arrayOf(
messyHair.createTransformation().withVisibility(visibility = false)
),
condition = { !it.isInWater },
animations = arrayOf(bedrock("quaxly", "sleep"))
)
watersleep = registerPose(
poseName = "water_sleeping",
poseType = PoseType.SLEEP,
transformedParts = arrayOf(
messyHair.createTransformation().withVisibility(visibility = false)
),
condition = { it.isInWater },
animations = arrayOf(bedrock("quaxly", "water_sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.UI_POSES + PoseType.STAND,
transformTicks = 10,
transformedParts = arrayOf(
messyHair.createTransformation().withVisibility(visibility = false)
),
condition = { !it.isBattling && !it.isInWater && !it.isUnderWater },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("quaxly", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
transformTicks = 10,
poseType = PoseType.WALK,
transformedParts = arrayOf(
messyHair.createTransformation().withVisibility(visibility = false)
),
condition = { !it.isInWater && !it.isUnderWater },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("quaxly", "ground_walk")
)
)
floating = registerPose(
poseName = "floating",
transformTicks = 10,
poseType = PoseType.FLOAT,
quirks = arrayOf(blink),
transformedParts = arrayOf(
messyHair.createTransformation().withVisibility(visibility = false)
),
condition = { it.isUnderWater },
animations = arrayOf(
singleBoneLook(),
bedrock("quaxly", "water_idle")
)
)
swimming = registerPose(
poseName = "swimming",
transformTicks = 10,
transformedParts = arrayOf(
messyHair.createTransformation().withVisibility(visibility = false)
),
condition = { it.isUnderWater },
poseType = PoseType.SWIM,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("quaxly", "water_swim"),
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
transformedParts = arrayOf(
messyHair.createTransformation().withVisibility(visibility = false)
),
condition = { it.isBattling && !it.isInWater },
animations = arrayOf(
singleBoneLook(),
bedrock("quaxly", "battle_idle")
)
)
waterbattleidle = registerPose(
poseName = "water_battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
transformedParts = arrayOf(
messyHair.createTransformation().withVisibility(visibility = false)
),
condition = { it.isBattling && it.isInWater },
animations = arrayOf(
singleBoneLook(),
bedrock("quaxly", "surfacewater_battle_idle")
)
)
water_surface_idle = registerPose(
poseName = "surface_idle",
poseTypes = PoseType.STATIONARY_POSES,
quirks = arrayOf(blink),
condition = { !it.isUnderWater && it.isInWater },
animations = arrayOf(
singleBoneLook(),
bedrock("quaxly", "surfacewater_idle"),
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.Y_AXIS, wateroffset),
messyHair.createTransformation().withVisibility(visibility = false)
)
)
water_surface_swim = registerPose(
poseName = "surface_swim",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
condition = { !it.isUnderWater && it.isInWater},
animations = arrayOf(
singleBoneLook(),
bedrock("quaxly", "surfacewater_swim"),
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.Y_AXIS, wateroffset),
messyHair.createTransformation().withVisibility(visibility = false)
)
)
}
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walk, battleidle, sleep)) bedrockStateful("quaxly", "faint") else if (state.isPosedIn(water_surface_idle, water_surface_swim, waterbattleidle, watersleep )) bedrockStateful("quaxly", "faint") else null
}
@@ -24,7 +24,7 @@ class QuaxwellModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val head = getPart("head")
override var portraitScale = 1.8F
override var portraitTranslation = Vec3(-0.2, 1.8, 0.0)
override var portraitTranslation = Vec3(-0.2, 1.4, 0.0)
override var profileScale = 0.5F
override var profileTranslation = Vec3(0.0, 1.0, 0.0)
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.client.render.models.blockbench.repository
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.Cobblemon.LOGGER
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.client.render.ModelLayer
import com.cobblemon.mod.common.client.render.ModelVariationSet
@@ -258,13 +259,9 @@ object VaryingModelRepository {
inbuilt("chansey", ::ChanseyModel)
inbuilt("crobat", ::CrobatModel)
inbuilt("cubone", ::CuboneModel)
inbuilt("dewgong", ::DewgongModel)
inbuilt("ditto", ::DittoModel)
inbuilt("dodrio", ::DodrioModel)
inbuilt("doduo", ::DoduoModel)
inbuilt("dragonair", ::DragonairModel)
inbuilt("dragonite", ::DragoniteModel)
inbuilt("dratini", ::DratiniModel)
inbuilt("drowzee", ::DrowzeeModel)
inbuilt("electabuzz", ::ElectabuzzModel)
inbuilt("exeggcute", ::ExeggcuteModel)
@@ -290,8 +287,6 @@ object VaryingModelRepository {
inbuilt("koffing", ::KoffingModel)
inbuilt("krabby", ::KrabbyModel)
inbuilt("lickitung", ::LickitungModel)
inbuilt("magnemite", ::MagnemiteModel)
inbuilt("magneton", ::MagnetonModel)
inbuilt("marowak", ::MarowakModel)
inbuilt("meowth", ::MeowthModel)
inbuilt("mew", ::MewModel)
@@ -319,8 +314,6 @@ object VaryingModelRepository {
inbuilt("rapidash", ::RapidashModel)
inbuilt("sandshrew", ::SandshrewModel)
inbuilt("sandslash", ::SandslashModel)
inbuilt("scyther", ::ScytherModel)
inbuilt("seel", ::SeelModel)
inbuilt("spearow", ::SpearowModel)
inbuilt("starmie", ::StarmieModel)
inbuilt("staryu", ::StaryuModel)
@@ -340,7 +333,6 @@ object VaryingModelRepository {
inbuilt("electivire", ::ElectivireModel)
inbuilt("lickilicky", ::LickilickyModel)
inbuilt("mimejr", ::MimejrModel)
inbuilt("scizor", ::ScizorModel)
inbuilt("tangrowth", ::TangrowthModel)
inbuilt("blissey", ::BlisseyModel)
inbuilt("piloswine", ::PiloswineModel)
@@ -365,7 +357,6 @@ object VaryingModelRepository {
inbuilt("yanmega", ::YanmegaModel)
inbuilt("basculin", ::BasculinModel)
inbuilt("emolga", ::EmolgaModel)
inbuilt("maractus", ::MaractusModel)
inbuilt("bounsweet", ::BounsweetModel)
inbuilt("dartrix", ::DartrixModel)
inbuilt("decidueye", ::DecidueyeModel)
@@ -384,7 +375,6 @@ object VaryingModelRepository {
inbuilt("sableye", ::SableyeModel)
inbuilt("natu", ::NatuModel)
inbuilt("xatu", ::XatuModel)
inbuilt("wailmer", ::WailmerModel)
inbuilt("wailord", ::WailordModel)
inbuilt("murkrow", ::MurkrowModel)
inbuilt("nacli", :: NacliModel)
@@ -431,7 +421,6 @@ object VaryingModelRepository {
inbuilt("exploud", :: ExploudModel)
inbuilt("luvdisc", :: LuvdiscModel)
inbuilt("cryogonal", :: CryogonalModel)
inbuilt("sigilyph", :: SigilyphModel)
inbuilt("pumpkaboo", :: PumpkabooModel)
inbuilt("gourgeist", :: GourgeistModel)
inbuilt("eiscue", :: EiscueModel)
@@ -445,9 +434,7 @@ object VaryingModelRepository {
inbuilt("shiftry", ::ShiftryModel)
inbuilt("kricketot", ::KricketotModel)
inbuilt("kricketune", ::KricketuneModel)
inbuilt("heatmor", ::HeatmorModel)
inbuilt("durant", ::DurantModel)
inbuilt("sharpedo", ::SharpedoModel)
inbuilt("mawile", ::MawileModel)
inbuilt("walkingwake", ::WalkingwakeModel)
inbuilt("ironleaves", ::IronleavesModel)
@@ -476,8 +463,6 @@ object VaryingModelRepository {
inbuilt("spinarak", ::SpinarakModel)
inbuilt("ariados", ::AriadosModel)
inbuilt("shuckle", ::ShuckleModel)
inbuilt("taillow", ::TaillowModel)
inbuilt("swellow", ::SwellowModel)
inbuilt("mudbray", ::MudbrayModel)
inbuilt("comfey", ::ComfeyModel)
inbuilt("tandemaus", ::TandemausModel)
@@ -495,8 +480,6 @@ object VaryingModelRepository {
inbuilt("gliscor", ::GliscorModel)
inbuilt("poochyena", ::PoochyenaModel)
inbuilt("mightyena", ::MightyenaModel)
inbuilt("floragato", ::FloragatoModel)
inbuilt("meowscarada", ::MeowscaradaModel)
inbuilt("shroomish", ::ShroomishModel)
inbuilt("breloom", ::BreloomModel)
inbuilt("charcadet", ::CharcadetModel)
@@ -523,19 +506,15 @@ object VaryingModelRepository {
inbuilt("sirfetchd", ::SirfetchdModel)
inbuilt("rookidee", ::RookideeModel)
inbuilt("corvisquire", ::CorvisquireModel)
inbuilt("corviknight", ::CorviknightModel)
inbuilt("duskull", ::DuskullModel)
inbuilt("dusclops", ::DusclopsModel)
inbuilt("dusknoir", ::DusknoirModel)
inbuilt("nickit", ::NickitModel)
inbuilt("thievul", ::ThievulModel)
inbuilt("cacnea", ::CacneaModel)
inbuilt("cacturne", ::CacturneModel)
inbuilt("glimmet", ::GlimmetModel)
inbuilt("glimmora", ::GlimmoraModel)
inbuilt("bonsly", ::BonslyModel)
inbuilt("sudowoodo", ::SudowoodoModel)
inbuilt("bouffalant", ::BouffalantModel)
inbuilt("cetoddle", ::CetoddleModel)
inbuilt("cetitan", ::CetitanModel)
inbuilt("venipede", ::VenipedeModel)
@@ -544,7 +523,6 @@ object VaryingModelRepository {
inbuilt("aipom", ::AipomModel)
inbuilt("ambipom", ::AmbipomModel)
inbuilt("hoothoot", ::HoothootModel)
inbuilt("noctowl", ::NoctowlModel)
inbuilt("wingull", ::WingullModel)
inbuilt("pelipper", ::PelipperModel)
inbuilt("shinx", ::ShinxModel)
@@ -584,7 +562,6 @@ object VaryingModelRepository {
inbuilt("fuecoco", :: FuecocoModel)
inbuilt("crocalor", :: CrocalorModel)
inbuilt("skeledirge", :: SkeledirgeModel)
inbuilt("quaxly", :: QuaxlyModel)
inbuilt("quaxwell", :: QuaxwellModel)
inbuilt("quaquaval", :: QuaquavalModel)
inbuilt("snubbull", :: SnubbullModel)
@@ -634,12 +611,6 @@ object VaryingModelRepository {
inbuilt("kirlia", ::KirliaModel)
inbuilt("gardevoir", ::GardevoirModel)
inbuilt("gallade", ::GalladeModel)
inbuilt("beldum", ::BeldumModel)
inbuilt("metang", ::MetangModel)
inbuilt("ursaluna", ::UrsalunaModel)
inbuilt("lechonk", ::LechonkModel)
inbuilt("oinkologne_male", ::OinkologneMaleModel)
inbuilt("oinkologne_female", ::OinkologneFemaleModel)
inbuilt("pidove", ::PidoveModel)
inbuilt("tranquill", ::TranquillModel)
inbuilt("unfezant", ::UnfezantModel)
@@ -647,8 +618,6 @@ object VaryingModelRepository {
inbuilt("gurdurr", ::GurdurrModel)
inbuilt("conkeldurr", ::ConkeldurrModel)
inbuilt("clodsire", ::ClodsireModel)
inbuilt("teddiursa", ::TeddiursaModel)
inbuilt("ursaring", ::UrsaringModel)
inbuilt("litwick", ::LitwickModel)
inbuilt("lampent", ::LampentModel)
inbuilt("chandelure", ::ChandelureModel)
@@ -684,8 +653,6 @@ object VaryingModelRepository {
inbuilt("zorua_hisuian", ::ZoruaHisuianModel)
inbuilt("zoroark", ::ZoroarkModel)
inbuilt("zoroark_hisuian", ::ZoroarkHisuianModel)
inbuilt("gossifleur", ::GossifleurModel)
inbuilt("eldegoss", ::EldegossModel)
inbuilt("amaura", ::AmauraModel)
inbuilt("aurorus", ::AurorusModel)
inbuilt("voltorb_hisuian", ::VoltorbHisuianModel)
@@ -703,7 +670,6 @@ object VaryingModelRepository {
inbuilt("darmanitan", ::DarmanitanModel)
inbuilt("darmanitan_zen", ::DarmanitanZenModel)
inbuilt("turtonator", ::TurtonatorModel)
inbuilt("stonjourner", ::StonjournerModel)
inbuilt("cufant", ::CufantModel)
inbuilt("copperajah", ::CopperajahModel)
inbuilt("budew", ::BudewModel)
@@ -812,7 +778,7 @@ object VaryingModelRepository {
for (directory in modelDirectories) {
MODEL_FACTORIES.forEach { (key, func) ->
resourceManager.listResources(directory) { path -> path.endsWith(key) }
.map { func.apply(it.key, it.value) }
.mapNotNull { func.apply(it.key, it.value) }
.forEach {
texturedModels[it.first] = it.second
models++
@@ -882,7 +848,7 @@ object VaryingModelRepository {
return null
}
fun registerFactory(id: String, factory: BiFunction<ResourceLocation, Resource, Pair<ResourceLocation, Bone>>) {
fun registerFactory(id: String, factory: BiFunction<ResourceLocation, Resource, Pair<ResourceLocation, Bone>?>) {
MODEL_FACTORIES[id] = factory
}
@@ -890,13 +856,17 @@ object VaryingModelRepository {
Needs to be java function to work with non kotlin sidemods.
- Waterpicker
*/
private var MODEL_FACTORIES = mutableMapOf<String, BiFunction<ResourceLocation, Resource, Pair<ResourceLocation, Bone>>>().also {
it[".geo.json"] = BiFunction<ResourceLocation, Resource, Pair<ResourceLocation, Bone>> { identifier: ResourceLocation, resource: Resource ->
private var MODEL_FACTORIES = mutableMapOf<String, BiFunction<ResourceLocation, Resource, Pair<ResourceLocation, Bone>?>>().also {
it[".geo.json"] = BiFunction<ResourceLocation, Resource, Pair<ResourceLocation, Bone>?> { identifier: ResourceLocation, resource: Resource ->
resource.open().use { stream ->
val json = String(stream.readAllBytes(), StandardCharsets.UTF_8)
val resolvedIdentifier = ResourceLocation.fromNamespaceAndPath(identifier.namespace, File(identifier.path).nameWithoutExtension)
val texturedModel = TexturedModel.from(json)
if (texturedModel == null) {
LOGGER.warn("Failed to load model file with identifier $identifier You can ignore this (and the above message) if this is not a cobblemon model")
return@BiFunction null
}
resolvedIdentifier to texturedModel.create().bakeRoot()
}
}
@@ -10,7 +10,9 @@ package com.cobblemon.mod.common.command
import com.cobblemon.mod.common.Cobblemon.LOGGER
import com.cobblemon.mod.common.api.permission.CobblemonPermissions
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.requiresWithPermission
import com.mojang.brigadier.Command
import com.mojang.brigadier.CommandDispatcher
@@ -45,7 +47,10 @@ object SpawnAllPokemon {
for (species in PokemonSpecies.implemented) {
if (species.nationalPokedexNumber in range) {
LOGGER.debug(species.name)
species.create().sendOut(player.level() as ServerLevel, player.position(), null)
val pokemonEntity = PokemonProperties.parse("species=${species.name} level=10").createEntity(context.source.level)
pokemonEntity.moveTo(player.x, player.y, player.z, pokemonEntity.yRot, pokemonEntity.xRot)
pokemonEntity.entityData.set(PokemonEntity.SPAWN_DIRECTION, pokemonEntity.random.nextFloat() * 360F)
context.source.level.addFreshEntity(pokemonEntity)
}
}

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