Compare commits

...
155 Commits
Author SHA1 Message Date
whatsy 149c1f85e0 Sound stuff + more tweaks 2026-11-07 11:34:27 -05:00
whatsy 0725fa83d6 Redstone functionality 2026-11-06 18:54:09 -05:00
whatsy 1f5bb78684 Data monitor stuff and things idk 2026-11-04 19:43:08 -05:00
whatsy 87c21d8906 Moved Gimmighoul chest logic to a PokemonDisguiseBlock interface to repurpose for future blocks 2026-11-04 17:19:26 -05:00
whatsy cadaf00d08 mower + fan 2026-11-04 16:47:16 -05:00
whatsy 30404192bd washer mostly done + mower started 2026-11-04 13:41:07 -05:00
whatsy 5b3566a2b5 copper fridge basics 2026-11-03 22:37:16 -05:00
whatsy 1feeab6f87 Merge remote-tracking branch 'origin/main' into applied-appliances
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonBlocks.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
2026-11-03 12:31:38 -05:00
Polymeta 99e0a26d7b Merge branch 'compat-improvements' into 'main'
teeny fixes to compat

See merge request cable-mc/cobblemon!2520
2026-11-02 09:17:39 +00:00
dhi_holo 71753df513 Leftovers
Also a slight fix to the order in changelog
2026-11-02 13:30:23 +10:00
dhi_holo 729f080f6e Merge branch 'main' into compat-improvements 2026-11-02 13:26:43 +10:00
dhi_holo 13eb57afb1 category fix
Fixing one recipe category I missed teehee
2026-11-02 13:23:42 +10:00
Jackson Bowes 72b6cb06ff Merge branch 'soon-to-be-implemented-steps' into 'main'
Implementing some steps

See merge request cable-mc/cobblemon!2519
2026-11-01 08:15:06 -06:00
Jackson Bowes 74a57eb972 Merge branch 'sterr/move-sound-implementation' into 'main'
Added sounds to Gigaton Hammer and Pyro Ball

See merge request cable-mc/cobblemon!2518
2026-11-01 08:14:14 -06:00
Sterrezo 7246c7f8e6 Update CHANGELOG.md 2026-11-01 13:22:32 +01:00
Sterrezo cd05f741ae Merge branch 'main' into soon-to-be-implemented-steps 2026-11-01 13:21:23 +01:00
Sterrezo 00222d929d Added sounds to Gigaton Hammer and Pyro Ball 2026-11-01 13:18:22 +01:00
Polymeta b8f4637cb3 Merge branch 'feat/power-ride-training' into 'main'
power bracer ride stat training

See merge request cable-mc/cobblemon!2503
2026-10-31 12:33:22 +00:00
Ronak Chavva 9f572250f5 fix(*): modularization 2026-10-31 06:59:37 -05:00
Ronak Chavva 0927d6fa43 fix(*): enum change, configurable item stat 2026-10-31 06:26:45 -05:00
Ronak Chavva a293b3d71f changelog additions 2026-10-31 05:09:36 -05:00
Ronak Chavva 162b1cc68f Merge branch 'main' of https://gitlab.com/ronakch8/cobblemon into feat/power-ride-training 2026-10-31 05:07:29 -05:00
Polymeta 67f906dec2 [skip-ci] changelog cleanup
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-30 23:47:43 +00:00
Polymeta 0570afbe05 Merge branch 'main' into 'main'
Fix habitat structure misspelling

Closes #2132

See merge request cable-mc/cobblemon!2500
2026-10-30 23:46:30 +00:00
Rayegun dfba2d27ab Fix habitat structure misspelling 2026-10-30 23:46:29 +00:00
Polymeta 9c7cd4b616 Merge branch 'healer-spawn-point' into 'main'
Healer spawn point

See merge request cable-mc/cobblemon!2489
2026-10-30 23:43:30 +00:00
Polymeta 9fe0e9c87e [skip-ci] changelog cleanup
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-30 23:40:22 +00:00
Polymeta bd0e5a44bd Merge branch 'feat/amethyst-core' into 'main'
feat/amethyst core

See merge request cable-mc/cobblemon!2505
2026-10-30 23:39:37 +00:00
Polymeta 229ec4176b [skip-ci] changelog cleanup
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-30 23:38:54 +00:00
Polymeta 323413efdc Merge branch 'fix/ponigiri-food-values-appleskin' into 'main'
fix: correct ponigiri values for AppleSkin

See merge request cable-mc/cobblemon!2513
2026-10-30 23:35:37 +00:00
Polymeta a309cc2522 [skip-ci] changelog cleanup
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-30 23:33:53 +00:00
Polymeta cb782a2aa1 Merge branch 'steppy-steps' into 'main'
Pokémon Stepsounds

Closes #2107

See merge request cable-mc/cobblemon!2432
2026-10-30 23:30:31 +00:00
Sterrezo 2c58dcb8ef Update CHANGELOG.md 2026-10-31 00:31:51 +01:00
Sterrezo d91cd4322c Merge branch 'main' into steppy-steps 2026-10-31 00:29:14 +01:00
whatsy e48e492392 Update CHANGELOG.md 2026-10-27 23:45:20 -04:00
whatsy 1f93994eba Merge branch 'main' into healer-spawn-point
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/world/gamerules/CobblemonGameRules.kt
2026-10-27 23:45:02 -04:00
whatsy 5210121b3d Update CHANGELOG.md 2026-10-27 23:36:23 -04:00
Gitoido Okaski 7fa3bf24d1 chore: update explanation skip_cl 2026-10-28 03:10:34 +00:00
Gitoido Okaski 1128d7edf3 fix: appleskin gradle stuff for runtime 2026-10-28 03:10:34 +00:00
Gitoido Okaski eef50a7237 fix: correct ponigiri values for AppleSkin 2026-10-28 03:10:34 +00:00
Hiroku f4140a097d Put the snap back on 2026-10-27 20:16:12 +10:00
Hiroku b79dbcca80 no scope. I mean no snap 2026-10-27 19:42:59 +10:00
Hiroku 5ac12a897a Merge remote-tracking branch 'origin/lang-updates' 2026-10-27 19:28:28 +10:00
Polymeta ae5f7c83f2 Merge branch 'implement_pokemon' into 'main'
implement_pokemon

See merge request cable-mc/cobblemon!2507
2026-10-26 23:10:50 +00:00
ewwww f14de9ab58 updated water shuriken 2026-10-26 16:35:00 -04:00
ewwww 8a1c846c2c Merge branch 'main' into implement_pokemon 2026-10-26 16:06:28 -04:00
Polymeta 459e7d3490 this doesnt make any sense
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-26 09:16:39 +00:00
Polymeta 5a9be8944f Merge branch 'hotbox-hitfix' into 'main'
Orb Ceiling Hitbox Correction

See merge request cable-mc/cobblemon!2512
2026-10-26 07:09:59 +00:00
Polymeta 3bb941b087 Merge branch 'dusclops-cry-fix' into 'main'
fixed dusclops using squirtle's cry

See merge request cable-mc/cobblemon!2511
2026-10-26 07:07:40 +00:00
dhi_holo 384b496d76 T H E O R B 2026-10-26 13:37:09 +10:00
geumu 4caa736e0b Translated using Weblate (Korean)
Currently translated at 99.6% (9549 of 9587 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/ko/
2026-10-26 02:38:47 +00:00
geumu c3e9051918 Translated using Weblate (Korean)
Currently translated at 98.5% (9445 of 9587 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/ko/
2026-10-26 02:26:52 +00:00
ewwww fe940caafc fixed dusclops using squirtle's cry 2026-10-25 21:33:38 -04:00
Polymeta c9d148ec9c bump showdown build and changelog
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-26 00:41:23 +00:00
Polymeta e611bf4a77 Merge branch 'fix-missing-recipe-book-data' into 'main'
Fixed Cooking Pot recipe book tabs and entries on Fabric

See merge request cable-mc/cobblemon!2510
2026-10-26 00:37:47 +00:00
Polymeta 8093822140 Merge branch 'battle-selection-fix' into 'main'
Fixed a bug with battle selection.

See merge request cable-mc/cobblemon!2509
2026-10-26 00:27:00 +00:00
Fyre520 f695ec15f9 Fixed Cooking Pot recipe book tabs and entries on Fabric 2026-10-26 02:01:15 +05:30
Deltric 1f6c791ce6 Fixed a bug with battle selection. 2026-10-25 14:24:44 -04:00
Polymeta 570805fdf1 Merge branch 'structure-tags-for-spawning' into 'main'
Structure Spawn Tags

See merge request cable-mc/cobblemon!2508
2026-10-25 16:53:38 +00:00
dhi_holo ddecb08bc7 Edit is_illager_structure.json 2026-10-26 00:21:36 +10:00
Kenji_64 a1b930a21f More Frogadier fixes (ty Mitchoo) 2026-10-25 14:14:44 +01:00
Kenji_64 7728ff3892 Fixed Fearow missing blink crashing during gliding 2026-10-25 14:11:22 +01:00
阿鱼 0b38e063d2 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.7% (9464 of 9587 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2026-10-25 10:52:25 +00:00
Hiroku 4d7cfcdf61 Added q.target_fainted to MoveInstruction 2026-10-25 11:11:52 +10:00
Hiroku e56dd6ef64 snap it back on 2026-10-25 10:43:01 +10:00
Kenji_64 236b98fa78 I forgot the changelog :( 2026-10-25 02:21:08 +02:00
Kenji_64 ac61e0d4d0 Had to fix Froakie again. Heck 2026-10-25 02:20:20 +02:00
Kenji_64 d8956fd66f Froakie line eye lid and animation fixes 2026-10-25 02:14:01 +02:00
ewwww 50a5a78dd4 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2026-10-24 19:16:59 -04:00
ewwww 76c2654399 it appears my lang tweaks were reverted somehow 2026-10-24 19:16:20 -04:00
Ronak Chavva 397d3c618d reverted amythest pokespawn condition 2026-10-23 18:28:22 -05:00
Ronak Chavva 066a6b56f7 Merge branch 'main' of https://gitlab.com/ronakch8/cobblemon into feat/power-ride-training 2026-10-23 18:13:32 -05:00
Ronak Chavva 29f6feab6c Merge branch 'main' of https://gitlab.com/ronakch8/cobblemon into feat/amethyst-core 2026-10-23 18:09:35 -05:00
Ronak Chavva ea5d3ae40f amethyst grows on core 2026-10-23 18:09:11 -05:00
Ronak Chavva 7687833add mapping rewrite 2026-10-22 21:35:48 -05:00
Ronak Chavva cb9ba82fcc holding power bracer while riding, 1 to all 5 stats 2026-10-22 03:11:14 -05:00
dhi_holo b5ac54cd16 Tweaks to prepare for Scrapes 2026-10-21 14:22:17 +10:00
dhi_holo dc703e67f7 Merge branch 'main' into structure-tags-for-spawning 2026-10-21 14:01:10 +10:00
whatsy bacc482bf0 finishing touches 2026-10-14 16:25:16 -04:00
Gertimoshka edb3f906f8 Simpler Mixin 2026-10-14 21:48:14 +02:00
whatsy 4171bf341b Add config option to allow using healing machines as a respawn point 2026-10-14 15:02:54 -04:00
dhi_holo 8e1fcc6f14 Structure Spawn Tags
Feel free to rename, delete, or rework any of these, it's moreso just setting the groundwork

`spawns/is_aquatic_monument` - Ocean Monuments and related structures
`spawns/is_aquatic_ruins` - Ocean Ruins and similar structures
`spawns/is_civilization` - Village and Towns tag, for anything that should spawn at any kind of village/town
`spawns/is_desert_monument` - Desert Pyramids and Temples
`spawns/is_dungeon` - Modded tag, the idea is things of the Stronghold *vibe*, but not being literal strongholds
`spawns/is_end_structure` - End Cities and related structures
`spawns/is_graveyard` - Modded tag, graveyards and crypts
`spawns/is_igloo` - just the vanilla igloo, it's me just wanting stuff in tags where it isn't yet so if some addon wants to give igloos another place they can
`spawns/is_illager_outpost` - small settlements for illagers, such as campsites and other small watchtower-like things
`spawns/is_illager_structure` - Bigger illager structures, the mansion, manors, stuff that has a sense of "infrastructure" I suppose
`spawns/is_jungle_monument` - Jungle Temples and Pyramids
`spawns/is_nether_structure` - is a structure of the Nether
`spawns/is_piglin_structure` - is a structure specifically inhabited by Piglins. Can be used to either add stuff specifically around Piglins, or to prevent things around them
`spawns/is_ruins` - Taking what we have as ruins and just applying that logic to other mods
`spawns/is_shipwreck` - not sure if we use this for spawns, but if we do this can be hooked into, if not then this could be deleted, no hassle, just felt like a logical thing to include. Is related to "surface" shipwrecks, not things like the coves
`spawns/is_witch_structure` - witch structures, like huts, villages, etc. Also added any structures that force black cat spawning, as that's used to reference to witches in the vanilla tags

Mods used within the tags so far:
https://modrinth.com/mod/dungeons-and-taverns (`nova_structures`)
A lot of https://modrinth.com/organization/nuVP8uUG mods (the Yung structure ones, usually starts as `better` and then the structure name)
https://modrinth.com/mod/enderscape
https://modrinth.com/mod/aquamirae
https://modrinth.com/mod/terralith
Will continue to investigate mods to add to these
2026-10-14 17:54:34 +10:00
Gitoido 61d53f3052 Merge branch 'main' into 'steppy-steps'
# Conflicts:
#   common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
2026-10-09 16:19:32 +00:00
Sterrezo 4221993f7d Added stepsounds to Mr. Mime 2026-10-03 14:39:21 +02:00
Sterrezo a616c25c8c Added stepsounds to Parasect 2026-09-30 14:45:00 +02:00
Sterrezo 6ce4bf5673 Added stepsounds to Rhyhorn 2026-09-30 14:34:07 +02:00
Sterrezo 1b652ba99f Added stepsounds to Rhydron 2026-09-30 14:01:50 +02:00
Sterrezo 11b59df386 Added stepsounds to Dewgong 2026-09-28 20:20:16 +02:00
Sterrezo ac2b068bf3 Added stepsounds to Blastoise 2026-09-28 14:06:42 +02:00
Sterrezo 8e8f346e52 Added stepsounds keyframes to Venusaur 2026-09-28 13:47:47 +02:00
dhi_holo b426df7271 A Metric Buttton of Tagging
Added a bunch of tags, IDs, and redundancies, it doesn't cover everything but it should cover a lot of the base game without much worry
2026-09-28 10:29:50 +10:00
Sterrezo 1543e06a06 Update CHANGELOG.md 2026-09-27 14:56:17 +02:00
Sterrezo d7b4ccb1e5 Update corviknight.animation.json 2026-09-27 14:46:07 +02:00
Sterrezo dedd449329 Update corviknight.animation.json 2026-09-27 14:45:31 +02:00
Sterrezo 38c589658f Finalized assets and added amethyst stepsounds it'S FINALLY DONE 2026-09-27 14:44:29 +02:00
Sterrezo 2f961bd7bf Expanded on all stepsounds to cover metal surfaces 2026-09-26 23:52:15 +02:00
Sterrezo b72244a986 Added large and medium claw stepsounds for glass surfaces 2026-09-26 19:42:06 +02:00
Sterrezo 6710f25190 Added medium and large claw stepsounds for mud, wood and snow surfaces, updated mud hoof stepsounds 2026-09-26 15:44:32 +02:00
Sterrezo 4089e5d7a9 Added medium and large claw stepsounds for dirt and sand surfaces, updated stone claw stepsounds 2026-09-26 11:54:45 +02:00
Sterrezo 0a49b5b17b Added medium and large claw stepsounds for stone surfaces, updated grass claw stepsounds 2026-09-25 16:57:06 +02:00
Sterrezo 34c40de429 Suppressed Pidgeot's and Corviknight's Minecraft stepsounds 2026-09-25 12:03:03 +02:00
Sterrezo 6d02144401 Updated grass claw stepsound assets 2026-09-25 12:01:42 +02:00
Sterrezo 561687ce0f Added stepsounds to Pidgeot's ride walk animations 2026-09-25 11:30:28 +02:00
dhi_holo 49c22f951d Update copper_fridge.json 2026-09-25 14:59:54 +10:00
dhi_holo a94cbc4eae Merge branch 'main' into applied-appliances 2026-09-25 14:59:00 +10:00
Sterrezo 20973c6724 Added stepsound keyframes to Pidgeot, added medium and large claw stepsounds for grass surfaces 2026-09-24 22:44:15 +02:00
Sterrezo bf10a4dcef Added medium and large hoof stepsounds for glass and ice surfaces 2026-09-24 21:23:37 +02:00
Sterrezo 565987a780 Added standard medium and large stepsounds for glass/ice surfaces, updated mud hoof sounds 2026-09-23 14:49:34 +02:00
Sterrezo 4f9a6c8e98 Added medium and large hoof stepsounds for mud surfaces 2026-09-23 10:46:56 +02:00
Sterrezo 3a3e92d441 Update CHANGELOG.md 2026-09-23 00:38:26 +02:00
Sterrezo bc0dc809f9 Merge branch 'main' into steppy-steps 2026-09-23 00:37:33 +02:00
Sterrezo 92310847aa Footsteps now check from depth 0 instead of 1 2026-09-23 00:08:37 +02:00
Polymeta 5bdc59830c change standingOn logic to consider non-full blocks
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-09-22 22:44:09 +01:00
Sterrezo 17f524d3da Added standard medium and large stepsounds for mud surfaces 2026-09-22 18:45:29 +02:00
Sterrezo 4d0de2bb45 Corrected the size sound variation for leaves stepsounds 2026-09-22 15:52:05 +02:00
Sterrezo b3b8f56bb8 Made block tags optional 2026-09-22 15:45:46 +02:00
Sterrezo f036b83693 Added universal stepsounds for leaves 2026-09-22 15:34:17 +02:00
Sterrezo 73fb31c2fc Added hoof stepsounds for wood surfaces 2026-09-22 10:49:03 +02:00
Sterrezo 381787f39d Updated standard wood stepsounds 2026-09-22 10:24:12 +02:00
dhi_holo 5083af626c Fridge Cleaning
Tried changing some stuff to fix the fridge, it failed, but the code is a bit more consistent now so I'll keep what it got to
2026-09-19 18:05:21 +10:00
dhi_holo 137bb37c29 Merge branch 'main' into applied-appliances 2026-09-19 16:26:53 +10:00
dhi_holo eec578b312 I. Am. AN IDIOT!
With a Axe and a Honeycomb.
2026-09-19 16:26:16 +10:00
dhi_holo b6abe9711d Pistons Die Now
Added Piston Reactions, cleaned up comments on Fridge
2026-09-17 15:10:16 +10:00
dhi_holo 38c2e0d194 Merge branch 'main' into applied-appliances 2026-09-17 14:49:34 +10:00
dhi_holo 69566a97ca Oxidation Four of Five
Untested on NeoForge, will test once I fix Fridge

Oven, Washer, Mower, and Fan all oxidize correctly, Fridge breaks instantly when ticking. I've got a couple theories to test on fixing it
2026-09-17 14:49:11 +10:00
dhi_holo 6866e9af9b Data Files
Loot Tables, Recipes, Recipe Advancements and Tags. More could be added, but this is a good starting point
2026-09-16 19:40:34 +10:00
dhi_holo e45f2c6261 Progress
Got a mostly working weathering block class, but the codec is pissing me off
2026-09-16 15:54:05 +10:00
dhi_holo d9bea49567 Merge branch 'main' into applied-appliances 2026-09-15 20:16:50 +10:00
dhi_holo 235b753a25 Fully Assetted
(Mostly)
Copper Fans still need their wall variant, but this gets everything reasonably testable for trying to get oxidation working
2026-09-15 20:16:33 +10:00
dhi_holo 3d48432390 Fridge Too
Fridge now places both halves and looks right and allat, yay yippee
2026-09-15 19:40:53 +10:00
dhi_holo 7b03940dab Checkpoint
Got the basic functions for the Fan, Mower, Washer, and Oven in. Temporarily removed oxidation classes because it wasn't behaving and I'll reinvestigate later. Fridge next, the concerning one
2026-09-15 18:38:40 +10:00
dhi_holo 8d5d37c750 Breaking Shit
I'm breaking everything lmao
2026-09-14 20:20:16 +10:00
dhi_holo cdb9c80c0e Commented Out Some Unused Pieces
Trying to slim what's there so I can work out the main things to then reassemble it all together properly later
2026-09-14 18:48:17 +10:00
dhi_holo a77f035617 Oh God Oh Fuck They're Doing Something Weird Again
Began some basic code for the Copper Appliance Blocks. It's uh, not pretty, but the purpose is to be a shell to test the visual behaviours on while the smartypants make the actual appliance work *work*.
2026-09-14 18:33:19 +10:00
Sterrezo 2cb942a24b Merge branch 'main' into steppy-steps 2026-09-10 21:26:50 +02:00
Sterrezo c79cb5731e Missclicked 2026-09-10 18:14:43 +02:00
Sterrezo 4760bb15a4 Added standard medium and large footsteps for wood surfaces 2026-09-10 18:14:28 +02:00
Sterrezo aac881f23c Added large and medium hoof footstep sounds 2026-09-09 18:31:27 +02:00
Sterrezo da19c51566 Implemented standard medium and large snow footsteps 2026-09-09 17:58:27 +02:00
Sterrezo 37dd354155 Merge branch 'main' into steppy-steps 2026-09-06 11:12:32 +02:00
Sterrezo acb1ebda19 Finalized hoof sounds 2026-05-27 12:34:57 +02:00
Sterrezo 5dddc05626 Merge branch 'main' into steppy-steps 2026-05-27 00:16:42 +02:00
Sterrezo 99890671bd Added hoof footsteps for sand surfaces and updated other hoof sounds 2026-05-26 22:21:56 +02:00
Sterrezo 9451ac5f46 Merge branch 'main' into steppy-steps 2026-05-26 21:42:41 +02:00
Sterrezo a8e4e21ba1 Merge branch 'main' into steppy-steps 2026-05-19 14:15:48 +02:00
Sterrezo f555ba3703 Made Molang slightly less cursed with proper random functions 2026-05-16 14:24:18 +02:00
Sterrezo 37677b3730 Asset updates, added hoof on stone sounds 2026-05-16 12:17:24 +02:00
Sterrezo 2a298b2268 Merge branch 'main' into steppy-steps 2026-05-16 11:01:28 +02:00
Sterrezo ad3f94fb80 Added hoof grass medium and large sounds 2026-05-16 02:27:46 +02:00
Sterrezo 719660798e Started hoof sound implementation with Wyrdeer, asset and keyframe updates 2026-05-15 18:17:04 +02:00
Sterrezo 8d973a09e1 Tweaks to the footstep function logic to better account for depth
If depth is 2 outright, the function could pick a block below the actual block the entity is standing on if it was checked earlier in the function. Loop iterates twice, so now it plays footsteps even when standing on the edge of a block or running down slopes.
2026-05-15 11:48:50 +02:00
Sterrezo 3579a86cde Merge branch 'main' into steppy-steps 2026-05-15 11:08:00 +02:00
Sterrezo ba96a6a205 Added standard medium and large sand footsteps 2026-05-14 20:18:04 +02:00
Sterrezo f07d2a9a9a First implementation of footstep keyframes with Arcanine 2026-05-14 16:56:13 +02:00
Sterrezo 2469067fd4 Allow for silencing step sounds within the species file 2026-05-14 02:24:18 +02:00
939 changed files with 19592 additions and 2379 deletions

No files matched your search

+15 -93
View File
@@ -1,107 +1,29 @@
# Changelog
## [1.8.3 (October 25th, 2026)](#1-8-3)
## [1.8.5 (MONTH xth, 2026)](#1-8-5)
### Additions
- Added compatability with AppleSkin.
### New Rideable Pokémon
- Vikavolt
- Fearow
### Particles
## New Move Animations
- Water Shuriken
### Cries added/updated for the following Pokémon
- Hoppip
- Skiploom
- Jumpluff
- Houndour
- Houndoom
- Wurmple
- Silcoon
- Beautifly
- Cascoon
- Dustox
- Surskit
- Masquerain
- Torkoal
- Starly
- Staravia
- Staraptor
- Combee
- Vespiquen
- Dusknoir
- Helioptile
- Heliolisk
- Grubbin
- Charjabug
- Vikavolt
- Applin (updated)
- Flapple (updated)
- Appletun
- Runerigus
- Dipplin
### Animation updates for the following Pokémon
- Vikavolt
- Magby
- Magmar
- Ninetales (+ Alolan)
- Spearow
- Fearow
- Squawkabilly
- Mudkip
- Marshtomp
- Swampert
- Added the `healersSetSpawn` gamerule. When enabled, using a healing machine will set your spawnpoint.
- A Pokémon holding a Power item now gains 1 point in the corresponding riding stat every two minutes while being ridden. The interval is configurable, and can be disabled with `-1`.
- Added sounds to Gigaton Hammer and Pyro Ball
- Added stepsounds to Venusaur, Blastoise, Dewgong, Rhydon, Rhyhorn, Parasect and Mr. Mime.
### Changes
- Changed the Misc icon in the Campfire Pot Recipe Book to Health Candy.
- Moved EXP Candies from the Medicine recipe book category to the Misc category.
- Removed Dynamic Lights data from the Magmarizer item for consistency with the block.
- Added `doPokemonPredation` game rule, which controls aggressiveness of Pokémon with the `hate_entity` brain task defined.
- Added `predation_chance` server config value, which controls the possibility of attacking the hated entity found in `hate_entity` brain tasks.
- Prehistoric Eroded Pillar generates slightly more frequently.
- Togekiss was changed from a jet-style mount to bird-style.
- Amethyst now grows from Typegem core blocks like typegems do
- Updated the recipe category for the Create compatibility EXP Candy recipe
- Added No Man's Lands' Honeyed Apple to the Leaves Leftovers tag
### Fixes
- Fixed datapacks with item interaction evolutions that don't specify an item crashing the world on load.
- Fixed the Pokédex evolution tree crashing when a datapack's dex entry is missing an evolution's form.
- Fixed the Pokédex evolution tree crashing with a stack overflow on evolutions that loop back on themselves.
- Fixed the Pokédex evolution tree crashing when looking at a dex that is not part of the "National Dex" aggregate.
- Fixed some display names in the Pokédex evolution tree having unintended font colours.
- Fixed evolution trees not building properly when a Pokémon has several Pokédex entries for different regions.
- Fixed form-changing evolutions sometimes resolving to the source form in the Pokédex evolution tree.
- Broken datapack evolutions are now logged and skipped in the Pokédex evolution tree instead of crashing.
- Fixed the `alpha` property having no tab completion in commands such as `/pokespawn`, `/pokegive` and `/pokeedit`, and added the missing `dmax_level`, `gmax_factor` and `tradable` aliases to tab completion.
- Fixed friendship booster items not being recognised as such.
- Fixed conflicts with other mods that would make use of recipe books in certain ways (Farmer's Delight Cooking Pot).
- Fixed Pokémon battles stalling when a sidemod cancels the `THROWN_POKEBALL_HIT` hit event.
- Fixed choice feature tab completion in `spawnpokemon/pokegive/pokeedit` commands.
- Fixed MoLang that's targeting players intermittedly failing when they have died, requiring them to relog.
- Fixed a NeoForge bug where none of the Cobblemon plants/berries could be placed into pots.
- Fixed party overlay not hiding when the player opens the Pokédex scanner.
- Fixed `hate_entity` task focusing on its own entity, therefore enabling deadly warfare between Zangoose and Seviper.
- Prehistoric Frozen Pond, Prehistoric Frozen Spike, and Prehistoric Lush Den now actually generate (oops).
- Fixed Frogadier floating in its `battle_idle` animation.
- Fixed absence or incorrect mergers in spawning conditions, causing the max height/depth of conditions to use the min value instead.
- Added stricter riding checks on server side to prevent possible packet forgery when a player tries to ride Pokémon.
- Fixed Pokémon cries and animation sounds played from GUIs, such as the starter selection screen and the Pokédex, being tied to the Master volume slider instead of Friendly Creatures.
- Fixed Archeops T-posing during its `air_cry` animation.
- Fixed Ponigiri food values for AppleSkin integration
- Fixed errors emitted by typos in Parched Peat bog structure files
### Developer
- Bumped NeoForge to `21.1.195` to get access to MixinExtras `0.5` and the expressions annotation.
- New Platform Event `PLAYER_RESPAWN` which is fired when a player respawns (either through death or returning from the end).
- Platform Events `SERVER_PLAYER_TICK_PRE` and `SERVER_PLAYER_TICK_POST` no longer fire when the player is dead.
- It is now tied much closer to the actual entity rather than the player or their connection.
### Molang & Datapacks
- Fixed `q.pokemon.nature` returning class instance instead of proper string value (`cobblemon:adamant`).
- Fixed `q.entity.is_looking_at` result being always `1` for whatever entity passed as the target parameter.
- Added hate chance optional parameter to `hate_entity` task. `1.0` will make an entity always attack the target.
- `q.is_standing_on_blocks` now properly checks for non-full blocks like slabs, Mud or Soul Sand
- Added Molang functions to play footstep sounds based on the corresponding surface. These are intended to be used by Pokémon animations.
- Pokémon can now have their Minecraft footstep sounds silenced in their poser. This doesn't affect emitting game events.
### Particles
### Localization
- Updated translations for:
- Russian
- Japanese
- Brazilian Portuguese
+2
View File
@@ -0,0 +1,2 @@
Spec Doc: https://docs.google.com/document/d/1hEKKrT4JEagJBykx-k9K2BoeNxiMGahUWXnf8YQ85xo/edit?tab=t.0
Marshal: dhi_holo
+107
View File
@@ -0,0 +1,107 @@
# Changelog
## [1.8.3 (October 25th, 2026)](#1-8-3)
### Additions
- Added compatability with AppleSkin.
### New Rideable Pokémon
- Vikavolt
- Fearow
### Particles
## New Move Animations
- Water Shuriken
### Cries added/updated for the following Pokémon
- Hoppip
- Skiploom
- Jumpluff
- Houndour
- Houndoom
- Wurmple
- Silcoon
- Beautifly
- Cascoon
- Dustox
- Surskit
- Masquerain
- Torkoal
- Starly
- Staravia
- Staraptor
- Combee
- Vespiquen
- Dusknoir
- Helioptile
- Heliolisk
- Grubbin
- Charjabug
- Vikavolt
- Applin (updated)
- Flapple (updated)
- Appletun
- Runerigus
- Dipplin
### Animation updates for the following Pokémon
- Vikavolt
- Magby
- Magmar
- Ninetales (+ Alolan)
- Spearow
- Fearow
- Squawkabilly
- Mudkip
- Marshtomp
- Swampert
### Changes
- Changed the Misc icon in the Campfire Pot Recipe Book to Health Candy.
- Moved EXP Candies from the Medicine recipe book category to the Misc category.
- Removed Dynamic Lights data from the Magmarizer item for consistency with the block.
- Added `doPokemonPredation` game rule, which controls aggressiveness of Pokémon with the `hate_entity` brain task defined.
- Added `predation_chance` server config value, which controls the possibility of attacking the hated entity found in `hate_entity` brain tasks.
- Prehistoric Eroded Pillar generates slightly more frequently.
- Togekiss was changed from a jet-style mount to bird-style.
### Fixes
- Fixed datapacks with item interaction evolutions that don't specify an item crashing the world on load.
- Fixed the Pokédex evolution tree crashing when a datapack's dex entry is missing an evolution's form.
- Fixed the Pokédex evolution tree crashing with a stack overflow on evolutions that loop back on themselves.
- Fixed the Pokédex evolution tree crashing when looking at a dex that is not part of the "National Dex" aggregate.
- Fixed some display names in the Pokédex evolution tree having unintended font colours.
- Fixed evolution trees not building properly when a Pokémon has several Pokédex entries for different regions.
- Fixed form-changing evolutions sometimes resolving to the source form in the Pokédex evolution tree.
- Broken datapack evolutions are now logged and skipped in the Pokédex evolution tree instead of crashing.
- Fixed the `alpha` property having no tab completion in commands such as `/pokespawn`, `/pokegive` and `/pokeedit`, and added the missing `dmax_level`, `gmax_factor` and `tradable` aliases to tab completion.
- Fixed friendship booster items not being recognised as such.
- Fixed conflicts with other mods that would make use of recipe books in certain ways (Farmer's Delight Cooking Pot).
- Fixed Pokémon battles stalling when a sidemod cancels the `THROWN_POKEBALL_HIT` hit event.
- Fixed choice feature tab completion in `spawnpokemon/pokegive/pokeedit` commands.
- Fixed MoLang that's targeting players intermittedly failing when they have died, requiring them to relog.
- Fixed a NeoForge bug where none of the Cobblemon plants/berries could be placed into pots.
- Fixed party overlay not hiding when the player opens the Pokédex scanner.
- Fixed `hate_entity` task focusing on its own entity, therefore enabling deadly warfare between Zangoose and Seviper.
- Prehistoric Frozen Pond, Prehistoric Frozen Spike, and Prehistoric Lush Den now actually generate (oops).
- Fixed Frogadier floating in its `battle_idle` animation.
- Fixed absence or incorrect mergers in spawning conditions, causing the max height/depth of conditions to use the min value instead.
- Added stricter riding checks on server side to prevent possible packet forgery when a player tries to ride Pokémon.
- Fixed Pokémon cries and animation sounds played from GUIs, such as the starter selection screen and the Pokédex, being tied to the Master volume slider instead of Friendly Creatures.
- Fixed Archeops T-posing during its `air_cry` animation.
### Developer
- Bumped NeoForge to `21.1.195` to get access to MixinExtras `0.5` and the expressions annotation.
- New Platform Event `PLAYER_RESPAWN` which is fired when a player respawns (either through death or returning from the end).
- Platform Events `SERVER_PLAYER_TICK_PRE` and `SERVER_PLAYER_TICK_POST` no longer fire when the player is dead.
- It is now tied much closer to the actual entity rather than the player or their connection.
### Molang & Datapacks
- Fixed `q.pokemon.nature` returning class instance instead of proper string value (`cobblemon:adamant`).
- Fixed `q.entity.is_looking_at` result being always `1` for whatever entity passed as the target parameter.
- Added hate chance optional parameter to `hate_entity` task. `1.0` will make an entity always attack the target.
### Localization
- Updated translations for:
- Russian
- Japanese
- Brazilian Portuguese
+25
View File
@@ -0,0 +1,25 @@
# Changelog
## [1.8.4 (October 27th, 2026)](#1-8-4)
### Changes
- The Froakie line now blinks. The world will never be the same.
### Fixes
- Fixed heaps of spawns not working. This was caused by us missing something before release. RIP.
- Fixed a crash caused by Fearow blinking while you're riding one. Makes sense to me.
- Fixed Minior's "Shields Down" ability being very broken.
- Fixed Dusclops using Squirtle's cry sound (lol).
- Fixed blank Cooking Pot recipe book entries and missing tabs on Fabric.
- Fixed a hitbox issue with placeable Orb held items attached to a ceiling.
- Fixed something sneaky. I'll tell you about it later.
### Molang & Datapacks
- Added `q.target_fainted` function to move action effects that checks if any opponents fainted from the move.
### Particles
- Updated Water Shuriken effect to be timed better when the opponent faints.
### Localization
- Updated translations for:
- Korean
- Simplified Chinese
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.api.riding.RidingStyle;
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawner;
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawnerFactory;
import com.cobblemon.mod.common.api.stats.CobblemonStats;
import com.cobblemon.mod.common.block.HealingMachineBlock;
import com.cobblemon.mod.common.duck.ServerLevelDuck;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
@@ -22,10 +23,14 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
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.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -33,6 +38,9 @@ import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
@Mixin(ServerPlayer.class)
public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
@@ -142,4 +150,17 @@ public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
((ServerLevelDuck) this.serverLevel()).cobblemon$getLevelResourceLocation()
);
}
@Inject(
method = "findRespawnAndUseSpawnBlock(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;FZZ)Ljava/util/Optional;",
at = @At(value = "HEAD"),
cancellable = true
)
private static void cobblemon$useHealthStationAsRespawn(ServerLevel level, BlockPos pos, float angle, boolean forced, boolean keepInventory, CallbackInfoReturnable<Optional<ServerPlayer.RespawnPosAngle>> cir) {
BlockState state = level.getBlockState(pos);
Block block = state.getBlock();
if (block instanceof HealingMachineBlock && HealingMachineBlock.Companion.canSetSpawn(level)) {
cir.setReturnValue(HealingMachineBlock.Companion.findStandUpPosition(EntityType.PLAYER, level, pos).map((vec3) -> ServerPlayer.RespawnPosAngle.of(vec3, pos)));
}
}
}
@@ -69,7 +69,7 @@ public abstract class ClientRecipeBookMixin {
value = "INVOKE",
target = "Lcom/google/common/collect/ImmutableMap;copyOf(Ljava/util/Map;)Lcom/google/common/collect/ImmutableMap;"
))
private void addCustomAggregateCategories(Iterable<RecipeHolder<?>> recipes, RegistryAccess registryAccess, CallbackInfo ci, @Local(name = "map2") Map<RecipeBookCategories, List<RecipeCollection>> map2) {
private void addCustomAggregateCategories(Iterable<RecipeHolder<?>> recipes, RegistryAccess registryAccess, CallbackInfo ci, @Local(ordinal = 1) Map<RecipeBookCategories, List<RecipeCollection>> map2) {
CobblemonRecipeCategories.Companion.getCustomAggregateCategories().forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List) list.stream().flatMap((recipeBookCategoriesx) -> ((List) map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
}
}
@@ -20,14 +20,14 @@ import org.spongepowered.asm.mixin.injection.At;
@Mixin(RecipeBookComponent.class)
public class RecipeBookComponentMixin {
@Definition(id = "recipeBookCategories", local = @Local(name = "recipeBookCategories"))
@Definition(id = "recipeBookCategories", local = @Local(type = RecipeBookCategories.class))
@Definition(id = "FURNACE_SEARCH", field = "Lnet/minecraft/client/RecipeBookCategories;FURNACE_SEARCH:Lnet/minecraft/client/RecipeBookCategories;")
@Expression("recipeBookCategories != FURNACE_SEARCH")
@ModifyExpressionValue(
method = "updateTabs",
at = @At(value = "MIXINEXTRAS:EXPRESSION")
)
private boolean notCookingPotSearch(boolean original, @Local(name = "recipeBookCategories") RecipeBookCategories recipeBookCategories) {
private boolean notCookingPotSearch(boolean original, @Local RecipeBookCategories recipeBookCategories) {
return original && recipeBookCategories != CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory();
}
}
@@ -8,6 +8,9 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.block.appliances.CopperFridgeBlockEntity
import com.cobblemon.mod.common.block.appliances.CopperMowerBlockEntity
import com.cobblemon.mod.common.block.appliances.CopperWasherBlockEntity
import com.cobblemon.mod.common.block.entity.*
import com.cobblemon.mod.common.block.habitat.HabitatBlockEntity
import com.cobblemon.mod.common.block.multiblock.FossilMultiblockBuilder
@@ -126,4 +129,49 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
CobblemonBlocks.MISTLEAF
).build(null)
)
@JvmField
val COPPER_FRIDGE: BlockEntityType<CopperFridgeBlockEntity> = this.create(
"copper_fridge",
BlockEntityType.Builder.of(::CopperFridgeBlockEntity,
CobblemonBlocks.COPPER_FRIDGE,
CobblemonBlocks.EXPOSED_COPPER_FRIDGE,
CobblemonBlocks.WEATHERED_COPPER_FRIDGE,
CobblemonBlocks.OXIDIZED_COPPER_FRIDGE,
CobblemonBlocks.WAXED_COPPER_FRIDGE,
CobblemonBlocks.WAXED_EXPOSED_COPPER_FRIDGE,
CobblemonBlocks.WAXED_WEATHERED_COPPER_FRIDGE,
CobblemonBlocks.WAXED_OXIDIZED_COPPER_FRIDGE
).build(null)
)
@JvmField
val COPPER_WASHER: BlockEntityType<CopperWasherBlockEntity> = this.create(
"copper_washer",
BlockEntityType.Builder.of(::CopperWasherBlockEntity,
CobblemonBlocks.COPPER_WASHER,
CobblemonBlocks.EXPOSED_COPPER_WASHER,
CobblemonBlocks.WEATHERED_COPPER_WASHER,
CobblemonBlocks.OXIDIZED_COPPER_WASHER,
CobblemonBlocks.WAXED_COPPER_WASHER,
CobblemonBlocks.WAXED_EXPOSED_COPPER_WASHER,
CobblemonBlocks.WAXED_WEATHERED_COPPER_WASHER,
CobblemonBlocks.WAXED_OXIDIZED_COPPER_WASHER
).build(null)
)
@JvmField
val COPPER_MOWER: BlockEntityType<CopperMowerBlockEntity> = this.create(
"copper_mower",
BlockEntityType.Builder.of(::CopperMowerBlockEntity,
CobblemonBlocks.COPPER_MOWER,
CobblemonBlocks.EXPOSED_COPPER_MOWER,
CobblemonBlocks.WEATHERED_COPPER_MOWER,
CobblemonBlocks.OXIDIZED_COPPER_MOWER,
CobblemonBlocks.WAXED_COPPER_MOWER,
CobblemonBlocks.WAXED_EXPOSED_COPPER_MOWER,
CobblemonBlocks.WAXED_WEATHERED_COPPER_MOWER,
CobblemonBlocks.WAXED_OXIDIZED_COPPER_MOWER
).build(null)
)
}
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.api.apricorn.Apricorn
import com.cobblemon.mod.common.api.pokemon.stats.Stats
import com.cobblemon.mod.common.block.*
import com.cobblemon.mod.common.block.LecternBlock
import com.cobblemon.mod.common.block.appliances.*
import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.block.campfirepot.CampfireBlock
import com.cobblemon.mod.common.block.campfirepot.CampfirePotBlock
@@ -28,12 +29,7 @@ import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
import com.cobblemon.mod.common.block.tmmachine.TMMachineBlock
import com.cobblemon.mod.common.block.general.MintLitterBlock
import com.cobblemon.mod.common.mixin.invoker.BlocksInvoker
import com.cobblemon.mod.common.mixin.invoker.DoorBlockInvoker
import com.cobblemon.mod.common.mixin.invoker.FireBlockInvoker
import com.cobblemon.mod.common.mixin.invoker.PressurePlateBlockInvoker
import com.cobblemon.mod.common.mixin.invoker.StairsBlockInvoker
import com.cobblemon.mod.common.mixin.invoker.TrapdoorBlockInvoker
import com.cobblemon.mod.common.mixin.invoker.*
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.core.BlockPos
@@ -792,6 +788,9 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val RESTORATION_TANK = create("restoration_tank", RestorationTankBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.GLASS).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).noOcclusion()))
@JvmField
val ROTOM_MONITOR = create("rotom_data_monitor", RotomMonitorBlock(BlockBehaviour.Properties.ofFullCopy(MONITOR)))
@JvmField
val HEALING_MACHINE = create("healing_machine", HealingMachineBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).strength(2F).noOcclusion().lightLevel { if (it.getValue(HealingMachineBlock.CHARGE_LEVEL) >= HealingMachineBlock.MAX_CHARGE_LEVEL) 12 else 5 }))
@@ -821,6 +820,94 @@ 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).requiresCorrectToolForDrops()))
//Rotom Blocks
//Oven
@JvmField
val COPPER_OVEN = create("copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(
CobblemonSounds.APPLIANCE_BLOCK_SOUNDS).pushReaction(PushReaction.BLOCK)))
@JvmField
val EXPOSED_COPPER_OVEN = create("exposed_copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
@JvmField
val WEATHERED_COPPER_OVEN = create("weathered_copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN).mapColor(MapColor.WARPED_STEM)))
@JvmField
val OXIDIZED_COPPER_OVEN = create("oxidized_copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN).mapColor(MapColor.WARPED_NYLIUM)))
@JvmField
val WAXED_COPPER_OVEN = create("waxed_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN)))
@JvmField
val WAXED_EXPOSED_COPPER_OVEN = create("waxed_exposed_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_OVEN)))
@JvmField
val WAXED_WEATHERED_COPPER_OVEN = create("waxed_weathered_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_OVEN)))
@JvmField
val WAXED_OXIDIZED_COPPER_OVEN = create("waxed_oxidized_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_OVEN)))
//Washer
@JvmField
val COPPER_WASHER = create("copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(CobblemonSounds.APPLIANCE_BLOCK_SOUNDS).pushReaction(PushReaction.BLOCK)))
@JvmField
val EXPOSED_COPPER_WASHER = create("exposed_copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
@JvmField
val WEATHERED_COPPER_WASHER = create("weathered_copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER).mapColor(MapColor.WARPED_STEM)))
@JvmField
val OXIDIZED_COPPER_WASHER = create("oxidized_copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER).mapColor(MapColor.WARPED_NYLIUM)))
@JvmField
val WAXED_COPPER_WASHER = create("waxed_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER)))
@JvmField
val WAXED_EXPOSED_COPPER_WASHER = create("waxed_exposed_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_WASHER)))
@JvmField
val WAXED_WEATHERED_COPPER_WASHER = create("waxed_weathered_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_WASHER)))
@JvmField
val WAXED_OXIDIZED_COPPER_WASHER = create("waxed_oxidized_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_WASHER)))
//Fan
@JvmField
val COPPER_FAN = create("copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(CobblemonSounds.APPLIANCE_BLOCK_SOUNDS).pushReaction(PushReaction.DESTROY)))
@JvmField
val EXPOSED_COPPER_FAN = create("exposed_copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_FAN).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
@JvmField
val WEATHERED_COPPER_FAN = create("weathered_copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_FAN).mapColor(MapColor.WARPED_STEM)))
@JvmField
val OXIDIZED_COPPER_FAN = create("oxidized_copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_FAN).mapColor(MapColor.WARPED_NYLIUM)))
@JvmField
val WAXED_COPPER_FAN = create("waxed_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_FAN)))
@JvmField
val WAXED_EXPOSED_COPPER_FAN = create("waxed_exposed_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_FAN)))
@JvmField
val WAXED_WEATHERED_COPPER_FAN = create("waxed_weathered_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_FAN)))
@JvmField
val WAXED_OXIDIZED_COPPER_FAN = create("waxed_oxidized_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_FAN)))
//Mower
@JvmField
val COPPER_MOWER = create("copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(CobblemonSounds.APPLIANCE_BLOCK_SOUNDS).pushReaction(PushReaction.NORMAL)))
@JvmField
val EXPOSED_COPPER_MOWER = create("exposed_copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
@JvmField
val WEATHERED_COPPER_MOWER = create("weathered_copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER).mapColor(MapColor.WARPED_STEM)))
@JvmField
val OXIDIZED_COPPER_MOWER = create("oxidized_copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER).mapColor(MapColor.WARPED_NYLIUM)))
@JvmField
val WAXED_COPPER_MOWER = create("waxed_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER)))
@JvmField
val WAXED_EXPOSED_COPPER_MOWER = create("waxed_exposed_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_MOWER)))
@JvmField
val WAXED_WEATHERED_COPPER_MOWER = create("waxed_weathered_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_MOWER)))
@JvmField
val WAXED_OXIDIZED_COPPER_MOWER = create("waxed_oxidized_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_MOWER)))
//Fridge
@JvmField
val COPPER_FRIDGE = create("copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(CobblemonSounds.APPLIANCE_BLOCK_SOUNDS).pushReaction(PushReaction.BLOCK)))
@JvmField
val EXPOSED_COPPER_FRIDGE = create("exposed_copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
@JvmField
val WEATHERED_COPPER_FRIDGE = create("weathered_copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE).mapColor(MapColor.WARPED_STEM)))
@JvmField
val OXIDIZED_COPPER_FRIDGE = create("oxidized_copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE).mapColor(MapColor.WARPED_NYLIUM)))
@JvmField
val WAXED_COPPER_FRIDGE = create("waxed_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE)))
@JvmField
val WAXED_EXPOSED_COPPER_FRIDGE = create("waxed_exposed_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_FRIDGE)))
@JvmField
val WAXED_WEATHERED_COPPER_FRIDGE = create("waxed_weathered_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_FRIDGE)))
@JvmField
val WAXED_OXIDIZED_COPPER_FRIDGE = create("waxed_oxidized_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_FRIDGE)))
// TODO after 1.7
// @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)))
@@ -849,7 +936,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val GALARICA_NUT_BUSH = this.create("galarica_nut_bush", NutBushBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).randomTicks().noCollission().sound(SoundType.SWEET_BERRY_BUSH).pushReaction(PushReaction.DESTROY)))
@JvmField
val RED_MINT_LEAF_LITTER = this.mintLitter("red_mint_leaf_litter", MapColor.COLOR_RED)
@JvmField
@@ -927,6 +1013,57 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
SACCHARINE_LOG to STRIPPED_SACCHARINE_LOG,
SACCHARINE_LOG_SLATHERED to STRIPPED_SACCHARINE_LOG
)
/**Same idea as above, but for Copper Oxidation over time (or when inverted, scraping with an axe)*/
fun oxidizingBlocks(): Map<Block, Block> = mapOf(
//Ovens
COPPER_OVEN to EXPOSED_COPPER_OVEN,
EXPOSED_COPPER_OVEN to WEATHERED_COPPER_OVEN,
WEATHERED_COPPER_OVEN to OXIDIZED_COPPER_OVEN,
//Washers
COPPER_WASHER to EXPOSED_COPPER_WASHER,
EXPOSED_COPPER_WASHER to WEATHERED_COPPER_WASHER,
WEATHERED_COPPER_WASHER to OXIDIZED_COPPER_WASHER,
//Fans
COPPER_FAN to EXPOSED_COPPER_FAN,
EXPOSED_COPPER_FAN to WEATHERED_COPPER_FAN,
WEATHERED_COPPER_FAN to OXIDIZED_COPPER_FAN,
//Fridges
COPPER_FRIDGE to EXPOSED_COPPER_FRIDGE,
EXPOSED_COPPER_FRIDGE to WEATHERED_COPPER_FRIDGE,
WEATHERED_COPPER_FRIDGE to OXIDIZED_COPPER_FRIDGE,
//Mowers
COPPER_MOWER to EXPOSED_COPPER_MOWER,
EXPOSED_COPPER_MOWER to WEATHERED_COPPER_MOWER,
WEATHERED_COPPER_MOWER to OXIDIZED_COPPER_MOWER
)
/**Same idea as above, but for waxing blocks with Honeycomb (or unwaxing them with an axe)*/
fun waxingBlocks(): Map<Block, Block> = mapOf(
//Ovens
COPPER_OVEN to WAXED_COPPER_OVEN,
EXPOSED_COPPER_OVEN to WAXED_EXPOSED_COPPER_OVEN,
WEATHERED_COPPER_OVEN to WAXED_WEATHERED_COPPER_OVEN,
OXIDIZED_COPPER_OVEN to WAXED_OXIDIZED_COPPER_OVEN,
//Washers
COPPER_WASHER to WAXED_COPPER_WASHER,
EXPOSED_COPPER_WASHER to WAXED_EXPOSED_COPPER_WASHER,
WEATHERED_COPPER_WASHER to WAXED_WEATHERED_COPPER_WASHER,
OXIDIZED_COPPER_WASHER to WAXED_OXIDIZED_COPPER_WASHER,
//Fans
COPPER_FAN to WAXED_COPPER_FAN,
EXPOSED_COPPER_FAN to WAXED_EXPOSED_COPPER_FAN,
WEATHERED_COPPER_FAN to WAXED_WEATHERED_COPPER_FAN,
OXIDIZED_COPPER_FAN to WAXED_OXIDIZED_COPPER_FAN,
//Fridges
COPPER_FRIDGE to WAXED_COPPER_FRIDGE,
EXPOSED_COPPER_FRIDGE to WAXED_EXPOSED_COPPER_FRIDGE,
WEATHERED_COPPER_FRIDGE to WAXED_WEATHERED_COPPER_FRIDGE,
OXIDIZED_COPPER_FRIDGE to WAXED_OXIDIZED_COPPER_FRIDGE,
//Mowers
COPPER_MOWER to WAXED_COPPER_MOWER,
EXPOSED_COPPER_MOWER to WAXED_EXPOSED_COPPER_MOWER,
WEATHERED_COPPER_MOWER to WAXED_WEATHERED_COPPER_MOWER,
OXIDIZED_COPPER_MOWER to WAXED_OXIDIZED_COPPER_MOWER
)
private fun apricornBlock(name: String, apricorn: Apricorn): ApricornBlock = this.create(name, ApricornBlock(BlockBehaviour.Properties.of().mapColor(apricorn.mapColor()).randomTicks().strength(Blocks.OAK_LOG.defaultDestroyTime(), Blocks.OAK_LOG.explosionResistance).sound(SoundType.WOOD).noOcclusion(), apricorn))
@@ -454,6 +454,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val DAMAGED_MONITOR = blockItem("damaged_monitor", CobblemonBlocks.DAMAGED_MONITOR)
@JvmField
val ROTOM_MONITOR = blockItem("rotom_data_monitor", CobblemonBlocks.ROTOM_MONITOR)
@JvmField
val HEALING_MACHINE = blockItem("healing_machine", CobblemonBlocks.HEALING_MACHINE, Rarity.UNCOMMON)
@JvmField
val PC = blockItem("pc", CobblemonBlocks.PC)
@@ -1517,6 +1519,87 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val BLANK_TM = this.create("blank_tm", CobblemonItem(Item.Properties()))
@JvmField
val COPPER_OVEN = this.create("copper_oven", BlockItem(CobblemonBlocks.COPPER_OVEN, Item.Properties()))
@JvmField
val EXPOSED_COPPER_OVEN = this.create("exposed_copper_oven", BlockItem(CobblemonBlocks.EXPOSED_COPPER_OVEN, Item.Properties()))
@JvmField
val WEATHERED_COPPER_OVEN = this.create("weathered_copper_oven", BlockItem(CobblemonBlocks.WEATHERED_COPPER_OVEN, Item.Properties()))
@JvmField
val OXIDIZED_COPPER_OVEN = this.create("oxidized_copper_oven", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_OVEN, Item.Properties()))
@JvmField
val WAXED_COPPER_OVEN = this.create("waxed_copper_oven", BlockItem(CobblemonBlocks.WAXED_COPPER_OVEN, Item.Properties()))
@JvmField
val WAXED_EXPOSED_COPPER_OVEN = this.create("waxed_exposed_copper_oven", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_OVEN, Item.Properties()))
@JvmField
val WAXED_WEATHERED_COPPER_OVEN = this.create("waxed_weathered_copper_oven", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_OVEN, Item.Properties()))
@JvmField
val WAXED_OXIDIZED_COPPER_OVEN = this.create("waxed_oxidized_copper_oven", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_OVEN, Item.Properties()))
@JvmField
val COPPER_WASHER = this.create("copper_washer", BlockItem(CobblemonBlocks.COPPER_WASHER, Item.Properties()))
@JvmField
val EXPOSED_COPPER_WASHER = this.create("exposed_copper_washer", BlockItem(CobblemonBlocks.EXPOSED_COPPER_WASHER, Item.Properties()))
@JvmField
val WEATHERED_COPPER_WASHER = this.create("weathered_copper_washer", BlockItem(CobblemonBlocks.WEATHERED_COPPER_WASHER, Item.Properties()))
@JvmField
val OXIDIZED_COPPER_WASHER = this.create("oxidized_copper_washer", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_WASHER, Item.Properties()))
@JvmField
val WAXED_COPPER_WASHER = this.create("waxed_copper_washer", BlockItem(CobblemonBlocks.WAXED_COPPER_WASHER, Item.Properties()))
@JvmField
val WAXED_EXPOSED_COPPER_WASHER = this.create("waxed_exposed_copper_washer", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_WASHER, Item.Properties()))
@JvmField
val WAXED_WEATHERED_COPPER_WASHER = this.create("waxed_weathered_copper_washer", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_WASHER, Item.Properties()))
@JvmField
val WAXED_OXIDIZED_COPPER_WASHER = this.create("waxed_oxidized_copper_washer", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_WASHER, Item.Properties()))
@JvmField
val COPPER_FAN = this.create("copper_fan", BlockItem(CobblemonBlocks.COPPER_FAN, Item.Properties()))
@JvmField
val EXPOSED_COPPER_FAN = this.create("exposed_copper_fan", BlockItem(CobblemonBlocks.EXPOSED_COPPER_FAN, Item.Properties()))
@JvmField
val WEATHERED_COPPER_FAN = this.create("weathered_copper_fan", BlockItem(CobblemonBlocks.WEATHERED_COPPER_FAN, Item.Properties()))
@JvmField
val OXIDIZED_COPPER_FAN = this.create("oxidized_copper_fan", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_FAN, Item.Properties()))
@JvmField
val WAXED_COPPER_FAN = this.create("waxed_copper_fan", BlockItem(CobblemonBlocks.WAXED_COPPER_FAN, Item.Properties()))
@JvmField
val WAXED_EXPOSED_COPPER_FAN = this.create("waxed_exposed_copper_fan", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_FAN, Item.Properties()))
@JvmField
val WAXED_WEATHERED_COPPER_FAN = this.create("waxed_weathered_copper_fan", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_FAN, Item.Properties()))
@JvmField
val WAXED_OXIDIZED_COPPER_FAN = this.create("waxed_oxidized_copper_fan", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_FAN, Item.Properties()))
@JvmField
val COPPER_MOWER = this.create("copper_mower", BlockItem(CobblemonBlocks.COPPER_MOWER, Item.Properties()))
@JvmField
val EXPOSED_COPPER_MOWER = this.create("exposed_copper_mower", BlockItem(CobblemonBlocks.EXPOSED_COPPER_MOWER, Item.Properties()))
@JvmField
val WEATHERED_COPPER_MOWER = this.create("weathered_copper_mower", BlockItem(CobblemonBlocks.WEATHERED_COPPER_MOWER, Item.Properties()))
@JvmField
val OXIDIZED_COPPER_MOWER = this.create("oxidized_copper_mower", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_MOWER, Item.Properties()))
@JvmField
val WAXED_COPPER_MOWER = this.create("waxed_copper_mower", BlockItem(CobblemonBlocks.WAXED_COPPER_MOWER, Item.Properties()))
@JvmField
val WAXED_EXPOSED_COPPER_MOWER = this.create("waxed_exposed_copper_mower", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_MOWER, Item.Properties()))
@JvmField
val WAXED_WEATHERED_COPPER_MOWER = this.create("waxed_weathered_copper_mower", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_MOWER, Item.Properties()))
@JvmField
val WAXED_OXIDIZED_COPPER_MOWER = this.create("waxed_oxidized_copper_mower", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_MOWER, Item.Properties()))
@JvmField
val COPPER_FRIDGE = this.create("copper_fridge", BlockItem(CobblemonBlocks.COPPER_FRIDGE, Item.Properties()))
@JvmField
val EXPOSED_COPPER_FRIDGE = this.create("exposed_copper_fridge", BlockItem(CobblemonBlocks.EXPOSED_COPPER_FRIDGE, Item.Properties()))
@JvmField
val WEATHERED_COPPER_FRIDGE = this.create("weathered_copper_fridge", BlockItem(CobblemonBlocks.WEATHERED_COPPER_FRIDGE, Item.Properties()))
@JvmField
val OXIDIZED_COPPER_FRIDGE = this.create("oxidized_copper_fridge", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_FRIDGE, Item.Properties()))
@JvmField
val WAXED_COPPER_FRIDGE = this.create("waxed_copper_fridge", BlockItem(CobblemonBlocks.WAXED_COPPER_FRIDGE, Item.Properties()))
@JvmField
val WAXED_EXPOSED_COPPER_FRIDGE = this.create("waxed_exposed_copper_fridge", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_FRIDGE, Item.Properties()))
@JvmField
val WAXED_WEATHERED_COPPER_FRIDGE = this.create("waxed_weathered_copper_fridge", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_FRIDGE, Item.Properties()))
@JvmField
val WAXED_OXIDIZED_COPPER_FRIDGE = this.create("waxed_oxidized_copper_fridge", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_FRIDGE, Item.Properties()))
// Type Gems
@JvmField
val NORMAL_GEM = this.create("normal_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_NORMAL))
@@ -12,6 +12,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.item.crafting.washer.WasherRecipe
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
@@ -26,7 +27,9 @@ object CobblemonRecipeSerializers : PlatformRegistry<Registry<RecipeSerializer<*
val COOKING_POT_SHAPELESS: RecipeSerializer<*> = register("cobblemon:cooking_pot_shapeless", CookingPotShapelessRecipe.Serializer())
val BREWING_STAND: RecipeSerializer<*> = register("cobblemon:brewing_stand", BrewingStandRecipe.Serializer())
val WASHER: RecipeSerializer<*> = register("cobblemon:washer", WasherRecipe.Serializer())
override val registry: Registry<RecipeSerializer<*>>
get() = BuiltInRegistries.RECIPE_SERIALIZER
override val resourceKey: ResourceKey<Registry<RecipeSerializer<*>>>
@@ -12,6 +12,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.item.crafting.washer.WasherRecipe
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
@@ -26,7 +27,9 @@ object CobblemonRecipeTypes : PlatformRegistry<Registry<RecipeType<*>>, Resource
val COOKING_POT_SHAPELESS: RecipeType<CookingPotShapelessRecipe> = register("cobblemon:cooking_pot_shapeless")
val BREWING_STAND: RecipeType<BrewingStandRecipe> = register("cobblemon:brewing_stand")
val WASHER: RecipeType<WasherRecipe> = register("cobblemon:washer")
override val registry: Registry<RecipeType<*>>
get() = BuiltInRegistries.RECIPE_TYPE
override val resourceKey: ResourceKey<Registry<RecipeType<*>>>
@@ -404,6 +404,17 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
@JvmField
val IMPACT_WATER = this.create("impact.water")
@JvmField
val APPLIANCE_STEP = this.create("block.appliance.roto_appliance_step")
@JvmField
val APPLIANCE_PLACE = this.create("block.appliance.roto_appliance_place")
@JvmField
val APPLIANCE_HIT = this.create("block.appliance.roto_appliance_hit")
@JvmField
val APPLIANCE_BREAK = this.create("block.appliance.roto_appliance_break")
@JvmField
val MOWER_CUT = this.create("block.appliance.roto_mower_cut")
// Note to self or whoever's peeking, block sounds have to be at 1.1f pitch
// For some reason, the game pitches them down and compensating for it here returns them to normal
@JvmField
@@ -424,6 +435,15 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
TUMBLESTONE_STEP
)
@JvmField
val APPLIANCE_BLOCK_SOUNDS = SoundType(1f, 1.1f,
APPLIANCE_BREAK,
APPLIANCE_STEP,
APPLIANCE_PLACE,
APPLIANCE_HIT,
APPLIANCE_STEP
)
@JvmField
val TYPE_GEM_BLOCK_BREAK = this.create("block.type_gem_block.break")
@JvmField
@@ -239,6 +239,10 @@ open class PokemonBattle(
}
fun writeShowdownAction(vararg messages: String) {
if (messages.any { it.contains("\n") || it.contains("\r") }) {
LOGGER.warn("Refusing to forward Showdown action with an embedded line break for battle {}: {}", battleId, messages.joinToString(" | "))
return
}
log(messages.joinToString("\n"))
ShowdownService.service.send(battleId, messages.toList().toTypedArray())
}
@@ -9,9 +9,12 @@
package com.cobblemon.mod.common.api.riding.stats
import com.cobblemon.mod.common.api.cooking.Flavour
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.util.lang
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.tags.TagKey
import net.minecraft.world.item.Item
/**
* A stat that is used for riding Pokémon. The exact implementation of each of these depends on the [com.cobblemon.mod.common.api.riding.controller.RideController].
@@ -20,13 +23,14 @@ import net.minecraft.network.chat.MutableComponent
* @since February 17th, 2025
*/
enum class RidingStat(
val flavour: Flavour
val flavour: Flavour,
val powerItem: TagKey<Item>
) {
ACCELERATION(Flavour.SPICY),
SKILL(Flavour.DRY),
SPEED(Flavour.SWEET),
STAMINA(Flavour.SOUR),
JUMP(Flavour.BITTER);
ACCELERATION(Flavour.SPICY, CobblemonItemTags.POWER_BRACER),
SKILL(Flavour.DRY, CobblemonItemTags.POWER_BELT),
SPEED(Flavour.SWEET, CobblemonItemTags.POWER_ANKLET),
STAMINA(Flavour.SOUR, CobblemonItemTags.POWER_WEIGHT),
JUMP(Flavour.BITTER, CobblemonItemTags.POWER_BAND);
companion object {
fun getByName(name: String) = RidingStat.entries.firstOrNull { it.name.equals(name, ignoreCase = true) }
@@ -198,7 +198,17 @@ interface Spawner {
val mid = chunk.getBlockState(startPos)
val above = chunk.getBlockState(abovePos)
return above.isPathfindable(PathComputationType.AIR) && mid.isAir
// Above must be non-solid
if (!above.isPathfindable(PathComputationType.AIR)) {
return false
}
// Position must be non-air
if (mid.isAir) {
return false
}
return true
}
fun constrainArea(area: SpawningZoneInput): SpawningZoneInput? {
@@ -117,6 +117,9 @@ abstract class ShowdownActionResponse(val type: ShowdownActionResponseType) {
data class MoveActionResponse(var moveName: String, var targetPnx: String? = null, var gimmickID: String? = null): ShowdownActionResponse(ShowdownActionResponseType.MOVE) {
override fun isValid(activeBattlePokemon: ActiveBattlePokemon, showdownMoveSet: ShowdownMoveset?, forceSwitch: Boolean): Boolean {
// Ensure that the gimmick ID the player is sending is valid
gimmickID?.let { if (it !in VALID_GIMMICK_IDS) return false }
if (forceSwitch || showdownMoveSet == null) {
return false
}
@@ -168,6 +171,10 @@ data class MoveActionResponse(var moveName: String, var targetPnx: String? = nul
gimmickID = buffer.readNullable { buffer.readString() }
return this
}
companion object {
private val VALID_GIMMICK_IDS = ShowdownMoveset.Gimmick.entries.map { it.id }.toSet()
}
}
data class HealItemActionResponse(var item: String) : ShowdownActionResponse(ShowdownActionResponseType.FORCE_PASS) {
@@ -183,7 +190,8 @@ data class HealItemActionResponse(var item: String) : ShowdownActionResponse(Sho
}
override fun isValid(activeBattlePokemon: ActiveBattlePokemon, showdownMoveSet: ShowdownMoveset?, forceSwitch: Boolean): Boolean {
return !forceSwitch
// Previously checked for !forceSwitch, excepts in the case of a forceSwitch, this couldn't legally be sent anyway.
return false
}
override fun toShowdownString(activeBattlePokemon: ActiveBattlePokemon, showdownMoveSet: ShowdownMoveset?): String {
@@ -37,7 +37,6 @@ import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import java.util.concurrent.CompletableFuture
import net.minecraft.world.entity.LivingEntity
/**
* Format: |move|POKEMON|MOVE|TARGET
@@ -77,7 +76,7 @@ class MoveInstruction(
val pokemonName = userPokemon.getName()
ShowdownInterpreter.lastCauser[battle.battleId] = message
// For Spread targets the message data only gives the pnx strings. So we can't know what pokemon are actually targeted until the previous messages have been interpreted
val spreadTargetPokemon = spreadTargets.map { battle.activePokemon.firstOrNull() { poke -> poke.getPNX() == it }?.battlePokemon }
val spreadTargetPokemon = spreadTargets.map { battle.activePokemon.firstOrNull { poke -> poke.getPNX() == it }?.battlePokemon }
val targetPokemonEntity = targetPokemon?.entity
if (targetPokemonEntity != null) {
@@ -137,10 +136,20 @@ class MoveInstruction(
val subsequentInstructions = instructionSet.findInstructionsCausedBy(this)
val missedTargets = subsequentInstructions.filterIsInstance<MissInstruction>().mapNotNull { it.target }
val faintedTargets = subsequentInstructions.filterIsInstance<FaintInstruction>().map { it.faintingPokemon }
val failed = subsequentInstructions.any { it is FailInstruction }
val failedTargets = subsequentInstructions.filterIsInstance<FailInstruction>().mapNotNull { it.target }
val hitCountInstruction = subsequentInstructions.filterIsInstance<HitCountInstruction>().firstOrNull()
runtime.environment.query.addFunction("target_fainted") { params ->
if (params.params.size == 0) {
return@addFunction DoubleValue(faintedTargets.isNotEmpty())
} else {
val entityUUID = params.getString(0)
return@addFunction DoubleValue(faintedTargets.any { it.entity?.stringUUID == entityUUID })
}
}
runtime.environment.query.addFunction("missed") { params ->
if (params.params.size == 0) {
return@addFunction DoubleValue(missedTargets.isNotEmpty())
@@ -24,6 +24,7 @@ import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerPlayer
import net.minecraft.util.RandomSource
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.EntityType
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.Item
@@ -31,13 +32,9 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.CollisionGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.BaseEntityBlock
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.HorizontalDirectionalBlock
import net.minecraft.world.level.block.Mirror
import net.minecraft.world.level.block.RenderShape
import net.minecraft.world.level.block.Rotation
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityType
@@ -48,9 +45,11 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty
import net.minecraft.world.level.block.state.properties.Property
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
import java.util.Optional
@Suppress("DEPRECATED", "OVERRIDE_DEPRECATION")
class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
@@ -79,6 +78,14 @@ class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
const val MAX_CHARGE_LEVEL = 5
val CHARGE_LEVEL: IntegerProperty = IntegerProperty.create("charge", 0, MAX_CHARGE_LEVEL + 1)
val NATURAL: BooleanProperty = BooleanProperty.create("natural")
fun canSetSpawn(level: Level): Boolean {
return level.gameRules.getBoolean(CobblemonGameRules.HEALER_SET_SPAWN)
}
fun findStandUpPosition(entityType: EntityType<*>, level: CollisionGetter, pos: BlockPos): Optional<Vec3> {
return RespawnAnchorBlock.findStandUpPosition(entityType, level, pos) // Exists if we ever want to make something more custom, but anchor block logic should suffice
}
}
init {
@@ -158,7 +165,12 @@ class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
}
val party = serverPlayerEntity.party()
val pc = serverPlayerEntity.pc()
val healPC = player.level().gameRules.getBoolean(CobblemonGameRules.HEALERS_HEAL_PC);
val healPC = player.level().gameRules.getBoolean(CobblemonGameRules.HEALERS_HEAL_PC)
// Do spawnpoint stuff
if (canSetSpawn(world)) {
player.setRespawnPosition(world.dimension(), blockPos, player.yRot, false, true)
}
if (party.none() && (!healPC || pc.none())) {
player.sendSystemMessage(lang("healingmachine.nopokemon").red(), true)
@@ -183,6 +195,7 @@ class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
player.sendSystemMessage(lang("healingmachine.notenoughcharge", "${((neededCharge/party.count())*100f).toInt()}%").red(), true)
}
party.forEach { it.tryRecallWithAnimation() }
return InteractionResult.CONSUME
}
@@ -35,6 +35,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType
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.BooleanProperty
import net.minecraft.world.level.block.state.properties.EnumProperty
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
@@ -46,7 +47,10 @@ class MonitorBlock(settings: Properties) : MultiblockBlock(settings) {
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH)
.setValue(SCREEN, MonitorScreen.OFF))
.setValue(SCREEN, MonitorScreen.OFF)
.setValue(NATURAL, false)
)
}
override fun createMultiBlockEntity(
@@ -110,6 +114,7 @@ class MonitorBlock(settings: Properties) : MultiblockBlock(settings) {
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HORIZONTAL_FACING)
builder.add(SCREEN)
builder.add(NATURAL)
}
override fun hasAnalogOutputSignal(state: BlockState): Boolean {
@@ -163,6 +168,7 @@ class MonitorBlock(settings: Properties) : MultiblockBlock(settings) {
//0 is off
val SCREEN = EnumProperty.create("screen", MonitorScreen::class.java)
val NATURAL = BooleanProperty.create("natural")
val HITBOX_SOUTH = Shapes.or(
Shapes.box(0.0625, 0.0, 0.0625, 0.9375, 0.375, 0.9375),
Shapes.box(0.0625, 0.875, 0.0625, 0.9375, 1.0, 0.9375),
@@ -30,7 +30,7 @@ class OrbBlock(properties: Properties) : SixFaceRotationalBlock(properties) {
val FLOOR_NORTH = Shapes.box(0.3125, 0.0, 0.3125, 0.6875, 0.375, 0.6875)
val WALL_NORTH = Shapes.box(0.3125, 0.3125, 0.625, 0.6875, 0.6875, 1.0)
val CEILING_NORTH = Shapes.box(0.3125, 0.625, 0.375, 0.6875, 1.0, 0.6875)
val CEILING_NORTH = Shapes.box(0.3125, 0.625, 0.3125, 0.6875, 1.0, 0.6875)
}
init {
@@ -0,0 +1,161 @@
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.scheduling.afterOnServer
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.math.FloatRange
import com.cobblemon.mod.common.util.party
import com.cobblemon.mod.common.util.toVec3d
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.server.level.ServerPlayer
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
import net.minecraft.util.RandomSource
import net.minecraft.world.InteractionResult
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.HorizontalDirectionalBlock
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.Vec3
/**
* A block that can transform into a [PokemonEntity].
* Call [spawnPokemon] to spawn.
*
* @author whatsy
*/
interface PokemonDisguiseBlock {
private val facingToYaw: HashMap<Direction, Float>
get() = hashMapOf(
Direction.NORTH to -179.0F,
Direction.WEST to 90.0F,
Direction.SOUTH to 0.0F,
Direction.EAST to -90.0F
)
/**
* An [IntRange] representing the possible level of the spawned Pokémon.
*/
val levelRange: IntRange
/**
* A [String] representing the [PokemonProperties] of the spawned Pokémon.
* Do not include level, scale, shiny, or alpha;
* Those are defined using [levelRange], [scaleRange], [shinyRate] and [alphaRate] respectively.
*/
val pokemonArgs: String
/**
* The chance of the spawned Pokémon being a shiny.
* Leave null if impossible.
* Defaults to [Cobblemon.config.shinyRate]
*/
val shinyRate: Float?
get() = Cobblemon.config.shinyRate
/**
* The chance of the spawned Pokémon being an Alpha.
* Leave null if impossible.
* Defaults to null
*/
val alphaRate: Float?
get() = null
/**
* The [BlockState] to replace the block with on interaction.
* Defaults to [Blocks.AIR]
* Leave null to leave the block unaltered.
*
* @param originalState The [BlockState] of the block being interacted with. Use to transfer properties to a new block.
*/
fun getReplacementBlock(originalState: BlockState): BlockState? = Blocks.AIR.defaultBlockState()
/**
* Whether or not a battle should be initiated when the Pokémon spawns.
* Defaults to true.
* Does not affect players in creative mode.
*/
val shouldInitiateBattle: Boolean
get() = true
/**
* The [SoundEvent], if any, to play when the Pokémon spawns.
* Defaults to null.
*/
val spawnSound: SoundEvent?
get() = null
/**
* A [FloatRange] representing the possible scale of the spawned Pokémon.
* Defaults to config values.
*/
val scaleRange: FloatRange
get() = FloatRange(Cobblemon.config.pokemonIntrinsicSizeMin, Cobblemon.config.pokemonIntrinsicSizeMax)
/**
* Defines a [Vec3] offset for where the Pokémon will spawn.
* Defaults to 0, 0, 0
*/
val offset: Vec3
get() = Vec3(0.0, 0.0, 0.0)
/**
* Returns the direction the Pokémon should be facing upon spawning.
* Defaults to the
*/
fun getPokemonFacing(state: BlockState): Direction
/**
* Spawn a Pokémon from this block.
*
* @param level The [Level] to spawn this Pokémon in.
* @param pos The [BlockPos] to spawn this Pokémon at.
* @param state The [BlockState] of the block at time of spawning.
* @param player The [ServerPlayer] to initiate the battle against.
*/
fun spawnPokemon(level: Level, pos: BlockPos, state: BlockState, player: ServerPlayer): InteractionResult {
val random = RandomSource.create()
val isShiny = shinyRate?.let { random.nextInt(it.toInt()) == 0 } ?: false
val isAlpha = alphaRate?.let { random.nextInt(it.toInt()) == 0 } ?: false
val properties = "$pokemonArgs lvl=${levelRange.random()} scale_modifier=${scaleRange.random()} alpha=${isAlpha} shiny=${isShiny}"
val pokemon = PokemonProperties.parse(properties)
val entity = pokemon.createEntity(level)
// The yaw based on the block's facing direction
val yaw = facingToYaw[getPokemonFacing(state)] ?: 0.0F
entity.entityData.set(PokemonEntity.SPAWN_DIRECTION, yaw)
val offsetDir = state.getValue(HorizontalDirectionalBlock.FACING)
val vec = pos.toVec3d()
.add(offsetDir.stepX * 0.1 + 0.5, 0.0, offsetDir.stepZ * 0.1 + 0.5)
.add(offset)
entity.moveTo(vec.x, vec.y, vec.z, yaw, entity.xRot)
entity.yBodyRot = yaw
entity.yBodyRotO = yaw
entity.yHeadRot = yaw
entity.yHeadRotO = yaw
level.addFreshEntity(entity)
if (getReplacementBlock(state) == Blocks.AIR) {
level.removeBlock(pos, false)
} else {
getReplacementBlock(state)?.let {
level.setBlockAndUpdate(pos, it)
}
}
afterOnServer(seconds = 0.1F) {
if (player !in player.level().players()) {
return@afterOnServer
}
if (!player.isCreative && shouldInitiateBattle) {
entity.forceBattle(player)
} else {
spawnSound?.let { level.playSound(null, pos, it, SoundSource.NEUTRAL) }
}
}
return InteractionResult.SUCCESS
}
}
@@ -0,0 +1,91 @@
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.block.DamagedMonitorBlock.BrokenMonitorScreen
import com.cobblemon.mod.common.block.DamagedMonitorBlock.Companion.HITBOX_EAST
import com.cobblemon.mod.common.block.DamagedMonitorBlock.Companion.HITBOX_NORTH
import com.cobblemon.mod.common.block.DamagedMonitorBlock.Companion.HITBOX_SOUTH
import com.cobblemon.mod.common.block.DamagedMonitorBlock.Companion.HITBOX_WEST
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.server.level.ServerPlayer
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.block.Block
import net.minecraft.world.level.block.HorizontalDirectionalBlock
import net.minecraft.world.level.block.state.BlockBehaviour
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.phys.BlockHitResult
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape
class RotomMonitorBlock(settings: Properties) : Block(settings), PokemonDisguiseBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(HorizontalDirectionalBlock.FACING, Direction.NORTH)
.setValue(MonitorBlock.SCREEN, MonitorBlock.MonitorScreen.OFF)
)
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
return defaultBlockState().setValue(HorizontalDirectionalBlock.FACING, context.horizontalDirection)
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block?, BlockState?>) {
builder.add(HorizontalDirectionalBlock.FACING)
builder.add(MonitorBlock.SCREEN)
}
override fun playerWillDestroy(level: Level, pos: BlockPos, state: BlockState, player: Player): BlockState? {
if (!level.isClientSide) {
spawnPokemon(level, pos, state, player as ServerPlayer)
}
return super.playerWillDestroy(level, pos, state, player)
}
override fun getShape(
state: BlockState,
level: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
return when (state.getValue(HorizontalDirectionalBlock.FACING)) {
Direction.WEST -> HITBOX_WEST
Direction.EAST -> HITBOX_EAST
Direction.SOUTH -> HITBOX_SOUTH
else -> HITBOX_NORTH
}
}
override fun useWithoutItem(
state: BlockState,
level: Level,
pos: BlockPos,
player: Player,
hitResult: BlockHitResult
): InteractionResult {
return if (player is ServerPlayer) {
spawnPokemon(level, pos, state, player)
} else {
InteractionResult.SUCCESS
}
}
override val levelRange = 35..60
override val pokemonArgs = "rotom"
override val spawnSound = CobblemonSounds.MONITOR_BREAK
override val offset = Vec3(0.0, 1.0, 0.0)
override fun getReplacementBlock(originalState: BlockState): BlockState =
CobblemonBlocks.MONITOR.defaultBlockState()
.setValue(HorizontalDirectionalBlock.FACING, originalState.getValue(HorizontalDirectionalBlock.FACING))
.setValue(MonitorBlock.NATURAL, true)
override fun getPokemonFacing(state: BlockState): Direction = state.getValue(HORIZONTAL_FACING).opposite
}
@@ -160,8 +160,8 @@ class TypeGemClusterBlock(
&& state.getValue(STAGE) == 3) return false
val supportPos = pos.relative(state.getValue(FACING).opposite)
val supportBlock = level.getBlockState(supportPos).block
return CobblemonBlocks.typeGemBlocks().containsValue(supportBlock) || (supportBlock == CobblemonBlocks.TYPE_GEM_CORE) // Cannot grow if not on any gem blocks
val supportState = level.getBlockState(supportPos)
return supportState.`is`(CobblemonBlockTags.TYPE_GEM_BLOCKS) || supportState.block == CobblemonBlocks.TYPE_GEM_CORE // Cannot grow if not on any gem blocks
}
@@ -51,10 +51,20 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
ResourceLocation.parse("cobblemon:dragon_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_DRAGON,
ResourceLocation.parse("cobblemon:dark_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_DARK,
ResourceLocation.parse("cobblemon:steel_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_STEEL,
ResourceLocation.parse("cobblemon:fairy_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_FAIRY
ResourceLocation.parse("cobblemon:fairy_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_FAIRY,
ResourceLocation.parse("minecraft:amethyst_block") to Blocks.SMALL_AMETHYST_BUD
)
}
val AMETHYST_STAGES = listOf(
Blocks.SMALL_AMETHYST_BUD,
Blocks.MEDIUM_AMETHYST_BUD,
Blocks.LARGE_AMETHYST_BUD,
Blocks.AMETHYST_CLUSTER
)
private fun isAmethystStage(block: Block) = block in AMETHYST_STAGES
fun getConnectedGemBlocks(level: BlockGetter, pos: BlockPos): List<Pair<BlockState, BlockPos>> {
val connectedGems = mutableListOf<Pair<BlockState, BlockPos>>()
val visited = mutableSetOf<BlockPos>()
@@ -85,12 +95,16 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
Direction.entries.forEach {
if (random.nextFloat() < Cobblemon.config.typeGemGrowthChance) {
val faceState = level.getBlockState(pos.relative(it))
val randomGrowthType = decideClusterGrowthType(level, pos)
val newState = BLOCK_TO_CLUSTER[BuiltInRegistries.BLOCK.getKey(state.block)]?.defaultBlockState()
var newState = BLOCK_TO_CLUSTER[BuiltInRegistries.BLOCK.getKey(state.block)]?.defaultBlockState()
?.setValue(DirectionalBlock.FACING, it)
?.setValue(GROWTH_TYPE, randomGrowthType)
?: return
if (newState.hasProperty(GROWTH_TYPE)) {
newState = newState.setValue(GROWTH_TYPE, decideClusterGrowthType(level, pos))
} else if (getConnectedGemBlocks(level, pos).size > Cobblemon.config.typeGemMaxConnected) {
return@forEach
}
if (faceState.`is`(Blocks.AIR)) {
level.setBlock(pos.relative(it), newState, 3)
}
@@ -132,7 +146,7 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
if (!visited.add(clusterPos)) continue
val clusterState = level.getBlockState(clusterPos)
if (clusterState.block == expectedCluster) {
if (clusterState.block == expectedCluster && clusterState.hasProperty(GROWTH_TYPE)) {
clusters += clusterState to clusterPos
}
}
@@ -178,13 +192,41 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
Direction.entries.forEach { direction ->
val relativePos = pos.relative(direction)
val relativeState = level.getBlockState(relativePos)
val clusterBlock = relativeState.block as? TypeGemClusterBlock ?: return@forEach
if ((relativeState.getValue(DirectionalBlock.FACING) == direction &&
random.nextFloat() < Cobblemon.config.typeGemGrowthChance) || forceGrow
) {
clusterBlock.advanceGrowth(relativeState, level, relativePos, random)
val matchesFace = relativeState.hasProperty(DirectionalBlock.FACING)
&& relativeState.getValue(DirectionalBlock.FACING) == direction
if (!(forceGrow || (matchesFace && random.nextFloat() < Cobblemon.config.typeGemGrowthChance))) {
return@forEach
}
val block = relativeState.block
if (block is TypeGemClusterBlock) {
block.advanceGrowth(relativeState, level, relativePos, random)
} else if (isAmethystStage(block)) {
advanceAmethyst(relativeState, level, relativePos)
}
}
}
private fun advanceAmethyst(state: BlockState, level: LevelAccessor, pos: BlockPos) {
val facing = state.getValue(DirectionalBlock.FACING)
val supportState = level.getBlockState(pos.relative(facing.opposite))
if (!supportState.`is`(CobblemonBlockTags.TYPE_GEM_BLOCKS) && supportState.block != CobblemonBlocks.TYPE_GEM_CORE) {
return
}
if (state.block != Blocks.AMETHYST_CLUSTER) {
val nextStage = AMETHYST_STAGES[AMETHYST_STAGES.indexOf(state.block) + 1]
level.setBlock(pos, nextStage.defaultBlockState().setValue(DirectionalBlock.FACING, facing), 3)
return
}
// Fully grown clusters mature into amethyst blocks unless boxed in, mirroring stunted type gems
val boxedIn = Direction.entries.any { direction ->
direction != facing.opposite
&& level.getBlockState(pos.relative(direction)).`is`(CobblemonBlockTags.TYPE_GEM_BLOCKS)
}
if (!boxedIn) {
level.setBlock(pos, Blocks.AMETHYST_BLOCK.defaultBlockState(), 3)
}
}
@@ -0,0 +1,157 @@
/*
* 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.appliances
import com.cobblemon.mod.common.util.rotateShape
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.server.level.ServerLevel
import net.minecraft.sounds.SoundEvents
import net.minecraft.sounds.SoundSource
import net.minecraft.util.RandomSource
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.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.entity.EntityTypeTest
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.phys.AABB
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
//TODO: All the Fan appliance stuff
//TODO: Able to place the Fan on Walls, models and hitbox are there (blockstate would need edits to support it)
open class CopperFanBlock(settings: Properties) : HorizontalDirectionalBlock(settings), SimpleWaterloggedBlock {
companion object {
val CODEC: MapCodec<CopperFanBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::CopperFanBlock) }
//val FACE = //TODO: Floor/Wall
val POWER = BlockStateProperties.POWER;
val PUSH = BooleanProperty.create("push")
val FLOOR_HITBOX = Shapes.or(
Shapes.box(0.0625, 0.125, 0.4375, 0.9375, 1.0, 0.5625),
Shapes.box(0.375, 0.0, 0.375, 0.625, 0.125, 0.625))
val WALL_HITBOX = Shapes.box(0.0625, 0.0625, 0.875, 0.9375, 0.9375, 1.0)
}
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH)
.setValue(WATERLOGGED, false)
//.setValue(FACE, AttachFace.FLOOR)
.setValue(POWER, 0)
.setValue(PUSH, true) //If True, fan pushes entities, If False, fan is cosmetic only
)
}
override fun useWithoutItem(
state: BlockState,
level: Level,
pos: BlockPos,
player: Player,
hitResult: BlockHitResult
): InteractionResult {
if (!level.isClientSide) {
level.setBlockAndUpdate(pos, state.setValue(PUSH, !state.getValue(PUSH)))
level.playSound(null, pos, SoundEvents.STONE_BUTTON_CLICK_ON, SoundSource.BLOCKS)
}
return InteractionResult.SUCCESS
}
override fun codec(): MapCodec<CopperFanBlock> = CODEC
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HORIZONTAL_FACING, WATERLOGGED, /*FACE,*/ POWER, PUSH)
}
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
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 (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
val direction = state.getValue(HORIZONTAL_FACING)
return rotateShape(Direction.NORTH, direction, FLOOR_HITBOX)
}
override fun neighborChanged(
state: BlockState,
level: Level,
pos: BlockPos,
neighborBlock: Block,
neighborPos: BlockPos,
movedByPiston: Boolean
) {
val power = level.getBestNeighborSignal(pos)
if (power != state.getValue(POWER)) {
level.setBlock(pos, state.setValue(POWER, power), UPDATE_CLIENTS)
if (power > 0) {
level.scheduleTick(pos, this, 1)
}
}
}
override fun tick(state: BlockState, level: ServerLevel, pos: BlockPos, random: RandomSource) {
val facing = state.getValue(HORIZONTAL_FACING)
val power = state.getValue(POWER)
if (power == 0) return
if (state.getValue(PUSH)) {
val area = AABB(pos.relative(facing)).expandTowards(
facing.stepX.toDouble() * (power - 1),
0.0,
facing.stepZ.toDouble() * (power - 1)
)
val entities = level.getEntities(null, area)
val pushForce = 0.05
entities.forEach { entity ->
val motion = entity.deltaMovement
entity.setDeltaMovement(
motion.x + facing.stepX * pushForce,
motion.y,
motion.z + facing.stepZ * pushForce
)
entity.hurtMarked = true
}
}
level.scheduleTick(pos, this, 1)
}
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
return getCollisionShape(state, level, pos, context)
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
val fluidState = context.level.getFluidState(context.clickedPos)
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection.opposite)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
}
}
@@ -0,0 +1,283 @@
/*
* 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.appliances
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.util.isServerSide
import com.cobblemon.mod.common.util.rotateShape
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.server.level.ServerLevel
import net.minecraft.sounds.SoundEvents
import net.minecraft.sounds.SoundSource
import net.minecraft.util.RandomSource
import net.minecraft.world.InteractionHand
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.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.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityType
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.block.state.properties.DoubleBlockHalf
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.phys.BlockHitResult
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
//TODO: Oxidation/Waxing/Scraping not breaking the blocks
//TODO: All the Fridge appliance stuff
open class CopperFridgeBlock(settings: Properties) : BaseEntityBlock(settings), SimpleWaterloggedBlock {
fun getBlockEntity(level: ServerLevel, pos: BlockPos) = level.getBlockEntity(getBottomPos(level, pos)) as CopperFridgeBlockEntity
companion object {
val CODEC: MapCodec<CopperFridgeBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::CopperFridgeBlock) }
val HALF: EnumProperty<DoubleBlockHalf> = BlockStateProperties.DOUBLE_BLOCK_HALF
val POWERED = BooleanProperty.create("powered")
val FACING = HorizontalDirectionalBlock.FACING
val LOWER_HITBOX = Shapes.or(
Shapes.box(0.0625, 0.0, 0.125, 0.9375, 0.0625, 0.9375),
Shapes.box(0.0, 0.0625, 0.0625, 1.0, 1.0, 1.0))
val UPPER_HITBOX = 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))
val UPPER_COLLISSIONBOX = Shapes.box(0.0, 0.0, 0.0625, 1.0, 1.0, 1.0)
//The handles get ignored by entity collission, because it feels nicer, but still count as part of the hitbox
}
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH)
.setValue(HALF, DoubleBlockHalf.LOWER)
.setValue(WATERLOGGED, false)
.setValue(POWERED, false)
)
}
override fun codec(): MapCodec<CopperFridgeBlock> = CODEC
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HORIZONTAL_FACING, HALF, WATERLOGGED, POWERED)
}
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
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.block is CopperFridgeBlock
val half = state.getValue(HALF)
if (!isFridge && half == DoubleBlockHalf.UPPER && neighborPos == pos.below()) {
return Blocks.AIR.defaultBlockState()
} else if (!isFridge && half == DoubleBlockHalf.LOWER && neighborPos == pos.above()) {
return Blocks.AIR.defaultBlockState()
}
return state
}
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
val direction = state.getValue(HORIZONTAL_FACING)
return if (state.getValue(HALF) == DoubleBlockHalf.LOWER) {
rotateShape(Direction.NORTH, direction, LOWER_HITBOX)
} else {
rotateShape(Direction.NORTH, direction, UPPER_COLLISSIONBOX)
}
}
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
val direction = state.getValue(HORIZONTAL_FACING)
return if (state.getValue(HALF) == DoubleBlockHalf.LOWER) {
rotateShape(Direction.NORTH, direction, LOWER_HITBOX)
} else {
rotateShape(Direction.NORTH, direction, UPPER_HITBOX)
}
}
override fun setPlacedBy(world: Level, pos: BlockPos, state: BlockState, placer: LivingEntity?, itemStack: ItemStack) {
world.setBlock(pos.above(),
state
.setValue(HALF, DoubleBlockHalf.UPPER)
.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(FACING, blockPlaceContext.horizontalDirection.opposite)
.setValue(HALF, DoubleBlockHalf.LOWER)
.setValue(WATERLOGGED, blockPlaceContext.level.getFluidState(blockPlaceContext.clickedPos).type == Fluids.WATER)
}
return null
}
override fun getRenderShape(state: BlockState) = RenderShape.MODEL
override fun canSurvive(state: BlockState, world: LevelReader, pos: BlockPos): Boolean {
val blockPos = pos.below()
val blockState = world.getBlockState(blockPos)
return if (state.getValue(HALF) == DoubleBlockHalf.LOWER) blockState.isFaceSturdy(world, blockPos, Direction.UP) else blockState.`is`(this)
}
override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
if (!world.isClientSide && player.isCreative) {
var blockPos: BlockPos = BlockPos.ZERO
var blockState: BlockState = state
val half = state.getValue(HALF)
if (half == DoubleBlockHalf.UPPER && world.getBlockState(pos.below().also { blockPos = it }).also { blockState = it }.`is`(state.block) && blockState.getValue(
HALF
) == DoubleBlockHalf.LOWER) {
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 hasAnalogOutputSignal(state: BlockState) = true
override fun useItemOn(
stack: ItemStack,
state: BlockState,
level: Level,
pos: BlockPos,
player: Player,
hand: InteractionHand,
hitResult: BlockHitResult
): ItemInteractionResult {
if (level.isServerSide()) {
val handStack = player.getItemInHand(hand)
val stack = getBlockEntity(level as ServerLevel, pos).theItem
when (stack.item) {
Items.AIR -> {
if (handStack.`is`(Items.WATER_BUCKET)) {
if (!player.isCreative) player.setItemInHand(hand, Items.BUCKET.defaultInstance)
getBlockEntity(level, pos).timer = 100
getBlockEntity(level, pos).theItem = Items.WATER_BUCKET.defaultInstance
level.playSound(null, pos, SoundEvents.BUCKET_EMPTY, SoundSource.BLOCKS, 1.0f, 1.0f)
return ItemInteractionResult.SUCCESS
} else {
return ItemInteractionResult.FAIL
}
}
Items.WATER_BUCKET -> {
if (handStack.`is`(Items.BUCKET)) {
player.setItemInHand(hand, Items.WATER_BUCKET.defaultInstance)
getBlockEntity(level, pos).theItem = Items.AIR.defaultInstance
getBlockEntity(level, pos).timer = 0
level.playSound(null, pos, SoundEvents.BUCKET_FILL, SoundSource.BLOCKS, 1.0f, 1.0f)
return ItemInteractionResult.SUCCESS
} else {
return ItemInteractionResult.FAIL
}
}
Items.ICE -> {
val facing = state.getValue(HORIZONTAL_FACING)
val spawnPos = getBottomPos(level, pos)
val itemEntity =
ItemEntity(level, spawnPos.x + 0.5, spawnPos.y + 0.5, spawnPos.z + 0.5, Items.ICE.defaultInstance)
itemEntity.deltaMovement = Vec3(facing.stepX.toDouble(), 0.0, facing.stepZ.toDouble()).scale(0.2)
level.addFreshEntity(itemEntity)
getBlockEntity(level, pos).theItem = Items.AIR.defaultInstance
return ItemInteractionResult.SUCCESS
}
}
} else {
return if (stack.`is`(Items.WATER_BUCKET)) ItemInteractionResult.SUCCESS
else ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION
}
return ItemInteractionResult.SUCCESS // should not be reachable, but intellij doesnt like that its not there
}
override fun getAnalogOutputSignal(state: BlockState, level: Level, pos: BlockPos): Int {
if (level.isClientSide) return 0
return when (getBlockEntity(level as ServerLevel, pos).theItem.item) {
Items.WATER_BUCKET -> 1
Items.ICE -> 2
else -> 0
}
}
override fun tick(state: BlockState, level: ServerLevel, pos: BlockPos, random: RandomSource) {
(level.getBlockEntity(pos) as CopperFridgeBlockEntity).processTick()
super.tick(state, level, pos, random)
}
override fun newBlockEntity(pos: BlockPos, state: BlockState) = if (state.getValue(HALF) == DoubleBlockHalf.LOWER) CopperFridgeBlockEntity(pos, state) else null
override fun neighborChanged(
state: BlockState,
level: Level,
pos: BlockPos,
neighborBlock: Block,
neighborPos: BlockPos,
movedByPiston: Boolean
) {
if (!level.isClientSide) {
val otherPos = if (state.getValue(HALF) == DoubleBlockHalf.LOWER) pos.above() else pos.below()
val powered = level.hasNeighborSignal(pos) || level.hasNeighborSignal(otherPos)
if (state.getValue(POWERED) != powered) {
level.setBlock(pos, state.setValue(POWERED, powered), 3)
}
val otherState = level.getBlockState(otherPos)
if (otherState.`is`(this) && otherState.getValue(POWERED) != powered) {
level.setBlock(otherPos, otherState.setValue(POWERED, powered), 3)
}
}
super.neighborChanged(state, level, pos, neighborBlock, neighborPos, movedByPiston)
}
override fun <T : BlockEntity> getTicker(
level: Level,
state: BlockState,
blockEntityType: BlockEntityType<T>
): BlockEntityTicker<T>? {
return if (level.isClientSide)
null
else
createTickerHelper(blockEntityType, CobblemonBlockEntities.COPPER_FRIDGE, CopperFridgeBlockEntity.TICKER::tick)
}
fun getBottomPos(level: Level, pos: BlockPos) = if (level.getBlockState(pos).getValue(HALF) == DoubleBlockHalf.UPPER) pos.below() else pos
}
@@ -0,0 +1,69 @@
package com.cobblemon.mod.common.block.appliances
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.Container
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.Vec3
import net.minecraft.world.ticks.ContainerSingleItem
class CopperFridgeBlockEntity(val pos: BlockPos, val state: BlockState) : BlockEntity(
CobblemonBlockEntities.COPPER_FRIDGE, pos, state
), ContainerSingleItem.BlockContainerSingleItem {
private var item: ItemStack = Items.AIR.defaultInstance
var timer: Int = -1
fun processTick() {
val serverLevel = level as? ServerLevel ?: return
if (item.`is`(Items.ICE) && serverLevel.gameTime % 20L == 0L) {
val facing = state.getValue(CopperFridgeBlock.FACING)
val particlePosition = Vec3(
pos.x + 0.5 + facing.stepX * 0.55,
pos.y + 1.0,
pos.z + 0.5 + facing.stepZ * 0.55
)
val packet = SpawnSnowstormParticlePacket(cobblemonResource("rotomfridge_doorready"), particlePosition)
serverLevel.players()
.filter { it.distanceToSqr(particlePosition.x, particlePosition.y, particlePosition.z) <= 32.0 * 32.0 }
.forEach { it.sendPacket(packet) }
}
if (!serverLevel.getBlockState(pos).getValue(CopperFridgeBlock.POWERED)) return
if (timer > 0) timer--
if (timer == 0 && item.item == Items.WATER_BUCKET) {
theItem = Items.ICE.defaultInstance
timer = -1
}
}
override fun getContainerBlockEntity() = this
override fun getTheItem() = item
override fun setTheItem(item: ItemStack) {
this.item = item
level?.updateNeighborsAt(pos, state.block)
}
override fun canTakeItem(target: Container, slot: Int, stack: ItemStack): Boolean {
return stack.item == Items.ICE
}
companion object {
internal val TICKER = BlockEntityTicker<CopperFridgeBlockEntity> { level, pos, state, entity ->
if (!level.isClientSide) {
entity.processTick()
}
}
}
}
@@ -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.appliances
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.rotateShape
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.server.level.ServerLevel
import net.minecraft.sounds.SoundSource
import net.minecraft.util.RandomSource
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.item.BlockItem
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.block.*
import net.minecraft.world.level.block.entity.BlockEntity
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.block.state.properties.BooleanProperty
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.storage.loot.LootParams
import net.minecraft.world.level.storage.loot.LootTable
import net.minecraft.world.level.storage.loot.parameters.LootContextParam
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
//TODO: All the Mower appliance stuff
open class CopperMowerBlock(settings: Properties) : HorizontalDirectionalBlock(settings), SimpleWaterloggedBlock {
companion object {
val CODEC: MapCodec<CopperMowerBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::CopperMowerBlock) }
val TRIGGERED = BooleanProperty.create("triggered")
val COLLISIONBOX = Shapes.or(
Shapes.box(0.1875, 0.0, 0.0, 0.8125, 0.375, 0.625),
Shapes.box(0.0625, 0.0, 0.625, 0.9375, 0.625, 1.0),
Shapes.box(0.125, 0.0, 0.1875, 0.875, 0.3125, 0.5),
//The next three lines are just so the handle does have collision, it feels awkward without it but it looks bad as hitbox
Shapes.box(0.375, 0.375, 0.375, 0.625, 0.625, 0.5625),
Shapes.box(0.4375, 0.5625, 0.5, 0.5625, 0.875, 0.625),
Shapes.box(0.25, 0.875, 0.5625, 0.75, 1.0, 0.6875)
)
val HITBOX = Shapes.or(
Shapes.box(0.1875, 0.0, 0.0, 0.8125, 0.375, 0.625),
Shapes.box(0.0625, 0.0, 0.625, 0.9375, 0.625, 1.0),
Shapes.box(0.125, 0.0, 0.1875, 0.875, 0.3125, 0.5)
)
}
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH)
.setValue(WATERLOGGED, false)
.setValue(TRIGGERED, false)
)
}
override fun neighborChanged(
state: BlockState,
level: Level,
pos: BlockPos,
sourceBlock: Block,
sourcePos: BlockPos,
notify: Boolean
) {
val powered = level.hasNeighborSignal(pos) || level.hasNeighborSignal(pos.above())
val triggered = state.getValue(TRIGGERED)
if (powered && !triggered) {
level.setBlock(pos, state.setValue(TRIGGERED, true), UPDATE_CLIENTS)
level.scheduleTick(pos, this, 1)
} else if (!powered && triggered) {
level.setBlock(pos, state.setValue(TRIGGERED, false), UPDATE_CLIENTS)
}
}
override fun hasAnalogOutputSignal(state: BlockState) = true
override fun tick(state: BlockState, level: ServerLevel, pos: BlockPos, random: RandomSource) {
val blockKey = BuiltInRegistries.BLOCK.getKey(level.getBlockState(pos.below()).block)
val tableKey = ResourceKey.create(Registries.LOOT_TABLE, cobblemonResource("mower/${blockKey.path}"))
val lootTable = level.server.reloadableRegistries().getLootTable(tableKey)
if (lootTable == LootTable.EMPTY) return
val params = LootParams.Builder(level)
.withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos.below()))
.withParameter(LootContextParams.BLOCK_STATE, level.getBlockState(pos.below()))
.withParameter(LootContextParams.TOOL, ItemStack.EMPTY)
.create(LootContextParamSets.BLOCK)
val result = lootTable.getRandomItems(params, random)
val block = result.getOrNull(0)?.item as? BlockItem
val item = result.getOrNull(1)
if (block == null || block == Blocks.AIR) {
level.destroyBlock(pos.below(), false)
} else {
level.setBlockAndUpdate(pos.below(), block.block.defaultBlockState())
}
item?.let {
val facing = state.getValue(HORIZONTAL_FACING).opposite
val itemEntity =
ItemEntity(level,
pos.x + 0.5, pos.y + 0.5, pos.z + 0.5,
it
)
itemEntity.deltaMovement = Vec3(facing.stepX.toDouble(), 0.0, facing.stepZ.toDouble()).scale(0.2)
level.addFreshEntity(itemEntity)
}
level.playSound(null, pos, CobblemonSounds.MOWER_CUT, SoundSource.BLOCKS)
}
override fun getRenderShape(state: BlockState) = RenderShape.MODEL
override fun codec(): MapCodec<CopperMowerBlock> = CODEC
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HORIZONTAL_FACING, WATERLOGGED, TRIGGERED)
}
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
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 (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
val direction = state.getValue(HORIZONTAL_FACING)
return rotateShape(Direction.NORTH, direction, COLLISIONBOX)
}
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
val direction = state.getValue(HORIZONTAL_FACING)
return rotateShape(Direction.NORTH, direction, HITBOX)
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
val fluidState = context.level.getFluidState(context.clickedPos)
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection.opposite)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
}
}
@@ -0,0 +1,12 @@
package com.cobblemon.mod.common.block.appliances
import com.cobblemon.mod.common.CobblemonBlockEntities
import net.minecraft.core.BlockPos
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState
class CopperMowerBlockEntity(val pos: BlockPos, val state: BlockState) : BlockEntity(
CobblemonBlockEntities.COPPER_MOWER,
pos, state
) {
}
@@ -0,0 +1,88 @@
/*
* 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.appliances
import com.cobblemon.mod.common.util.rotateShape
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.util.StringRepresentable
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.*
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.block.state.properties.BooleanProperty
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.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
//TODO: All the Oven appliance stuff - Good Luck Coders
open class CopperOvenBlock(settings: Properties) : HorizontalDirectionalBlock(settings), SimpleWaterloggedBlock {
companion object {
val CODEC: MapCodec<CopperOvenBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::CopperOvenBlock) }
val EJECTING = BooleanProperty.create("ejecting")
val COOKING = EnumProperty.create("cooking", CookingState::class.java)
val HITBOX = Shapes.box(0.0625, 0.0, 0.3125, 0.9375, 0.625, 0.9375)
}
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH)
.setValue(WATERLOGGED, false)
.setValue(COOKING, CookingState.CLOSED)
.setValue(EJECTING, false)
)
}
enum class CookingState : StringRepresentable {
CLOSED, //Door is closed
OPEN, //Door is open
COOKING; //Door is locked closed and the light level is cranked up, as long as the block is powered by redstone. Acts as closed lid in the original Campfire Pot
override fun getSerializedName(): String = this.name.lowercase()
}
override fun codec(): MapCodec<CopperOvenBlock> = CODEC
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HORIZONTAL_FACING, WATERLOGGED, COOKING, EJECTING)
}
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
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 (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
val direction = state.getValue(HORIZONTAL_FACING)
return rotateShape(Direction.NORTH, direction, HITBOX)
}
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
return getCollisionShape(state, level, pos, context).singleEncompassing()
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
val fluidState = context.level.getFluidState(context.clickedPos)
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection.opposite)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
}
}
@@ -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.appliances
import com.cobblemon.mod.common.util.isServerSide
import com.cobblemon.mod.common.util.rotateShape
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.sounds.SoundEvents
import net.minecraft.sounds.SoundSource
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.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.entity.BlockEntity
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.block.state.properties.BooleanProperty
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
open class CopperWasherBlock(settings: Properties) : BaseEntityBlock(settings), SimpleWaterloggedBlock {
companion object {
val CODEC: MapCodec<CopperWasherBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::CopperWasherBlock) }
val POWERED = BooleanProperty.create("powered")
val HITBOX = Shapes.box(0.0625, 0.0, 0.125, 0.9375, 1.0, 1.0)
}
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH)
.setValue(WATERLOGGED, false)
.setValue(POWERED, false)
)
}
override fun codec(): MapCodec<CopperWasherBlock> = CODEC
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HORIZONTAL_FACING, WATERLOGGED, POWERED)
}
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
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 (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
val direction = state.getValue(HORIZONTAL_FACING)
return rotateShape(Direction.NORTH, direction, HITBOX)
}
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
return getCollisionShape(state, level, pos, context).singleEncompassing()
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
val fluidState = context.level.getFluidState(context.clickedPos)
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection.opposite)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
}
override fun newBlockEntity(pos: BlockPos, state: BlockState) = CopperWasherBlockEntity(pos, state)
override fun getRenderShape(state: BlockState) = RenderShape.MODEL
override fun hasAnalogOutputSignal(state: BlockState) = true
override fun getAnalogOutputSignal(state: BlockState, level: Level, pos: BlockPos): Int {
return if ((level.getBlockEntity(pos) as CopperWasherBlockEntity).theItem != ItemStack.EMPTY) 1 else 0
}
override fun useItemOn(
stack: ItemStack,
state: BlockState,
level: Level,
pos: BlockPos,
player: Player,
hand: InteractionHand,
hitResult: BlockHitResult
): ItemInteractionResult {
val entity = level.getBlockEntity(pos) as CopperWasherBlockEntity
val item = entity.theItem
if (item == ItemStack.EMPTY) {
if (level.isServerSide()) {
entity.theItem = stack.copyWithCount(1)
if (!player.isCreative) stack.shrink(1)
entity.craft()
}
return ItemInteractionResult.SUCCESS
} else {
if (level.isServerSide()) {
val facing = state.getValue(HORIZONTAL_FACING)
val itemEntity =
ItemEntity(level, pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, entity.theItem)
itemEntity.deltaMovement = Vec3(facing.stepX.toDouble(), 0.0, facing.stepZ.toDouble()).scale(0.2)
level.addFreshEntity(itemEntity)
entity.theItem = ItemStack.EMPTY
level.playSound(null, pos, SoundEvents.ITEM_FRAME_REMOVE_ITEM, SoundSource.BLOCKS)
}
return ItemInteractionResult.SUCCESS
}
}
}
@@ -0,0 +1,40 @@
package com.cobblemon.mod.common.block.appliances
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonRecipeTypes
import com.cobblemon.mod.common.item.crafting.washer.WasherInput
import com.cobblemon.mod.common.util.isServerSide
import net.minecraft.core.BlockPos
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.ticks.ContainerSingleItem
class CopperWasherBlockEntity(val pos: BlockPos, val state: BlockState): BlockEntity(
CobblemonBlockEntities.COPPER_WASHER,
pos, state
), ContainerSingleItem.BlockContainerSingleItem {
private var item: ItemStack = ItemStack.EMPTY
override fun getContainerBlockEntity() = this
override fun getTheItem() = item
override fun setTheItem(item: ItemStack) {
this.item = item
level?.updateNeighborsAt(pos, state.block)
}
fun craft() {
val level = level ?: return
if (level.isClientSide || theItem.isEmpty) return
val input = WasherInput(theItem.copyWithCount(1))
val recipe = level.recipeManager
.getRecipeFor(CobblemonRecipeTypes.WASHER, input, level)
.orElse(null) ?: return
theItem = recipe.value().assemble(input, level.registryAccess())
setChanged()
level.sendBlockUpdated(worldPosition, blockState, blockState, 3)
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.appliances
import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.world.level.block.WeatheringCopper
import net.minecraft.world.level.block.state.BlockState
class WeatheringCopperFanBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
CopperFanBlock(properties), WeatheringCopper {
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
this.changeOverTime(state, level, pos, random)
}
override fun isRandomlyTicking(state: BlockState): Boolean {
return WeatheringCopper.getNext(state.getBlock()).isPresent()
}
override fun getAge(): WeatheringCopper.WeatherState {
return this.weatherState
}
}
@@ -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.block.appliances
import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.WeatheringCopper
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf
class WeatheringCopperFridgeBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
CopperFridgeBlock(properties), WeatheringCopper {
override fun randomTick(state: BlockState, level: ServerLevel, pos: BlockPos, random: RandomSource) {
if (state.getValue(HALF) == DoubleBlockHalf.LOWER) {
this.changeOverTime(state, level, pos, random)
}
}
override fun changeOverTime(state: BlockState, level: ServerLevel, pos: BlockPos, random: RandomSource) {
val upperPos = pos.above()
val upperState = level.getBlockState(upperPos)
if (upperState.block != this || upperState.getValue(HALF) != DoubleBlockHalf.UPPER) {
return
}
if (random.nextFloat() < 0.05688889F) {
getNextState(state, level, pos, random).ifPresent { nextState ->
val nextLowerState = nextState.setValue(HALF, DoubleBlockHalf.LOWER)
val nextUpperState = nextState
.setValue(HALF, DoubleBlockHalf.UPPER)
.setValue(FACING, upperState.getValue(FACING))
.setValue(BlockStateProperties.WATERLOGGED, upperState.getValue(BlockStateProperties.WATERLOGGED))
.setValue(POWERED, upperState.getValue(POWERED))
level.setBlock(pos, nextLowerState, UPDATE_CLIENTS)
level.setBlock(upperPos, nextUpperState, UPDATE_ALL)
}
}
}
override fun isRandomlyTicking(state: BlockState): Boolean {
return WeatheringCopper.getNext(state.block).isPresent
}
override fun getAge(): WeatheringCopper.WeatherState {
return this.weatherState
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.appliances
import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.world.level.block.WeatheringCopper
import net.minecraft.world.level.block.state.BlockState
class WeatheringCopperMowerBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
CopperMowerBlock(properties), WeatheringCopper {
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
this.changeOverTime(state, level, pos, random)
}
override fun isRandomlyTicking(state: BlockState): Boolean {
return WeatheringCopper.getNext(state.getBlock()).isPresent()
}
override fun getAge(): WeatheringCopper.WeatherState {
return this.weatherState
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.appliances
import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.world.level.block.WeatheringCopper
import net.minecraft.world.level.block.state.BlockState
class WeatheringCopperOvenBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
CopperOvenBlock(properties), WeatheringCopper {
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
this.changeOverTime(state, level, pos, random)
}
override fun isRandomlyTicking(state: BlockState): Boolean {
return WeatheringCopper.getNext(state.getBlock()).isPresent()
}
override fun getAge(): WeatheringCopper.WeatherState {
return this.weatherState
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.appliances
import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.world.level.block.WeatheringCopper
import net.minecraft.world.level.block.state.BlockState
class WeatheringCopperWasherBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
CopperWasherBlock(properties), WeatheringCopper {
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
this.changeOverTime(state, level, pos, random)
}
override fun isRandomlyTicking(state: BlockState): Boolean {
return WeatheringCopper.getNext(state.getBlock()).isPresent()
}
override fun getAge(): WeatheringCopper.WeatherState {
return this.weatherState
}
}
@@ -11,9 +11,11 @@ package com.cobblemon.mod.common.block.chest
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.scheduling.afterOnServer
import com.cobblemon.mod.common.block.PokemonDisguiseBlock
import com.cobblemon.mod.common.block.entity.GildedChestBlockEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.math.FloatRange
import com.cobblemon.mod.common.util.party
import com.cobblemon.mod.common.util.toVec3d
import com.mojang.serialization.MapCodec
@@ -25,6 +27,7 @@ import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
import net.minecraft.util.RandomSource
import net.minecraft.util.StringRepresentable
@@ -54,7 +57,7 @@ import net.minecraft.world.phys.shapes.VoxelShape
@Suppress("OVERRIDE_DEPRECATION")
class GildedChestBlock(settings: Properties, val type: Type = Type.RED) : BaseEntityBlock(settings),
SimpleWaterloggedBlock {
SimpleWaterloggedBlock, PokemonDisguiseBlock {
init {
registerDefaultState(stateDefinition.any()
@@ -70,9 +73,6 @@ class GildedChestBlock(settings: Properties, val type: Type = Type.RED) : BaseEn
).apply(it, ::GildedChestBlock)
}
val POKEMON_ARGS = "gimmighoul"
val LEVEL_RANGE = 5..30
val SOUTH_OUTLINE = Shapes.or(
Shapes.box(0.0, 0.0, 0.25, 1.0, 1.0, 0.9375)
)
@@ -127,13 +127,6 @@ class GildedChestBlock(settings: Properties, val type: Type = Type.RED) : BaseEn
builder.add(WATERLOGGED)
}
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 if (isFake()) Component.translatable("block.cobblemon.gilded_chest") else super.getName()
}
@@ -149,35 +142,6 @@ class GildedChestBlock(settings: Properties, val type: Type = Type.RED) : BaseEn
return super.playerWillDestroy(world, pos, state, player)
}
private fun spawnPokemon(world: Level, pos: BlockPos, state: BlockState, player: ServerPlayer): InteractionResult {
val properties = "$POKEMON_ARGS lvl=${LEVEL_RANGE.random()}"
val pokemon = PokemonProperties.parse(properties)
val entity = pokemon.createEntity(world)
// The yaw based on the block's facing direction
val yaw = facingToYaw[state.getValue(HorizontalDirectionalBlock.FACING)] ?: 0.0F
entity.entityData.set(PokemonEntity.SPAWN_DIRECTION, yaw)
val offsetDir = state.getValue(HorizontalDirectionalBlock.FACING)
val vec = pos.toVec3d().add(offsetDir.stepX * 0.1 + 0.5, 0.0, offsetDir.stepZ * 0.1 + 0.5)
entity.moveTo(vec.x, vec.y, vec.z, yaw, entity.xRot)
world.addFreshEntity(entity)
world.removeBlock(pos, false)
afterOnServer(seconds = 0.1F) {
if (player !in player.level().players()) {
return@afterOnServer
}
val party = player.party()
if (!player.isCreative) {
entity.forceBattle(player)
} else {
world.playSound(null, pos, CobblemonSounds.GIMMIGHOUL_REVEAL, SoundSource.NEUTRAL)
}
}
return InteractionResult.SUCCESS
}
override fun useWithoutItem(
state: BlockState,
world: Level,
@@ -290,4 +254,10 @@ class GildedChestBlock(settings: Properties, val type: Type = Type.RED) : BaseEn
blockEntity.tick()
}
override val levelRange = 5..30
override val pokemonArgs = "gimmighoul"
override val spawnSound = CobblemonSounds.GIMMIGHOUL_REVEAL
override val scaleRange = FloatRange(1f, 1f)
override fun getPokemonFacing(state: BlockState): Direction = state.getValue(HORIZONTAL_FACING)
override val shinyRate = null
}
@@ -11,8 +11,11 @@ package com.cobblemon.mod.common.block.dispenser
import com.cobblemon.mod.common.block.SaccharineLeafBlock
import com.cobblemon.mod.common.block.SaccharineLogBlock
import com.cobblemon.mod.common.block.SaccharineLogSlatheredBlock
import com.cobblemon.mod.common.block.appliances.CopperFridgeBlock
import com.cobblemon.mod.common.mixin.accessor.DispenserBlockAccessor
import net.minecraft.core.dispenser.DispenseItemBehavior
import net.minecraft.sounds.SoundEvents
import net.minecraft.sounds.SoundSource
import net.minecraft.world.item.Item
import net.minecraft.world.item.Items
import net.minecraft.world.item.alchemy.PotionContents
@@ -86,5 +89,30 @@ object DispenserBehaviorRegistry {
).item
)
)
register(
{ dispenseWaterBucketIntoFridge() },
items = listOf(Items.WATER_BUCKET)
)
}
private fun dispenseWaterBucketIntoFridge(): DispenseItemBehavior =
DispenseItemBehavior { source, stack ->
val level = source.level
val pos = source.pos.relative(source.state.getValue(DispenserBlock.FACING))
val fridge = level.getBlockState(pos).block as? CopperFridgeBlock
if (fridge == null) {
stack
} else {
val fridgeEntity = fridge.getBlockEntity(level, pos)
if (!fridgeEntity.theItem.isEmpty) {
stack
} else {
fridgeEntity.theItem = Items.WATER_BUCKET.defaultInstance
fridgeEntity.timer = 100
level.playSound(null, pos, SoundEvents.BUCKET_EMPTY, SoundSource.BLOCKS, 1.0f, 1.0f)
Items.BUCKET.defaultInstance
}
}
}
}
@@ -41,6 +41,7 @@ import net.minecraft.world.Containers
import net.minecraft.world.InteractionResult
import net.minecraft.world.ItemInteractionResult
import net.minecraft.world.InteractionHand
import net.minecraft.world.entity.LightningBolt
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.Pose
import net.minecraft.world.entity.item.ItemEntity
@@ -617,11 +618,14 @@ open class FossilMultiblockEntity(
}
companion object {
val TICKER = BlockEntityTicker<FossilMultiblockEntity> {level, _, _, blockEntity ->
if (blockEntity.multiblockStructure != null) return@BlockEntityTicker
if(blockEntity.porygonProcess == PorygonProcessType.INACTIVE) return@BlockEntityTicker
val TICKER = BlockEntityTicker<FossilMultiblockEntity> { level, _, _, blockEntity ->
val serverLevel = level as? ServerLevel ?: return@BlockEntityTicker
blockEntity.tickPorygon(level)
if (blockEntity.checkLightning(serverLevel)) return@BlockEntityTicker
if (blockEntity.multiblockStructure != null) return@BlockEntityTicker
if (blockEntity.porygonProcess == PorygonProcessType.INACTIVE) return@BlockEntityTicker
blockEntity.tickPorygon(serverLevel)
}
}
@@ -697,4 +701,29 @@ open class FossilMultiblockEntity(
//Fallback: If no safe location is found, just spawn it directly in front of the monitor
return origin.relative(facing)
}
private var lastLightningBolt: UUID? = null
fun checkLightning(level: ServerLevel): Boolean {
val bolt = level.getEntitiesOfClass(
LightningBolt::class.java,
AABB.ofSize(blockPos.center, 1.0, 4.0, 1.0)
).firstOrNull {
(it.blockPosition() == blockPos || it.blockPosition().below() == blockPos) &&
it.uuid != lastLightningBolt
} ?: return false
lastLightningBolt = bolt.uuid
level.setBlockAndUpdate(
blockPos,
CobblemonBlocks.ROTOM_MONITOR.defaultBlockState()
.setValue(
HorizontalDirectionalBlock.FACING,
level.getBlockState(blockPos).getValue(HorizontalDirectionalBlock.FACING)
)
)
return true
}
}
@@ -391,7 +391,7 @@ object CobblemonClient {
CobblemonBlocks.X_SP_ATK,
CobblemonBlocks.X_SP_DEF,
CobblemonBlocks.X_SPEED,
CobblemonBlocks.TM_MACHINE,
CobblemonBlocks.TM_MACHINE,
CobblemonBlocks.GALARICA_CUFF,
CobblemonBlocks.GALARICA_WREATH,
@@ -419,7 +419,7 @@ object CobblemonClient {
CobblemonBlocks.MOOMOO_MILK,
CobblemonBlocks.MEDICINAL_BREW,
CobblemonBlocks.TERRAIN_EXTENDER,
CobblemonBlocks.RED_MINT_LEAF_LITTER,
CobblemonBlocks.POTTED_RED_MINT,
CobblemonBlocks.BLUE_MINT_LEAF_LITTER,
@@ -516,7 +516,17 @@ object CobblemonClient {
CobblemonBlocks.POTTED_WATMEL_BERRY,
CobblemonBlocks.POTTED_WEPEAR_BERRY,
CobblemonBlocks.POTTED_WIKI_BERRY,
CobblemonBlocks.POTTED_YACHE_BERRY
CobblemonBlocks.POTTED_YACHE_BERRY,
CobblemonBlocks.SCOPE_LENS,
CobblemonBlocks.COPPER_FAN,
CobblemonBlocks.EXPOSED_COPPER_FAN,
CobblemonBlocks.WEATHERED_COPPER_FAN,
CobblemonBlocks.OXIDIZED_COPPER_FAN,
CobblemonBlocks.WAXED_COPPER_FAN,
CobblemonBlocks.WAXED_EXPOSED_COPPER_FAN,
CobblemonBlocks.WAXED_WEATHERED_COPPER_FAN,
CobblemonBlocks.WAXED_OXIDIZED_COPPER_FAN
)
this.createBoatModelLayers()
@@ -34,7 +34,7 @@ class DusclopsModel (root: ModelPart) : PokemonPosableModel(root) {
lateinit var battleidle: Pose
override fun registerPoses() {
animations["cry"] = "q.bedrock_stateful('squirtle', 'cry')".asExpressionLike()
animations["cry"] = "q.bedrock_stateful('dusclops', 'cry')".asExpressionLike()
val blink = quirk { bedrockStateful("dusclops", "blink") }
@@ -47,6 +47,10 @@ class CobblemonConfig {
@IntConstraint(min = 0, max = 1000)
var maxPokemonFriendship = 255
@CobblemonConfigField(Category.Pokemon, lang = "power_item_ride_stat_gain_interval_seconds", SERVER)
@IntConstraint(min = -1, max = Int.MAX_VALUE)
var powerItemRideStatGainIntervalSeconds = 120
@CobblemonConfigField(Category.Pokemon, lang = "announce_drop_items", SERVER)
var announceDropItems = true
@CobblemonConfigField(Category.Pokemon, lang = "default_drop_item_method", SERVER)
@@ -2744,4 +2744,9 @@ open class PokemonEntity(
}
fun hasRider() = this.passengers.any { it is LivingEntity }
}
override fun playStepSound(pos: BlockPos, state: BlockState) {
if (this.pokemon.species.silenceStepSounds) return
super.playStepSound(pos, state)
}
}
@@ -22,6 +22,7 @@ import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.feature.TickingSpeciesFeature
import com.cobblemon.mod.common.api.pokemon.status.Statuses
import com.cobblemon.mod.common.api.riding.stats.RidingStat
import com.cobblemon.mod.common.api.spawning.fishing.FishingSpawnCause.Companion.DROPS_REROLL_ASPECT
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.battles.BattleRegistry
@@ -46,10 +47,15 @@ import kotlin.math.*
/** Handles purely server logic for a Pokémon */
class PokemonServerDelegate : PokemonSideDelegate {
companion object {
private const val RIDE_STAT_GAIN_AMOUNT = 1F
}
lateinit var entity: PokemonEntity
var acknowledgedHPValue = -1
var acknowledgedLevel = -1
val passengerOffsets = mutableMapOf<Int, Vec3>()
private var rideStatGainAnchor: Vec3? = null
/** Mocked properties exposed to the client [PokemonEntity]. */
private val mock: PokemonProperties?
@@ -355,9 +361,30 @@ class PokemonServerDelegate : PokemonSideDelegate {
}
}
val rideStatGainIntervalSeconds = Cobblemon.config.powerItemRideStatGainIntervalSeconds
if (rideStatGainIntervalSeconds > 0) {
val rideStatGainIntervalTicks = rideStatGainIntervalSeconds * 20L
if (entity.level().gameTime % rideStatGainIntervalTicks == 0L) {
trainRideStats()
}
}
updateTrackedValues()
}
private fun trainRideStats() {
val position = entity.position()
val anchor = rideStatGainAnchor
rideStatGainAnchor = position
if (anchor == null || anchor == position || entity.passengers.isEmpty()) return
val heldItem = entity.pokemon.heldItemNoCopy()
if (heldItem.isEmpty) return
val stat = RidingStat.entries.firstOrNull { heldItem.`is`(it.powerItem) } ?: return
entity.pokemon.addRideBoost(stat, RIDE_STAT_GAIN_AMOUNT)
}
fun updateShownItem() {
val trackedShownItem = when {
// Show Hand Item if Held item is hidden
@@ -0,0 +1,16 @@
package com.cobblemon.mod.common.item.crafting.washer
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.crafting.Ingredient
import net.minecraft.world.item.crafting.RecipeInput
class WasherInput(
val item: ItemStack = ItemStack.EMPTY
) : RecipeInput {
override fun getItem(index: Int): ItemStack? {
return if (index == 0) item else null
}
override fun size() = 1
}
@@ -0,0 +1,79 @@
package com.cobblemon.mod.common.item.crafting.washer
import com.cobblemon.mod.common.CobblemonRecipeSerializers
import com.cobblemon.mod.common.CobblemonRecipeTypes
import com.mojang.serialization.Codec
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.component.DataComponents
import net.minecraft.core.HolderLookup
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.network.codec.StreamCodec
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.crafting.Ingredient
import net.minecraft.world.item.crafting.Recipe
import net.minecraft.world.item.crafting.RecipeSerializer
import net.minecraft.world.level.Level
class WasherRecipe(
val input: Ingredient,
val result: ItemStack,
val preserveInputComponents: Boolean = false,
val removeDyedColor: Boolean = false
) : Recipe<WasherInput> {
override fun getType() = CobblemonRecipeTypes.WASHER
override fun canCraftInDimensions(width: Int, height: Int) = true
override fun assemble(input: WasherInput, registries: HolderLookup.Provider): ItemStack {
val output = if (preserveInputComponents) {
input.item.transmuteCopy(result.item, result.count)
} else {
result.copy()
}
if (removeDyedColor) {
output.remove(DataComponents.DYED_COLOR)
}
return output
}
override fun getSerializer() = CobblemonRecipeSerializers.WASHER
override fun getResultItem(registries: HolderLookup.Provider): ItemStack = result.copy()
override fun matches(input: WasherInput, level: Level) =
this.input.test(input.item) && (!removeDyedColor || input.item.has(DataComponents.DYED_COLOR))
class Serializer : RecipeSerializer<WasherRecipe> {
companion object {
val CODEC: MapCodec<WasherRecipe> = RecordCodecBuilder.mapCodec { instance ->
instance.group(
Ingredient.CODEC.fieldOf("input").forGetter { recipe -> recipe.input },
ItemStack.STRICT_CODEC.fieldOf("result").forGetter { recipe -> recipe.result },
Codec.BOOL.optionalFieldOf("preserve_input_components", false)
.forGetter { recipe -> recipe.preserveInputComponents },
Codec.BOOL.optionalFieldOf("remove_dyed_color", false)
.forGetter { recipe -> recipe.removeDyedColor }
).apply(instance, ::WasherRecipe)
}
}
val STREAM_CODEC: StreamCodec<RegistryFriendlyByteBuf, WasherRecipe> =
StreamCodec.of(::toNetwork, ::fromNetwork)
private fun fromNetwork(buffer: RegistryFriendlyByteBuf): WasherRecipe {
val input = Ingredient.CONTENTS_STREAM_CODEC.decode(buffer)
val result = ItemStack.STREAM_CODEC.decode(buffer)
val preserveInputComponents = buffer.readBoolean()
val removeDyedColor = buffer.readBoolean()
return WasherRecipe(input, result, preserveInputComponents, removeDyedColor)
}
private fun toNetwork(buffer: RegistryFriendlyByteBuf, recipe: WasherRecipe) {
Ingredient.CONTENTS_STREAM_CODEC.encode(buffer, recipe.input)
ItemStack.STREAM_CODEC.encode(buffer, recipe.result)
buffer.writeBoolean(recipe.preserveInputComponents)
buffer.writeBoolean(recipe.removeDyedColor)
}
override fun codec() = CODEC
override fun streamCodec() = STREAM_CODEC
}
}
@@ -394,6 +394,7 @@ object CobblemonItemGroups {
entries.accept(CobblemonItems.FOSSIL_ANALYZER)
entries.accept(CobblemonItems.MONITOR)
entries.accept(CobblemonItems.DAMAGED_MONITOR)
entries.accept(CobblemonItems.ROTOM_MONITOR)
entries.accept(CobblemonItems.PC)
entries.accept(CobblemonItems.HEALING_MACHINE)
entries.accept(CobblemonItems.PASTURE)
@@ -570,6 +571,47 @@ object CobblemonItemGroups {
entries.accept(CobblemonItems.PINK_PLAQUE)
CobblemonItems.campfire_pots.forEach(entries::accept)
entries.accept(CobblemonItems.COPPER_OVEN)
entries.accept(CobblemonItems.COPPER_WASHER)
entries.accept(CobblemonItems.COPPER_FAN)
entries.accept(CobblemonItems.COPPER_MOWER)
entries.accept(CobblemonItems.COPPER_FRIDGE)
entries.accept(CobblemonItems.EXPOSED_COPPER_OVEN)
entries.accept(CobblemonItems.EXPOSED_COPPER_WASHER)
entries.accept(CobblemonItems.EXPOSED_COPPER_FAN)
entries.accept(CobblemonItems.EXPOSED_COPPER_MOWER)
entries.accept(CobblemonItems.EXPOSED_COPPER_FRIDGE)
entries.accept(CobblemonItems.WEATHERED_COPPER_OVEN)
entries.accept(CobblemonItems.WEATHERED_COPPER_WASHER)
entries.accept(CobblemonItems.WEATHERED_COPPER_FAN)
entries.accept(CobblemonItems.WEATHERED_COPPER_MOWER)
entries.accept(CobblemonItems.WEATHERED_COPPER_FRIDGE)
entries.accept(CobblemonItems.OXIDIZED_COPPER_OVEN)
entries.accept(CobblemonItems.OXIDIZED_COPPER_WASHER)
entries.accept(CobblemonItems.OXIDIZED_COPPER_FAN)
entries.accept(CobblemonItems.OXIDIZED_COPPER_MOWER)
entries.accept(CobblemonItems.OXIDIZED_COPPER_FRIDGE)
entries.accept(CobblemonItems.WAXED_COPPER_OVEN)
entries.accept(CobblemonItems.WAXED_COPPER_WASHER)
entries.accept(CobblemonItems.WAXED_COPPER_FAN)
entries.accept(CobblemonItems.WAXED_COPPER_MOWER)
entries.accept(CobblemonItems.WAXED_COPPER_FRIDGE)
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_OVEN)
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_WASHER)
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_FAN)
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_MOWER)
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_FRIDGE)
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_OVEN)
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_WASHER)
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_FAN)
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_MOWER)
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_FRIDGE)
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_OVEN)
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_WASHER)
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_FAN)
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_MOWER)
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_FRIDGE)
}
private fun consumableEntries(displayContext: ItemDisplayParameters, entries: Output) {
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.item.interactive
import com.cobblemon.mod.common.CobblemonItemComponents
import com.cobblemon.mod.common.item.components.FoodComponent
import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundEvents
@@ -23,10 +24,15 @@ import net.minecraft.world.level.Level
class PonigiriItem : Item(
Properties().stacksTo(64)
.food(FoodProperties.Builder()
.nutrition(2)
.saturationModifier(0.55f)
.nutrition(NUTRITION)
.saturationModifier(SATURATION_MODIFIER)
.build())
) {
companion object {
const val NUTRITION = 2
const val SATURATION_MODIFIER = 0.55f
}
override fun getName(stack: ItemStack): Component {
val ingredients = stack.get(CobblemonItemComponents.INGREDIENT)
@@ -59,4 +65,9 @@ class PonigiriItem : Item(
override fun getEatingSound(): SoundEvent {
return SoundEvents.GENERIC_EAT
}
}
fun getFoodValues(stack: ItemStack): Pair<Int, Float> {
val (hunger, saturation) = stack.getOrDefault(CobblemonItemComponents.FOOD, FoodComponent(NUTRITION, SATURATION_MODIFIER))
return hunger to saturation
}
}
@@ -8,9 +8,12 @@
package com.cobblemon.mod.common.net.serverhandling.battle
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.api.text.red
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.battles.HealItemActionResponse
import com.cobblemon.mod.common.battles.MoveActionResponse
import com.cobblemon.mod.common.exception.IllegalActionChoiceException
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
import com.cobblemon.mod.common.net.messages.client.battle.BattleQueueRequestPacket
@@ -25,6 +28,27 @@ object BattleSelectActionsHandler : ServerNetworkPacketHandler<BattleSelectActio
if (!actor.mustChoose) {
return
}
// Battle command injection attempt detection
packet.showdownActionResponses.asSequence()
.flatMap {
when (it) {
is MoveActionResponse -> sequenceOf(it.moveName, it.targetPnx, it.gimmickID)
is HealItemActionResponse -> sequenceOf(it.item)
else -> emptySequence()
}
}
.filterNotNull()
.firstOrNull { field -> field.any(Char::isISOControl) }
?.let {
// Escapes control chars as \uXXXX to prevent forging logs.
val printable = it.replace(Regex("\\p{Cc}")) { "\\u%04x".format(it.value[0].code) }
Cobblemon.LOGGER.warn("Blocked battle command injection from ${player.name.string}: $printable")
actor.sendUpdate(BattleQueueRequestPacket(actor.request!!))
actor.sendUpdate(BattleMakeChoicePacket())
return
}
try {
actor.setActionResponses(packet.showdownActionResponses)
} catch (e: IllegalActionChoiceException) {
@@ -173,6 +173,7 @@ class Species : ShowdownIdentifiable {
.addStandardFunctions()
.addSpeciesFunctions(this)
var silenceStepSounds = false
fun initialize() {
Cobblemon.statProvider.provide(this)
@@ -256,6 +257,7 @@ class Species : ShowdownIdentifiable {
}
this.riding.encode(buffer)
buffer.writeBoolean(this.silenceStepSounds)
}
fun decode(buffer: RegistryFriendlyByteBuf) {
@@ -299,6 +301,7 @@ class Species : ShowdownIdentifiable {
}
}
this.riding = RidingProperties.decode(buffer)
this.silenceStepSounds = buffer.readBoolean()
this.initialize()
}
@@ -234,11 +234,11 @@ fun Entity.isDusk(): Boolean {
}
fun Entity.isStandingOn(blocks: Set<String>, depth: Int = 2): Boolean {
for (currentDepth in 1..depth) {
val bellowBlockPos = blockPosition().below(currentDepth)
for (currentDepth in 0..depth) {
val bellowBlockPos = blockPosBelowThatAffectsMyMovement.below(currentDepth)
val blockState = level().getBlockState(bellowBlockPos)
if (blockState.isAir || !blockState.isCollisionShapeFullBlock(level(), bellowBlockPos)) continue
if (blockState.isAir) continue
val elementOrTags = ExtraCodecs.TAG_OR_ELEMENT_ID.listOf().decode(JavaOps.INSTANCE, blocks.toList()).result().get().first
elementOrTags.forEach {
@@ -95,6 +95,8 @@ class FloatRange(override val start: Float, override val endInclusive: Float) :
override fun hashCode(): Int = 31 * start.hashCode() + endInclusive.hashCode()
override fun toString(): String = "$start..$endInclusive"
fun random() = Random.nextFloat() * (endInclusive - start) + start
}
class DoubleRange(override val start: Double, override val endInclusive: Double) : ClosedFloatingPointRange<Double> {
@@ -27,5 +27,7 @@ object CobblemonGameRules {
@JvmField
val HEALERS_HEAL_PC: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("healersHealPC", GameRules.Category.MISC, BooleanRuleInvoker.`cobblemon$create`(false))
@JvmField
val HEALER_SET_SPAWN: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("healersSetSpawn", GameRules.Category.MISC, BooleanRuleInvoker.`cobblemon$create`(false))
@JvmField
val DO_POKEMON_PREDATION: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("doPokemonPredation", GameRules.Category.MOBS, BooleanRuleInvoker.`cobblemon$create`(true))
}
@@ -0,0 +1,68 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:rotomfridge_doorready",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/vanilla/generic"
}
},
"curves": {
"variable.debrissize": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 1, 0.96, 0.86, 0.7, 0.47, 0]
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": 8,
"max_particles": 100
},
"minecraft:emitter_lifetime_expression": {
"activation_expression": 1
},
"minecraft:emitter_shape_box": {
"offset": [0, -1, 0.5],
"half_dimensions": [0.5, 0.75, 0],
"surface_only": true,
"direction": "outwards"
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(1.2,2)"
},
"minecraft:particle_initial_spin": {
"rotation": "math.random_integer(0,3)*90"
},
"minecraft:particle_initial_speed": "math.random(2.5,3.5)*0.1",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": [0, 0.1, 0],
"linear_drag_coefficient": 1
},
"minecraft:particle_appearance_billboard": {
"size": ["0.25*v.debrissize", "0.25*v.debrissize"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 64,
"texture_height": 8,
"flipbook": {
"base_UV": [56, 0],
"size_UV": [8, 8],
"step_UV": [-8, 0],
"frames_per_second": 6,
"max_frame": 8
}
}
},
"minecraft:particle_motion_collision": {
"collision_radius": 0.01
},
"minecraft:particle_appearance_lighting": {},
"minecraft:particle_appearance_tinting": {
"color": [0.7098, 0.95294, 1, 0.74902]
}
}
}
}
@@ -64,7 +64,7 @@
"rotation": "math.random_integer(0,3)*90"
},
"minecraft:particle_motion_parametric": {
"relative_position": ["-(v.target_deltax+((v.particle_random_1-0.5)*2))*(v.particle_age / v.particle_lifetime)", "(v.target_deltay+((v.particle_random_2-0.5)*2))*(v.particle_age / v.particle_lifetime)", "-v.target_deltaz*(v.particle_age / v.particle_lifetime)"]
"relative_position": ["-(v.target_deltax+((v.particle_random_1-0.5)*1.33))*(v.particle_age / v.particle_lifetime)", "(v.target_deltay+((v.particle_random_2-0.5)*1.33))*(v.particle_age / v.particle_lifetime)", "-v.target_deltaz*(v.particle_age / v.particle_lifetime)"]
},
"minecraft:particle_appearance_billboard": {
"size": ["0.4*v.rsize", "0.4*v.rsize"],
@@ -456,6 +456,12 @@
"cannon_left": {
"position": [0, 0, 3]
}
},
"timeline": {
"0.25": "q.run_molang('cobblemon:stepsound_standard_large');",
"1.25": "q.run_molang('cobblemon:stepsound_standard_large');",
"2.25": "q.run_molang('cobblemon:stepsound_standard_large');",
"3.25": "q.run_molang('cobblemon:stepsound_standard_large');"
}
},
"animation.blastoise.ground_run": {
@@ -1815,6 +1815,12 @@
"wings_open": {
"scale": 0
}
},
"timeline": {
"0.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
"0.5": "q.run_molang('cobblemon:stepsound_claw_medium');",
"1.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
"1.5": "q.run_molang('cobblemon:stepsound_claw_medium');"
}
},
"animation.pidgeot.mount_ground_idle": {
@@ -3631,6 +3637,12 @@
"wings_open": {
"scale": 0
}
},
"timeline": {
"0.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
"0.5": "q.run_molang('cobblemon:stepsound_claw_medium');",
"1.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
"1.5": "q.run_molang('cobblemon:stepsound_claw_medium');"
}
},
"animation.pidgeot.ride_ground_walk": {
@@ -83,6 +83,7 @@
},
"animation.parasect.ground_walk": {
"loop": true,
"animation_length": 1,
"bones": {
"body": {
"rotation": [0, 0, 0],
@@ -134,6 +135,12 @@
"locator_seat_1": {
"rotation": [7.5, 0, 0]
}
},
"timeline": {
"0.0": "q.run_molang('cobblemon:stepsound_minecraft');",
"0.25": "q.run_molang('cobblemon:stepsound_minecraft');",
"0.5": "q.run_molang('cobblemon:stepsound_minecraft');",
"0.75": "q.run_molang('cobblemon:stepsound_minecraft');"
}
},
"animation.parasect.ground_run": {
@@ -258,6 +265,10 @@
"rotation": ["5+Math.cos((query.anim_time) * 90 * 16 - 90) * 2", 0, 0],
"position": [0, "0+Math.cos((query.anim_time) * 90 * 32) * -0.2", -0.25]
}
},
"timeline": {
"0.0": "q.run_molang('cobblemon:stepsound_minecraft');",
"0.125": "q.run_molang('cobblemon:stepsound_minecraft');"
}
},
"animation.parasect.ride_ground_run": {
@@ -1682,6 +1682,12 @@
"1.3333": [10, 9, 0]
}
}
},
"timeline": {
"0.0": "q.run_molang('cobblemon:stepsound_standard_medium');",
"0.4583": "q.run_molang('cobblemon:stepsound_standard_medium');",
"0.6667": "q.run_molang('cobblemon:stepsound_standard_medium');",
"1.125": "q.run_molang('cobblemon:stepsound_standard_medium');"
}
},
"animation.arcanine.ride_ground_walk": {
@@ -2639,6 +2645,12 @@
"chest_fluff_right": {
"rotation": [5, "-22.5+math.cos(q.anim_time*90*8-120)*15", "-math.sin(q.anim_time*90*8-120)*3"]
}
},
"timeline": {
"0.125": "q.run_molang('cobblemon:stepsound_standard_medium');",
"0.2083": "q.run_molang('cobblemon:stepsound_standard_large');",
"0.2917": "q.run_molang('cobblemon:stepsound_standard_medium');",
"0.375": "q.run_molang('cobblemon:stepsound_standard_medium');"
}
},
"animation.arcanine.ride_ground_run": {
@@ -4161,41 +4173,101 @@
"eye_left": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
"0.5": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
"1.6667": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [0, 0, 0],
"post": [-0.1, 0, 0.1]
},
"0.5": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0, 0.1]
},
"1.6667": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eye_right": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
"0.5": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
"1.6667": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [0, 0, 0],
"post": [0.1, 0, 0.1]
},
"0.5": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0, 0.1]
},
"1.6667": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"0.5": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"1.6667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"0.5": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"1.6667": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"0.5": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"1.6667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"0.5": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"1.6667": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"jaw": {
@@ -4823,41 +4895,101 @@
"eye_left": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
"0.5": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
"1.6667": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [0, 0, 0],
"post": [-0.1, 0, 0.1]
},
"0.5": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0, 0.1]
},
"1.6667": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eye_right": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
"0.5": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
"1.6667": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [0, 0, 0],
"post": [0.1, 0, 0.1]
},
"0.5": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0, 0.1]
},
"1.6667": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"0.5": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"1.6667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"0.5": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"1.6667": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"0.5": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"1.6667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"0.5": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"1.6667": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"jaw": {
@@ -5287,14 +5419,20 @@
"position": {
"0.0": [-0.1, 0, 0.1],
"0.125": [-0.1, 0, 0.1],
"0.1667": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]}
"0.1667": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
}
}
},
"eye_right": {
"position": {
"0.0": [0.1, 0, 0.1],
"0.125": [0.1, 0, 0.1],
"0.1667": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]}
"0.1667": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
}
}
}
}
@@ -5491,47 +5629,95 @@
"eye_left": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.2, 0, 0.1]
},
"0.3333": {
"pre": [-0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eye_right": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [0.2, 0, 0.1]
},
"0.3333": {
"pre": [0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.2, 0, 0.1]
},
"0.3333": {
"pre": [-0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [0.2, 0, 0.1]
},
"0.3333": {
"pre": [0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left_hurt": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"0.3333": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"0.3333": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"eyelid_right_hurt": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"0.3333": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"0.3333": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"jaw": {
@@ -6238,47 +6424,95 @@
"eye_left": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.2, 0, 0.1]
},
"0.3333": {
"pre": [-0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eye_right": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [0.2, 0, 0.1]
},
"0.3333": {
"pre": [0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.2, 0, 0.1]
},
"0.3333": {
"pre": [-0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [0.2, 0, 0.1]
},
"0.3333": {
"pre": [0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left_hurt": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"0.3333": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"0.3333": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"eyelid_right_hurt": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"0.3333": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"0.3333": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"jaw": {
@@ -391,6 +391,10 @@
"0.7083": [0, 0, 0]
}
}
},
"timeline": {
"0.0833": "q.run_molang('cobblemon:stepsound_standard_medium');",
"0.2917": "q.run_molang('cobblemon:stepsound_standard_medium');"
}
},
"animation.dewgong.water_idle": {
@@ -1071,6 +1071,16 @@
"head": {
"rotation": ["-0.8*math.cos(q.anim_time*90*8-120)", 0, "3*math.sin(q.anim_time*90*4+70)"]
}
},
"timeline": {
"0.0": "q.run_molang('cobblemon:stepsound_standard_large');",
"0.5": "q.run_molang('cobblemon:stepsound_standard_large');",
"1.0": "q.run_molang('cobblemon:stepsound_standard_large');",
"1.5": "q.run_molang('cobblemon:stepsound_standard_large');",
"2.0": "q.run_molang('cobblemon:stepsound_standard_large');",
"2.5": "q.run_molang('cobblemon:stepsound_standard_large');",
"3.0": "q.run_molang('cobblemon:stepsound_standard_large');",
"3.5": "q.run_molang('cobblemon:stepsound_standard_large');"
}
},
"animation.rhyhorn.ride_ground_walk": {
@@ -1917,6 +1927,16 @@
],
"position": [0, "0.4+0.6*math.cos(q.anim_time*90*8-120)", 0]
}
},
"timeline": {
"0.0": "q.run_molang('cobblemon:stepsound_standard_large');",
"0.375": "q.run_molang('cobblemon:stepsound_standard_medium');",
"0.5": "q.run_molang('cobblemon:stepsound_standard_large');",
"0.875": "q.run_molang('cobblemon:stepsound_standard_medium');",
"1.0": "q.run_molang('cobblemon:stepsound_standard_large');",
"1.375": "q.run_molang('cobblemon:stepsound_standard_medium');",
"1.5": "q.run_molang('cobblemon:stepsound_standard_large');",
"1.875": "q.run_molang('cobblemon:stepsound_standard_medium');"
}
},
"animation.rhyhorn.ride_ground_run": {
@@ -329,6 +329,12 @@
"locator_seat_1": {
"rotation": [-15, 0, 0]
}
},
"timeline": {
"0.0": "q.run_molang('cobblemon:stepsound_standard_large');",
"1.0": "q.run_molang('cobblemon:stepsound_standard_large');",
"2.0": "q.run_molang('cobblemon:stepsound_standard_large');",
"3.0": "q.run_molang('cobblemon:stepsound_standard_large');"
}
},
"animation.rhydon.ride_ground_walk": {
@@ -807,6 +813,12 @@
"locator_seat_1": {
"rotation": [-15, 0, 0]
}
},
"timeline": {
"0.3333": "q.run_molang('cobblemon:stepsound_standard_large');",
"0.8333": "q.run_molang('cobblemon:stepsound_standard_large');",
"1.3333": "q.run_molang('cobblemon:stepsound_standard_large');",
"1.8333": "q.run_molang('cobblemon:stepsound_standard_large');"
}
},
"animation.rhydon.ride_ground_run": {
@@ -391,6 +391,10 @@
"1.0": [0, 0, 0]
}
}
},
"timeline": {
"0.0833": "q.run_molang('cobblemon:stepsound_minecraft');",
"0.5833": "q.run_molang('cobblemon:stepsound_minecraft');"
}
},
"animation.mr_mime.ground_run": {
@@ -3150,6 +3150,10 @@
"locator_seat_2": {
"rotation": [45, 0, 0]
}
},
"timeline": {
"0.5": "q.run_molang('cobblemon:stepsound_claw_large');",
"1.5": "q.run_molang('cobblemon:stepsound_claw_large');"
}
},
"animation.corviknight.ground_run": {
@@ -4473,6 +4477,10 @@
"locator_seat_2": {
"rotation": [25, 0, 0]
}
},
"timeline": {
"0.3333": "q.run_molang('cobblemon:stepsound_claw_large');",
"0.8333": "q.run_molang('cobblemon:stepsound_claw_large');"
}
},
"animation.corviknight.air_idle": {
@@ -566,6 +566,12 @@
"1.5": [0, 0.2, 0]
}
}
},
"timeline": {
"0.5417": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.7083": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"1.2917": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"1.4583": "q.run_molang('cobblemon:stepsound_hoof_medium');"
}
},
"animation.wyrdeer.sleep": {
@@ -780,15 +786,27 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"0.5": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
"0.25": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"0.5": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"0.5": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
"0.25": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"0.5": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"ear_right": {
@@ -1186,18 +1204,36 @@
"position": {
"0.0": [0, 0, 0],
"1.5833": [-0.1, 0, -0.1],
"1.6667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
"3.0": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"3.125": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
"1.6667": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
},
"3.0": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"3.125": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"1.5833": [0.1, 0, -0.1],
"1.6667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
"3.0": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"3.125": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
"1.6667": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
},
"3.0": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"3.125": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"tail": {
@@ -2204,6 +2240,16 @@
"1.1667": [0, 0, 0]
}
}
},
"timeline": {
"0.2083": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.2917": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.375": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.4583": "q.run_molang('cobblemon:stepsound_hoof_large');",
"0.7917": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.875": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.9583": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"1.0417": "q.run_molang('cobblemon:stepsound_hoof_large');"
}
},
"animation.wyrdeer.ride_jump": {
@@ -227,6 +227,14 @@
{"origin": [3.1, 20.8, -0.84], "size": [2, 1, 1], "inflate": 0.1, "uv": [60, 42]}
]
},
{
"name": "eyelid_closed_left",
"parent": "head_left",
"pivot": [3.6, 19.7, -0.91],
"cubes": [
{"origin": [2.1, 17.2, -0.66], "size": [3, 5, 1], "inflate": 0.25, "uv": [98, 2]}
]
},
{
"name": "face_ditto_left",
"parent": "head_left",
@@ -332,6 +340,14 @@
{"origin": [-5.1, 20.8, -0.84], "size": [2, 1, 1], "inflate": 0.1, "uv": [51, 42], "mirror": true}
]
},
{
"name": "eyelid_closed_right",
"parent": "head_right",
"pivot": [-3.6, 19.7, -0.91],
"cubes": [
{"origin": [-5.1, 17.2, -0.66], "size": [3, 5, 1], "inflate": 0.25, "uv": [89, 2], "mirror": true}
]
},
{
"name": "face_ditto_right",
"parent": "head_right",
@@ -134,229 +134,114 @@
"jaw2": [0, 27, -7.35]
}
},
{
"name": "head_right",
"parent": "head_angle",
"pivot": [-3.525, 31, 0.25],
"rotation": [5, 0, 0],
"cubes": [
{"origin": [-4.525, 29.5, -4.75], "size": [2, 5, 5], "uv": [51, 11]},
{"origin": [-3.625, 31.5, 0.25], "size": [0, 3, 5], "uv": [52, 55]}
]
},
{
"name": "locator_eye_right",
"parent": "head_right",
"pivot": [-4.5, 31, -2.5],
"rotation": [0, 90, 0],
"locators": {
"eye1": [-4.5, 31, -2.5]
}
},
{
"name": "eye_right",
"parent": "head_right",
"pivot": [-4.525, 31.35, -2.25],
"cubes": [
{"origin": [-4.525, 28.85, -4.25], "size": [1, 5, 4], "inflate": 0.01, "uv": [66, 2], "mirror": true}
]
},
{
"name": "eye_neutral_right",
"parent": "eye_right",
"pivot": [-4.525, 32.85095, -2.27179],
"cubes": [
{"origin": [-4.505, 31.85, -4.25], "size": [1, 2, 4], "inflate": 0.05, "uv": [66, 12], "mirror": true}
]
},
{
"name": "eye_angry_right",
"parent": "eye_right",
"pivot": [-4.435, 32.1, -2.5],
"cubes": [
{"origin": [-4.405, 30.85, -4.25], "size": [1, 3, 4], "inflate": 0.05, "uv": [66, 26], "mirror": true},
{"origin": [-4.44, 31.35, -3.27], "size": [1, 1, 1], "inflate": 0.02, "uv": [73, 27], "mirror": true}
]
},
{
"name": "eye_sad_right",
"parent": "eye_right",
"pivot": [-4.435, 32.85, -2.5],
"cubes": [
{"origin": [-4.405, 31.85, -4.25], "size": [1, 2, 4], "inflate": 0.05, "uv": [66, 19], "mirror": true},
{"origin": [-4.44, 32.35, -3.27], "size": [1, 1, 1], "inflate": 0.02, "uv": [73, 20], "mirror": true}
]
},
{
"name": "pupil_right",
"parent": "eye_right",
"pivot": [-4.525, 30.85095, -3.02179],
"cubes": [
{"origin": [-4.525, 29.35, -4.04], "size": [1, 3, 2], "inflate": 0.02, "uv": [73, 0], "mirror": true}
]
},
{
"name": "pupil_right2",
"parent": "pupil_right",
"pivot": [-4.55, 31.35095, -3.02179],
"cubes": [
{"origin": [-4.55, 30.35, -3.55], "size": [1, 2, 1], "uv": [84, 2], "mirror": true}
]
},
{
"name": "eyelid_right",
"parent": "head_right",
"pivot": [-3.925, 31.35095, -2.27179],
"cubes": [
{"origin": [-4.425, 28.85, -4.25], "size": [1, 5, 4], "inflate": 0.01, "uv": [77, 2], "mirror": true}
]
},
{
"name": "pupil_eyelid_right",
"parent": "eyelid_right",
"pivot": [-4.425, 30.80095, -2.27179],
"cubes": [
{"origin": [-4.435, 30.3, -3.75], "size": [1, 1, 3], "inflate": 0.01, "uv": [77, 14], "mirror": true}
]
},
{
"name": "eyelid_right2",
"parent": "eyelid_right",
"pivot": [-3.925, 32.85095, -2.27179],
"cubes": [
{"origin": [-4.405, 31.85, -4.25], "size": [1, 2, 4], "inflate": 0.05, "uv": [66, 12], "mirror": true}
]
},
{
"name": "pupil_happy_right",
"parent": "eyelid_right",
"pivot": [-4.325, 30.80095, -2.27179],
"cubes": [
{"origin": [-4.325, 30.30095, -3.77179], "size": [1, 2, 3], "inflate": 0.05, "uv": [77, 20], "mirror": true}
]
},
{
"name": "face_ditto_right",
"parent": "head_right",
"pivot": [-4.435, 32, -2.25]
},
{
"name": "eye_ditto_right",
"parent": "face_ditto_right",
"pivot": [-4.435, 32, -2.25],
"cubes": [
{"origin": [-4.435, 31.5, -2.75], "size": [0, 1, 1], "uv": [113, 1]}
]
},
{
"name": "eye_closed_ditto_right",
"parent": "face_ditto_right",
"pivot": [-4.335, 32, -2.25],
"cubes": [
{"origin": [-4.335, 31.5, -3.25], "size": [0, 1, 2], "uv": [112, 2]},
{"origin": [-4.345, 32, -2.75], "size": [0, 1, 1], "uv": [113, 5]}
]
},
{
"name": "head_left",
"parent": "head_angle",
"pivot": [3.525, 31, 0.25],
"pivot": [3.53, 31, 0.25],
"rotation": [5, 0, 0],
"cubes": [
{"origin": [2.525, 29.5, -4.75], "size": [2, 5, 5], "uv": [51, 21], "mirror": true},
{"origin": [3.625, 31.5, 0.25], "size": [0, 3, 5], "uv": [40, 55], "mirror": true}
{"origin": [2.53, 29.5, -4.75], "size": [2, 5, 5], "uv": [51, 21], "mirror": true},
{"origin": [3.63, 31.5, 0.25], "size": [0, 3, 5], "uv": [40, 55], "mirror": true}
]
},
{
"name": "locator_eye_left",
"parent": "head_left",
"pivot": [4.5, 31, -2.5],
"rotation": [0, -90, 0],
"locators": {
"eye2": [4.5, 31, -2.5]
}
},
{
"name": "eye_left",
"parent": "head_left",
"pivot": [4.525, 31.35, -2.25],
"pivot": [4.53, 31.5, -2.25],
"cubes": [
{"origin": [3.525, 28.85, -4.25], "size": [1, 5, 4], "inflate": 0.01, "uv": [88, 2]}
{"origin": [3.54, 29, -4.25], "size": [1, 5, 4], "uv": [88, 2]}
]
},
{
"name": "eye_neutral_left",
"parent": "eye_left",
"pivot": [4.525, 32.85095, -2.27179],
"pivot": [4.54, 33, -2.25],
"cubes": [
{"origin": [3.505, 31.85, -4.25], "size": [1, 2, 4], "inflate": 0.05, "uv": [88, 12]}
{"origin": [3.54, 32, -4.25], "size": [1, 2, 4], "inflate": 0.021, "uv": [88, 12]}
]
},
{
"name": "eye_angry_left",
"parent": "eye_left",
"pivot": [4.435, 32.1, -2.5],
"pivot": [4.44, 32.5, -2.25],
"cubes": [
{"origin": [3.405, 30.85, -4.25], "size": [1, 3, 4], "inflate": 0.05, "uv": [88, 26]},
{"origin": [3.44, 31.35, -3.27], "size": [1, 1, 1], "inflate": 0.02, "uv": [95, 27]}
{"origin": [3.44, 31, -4.25], "size": [1, 3, 4], "inflate": 0.021, "uv": [88, 26]},
{"origin": [3.44, 31.5, -3.25], "size": [1, 1, 1], "inflate": 0.03, "uv": [95, 27]}
]
},
{
"name": "eye_sad_left",
"parent": "eye_left",
"pivot": [4.435, 32.85, -2.5],
"pivot": [4.43, 33, -2.25],
"cubes": [
{"origin": [3.405, 31.85, -4.25], "size": [1, 2, 4], "inflate": 0.05, "uv": [88, 19]},
{"origin": [3.44, 32.35, -3.27], "size": [1, 1, 1], "inflate": 0.02, "uv": [95, 20]}
{"origin": [3.44, 32, -4.25], "size": [1, 2, 4], "inflate": 0.021, "uv": [88, 19]},
{"origin": [3.44, 32.5, -3.25], "size": [1, 1, 1], "inflate": 0.03, "uv": [95, 20]}
]
},
{
"name": "pupil_left",
"parent": "eye_left",
"pivot": [4.525, 30.85095, -3.02179],
"pivot": [4.55, 31, -3.05],
"cubes": [
{"origin": [3.525, 29.35, -4.04], "size": [1, 3, 2], "inflate": 0.02, "uv": [95, 0]}
{"origin": [3.55, 29.5, -4.05], "size": [1, 3, 2], "uv": [95, 0]}
]
},
{
"name": "pupil_left2",
"name": "eye_shine_left",
"parent": "pupil_left",
"pivot": [4.55, 31.35095, -3.02179],
"pivot": [4.55, 31.5, -3.05],
"cubes": [
{"origin": [3.55, 30.35, -3.55], "size": [1, 2, 1], "uv": [106, 2]}
{"origin": [3.56, 30.5, -3.55], "size": [1, 2, 1], "uv": [106, 2]}
]
},
{
"name": "open_eye_left",
"parent": "head_left",
"pivot": [4.44, 31.5, -2.25],
"cubes": [
{"origin": [3.44, 29, -4.25], "size": [1, 5, 4], "uv": [99, 2]}
]
},
{
"name": "open_pupil_left",
"parent": "open_eye_left",
"pivot": [4.45, 31.5, -2.25],
"cubes": [
{"origin": [3.45, 31, -3.75], "size": [1, 1, 3], "uv": [99, 14]}
]
},
{
"name": "open_neutral_left",
"parent": "open_eye_left",
"pivot": [4.34, 33, -2.25],
"cubes": [
{"origin": [3.34, 32, -4.25], "size": [1, 2, 4], "inflate": 0.021, "uv": [88, 12]}
]
},
{
"name": "open_happy_left",
"parent": "open_eye_left",
"pivot": [4.35, 32, -2.25],
"cubes": [
{"origin": [3.35, 31, -3.75], "size": [1, 2, 3], "uv": [99, 20]}
]
},
{
"name": "eyelid_left",
"parent": "head_left",
"pivot": [3.925, 31.35095, -2.27179],
"pivot": [4.44, 31.5, -2.25],
"cubes": [
{"origin": [3.425, 28.85, -4.25], "size": [1, 5, 4], "inflate": 0.01, "uv": [99, 2]}
{"origin": [3.44, 29, -4.25], "size": [1, 5, 4], "inflate": 0.022, "uv": [99, 26]}
]
},
{
"name": "pupil_eyelid_left",
"parent": "eyelid_left",
"pivot": [4.425, 30.80095, -2.27179],
"cubes": [
{"origin": [3.435, 30.3, -3.75], "size": [1, 1, 3], "inflate": 0.01, "uv": [99, 14]}
]
},
{
"name": "eyelid_left2",
"parent": "eyelid_left",
"pivot": [3.925, 32.85095, -2.27179],
"cubes": [
{"origin": [3.405, 31.85, -4.25], "size": [1, 2, 4], "inflate": 0.05, "uv": [88, 12]}
]
},
{
"name": "pupil_happy_left",
"parent": "eyelid_left",
"pivot": [4.325, 30.80095, -2.27179],
"cubes": [
{"origin": [3.325, 30.30095, -3.77179], "size": [1, 2, 3], "inflate": 0.05, "uv": [99, 20]}
]
"name": "locator_eye_left",
"parent": "head_left",
"pivot": [4.54, 31, -2.46],
"rotation": [0, -90, 0],
"locators": {
"eye2": [4.54, 31, -2.46]
}
},
{
"name": "face_ditto_left",
@@ -368,7 +253,7 @@
"parent": "face_ditto_left",
"pivot": [4.435, 32, -2.25],
"cubes": [
{"origin": [4.435, 31.5, -2.75], "size": [0, 1, 1], "uv": [118, 1], "mirror": true}
{"origin": [4.435, 31.5, -2.75], "size": [0, 1, 1], "uv": [113, 1]}
]
},
{
@@ -376,8 +261,139 @@
"parent": "face_ditto_left",
"pivot": [4.335, 32, -2.25],
"cubes": [
{"origin": [4.335, 31.5, -3.25], "size": [0, 1, 2], "uv": [117, 2], "mirror": true},
{"origin": [4.345, 32, -2.75], "size": [0, 1, 1], "uv": [118, 5], "mirror": true}
{"origin": [4.335, 31.5, -3.25], "size": [0, 1, 2], "uv": [112, 2]},
{"origin": [4.345, 32, -2.75], "size": [0, 1, 1], "uv": [113, 5]}
]
},
{
"name": "head_right",
"parent": "head_angle",
"pivot": [-3.53, 31, 0.25],
"rotation": [5, 0, 0],
"cubes": [
{"origin": [-4.53, 29.5, -4.75], "size": [2, 5, 5], "uv": [51, 11]},
{"origin": [-3.63, 31.5, 0.25], "size": [0, 3, 5], "uv": [40, 55]}
]
},
{
"name": "eye_right",
"parent": "head_right",
"pivot": [-4.53, 31.5, -2.25],
"cubes": [
{"origin": [-4.54, 29, -4.25], "size": [1, 5, 4], "uv": [66, 2], "mirror": true}
]
},
{
"name": "eye_neutral_right",
"parent": "eye_right",
"pivot": [-4.54, 33, -2.25],
"cubes": [
{"origin": [-4.54, 32, -4.25], "size": [1, 2, 4], "inflate": 0.021, "uv": [66, 12], "mirror": true}
]
},
{
"name": "eye_angry_right",
"parent": "eye_right",
"pivot": [-4.44, 32.5, -2.25],
"cubes": [
{"origin": [-4.44, 31, -4.25], "size": [1, 3, 4], "inflate": 0.021, "uv": [66, 26], "mirror": true},
{"origin": [-4.44, 31.5, -3.25], "size": [1, 1, 1], "inflate": 0.03, "uv": [73, 27], "mirror": true}
]
},
{
"name": "eye_sad_right",
"parent": "eye_right",
"pivot": [-4.43, 33, -2.25],
"cubes": [
{"origin": [-4.44, 32, -4.25], "size": [1, 2, 4], "inflate": 0.021, "uv": [66, 19], "mirror": true},
{"origin": [-4.44, 32.5, -3.25], "size": [1, 1, 1], "inflate": 0.03, "uv": [73, 20], "mirror": true}
]
},
{
"name": "pupil_right",
"parent": "eye_right",
"pivot": [-4.55, 31, -3.05],
"cubes": [
{"origin": [-4.55, 29.5, -4.05], "size": [1, 3, 2], "uv": [73, 0], "mirror": true}
]
},
{
"name": "eye_shine_right",
"parent": "pupil_right",
"pivot": [-4.55, 31.5, -3.05],
"cubes": [
{"origin": [-4.56, 30.5, -3.55], "size": [1, 2, 1], "uv": [84, 2], "mirror": true}
]
},
{
"name": "open_eye_right",
"parent": "head_right",
"pivot": [-4.44, 31.5, -2.25],
"cubes": [
{"origin": [-4.44, 29, -4.25], "size": [1, 5, 4], "uv": [77, 2], "mirror": true}
]
},
{
"name": "open_pupil_right",
"parent": "open_eye_right",
"pivot": [-4.45, 31.5, -2.25],
"cubes": [
{"origin": [-4.45, 31, -3.75], "size": [1, 1, 3], "uv": [77, 14], "mirror": true}
]
},
{
"name": "open_neutral_right",
"parent": "open_eye_right",
"pivot": [-4.34, 33, -2.25],
"cubes": [
{"origin": [-4.34, 32, -4.25], "size": [1, 2, 4], "inflate": 0.021, "uv": [66, 12], "mirror": true}
]
},
{
"name": "open_happy_right",
"parent": "open_eye_right",
"pivot": [-4.35, 32, -2.25],
"cubes": [
{"origin": [-4.35, 31, -3.75], "size": [1, 2, 3], "uv": [77, 20], "mirror": true}
]
},
{
"name": "eyelid_right",
"parent": "head_right",
"pivot": [-4.44, 31.5, -2.25],
"cubes": [
{"origin": [-4.44, 29, -4.25], "size": [1, 5, 4], "inflate": 0.022, "uv": [77, 26], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "head_right",
"pivot": [-4.54, 31, -2.46],
"rotation": [0, 90, 0],
"locators": {
"eye1": [-4.54, 31, -2.46]
}
},
{
"name": "face_ditto_right",
"parent": "head_right",
"pivot": [-4.435, 32, -2.25]
},
{
"name": "eye_ditto_right",
"parent": "face_ditto_right",
"pivot": [-4.435, 32, -2.25],
"cubes": [
{"origin": [-4.435, 31.5, -2.75], "size": [0, 1, 1], "uv": [118, 1], "mirror": true}
]
},
{
"name": "eye_closed_ditto_right",
"parent": "face_ditto_right",
"pivot": [-4.335, 32, -2.25],
"cubes": [
{"origin": [-4.335, 31.5, -3.25], "size": [0, 1, 2], "uv": [117, 2], "mirror": true},
{"origin": [-4.345, 32, -2.75], "size": [0, 1, 1], "uv": [118, 5], "mirror": true}
]
},
{
@@ -830,11 +830,6 @@
{"origin": [-3.5, 38.3, 33.75], "size": [7, 5, 9], "uv": [106, 33]}
]
},
{
"name": "tongue6",
"parent": "tongue5",
"pivot": [0, 40.8, 40.5]
},
{
"name": "muzzle",
"parent": "head_angle",
@@ -913,6 +908,15 @@
{"origin": [-0.1, 44.3, -8.11], "size": [4, 2, 1], "uv": [87, 72]}
]
},
{
"name": "eyelid_base_left",
"parent": "eye_left_base",
"pivot": [1.9, 43.9, -8.11],
"cubes": [
{"origin": [-0.1, 45.3, -8.11], "size": [4, 1, 1], "uv": [87, 76]},
{"origin": [-0.1, 41.9, -8.11], "size": [4, 4, 1], "uv": [87, 79]}
]
},
{
"name": "eye_left",
"parent": "eye_left_base",
@@ -950,7 +954,7 @@
"parent": "eye_left",
"pivot": [1.9, 44.2, -8.07],
"cubes": [
{"origin": [0.4, 43.7, -8.07], "size": [3, 1, 1], "inflate": 0.02, "uv": [87, 76]}
{"origin": [0.4, 43.7, -8.07], "size": [3, 1, 1], "inflate": 0.02, "uv": [87, 85]}
]
},
{
@@ -958,7 +962,7 @@
"parent": "eye_left",
"pivot": [1.9, 44.2, -8.07],
"cubes": [
{"origin": [0.4, 42.95, -8.07], "size": [3, 2, 1], "inflate": 0.02, "uv": [87, 79]}
{"origin": [0.4, 42.95, -8.07], "size": [3, 2, 1], "inflate": 0.02, "uv": [87, 88]}
]
},
{
@@ -995,6 +999,15 @@
{"origin": [-3.9, 44.3, -8.11], "size": [4, 2, 1], "uv": [76, 72], "mirror": true}
]
},
{
"name": "eyelid_base_right",
"parent": "eye_right_base",
"pivot": [-1.9, 43.9, -8.11],
"cubes": [
{"origin": [-3.9, 45.3, -8.11], "size": [4, 1, 1], "uv": [76, 76], "mirror": true},
{"origin": [-3.9, 41.9, -8.11], "size": [4, 4, 1], "uv": [76, 79], "mirror": true}
]
},
{
"name": "eye_right",
"parent": "eye_right_base",
@@ -1032,7 +1045,7 @@
"parent": "eye_right",
"pivot": [-1.9, 44.2, -8.07],
"cubes": [
{"origin": [-3.4, 43.7, -8.07], "size": [3, 1, 1], "inflate": 0.02, "uv": [76, 76], "mirror": true}
{"origin": [-3.4, 43.7, -8.07], "size": [3, 1, 1], "inflate": 0.02, "uv": [76, 85], "mirror": true}
]
},
{
@@ -1040,7 +1053,7 @@
"parent": "eye_right",
"pivot": [-1.9, 44.2, -8.07],
"cubes": [
{"origin": [-3.4, 42.95, -8.07], "size": [3, 2, 1], "inflate": 0.02, "uv": [76, 79], "mirror": true}
{"origin": [-3.4, 42.95, -8.07], "size": [3, 2, 1], "inflate": 0.02, "uv": [76, 88], "mirror": true}
]
},
{
@@ -8,7 +8,6 @@
"poses": {
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"isBattle": false,
"animations": [
"q.look('neck', 1, 1, 70, -10, 20, -20)",
"q.look('head_ai')",
@@ -35,6 +34,9 @@
"part": "wing_closed_left",
"isVisible": true
}
],
"quirks": [
"q.bedrock_quirk('fearow', 'blink')"
]
},
"walking": {
@@ -65,6 +67,9 @@
"part": "wing_closed_left",
"isVisible": true
}
],
"quirks": [
"q.bedrock_quirk('fearow', 'blink')"
]
},
"hover": {
@@ -96,6 +101,9 @@
"part": "wing_closed_left",
"isVisible": false
}
],
"quirks": [
"q.bedrock_quirk('fearow', 'blink')"
]
},
"fly": {
@@ -128,6 +136,9 @@
"part": "wing_closed_left",
"isVisible": false
}
],
"quirks": [
"q.bedrock_quirk('fearow', 'blink')"
]
},
"sleep": {
@@ -27,7 +27,7 @@
"q.look('head_ai')",
"q.bedrock('froakie', 'ground_idle')"
],
"quirks": []
"quirks": ["q.bedrock_quirk('froakie', 'blink')"]
},
"walking": {
"poseTypes": ["WALK"],
@@ -36,7 +36,7 @@
"q.look('head_ai')",
"q.bedrock('froakie', 'ground_walk')"
],
"quirks": []
"quirks": ["q.bedrock_quirk('froakie', 'blink')"]
},
"swimming": {
"poseTypes": ["WALK","SWIM"],
@@ -46,7 +46,7 @@
"q.look('head_ai')",
"q.bedrock('froakie', 'water_swim')"
],
"quirks": []
"quirks": ["q.bedrock_quirk('froakie', 'blink')"]
},
"float": {
"poseTypes": ["STAND","FLOAT"],
@@ -55,7 +55,7 @@
"q.look('head_ai')",
"q.bedrock('froakie', 'water_idle')"
],
"quirks": []
"quirks": ["q.bedrock_quirk('froakie', 'blink')"]
},
"sleep": {
"poseTypes": ["SLEEP"],
@@ -27,7 +27,7 @@
"q.look('head_ai', 1, 1, 5, -45, 45, -45)",
"q.bedrock('frogadier', 'ground_idle')"
],
"quirks": []
"quirks": ["q.bedrock_quirk('frogadier', 'blink')"]
},
"walking": {
"poseTypes": ["WALK"],
@@ -36,7 +36,7 @@
"q.look('head_ai', 1, 1, 0, -45, 45, -45)",
"q.bedrock('frogadier', 'ground_walk')"
],
"quirks": []
"quirks": ["q.bedrock_quirk('frogadier', 'blink')"]
},
"swimming": {
"poseTypes": ["WALK","SWIM"],
@@ -46,7 +46,7 @@
"q.look('head_ai')",
"q.bedrock('frogadier', 'water_swim')"
],
"quirks": []
"quirks": ["q.bedrock_quirk('frogadier', 'blink')"]
},
"float": {
"poseTypes": ["STAND","FLOAT"],
@@ -55,7 +55,7 @@
"q.look('head_ai')",
"q.bedrock('frogadier', 'water_idle')"
],
"quirks": []
"quirks": ["q.bedrock_quirk('frogadier', 'blink')"]
},
"sleep": {
"poseTypes": ["SLEEP"],
@@ -66,7 +66,7 @@
"q.bedrock('greninja', math.random(0, 1) < 0.4 ? 'ground_idle_alt' : 'ground_idle')"
],
"quirks": [
"q.bedrock_quirk('greninja', q.array('quirk_look_left', 'quirk_look_right'), 8, 30, 1)"
"q.bedrock_quirk('greninja', 'blink')","q.bedrock_quirk('greninja', q.array('quirk_look_left', 'quirk_look_right'), 8, 30, 1)"
]
},
"walking": {
@@ -78,7 +78,7 @@
"q.look('tongue1', -1, 1, 70, -45, 0, 0)",
"q.bedrock('greninja', 'ground_walk')"
],
"quirks": []
"quirks": ["q.bedrock_quirk('greninja', 'blink')"]
},
"running": {
"poseTypes": ["WALK"],
@@ -89,7 +89,7 @@
"q.look('tongue1', -1, 1, 70, -45, 0, 0)",
"q.bedrock('greninja', 'ground_run')"
],
"quirks": []
"quirks": ["q.bedrock_quirk('greninja', 'blink')"]
},
"surface-swimming": {
"poseTypes": ["WALK","SWIM"],
@@ -101,7 +101,7 @@
"q.look('tongue1', -1, 1, 70, -45, 0, 0)",
"q.bedrock('greninja', 'water_swim')"
],
"quirks": [],
"quirks": ["q.bedrock_quirk('greninja', 'blink')"],
"transformedParts": [
{
"part": "body",
@@ -118,7 +118,7 @@
"q.look('tongue1', -1, 1, 70, -45, 0, 0)",
"q.bedrock('greninja', 'water_idle')"
],
"quirks": [],
"quirks": ["q.bedrock_quirk('greninja', 'blink')"],
"transformedParts": [
{
"part": "body",
@@ -136,7 +136,7 @@
"q.look('tongue1', -1, 1, 70, -45, 0, 0)",
"q.bedrock('greninja', 'water_swim')"
],
"quirks": [],
"quirks": ["q.bedrock_quirk('greninja', 'blink')"],
"transformedParts": [
{
"part": "body",
@@ -153,7 +153,7 @@
"q.look('tongue1', -1, 1, 70, -45, 0, 0)",
"q.bedrock('greninja', 'water_idle')"
],
"quirks": [],
"quirks": ["q.bedrock_quirk('greninja', 'blink')"],
"transformedParts": [
{
"part": "body",
@@ -0,0 +1,469 @@
{
"variants": {
"facing=east,power=0": {
"model": "cobblemon:block/copper_fan_unpowered",
"y": 90
},
"facing=north,power=0": {
"model": "cobblemon:block/copper_fan_unpowered"
},
"facing=south,power=0": {
"model": "cobblemon:block/copper_fan_unpowered",
"y": 180
},
"facing=west,power=0": {
"model": "cobblemon:block/copper_fan_unpowered",
"y": 270
},
"facing=east,power=1,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=1,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=1,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=1,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=1,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=1,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=1,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=1,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=2,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=2,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=2,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=2,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=2,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=2,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=2,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=2,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=3,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=3,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=3,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=3,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=3,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=3,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=3,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=3,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=4,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=4,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=4,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=4,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=4,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=4,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=4,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=4,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=5,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=5,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=5,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=5,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=5,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=5,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=5,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=5,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=6,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=6,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=6,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=6,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=6,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=6,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=6,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=6,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=7,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=7,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=7,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=7,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=7,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=7,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=7,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=7,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=8,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=8,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=8,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=8,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=8,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=8,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=8,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=8,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=9,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=9,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=9,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=9,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=9,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=9,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=9,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=9,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=10,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=10,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=10,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=10,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=10,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=10,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=10,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=10,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=11,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=11,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=11,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=11,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=11,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=11,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=11,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=11,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=12,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=12,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=12,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=12,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=12,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=12,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=12,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=12,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=13,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=13,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=13,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=13,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=13,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=13,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=13,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=13,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=14,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=14,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=14,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=14,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=14,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=14,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=14,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=14,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=15,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=15,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=15,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=15,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=15,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=15,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=15,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=15,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
}
}
}
@@ -0,0 +1,34 @@
{
"variants": {
"facing=east,half=lower": {
"model": "cobblemon:block/copper_fridge_bottom",
"y": 90
},
"facing=north,half=lower": {
"model": "cobblemon:block/copper_fridge_bottom"
},
"facing=south,half=lower": {
"model": "cobblemon:block/copper_fridge_bottom",
"y": 180
},
"facing=west,half=lower": {
"model": "cobblemon:block/copper_fridge_bottom",
"y": 270
},
"facing=east,half=upper": {
"model": "cobblemon:block/copper_fridge_top",
"y": 90
},
"facing=north,half=upper": {
"model": "cobblemon:block/copper_fridge_top"
},
"facing=south,half=upper": {
"model": "cobblemon:block/copper_fridge_top",
"y": 180
},
"facing=west,half=upper": {
"model": "cobblemon:block/copper_fridge_top",
"y": 270
}
}
}
@@ -0,0 +1,19 @@
{
"variants": {
"facing=east": {
"model": "cobblemon:block/copper_mower",
"y": 90
},
"facing=north": {
"model": "cobblemon:block/copper_mower"
},
"facing=south": {
"model": "cobblemon:block/copper_mower",
"y": 180
},
"facing=west": {
"model": "cobblemon:block/copper_mower",
"y": 270
}
}
}
@@ -0,0 +1,64 @@
{
"variants": {
"facing=east,cooking=closed,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 90
},
"facing=north,cooking=closed,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed"
},
"facing=south,cooking=closed,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 180
},
"facing=west,cooking=closed,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 270
},
"facing=east,cooking=open,ejecting=false": {
"model": "cobblemon:block/copper_oven_open",
"y": 90
},
"facing=north,cooking=open,ejecting=false": {
"model": "cobblemon:block/copper_oven_open"
},
"facing=south,cooking=open,ejecting=false": {
"model": "cobblemon:block/copper_oven_open",
"y": 180
},
"facing=west,cooking=open,ejecting=false": {
"model": "cobblemon:block/copper_oven_open",
"y": 270
},
"facing=east,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 90
},
"facing=north,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed"
},
"facing=south,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 180
},
"facing=west,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 270
},
"facing=east,ejecting=true": {
"model": "cobblemon:block/copper_oven_open",
"y": 90
},
"facing=north,ejecting=true": {
"model": "cobblemon:block/copper_oven_open"
},
"facing=south,ejecting=true": {
"model": "cobblemon:block/copper_oven_open",
"y": 180
},
"facing=west,ejecting=true": {
"model": "cobblemon:block/copper_oven_open",
"y": 270
}
}
}
@@ -0,0 +1,19 @@
{
"variants": {
"facing=east": {
"model": "cobblemon:block/copper_washer",
"y": 90
},
"facing=north": {
"model": "cobblemon:block/copper_washer"
},
"facing=south": {
"model": "cobblemon:block/copper_washer",
"y": 180
},
"facing=west": {
"model": "cobblemon:block/copper_washer",
"y": 270
}
}
}
@@ -0,0 +1,469 @@
{
"variants": {
"facing=east,power=0": {
"model": "cobblemon:block/exposed_copper_fan_unpowered",
"y": 90
},
"facing=north,power=0": {
"model": "cobblemon:block/exposed_copper_fan_unpowered"
},
"facing=south,power=0": {
"model": "cobblemon:block/exposed_copper_fan_unpowered",
"y": 180
},
"facing=west,power=0": {
"model": "cobblemon:block/exposed_copper_fan_unpowered",
"y": 270
},
"facing=east,power=1,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 90
},
"facing=north,power=1,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative"
},
"facing=south,power=1,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 180
},
"facing=west,power=1,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 270
},
"facing=east,power=1,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 90
},
"facing=north,power=1,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing"
},
"facing=south,power=1,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 180
},
"facing=west,power=1,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 270
},
"facing=east,power=2,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 90
},
"facing=north,power=2,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative"
},
"facing=south,power=2,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 180
},
"facing=west,power=2,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 270
},
"facing=east,power=2,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 90
},
"facing=north,power=2,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing"
},
"facing=south,power=2,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 180
},
"facing=west,power=2,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 270
},
"facing=east,power=3,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 90
},
"facing=north,power=3,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative"
},
"facing=south,power=3,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 180
},
"facing=west,power=3,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 270
},
"facing=east,power=3,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 90
},
"facing=north,power=3,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing"
},
"facing=south,power=3,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 180
},
"facing=west,power=3,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 270
},
"facing=east,power=4,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 90
},
"facing=north,power=4,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative"
},
"facing=south,power=4,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 180
},
"facing=west,power=4,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 270
},
"facing=east,power=4,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 90
},
"facing=north,power=4,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing"
},
"facing=south,power=4,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 180
},
"facing=west,power=4,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 270
},
"facing=east,power=5,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 90
},
"facing=north,power=5,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative"
},
"facing=south,power=5,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 180
},
"facing=west,power=5,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 270
},
"facing=east,power=5,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 90
},
"facing=north,power=5,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing"
},
"facing=south,power=5,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 180
},
"facing=west,power=5,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 270
},
"facing=east,power=6,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 90
},
"facing=north,power=6,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative"
},
"facing=south,power=6,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 180
},
"facing=west,power=6,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 270
},
"facing=east,power=6,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 90
},
"facing=north,power=6,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing"
},
"facing=south,power=6,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 180
},
"facing=west,power=6,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 270
},
"facing=east,power=7,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 90
},
"facing=north,power=7,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative"
},
"facing=south,power=7,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 180
},
"facing=west,power=7,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative",
"y": 270
},
"facing=east,power=7,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 90
},
"facing=north,power=7,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing"
},
"facing=south,power=7,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 180
},
"facing=west,power=7,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing",
"y": 270
},
"facing=east,power=8,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=8,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
},
"facing=south,power=8,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=8,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=8,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=8,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
},
"facing=south,power=8,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=8,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=9,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=9,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
},
"facing=south,power=9,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=9,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=9,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=9,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
},
"facing=south,power=9,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=9,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=10,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=10,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
},
"facing=south,power=10,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=10,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=10,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=10,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
},
"facing=south,power=10,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=10,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=11,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=11,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
},
"facing=south,power=11,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=11,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=11,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=11,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
},
"facing=south,power=11,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=11,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=12,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=12,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
},
"facing=south,power=12,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=12,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=12,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=12,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
},
"facing=south,power=12,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=12,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=13,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=13,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
},
"facing=south,power=13,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=13,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=13,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=13,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
},
"facing=south,power=13,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=13,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=14,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=14,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
},
"facing=south,power=14,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=14,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=14,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=14,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
},
"facing=south,power=14,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=14,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=15,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=15,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
},
"facing=south,power=15,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=15,push=false": {
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=15,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=15,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
},
"facing=south,power=15,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=15,push=true": {
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
"y": 270
}
}
}
@@ -0,0 +1,34 @@
{
"variants": {
"facing=east,half=lower": {
"model": "cobblemon:block/exposed_copper_fridge_bottom",
"y": 90
},
"facing=north,half=lower": {
"model": "cobblemon:block/exposed_copper_fridge_bottom"
},
"facing=south,half=lower": {
"model": "cobblemon:block/exposed_copper_fridge_bottom",
"y": 180
},
"facing=west,half=lower": {
"model": "cobblemon:block/exposed_copper_fridge_bottom",
"y": 270
},
"facing=east,half=upper": {
"model": "cobblemon:block/exposed_copper_fridge_top",
"y": 90
},
"facing=north,half=upper": {
"model": "cobblemon:block/exposed_copper_fridge_top"
},
"facing=south,half=upper": {
"model": "cobblemon:block/exposed_copper_fridge_top",
"y": 180
},
"facing=west,half=upper": {
"model": "cobblemon:block/exposed_copper_fridge_top",
"y": 270
}
}
}
@@ -0,0 +1,19 @@
{
"variants": {
"facing=east": {
"model": "cobblemon:block/exposed_copper_mower",
"y": 90
},
"facing=north": {
"model": "cobblemon:block/exposed_copper_mower"
},
"facing=south": {
"model": "cobblemon:block/exposed_copper_mower",
"y": 180
},
"facing=west": {
"model": "cobblemon:block/exposed_copper_mower",
"y": 270
}
}
}
@@ -0,0 +1,64 @@
{
"variants": {
"facing=east,cooking=closed,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_closed",
"y": 90
},
"facing=north,cooking=closed,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_closed"
},
"facing=south,cooking=closed,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_closed",
"y": 180
},
"facing=west,cooking=closed,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_closed",
"y": 270
},
"facing=east,cooking=open,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_open",
"y": 90
},
"facing=north,cooking=open,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_open"
},
"facing=south,cooking=open,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_open",
"y": 180
},
"facing=west,cooking=open,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_open",
"y": 270
},
"facing=east,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_closed",
"y": 90
},
"facing=north,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_closed"
},
"facing=south,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_closed",
"y": 180
},
"facing=west,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/exposed_copper_oven_closed",
"y": 270
},
"facing=east,ejecting=true": {
"model": "cobblemon:block/exposed_copper_oven_open",
"y": 90
},
"facing=north,ejecting=true": {
"model": "cobblemon:block/exposed_copper_oven_open"
},
"facing=south,ejecting=true": {
"model": "cobblemon:block/exposed_copper_oven_open",
"y": 180
},
"facing=west,ejecting=true": {
"model": "cobblemon:block/exposed_copper_oven_open",
"y": 270
}
}
}
@@ -0,0 +1,19 @@
{
"variants": {
"facing=east": {
"model": "cobblemon:block/exposed_copper_washer",
"y": 90
},
"facing=north": {
"model": "cobblemon:block/exposed_copper_washer"
},
"facing=south": {
"model": "cobblemon:block/exposed_copper_washer",
"y": 180
},
"facing=west": {
"model": "cobblemon:block/exposed_copper_washer",
"y": 270
}
}
}
@@ -0,0 +1,469 @@
{
"variants": {
"facing=east,power=0": {
"model": "cobblemon:block/oxidized_copper_fan_unpowered",
"y": 90
},
"facing=north,power=0": {
"model": "cobblemon:block/oxidized_copper_fan_unpowered"
},
"facing=south,power=0": {
"model": "cobblemon:block/oxidized_copper_fan_unpowered",
"y": 180
},
"facing=west,power=0": {
"model": "cobblemon:block/oxidized_copper_fan_unpowered",
"y": 270
},
"facing=east,power=1,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 90
},
"facing=north,power=1,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative"
},
"facing=south,power=1,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 180
},
"facing=west,power=1,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 270
},
"facing=east,power=1,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 90
},
"facing=north,power=1,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing"
},
"facing=south,power=1,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 180
},
"facing=west,power=1,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 270
},
"facing=east,power=2,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 90
},
"facing=north,power=2,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative"
},
"facing=south,power=2,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 180
},
"facing=west,power=2,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 270
},
"facing=east,power=2,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 90
},
"facing=north,power=2,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing"
},
"facing=south,power=2,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 180
},
"facing=west,power=2,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 270
},
"facing=east,power=3,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 90
},
"facing=north,power=3,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative"
},
"facing=south,power=3,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 180
},
"facing=west,power=3,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 270
},
"facing=east,power=3,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 90
},
"facing=north,power=3,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing"
},
"facing=south,power=3,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 180
},
"facing=west,power=3,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 270
},
"facing=east,power=4,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 90
},
"facing=north,power=4,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative"
},
"facing=south,power=4,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 180
},
"facing=west,power=4,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 270
},
"facing=east,power=4,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 90
},
"facing=north,power=4,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing"
},
"facing=south,power=4,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 180
},
"facing=west,power=4,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 270
},
"facing=east,power=5,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 90
},
"facing=north,power=5,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative"
},
"facing=south,power=5,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 180
},
"facing=west,power=5,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 270
},
"facing=east,power=5,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 90
},
"facing=north,power=5,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing"
},
"facing=south,power=5,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 180
},
"facing=west,power=5,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 270
},
"facing=east,power=6,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 90
},
"facing=north,power=6,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative"
},
"facing=south,power=6,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 180
},
"facing=west,power=6,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 270
},
"facing=east,power=6,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 90
},
"facing=north,power=6,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing"
},
"facing=south,power=6,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 180
},
"facing=west,power=6,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 270
},
"facing=east,power=7,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 90
},
"facing=north,power=7,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative"
},
"facing=south,power=7,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 180
},
"facing=west,power=7,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative",
"y": 270
},
"facing=east,power=7,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 90
},
"facing=north,power=7,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing"
},
"facing=south,power=7,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 180
},
"facing=west,power=7,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing",
"y": 270
},
"facing=east,power=8,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=8,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
},
"facing=south,power=8,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=8,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=8,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=8,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
},
"facing=south,power=8,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=8,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=9,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=9,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
},
"facing=south,power=9,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=9,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=9,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=9,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
},
"facing=south,power=9,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=9,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=10,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=10,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
},
"facing=south,power=10,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=10,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=10,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=10,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
},
"facing=south,power=10,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=10,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=11,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=11,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
},
"facing=south,power=11,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=11,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=11,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=11,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
},
"facing=south,power=11,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=11,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=12,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=12,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
},
"facing=south,power=12,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=12,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=12,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=12,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
},
"facing=south,power=12,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=12,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=13,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=13,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
},
"facing=south,power=13,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=13,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=13,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=13,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
},
"facing=south,power=13,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=13,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=14,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=14,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
},
"facing=south,power=14,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=14,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=14,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=14,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
},
"facing=south,power=14,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=14,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=15,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=15,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
},
"facing=south,power=15,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=15,push=false": {
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=15,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=15,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
},
"facing=south,power=15,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=15,push=true": {
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
"y": 270
}
}
}
@@ -0,0 +1,34 @@
{
"variants": {
"facing=east,half=lower": {
"model": "cobblemon:block/oxidized_copper_fridge_bottom",
"y": 90
},
"facing=north,half=lower": {
"model": "cobblemon:block/oxidized_copper_fridge_bottom"
},
"facing=south,half=lower": {
"model": "cobblemon:block/oxidized_copper_fridge_bottom",
"y": 180
},
"facing=west,half=lower": {
"model": "cobblemon:block/oxidized_copper_fridge_bottom",
"y": 270
},
"facing=east,half=upper": {
"model": "cobblemon:block/oxidized_copper_fridge_top",
"y": 90
},
"facing=north,half=upper": {
"model": "cobblemon:block/oxidized_copper_fridge_top"
},
"facing=south,half=upper": {
"model": "cobblemon:block/oxidized_copper_fridge_top",
"y": 180
},
"facing=west,half=upper": {
"model": "cobblemon:block/oxidized_copper_fridge_top",
"y": 270
}
}
}
@@ -0,0 +1,19 @@
{
"variants": {
"facing=east": {
"model": "cobblemon:block/oxidized_copper_mower",
"y": 90
},
"facing=north": {
"model": "cobblemon:block/oxidized_copper_mower"
},
"facing=south": {
"model": "cobblemon:block/oxidized_copper_mower",
"y": 180
},
"facing=west": {
"model": "cobblemon:block/oxidized_copper_mower",
"y": 270
}
}
}
@@ -0,0 +1,64 @@
{
"variants": {
"facing=east,cooking=closed,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_closed",
"y": 90
},
"facing=north,cooking=closed,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_closed"
},
"facing=south,cooking=closed,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_closed",
"y": 180
},
"facing=west,cooking=closed,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_closed",
"y": 270
},
"facing=east,cooking=open,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_open",
"y": 90
},
"facing=north,cooking=open,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_open"
},
"facing=south,cooking=open,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_open",
"y": 180
},
"facing=west,cooking=open,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_open",
"y": 270
},
"facing=east,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_closed",
"y": 90
},
"facing=north,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_closed"
},
"facing=south,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_closed",
"y": 180
},
"facing=west,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/oxidized_copper_oven_closed",
"y": 270
},
"facing=east,ejecting=true": {
"model": "cobblemon:block/oxidized_copper_oven_open",
"y": 90
},
"facing=north,ejecting=true": {
"model": "cobblemon:block/oxidized_copper_oven_open"
},
"facing=south,ejecting=true": {
"model": "cobblemon:block/oxidized_copper_oven_open",
"y": 180
},
"facing=west,ejecting=true": {
"model": "cobblemon:block/oxidized_copper_oven_open",
"y": 270
}
}
}
@@ -0,0 +1,19 @@
{
"variants": {
"facing=east": {
"model": "cobblemon:block/oxidized_copper_washer",
"y": 90
},
"facing=north": {
"model": "cobblemon:block/oxidized_copper_washer"
},
"facing=south": {
"model": "cobblemon:block/oxidized_copper_washer",
"y": 180
},
"facing=west": {
"model": "cobblemon:block/oxidized_copper_washer",
"y": 270
}
}
}
@@ -0,0 +1,484 @@
{
"variants": {
"facing=south,screen=off": {
"model": "cobblemon:block/monitor"
},
"facing=west,screen=off": {
"model": "cobblemon:block/monitor",
"y": 90
},
"facing=north,screen=off": {
"model": "cobblemon:block/monitor",
"y": 180
},
"facing=east,screen=off": {
"model": "cobblemon:block/monitor",
"y": 270
},
"facing=south,screen=blue_progress_1": {
"model": "cobblemon:block/monitor_scanning_0"
},
"facing=west,screen=blue_progress_1": {
"model": "cobblemon:block/monitor_scanning_0",
"y": 90
},
"facing=north,screen=blue_progress_1": {
"model": "cobblemon:block/monitor_scanning_0",
"y": 180
},
"facing=east,screen=blue_progress_1": {
"model": "cobblemon:block/monitor_scanning_0",
"y": 270
},
"facing=south,screen=blue_progress_2": {
"model": "cobblemon:block/monitor_scanning_1"
},
"facing=west,screen=blue_progress_2": {
"model": "cobblemon:block/monitor_scanning_1",
"y": 90
},
"facing=north,screen=blue_progress_2": {
"model": "cobblemon:block/monitor_scanning_1",
"y": 180
},
"facing=east,screen=blue_progress_2": {
"model": "cobblemon:block/monitor_scanning_1",
"y": 270
},
"facing=south,screen=blue_progress_3": {
"model": "cobblemon:block/monitor_scanning_2"
},
"facing=west,screen=blue_progress_3": {
"model": "cobblemon:block/monitor_scanning_2",
"y": 90
},
"facing=north,screen=blue_progress_3": {
"model": "cobblemon:block/monitor_scanning_2",
"y": 180
},
"facing=east,screen=blue_progress_3": {
"model": "cobblemon:block/monitor_scanning_2",
"y": 270
},
"facing=south,screen=blue_progress_4": {
"model": "cobblemon:block/monitor_scanning_3"
},
"facing=west,screen=blue_progress_4": {
"model": "cobblemon:block/monitor_scanning_3",
"y": 90
},
"facing=north,screen=blue_progress_4": {
"model": "cobblemon:block/monitor_scanning_3",
"y": 180
},
"facing=east,screen=blue_progress_4": {
"model": "cobblemon:block/monitor_scanning_3",
"y": 270
},
"facing=south,screen=blue_progress_5": {
"model": "cobblemon:block/monitor_scanning_4"
},
"facing=west,screen=blue_progress_5": {
"model": "cobblemon:block/monitor_scanning_4",
"y": 90
},
"facing=north,screen=blue_progress_5": {
"model": "cobblemon:block/monitor_scanning_4",
"y": 180
},
"facing=east,screen=blue_progress_5": {
"model": "cobblemon:block/monitor_scanning_4",
"y": 270
},
"facing=south,screen=blue_progress_6": {
"model": "cobblemon:block/monitor_scanning_5"
},
"facing=west,screen=blue_progress_6": {
"model": "cobblemon:block/monitor_scanning_5",
"y": 90
},
"facing=north,screen=blue_progress_6": {
"model": "cobblemon:block/monitor_scanning_5",
"y": 180
},
"facing=east,screen=blue_progress_6": {
"model": "cobblemon:block/monitor_scanning_5",
"y": 270
},
"facing=south,screen=blue_progress_7": {
"model": "cobblemon:block/monitor_scanning_6"
},
"facing=west,screen=blue_progress_7": {
"model": "cobblemon:block/monitor_scanning_6",
"y": 90
},
"facing=north,screen=blue_progress_7": {
"model": "cobblemon:block/monitor_scanning_6",
"y": 180
},
"facing=east,screen=blue_progress_7": {
"model": "cobblemon:block/monitor_scanning_6",
"y": 270
},
"facing=south,screen=blue_progress_8": {
"model": "cobblemon:block/monitor_scanning_7"
},
"facing=west,screen=blue_progress_8": {
"model": "cobblemon:block/monitor_scanning_7",
"y": 90
},
"facing=north,screen=blue_progress_8": {
"model": "cobblemon:block/monitor_scanning_7",
"y": 180
},
"facing=east,screen=blue_progress_8": {
"model": "cobblemon:block/monitor_scanning_7",
"y": 270
},
"facing=south,screen=blue_progress_9": {
"model": "cobblemon:block/monitor_scanning_8"
},
"facing=west,screen=blue_progress_9": {
"model": "cobblemon:block/monitor_scanning_8",
"y": 90
},
"facing=north,screen=blue_progress_9": {
"model": "cobblemon:block/monitor_scanning_8",
"y": 180
},
"facing=east,screen=blue_progress_9": {
"model": "cobblemon:block/monitor_scanning_8",
"y": 270
},
"facing=south,screen=green_progress_9": {
"model": "cobblemon:block/monitor_locked"
},
"facing=west,screen=green_progress_9": {
"model": "cobblemon:block/monitor_locked",
"y": 90
},
"facing=north,screen=green_progress_9": {
"model": "cobblemon:block/monitor_locked",
"y": 180
},
"facing=east,screen=green_progress_9": {
"model": "cobblemon:block/monitor_locked",
"y": 270
},
"facing=south,screen=tm_normal": {
"model": "cobblemon:block/monitor_tm_normal"
},
"facing=west,screen=tm_normal": {
"model": "cobblemon:block/monitor_tm_normal",
"y": 90
},
"facing=north,screen=tm_normal": {
"model": "cobblemon:block/monitor_tm_normal",
"y": 180
},
"facing=east,screen=tm_normal": {
"model": "cobblemon:block/monitor_tm_normal",
"y": 270
},
"facing=south,screen=tm_fire": {
"model": "cobblemon:block/monitor_tm_fire"
},
"facing=west,screen=tm_fire": {
"model": "cobblemon:block/monitor_tm_fire",
"y": 90
},
"facing=north,screen=tm_fire": {
"model": "cobblemon:block/monitor_tm_fire",
"y": 180
},
"facing=east,screen=tm_fire": {
"model": "cobblemon:block/monitor_tm_fire",
"y": 270
},
"facing=south,screen=tm_water": {
"model": "cobblemon:block/monitor_tm_water"
},
"facing=west,screen=tm_water": {
"model": "cobblemon:block/monitor_tm_water",
"y": 90
},
"facing=north,screen=tm_water": {
"model": "cobblemon:block/monitor_tm_water",
"y": 180
},
"facing=east,screen=tm_water": {
"model": "cobblemon:block/monitor_tm_water",
"y": 270
},
"facing=south,screen=tm_grass": {
"model": "cobblemon:block/monitor_tm_grass"
},
"facing=west,screen=tm_grass": {
"model": "cobblemon:block/monitor_tm_grass",
"y": 90
},
"facing=north,screen=tm_grass": {
"model": "cobblemon:block/monitor_tm_grass",
"y": 180
},
"facing=east,screen=tm_grass": {
"model": "cobblemon:block/monitor_tm_grass",
"y": 270
},
"facing=south,screen=tm_electric": {
"model": "cobblemon:block/monitor_tm_electric"
},
"facing=west,screen=tm_electric": {
"model": "cobblemon:block/monitor_tm_electric",
"y": 90
},
"facing=north,screen=tm_electric": {
"model": "cobblemon:block/monitor_tm_electric",
"y": 180
},
"facing=east,screen=tm_electric": {
"model": "cobblemon:block/monitor_tm_electric",
"y": 270
},
"facing=south,screen=tm_ice": {
"model": "cobblemon:block/monitor_tm_ice"
},
"facing=west,screen=tm_ice": {
"model": "cobblemon:block/monitor_tm_ice",
"y": 90
},
"facing=north,screen=tm_ice": {
"model": "cobblemon:block/monitor_tm_ice",
"y": 180
},
"facing=east,screen=tm_ice": {
"model": "cobblemon:block/monitor_tm_ice",
"y": 270
},
"facing=south,screen=tm_fighting": {
"model": "cobblemon:block/monitor_tm_fighting"
},
"facing=west,screen=tm_fighting": {
"model": "cobblemon:block/monitor_tm_fighting",
"y": 90
},
"facing=north,screen=tm_fighting": {
"model": "cobblemon:block/monitor_tm_fighting",
"y": 180
},
"facing=east,screen=tm_fighting": {
"model": "cobblemon:block/monitor_tm_fighting",
"y": 270
},
"facing=south,screen=tm_poison": {
"model": "cobblemon:block/monitor_tm_poison"
},
"facing=west,screen=tm_poison": {
"model": "cobblemon:block/monitor_tm_poison",
"y": 90
},
"facing=north,screen=tm_poison": {
"model": "cobblemon:block/monitor_tm_poison",
"y": 180
},
"facing=east,screen=tm_poison": {
"model": "cobblemon:block/monitor_tm_poison",
"y": 270
},
"facing=south,screen=tm_ground": {
"model": "cobblemon:block/monitor_tm_ground"
},
"facing=west,screen=tm_ground": {
"model": "cobblemon:block/monitor_tm_ground",
"y": 90
},
"facing=north,screen=tm_ground": {
"model": "cobblemon:block/monitor_tm_ground",
"y": 180
},
"facing=east,screen=tm_ground": {
"model": "cobblemon:block/monitor_tm_ground",
"y": 270
},
"facing=south,screen=tm_flying": {
"model": "cobblemon:block/monitor_tm_flying"
},
"facing=west,screen=tm_flying": {
"model": "cobblemon:block/monitor_tm_flying",
"y": 90
},
"facing=north,screen=tm_flying": {
"model": "cobblemon:block/monitor_tm_flying",
"y": 180
},
"facing=east,screen=tm_flying": {
"model": "cobblemon:block/monitor_tm_flying",
"y": 270
},
"facing=south,screen=tm_psychic": {
"model": "cobblemon:block/monitor_tm_psychic"
},
"facing=west,screen=tm_psychic": {
"model": "cobblemon:block/monitor_tm_psychic",
"y": 90
},
"facing=north,screen=tm_psychic": {
"model": "cobblemon:block/monitor_tm_psychic",
"y": 180
},
"facing=east,screen=tm_psychic": {
"model": "cobblemon:block/monitor_tm_psychic",
"y": 270
},
"facing=south,screen=tm_bug": {
"model": "cobblemon:block/monitor_tm_bug"
},
"facing=west,screen=tm_bug": {
"model": "cobblemon:block/monitor_tm_bug",
"y": 90
},
"facing=north,screen=tm_bug": {
"model": "cobblemon:block/monitor_tm_bug",
"y": 180
},
"facing=east,screen=tm_bug": {
"model": "cobblemon:block/monitor_tm_bug",
"y": 270
},
"facing=south,screen=tm_rock": {
"model": "cobblemon:block/monitor_tm_rock"
},
"facing=west,screen=tm_rock": {
"model": "cobblemon:block/monitor_tm_rock",
"y": 90
},
"facing=north,screen=tm_rock": {
"model": "cobblemon:block/monitor_tm_rock",
"y": 180
},
"facing=east,screen=tm_rock": {
"model": "cobblemon:block/monitor_tm_rock",
"y": 270
},
"facing=south,screen=tm_ghost": {
"model": "cobblemon:block/monitor_tm_ghost"
},
"facing=west,screen=tm_ghost": {
"model": "cobblemon:block/monitor_tm_ghost",
"y": 90
},
"facing=north,screen=tm_ghost": {
"model": "cobblemon:block/monitor_tm_ghost",
"y": 180
},
"facing=east,screen=tm_ghost": {
"model": "cobblemon:block/monitor_tm_ghost",
"y": 270
},
"facing=south,screen=tm_dragon": {
"model": "cobblemon:block/monitor_tm_dragon"
},
"facing=west,screen=tm_dragon": {
"model": "cobblemon:block/monitor_tm_dragon",
"y": 90
},
"facing=north,screen=tm_dragon": {
"model": "cobblemon:block/monitor_tm_dragon",
"y": 180
},
"facing=east,screen=tm_dragon": {
"model": "cobblemon:block/monitor_tm_dragon",
"y": 270
},
"facing=south,screen=tm_dark": {
"model": "cobblemon:block/monitor_tm_dark"
},
"facing=west,screen=tm_dark": {
"model": "cobblemon:block/monitor_tm_dark",
"y": 90
},
"facing=north,screen=tm_dark": {
"model": "cobblemon:block/monitor_tm_dark",
"y": 180
},
"facing=east,screen=tm_dark": {
"model": "cobblemon:block/monitor_tm_dark",
"y": 270
},
"facing=south,screen=tm_steel": {
"model": "cobblemon:block/monitor_tm_steel"
},
"facing=west,screen=tm_steel": {
"model": "cobblemon:block/monitor_tm_steel",
"y": 90
},
"facing=north,screen=tm_steel": {
"model": "cobblemon:block/monitor_tm_steel",
"y": 180
},
"facing=east,screen=tm_steel": {
"model": "cobblemon:block/monitor_tm_steel",
"y": 270
},
"facing=south,screen=tm_fairy": {
"model": "cobblemon:block/monitor_tm_fairy"
},
"facing=west,screen=tm_fairy": {
"model": "cobblemon:block/monitor_tm_fairy",
"y": 90
},
"facing=north,screen=tm_fairy": {
"model": "cobblemon:block/monitor_tm_fairy",
"y": 180
},
"facing=east,screen=tm_fairy": {
"model": "cobblemon:block/monitor_tm_fairy",
"y": 270
},
"facing=south,screen=music": {
"model": "cobblemon:block/monitor_music"
},
"facing=west,screen=music": {
"model": "cobblemon:block/monitor_music",
"y": 90
},
"facing=north,screen=music": {
"model": "cobblemon:block/monitor_music",
"y": 180
},
"facing=east,screen=music": {
"model": "cobblemon:block/monitor_music",
"y": 270
},
"facing=south,screen=porygon_grid": {
"model": "cobblemon:block/monitor_grid"
},
"facing=west,screen=porygon_grid": {
"model": "cobblemon:block/monitor_grid",
"y": 90
},
"facing=north,screen=porygon_grid": {
"model": "cobblemon:block/monitor_grid",
"y": 180
},
"facing=east,screen=porygon_grid": {
"model": "cobblemon:block/monitor_grid",
"y": 270
},
"facing=south,screen=porygon_glitching": {
"model": "cobblemon:block/monitor_glitching"
},
"facing=west,screen=porygon_glitching": {
"model": "cobblemon:block/monitor_glitching",
"y": 90
},
"facing=north,screen=porygon_glitching": {
"model": "cobblemon:block/monitor_glitching",
"y": 180
},
"facing=east,screen=porygon_glitching": {
"model": "cobblemon:block/monitor_glitching",
"y": 270
}
}
}
@@ -0,0 +1,469 @@
{
"variants": {
"facing=east,power=0": {
"model": "cobblemon:block/copper_fan_unpowered",
"y": 90
},
"facing=north,power=0": {
"model": "cobblemon:block/copper_fan_unpowered"
},
"facing=south,power=0": {
"model": "cobblemon:block/copper_fan_unpowered",
"y": 180
},
"facing=west,power=0": {
"model": "cobblemon:block/copper_fan_unpowered",
"y": 270
},
"facing=east,power=1,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=1,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=1,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=1,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=1,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=1,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=1,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=1,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=2,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=2,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=2,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=2,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=2,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=2,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=2,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=2,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=3,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=3,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=3,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=3,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=3,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=3,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=3,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=3,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=4,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=4,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=4,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=4,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=4,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=4,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=4,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=4,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=5,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=5,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=5,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=5,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=5,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=5,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=5,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=5,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=6,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=6,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=6,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=6,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=6,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=6,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=6,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=6,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=7,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 90
},
"facing=north,power=7,push=false": {
"model": "cobblemon:block/copper_fan_decorative"
},
"facing=south,power=7,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 180
},
"facing=west,power=7,push=false": {
"model": "cobblemon:block/copper_fan_decorative",
"y": 270
},
"facing=east,power=7,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 90
},
"facing=north,power=7,push=true": {
"model": "cobblemon:block/copper_fan_pushing"
},
"facing=south,power=7,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 180
},
"facing=west,power=7,push=true": {
"model": "cobblemon:block/copper_fan_pushing",
"y": 270
},
"facing=east,power=8,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=8,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=8,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=8,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=8,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=8,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=8,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=8,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=9,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=9,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=9,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=9,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=9,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=9,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=9,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=9,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=10,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=10,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=10,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=10,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=10,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=10,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=10,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=10,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=11,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=11,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=11,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=11,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=11,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=11,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=11,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=11,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=12,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=12,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=12,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=12,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=12,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=12,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=12,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=12,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=13,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=13,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=13,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=13,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=13,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=13,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=13,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=13,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=14,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=14,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=14,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=14,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=14,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=14,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=14,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=14,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
},
"facing=east,power=15,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 90
},
"facing=north,power=15,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong"
},
"facing=south,power=15,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 180
},
"facing=west,power=15,push=false": {
"model": "cobblemon:block/copper_fan_decorative_strong",
"y": 270
},
"facing=east,power=15,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 90
},
"facing=north,power=15,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong"
},
"facing=south,power=15,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 180
},
"facing=west,power=15,push=true": {
"model": "cobblemon:block/copper_fan_pushing_strong",
"y": 270
}
}
}
@@ -0,0 +1,34 @@
{
"variants": {
"facing=east,half=lower": {
"model": "cobblemon:block/copper_fridge_bottom",
"y": 90
},
"facing=north,half=lower": {
"model": "cobblemon:block/copper_fridge_bottom"
},
"facing=south,half=lower": {
"model": "cobblemon:block/copper_fridge_bottom",
"y": 180
},
"facing=west,half=lower": {
"model": "cobblemon:block/copper_fridge_bottom",
"y": 270
},
"facing=east,half=upper": {
"model": "cobblemon:block/copper_fridge_top",
"y": 90
},
"facing=north,half=upper": {
"model": "cobblemon:block/copper_fridge_top"
},
"facing=south,half=upper": {
"model": "cobblemon:block/copper_fridge_top",
"y": 180
},
"facing=west,half=upper": {
"model": "cobblemon:block/copper_fridge_top",
"y": 270
}
}
}
@@ -0,0 +1,19 @@
{
"variants": {
"facing=east": {
"model": "cobblemon:block/copper_mower",
"y": 90
},
"facing=north": {
"model": "cobblemon:block/copper_mower"
},
"facing=south": {
"model": "cobblemon:block/copper_mower",
"y": 180
},
"facing=west": {
"model": "cobblemon:block/copper_mower",
"y": 270
}
}
}
@@ -0,0 +1,64 @@
{
"variants": {
"facing=east,cooking=closed,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 90
},
"facing=north,cooking=closed,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed"
},
"facing=south,cooking=closed,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 180
},
"facing=west,cooking=closed,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 270
},
"facing=east,cooking=open,ejecting=false": {
"model": "cobblemon:block/copper_oven_open",
"y": 90
},
"facing=north,cooking=open,ejecting=false": {
"model": "cobblemon:block/copper_oven_open"
},
"facing=south,cooking=open,ejecting=false": {
"model": "cobblemon:block/copper_oven_open",
"y": 180
},
"facing=west,cooking=open,ejecting=false": {
"model": "cobblemon:block/copper_oven_open",
"y": 270
},
"facing=east,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 90
},
"facing=north,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed"
},
"facing=south,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 180
},
"facing=west,cooking=cooking,ejecting=false": {
"model": "cobblemon:block/copper_oven_closed",
"y": 270
},
"facing=east,ejecting=true": {
"model": "cobblemon:block/copper_oven_open",
"y": 90
},
"facing=north,ejecting=true": {
"model": "cobblemon:block/copper_oven_open"
},
"facing=south,ejecting=true": {
"model": "cobblemon:block/copper_oven_open",
"y": 180
},
"facing=west,ejecting=true": {
"model": "cobblemon:block/copper_oven_open",
"y": 270
}
}
}
@@ -0,0 +1,19 @@
{
"variants": {
"facing=east": {
"model": "cobblemon:block/copper_washer",
"y": 90
},
"facing=north": {
"model": "cobblemon:block/copper_washer"
},
"facing=south": {
"model": "cobblemon:block/copper_washer",
"y": 180
},
"facing=west": {
"model": "cobblemon:block/copper_washer",
"y": 270
}
}
}
Loaded 100 of 939 files, more files were not shown because too many files have changed in this diff. Show more