Merge branch 'flora-heals-an-aching-soul-' into 'main'

Flora Update

See merge request cable-mc/cobblemon!2412
This commit is contained in:
Polymeta
2026-10-04 00:02:50 +00:00
528 changed files with 17690 additions and 38 deletions
+8
View File
@@ -13,6 +13,10 @@
- Galarica Wreath, Cleanse Tag, Spell Tag, Sharp Beak, Covert Cloak, Shell Helmet, and Never-Melt Ice.
- Wearable items can now be equipped by a player by holding it and right-clicking (or rebound use/interact)
- Wearable items that can be placed down are exempt from this behaviour.
- Mint Leaves can now be placed on the ground as Leaf Litter, or in Flower Pots
- Added Oricorio Flowers
- Added Terrain Plants
- Berries can now be placed in Flower Pots
- The evolution tree can now be viewed on the Pokédex, showing a Pokémon's full family line and what's needed to evolve into each stage.
- Added custom sounds to a bunch of items that can be placed as blocks: liquid bottles, pill bottles, powders and dice.
@@ -81,6 +85,10 @@
- Bellossom
### Changes
- Terrain Seeds can now be planted
- Terrain Seeds are now consumed during PvP and NPC battles
- Glow Item Frames can be crafted using Bright Powder as an alternative to Glow Ink Sacs
- Bright Powder can be used on Signs and Hanging Signs to make text glow, as an alternative to Glow Ink Sacs
- Updated various recipes to display in Recipe Groups within the Recipe Book
- Updated most recipes to display more logically/consistently within the Recipe Book's categories
- Make ride rotations less jittery in multiplayer.
@@ -109,4 +109,21 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
"poke_snack",
BlockEntityType.Builder.of(::PokeSnackBlockEntity, CobblemonBlocks.POKE_SNACK, CobblemonBlocks.POKE_CAKE).build(null)
)
@JvmField
val TERRAIN_PLANT: BlockEntityType<TerrainPlantBlockEntity> = this.create(
"terrain_plant",
BlockEntityType.Builder.of(::TerrainPlantBlockEntity,
CobblemonBlocks.VOLTACONIA,
CobblemonBlocks.LUCIBELL,
CobblemonBlocks.VERDROOT
).build(null)
)
@JvmField
val MISTLEAF_FLOWER: BlockEntityType<MistleafFlowerBlockEntity> = this.create(
"mistleaf",
BlockEntityType.Builder.of(::MistleafFlowerBlockEntity,
CobblemonBlocks.MISTLEAF
).build(null)
)
}
@@ -16,8 +16,7 @@ import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.block.campfirepot.CampfireBlock
import com.cobblemon.mod.common.block.campfirepot.CampfirePotBlock
import com.cobblemon.mod.common.block.chest.GildedChestBlock
import com.cobblemon.mod.common.block.decor.ActivatableDecorationBlock
import com.cobblemon.mod.common.block.decor.RingTargetBlock
import com.cobblemon.mod.common.block.decor.*
import com.cobblemon.mod.common.block.general.BaleBlock
import com.cobblemon.mod.common.block.general.HorizontalRotationCarpetBlock
import com.cobblemon.mod.common.block.general.HorizontalRotationalBlock
@@ -28,6 +27,7 @@ import com.cobblemon.mod.common.block.sign.CobblemonSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
import com.cobblemon.mod.common.block.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
@@ -857,6 +857,64 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val POTTED_SACCHARINE_SAPLING = this.create("potted_saccharine_sapling", BlocksInvoker.createFlowerPotBlock(SACCHARINE_SAPLING))
@JvmField
val RED_MINT_LEAF_LITTER = this.mintLitter("red_mint_leaf_litter", MapColor.COLOR_RED)
@JvmField
val POTTED_RED_MINT = this.pottedPlant("potted_red_mint", RED_MINT_LEAF_LITTER)
@JvmField
val BLUE_MINT_LEAF_LITTER = this.mintLitter("blue_mint_leaf_litter", MapColor.COLOR_BLUE)
@JvmField
val POTTED_BLUE_MINT = this.pottedPlant("potted_blue_mint", BLUE_MINT_LEAF_LITTER)
@JvmField
val CYAN_MINT_LEAF_LITTER = this.mintLitter("cyan_mint_leaf_litter", MapColor.COLOR_CYAN)
@JvmField
val POTTED_CYAN_MINT = this.pottedPlant("potted_cyan_mint", CYAN_MINT_LEAF_LITTER)
@JvmField
val PINK_MINT_LEAF_LITTER = this.mintLitter("pink_mint_leaf_litter", MapColor.COLOR_PINK)
@JvmField
val POTTED_PINK_MINT = this.pottedPlant("potted_pink_mint", PINK_MINT_LEAF_LITTER)
@JvmField
val GREEN_MINT_LEAF_LITTER = this.mintLitter("green_mint_leaf_litter", MapColor.COLOR_GREEN)
@JvmField
val POTTED_GREEN_MINT = this.pottedPlant("potted_green_mint", GREEN_MINT_LEAF_LITTER)
@JvmField
val WHITE_MINT_LEAF_LITTER = this.mintLitter("white_mint_leaf_litter", MapColor.SNOW)
@JvmField
val POTTED_WHITE_MINT = this.pottedPlant("potted_white_mint", WHITE_MINT_LEAF_LITTER)
@JvmField
val LOBAILA = this.create("lobaila", LobailaFlowerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().instabreak().sound(SoundType.GRASS).offsetType(BlockBehaviour.OffsetType.XZ).ignitedByLava().pushReaction(PushReaction.DESTROY)))
@JvmField
val POMOHANA = this.create("pomohana", PomohanaFlowerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().instabreak().sound(SoundType.GRASS).ignitedByLava().pushReaction(PushReaction.DESTROY)))
@JvmField
val PAUVILLEA = this.create("pauvillea",PauvilleaFlowerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().sound(SoundType.GRASS).instabreak().ignitedByLava().pushReaction(PushReaction.DESTROY)))
@JvmField
val WISTENSU = this.create("wistensu", WistensuFlowerHeadBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().sound(SoundType.GRASS).instabreak().ignitedByLava().pushReaction(PushReaction.DESTROY).lightLevel{11}))
@JvmField
val WISTENSU_VINE = this.create("wistensu_vine", WistensuFlowerVineBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().sound(SoundType.GRASS).instabreak().ignitedByLava().pushReaction(PushReaction.DESTROY)))
@JvmField
val ELECTRIC_SEED = this.terrainSeed("electric_seed", TerrainSeedBlock.TerrainSeedType.ELECTRIC)
@JvmField
val PSYCHIC_SEED = this.terrainSeed("psychic_seed", TerrainSeedBlock.TerrainSeedType.PSYCHIC)
@JvmField
val MISTY_SEED = this.terrainSeed("misty_seed", TerrainSeedBlock.TerrainSeedType.MISTY)
@JvmField
val GRASSY_SEED = this.terrainSeed("grassy_seed", TerrainSeedBlock.TerrainSeedType.GRASSY)
@JvmField
val VOLTACONIA = this.terrainPlant("voltaconia") { state -> if (state.getValue(TerrainPlantBlock.GLOWING)) 8 else 0 }
@JvmField
val VERDROOT = this.terrainPlant("verdroot") { state -> if (state.getValue(TerrainPlantBlock.GLOWING)) 5 else 0 }
@JvmField
val LUCIBELL = this.terrainPlant("lucibell") { state -> if (state.getValue(TerrainPlantBlock.GLOWING)) 8 else 0 }
@JvmField
val MISTLEAF = this.create(
"mistleaf",
MistleafFlowerBlock {
if ((it.getValue(MistleafFlowerBlock.GLOWING) >= 1)) it.getValue(MistleafFlowerBlock.GLOWING) + 2 else 0
}
)
@JvmField
val HEARTY_GRAIN_BALE = this.create("hearty_grain_bale", BaleBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).instrument(NoteBlockInstrument.BANJO).strength(0.5F).sound(CobblemonSounds.HEARTY_GRAIN_BALE_SOUNDS)))
@JvmField
@@ -1033,6 +1091,147 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val YACHE_BERRY = this.berryBlock("yache")
//val BINDING_SOIL = this.create("binding_soil", BindingSoilBlock(BlockBehaviour.Properties.of()))
@JvmField
val POTTED_AGUAV_BERRY = this.create("potted_aguav_berry", BlocksInvoker.createFlowerPotBlock(AGUAV_BERRY))
@JvmField
val POTTED_APICOT_BERRY = this.create("potted_apicot_berry", BlocksInvoker.createFlowerPotBlock(APICOT_BERRY))
@JvmField
val POTTED_ASPEAR_BERRY = this.create("potted_aspear_berry", BlocksInvoker.createFlowerPotBlock(ASPEAR_BERRY))
@JvmField
val POTTED_BABIRI_BERRY = this.create("potted_babiri_berry", BlocksInvoker.createFlowerPotBlock(BABIRI_BERRY))
@JvmField
val POTTED_BELUE_BERRY = this.create("potted_belue_berry", BlocksInvoker.createFlowerPotBlock(BELUE_BERRY))
@JvmField
val POTTED_BLUK_BERRY = this.create("potted_bluk_berry", BlocksInvoker.createFlowerPotBlock(BLUK_BERRY))
@JvmField
val POTTED_CHARTI_BERRY = this.create("potted_charti_berry", BlocksInvoker.createFlowerPotBlock(CHARTI_BERRY))
@JvmField
val POTTED_CHERI_BERRY = this.create("potted_cheri_berry", BlocksInvoker.createFlowerPotBlock(CHERI_BERRY))
@JvmField
val POTTED_CHESTO_BERRY = this.create("potted_chesto_berry", BlocksInvoker.createFlowerPotBlock(CHESTO_BERRY))
@JvmField
val POTTED_CHILAN_BERRY = this.create("potted_chilan_berry", BlocksInvoker.createFlowerPotBlock(CHILAN_BERRY))
@JvmField
val POTTED_CHOPLE_BERRY = this.create("potted_chople_berry", BlocksInvoker.createFlowerPotBlock(CHOPLE_BERRY))
@JvmField
val POTTED_COBA_BERRY = this.create("potted_coba_berry", BlocksInvoker.createFlowerPotBlock(COBA_BERRY))
@JvmField
val POTTED_COLBUR_BERRY = this.create("potted_colbur_berry", BlocksInvoker.createFlowerPotBlock(COLBUR_BERRY))
@JvmField
val POTTED_CORNN_BERRY = this.create("potted_cornn_berry", BlocksInvoker.createFlowerPotBlock(CORNN_BERRY))
@JvmField
val POTTED_CUSTAP_BERRY = this.create("potted_custap_berry", BlocksInvoker.createFlowerPotBlock(CUSTAP_BERRY))
@JvmField
val POTTED_DURIN_BERRY = this.create("potted_durin_berry", BlocksInvoker.createFlowerPotBlock(DURIN_BERRY))
@JvmField
val POTTED_EGGANT_BERRY = this.create("potted_eggant_berry", BlocksInvoker.createFlowerPotBlock(EGGANT_BERRY))
@JvmField
val POTTED_ENIGMA_BERRY = this.create("potted_enigma_berry", BlocksInvoker.createFlowerPotBlock(ENIGMA_BERRY))
@JvmField
val POTTED_FIGY_BERRY = this.create("potted_figy_berry", BlocksInvoker.createFlowerPotBlock(FIGY_BERRY))
@JvmField
val POTTED_GANLON_BERRY = this.create("potted_ganlon_berry", BlocksInvoker.createFlowerPotBlock(GANLON_BERRY))
@JvmField
val POTTED_GREPA_BERRY = this.create("potted_grepa_berry", BlocksInvoker.createFlowerPotBlock(GREPA_BERRY))
@JvmField
val POTTED_HABAN_BERRY = this.create("potted_haban_berry", BlocksInvoker.createFlowerPotBlock(HABAN_BERRY))
@JvmField
val POTTED_HONDEW_BERRY = this.create("potted_hondew_berry", BlocksInvoker.createFlowerPotBlock(HONDEW_BERRY))
@JvmField
val POTTED_HOPO_BERRY = this.create("potted_hopo_berry", BlocksInvoker.createFlowerPotBlock(HOPO_BERRY))
@JvmField
val POTTED_IAPAPA_BERRY = this.create("potted_iapapa_berry", BlocksInvoker.createFlowerPotBlock(IAPAPA_BERRY))
@JvmField
val POTTED_JABOCA_BERRY = this.create("potted_jaboca_berry", BlocksInvoker.createFlowerPotBlock(JABOCA_BERRY))
@JvmField
val POTTED_KASIB_BERRY = this.create("potted_kasib_berry", BlocksInvoker.createFlowerPotBlock(KASIB_BERRY))
@JvmField
val POTTED_KEBIA_BERRY = this.create("potted_kebia_berry", BlocksInvoker.createFlowerPotBlock(KEBIA_BERRY))
@JvmField
val POTTED_KEE_BERRY = this.create("potted_kee_berry", BlocksInvoker.createFlowerPotBlock(KEE_BERRY))
@JvmField
val POTTED_KELPSY_BERRY = this.create("potted_kelpsy_berry", BlocksInvoker.createFlowerPotBlock(KELPSY_BERRY))
@JvmField
val POTTED_LANSAT_BERRY = this.create("potted_lansat_berry", BlocksInvoker.createFlowerPotBlock(LANSAT_BERRY))
@JvmField
val POTTED_LEPPA_BERRY = this.create("potted_leppa_berry", BlocksInvoker.createFlowerPotBlock(LEPPA_BERRY))
@JvmField
val POTTED_LIECHI_BERRY = this.create("potted_liechi_berry", BlocksInvoker.createFlowerPotBlock(LIECHI_BERRY))
@JvmField
val POTTED_LUM_BERRY = this.create("potted_lum_berry", BlocksInvoker.createFlowerPotBlock(LUM_BERRY))
@JvmField
val POTTED_MAGO_BERRY = this.create("potted_mago_berry", BlocksInvoker.createFlowerPotBlock(MAGO_BERRY))
@JvmField
val POTTED_MAGOST_BERRY = this.create("potted_magost_berry", BlocksInvoker.createFlowerPotBlock(MAGOST_BERRY))
@JvmField
val POTTED_MARANGA_BERRY = this.create("potted_maranga_berry", BlocksInvoker.createFlowerPotBlock(MARANGA_BERRY))
@JvmField
val POTTED_MICLE_BERRY = this.create("potted_micle_berry", BlocksInvoker.createFlowerPotBlock(MICLE_BERRY))
@JvmField
val POTTED_NANAB_BERRY = this.create("potted_nanab_berry", BlocksInvoker.createFlowerPotBlock(NANAB_BERRY))
@JvmField
val POTTED_NOMEL_BERRY = this.create("potted_nomel_berry", BlocksInvoker.createFlowerPotBlock(NOMEL_BERRY))
@JvmField
val POTTED_OCCA_BERRY = this.create("potted_occa_berry", BlocksInvoker.createFlowerPotBlock(OCCA_BERRY))
@JvmField
val POTTED_ORAN_BERRY = this.create("potted_oran_berry", BlocksInvoker.createFlowerPotBlock(ORAN_BERRY))
@JvmField
val POTTED_PAMTRE_BERRY = this.create("potted_pamtre_berry", BlocksInvoker.createFlowerPotBlock(PAMTRE_BERRY))
@JvmField
val POTTED_PASSHO_BERRY = this.create("potted_passho_berry", BlocksInvoker.createFlowerPotBlock(PASSHO_BERRY))
@JvmField
val POTTED_PAYAPA_BERRY = this.create("potted_payapa_berry", BlocksInvoker.createFlowerPotBlock(PAYAPA_BERRY))
@JvmField
val POTTED_PECHA_BERRY = this.create("potted_pecha_berry", BlocksInvoker.createFlowerPotBlock(PECHA_BERRY))
@JvmField
val POTTED_PERSIM_BERRY = this.create("potted_persim_berry", BlocksInvoker.createFlowerPotBlock(PERSIM_BERRY))
@JvmField
val POTTED_PETAYA_BERRY = this.create("potted_petaya_berry", BlocksInvoker.createFlowerPotBlock(PETAYA_BERRY))
@JvmField
val POTTED_PINAP_BERRY = this.create("potted_pinap_berry", BlocksInvoker.createFlowerPotBlock(PINAP_BERRY))
@JvmField
val POTTED_POMEG_BERRY = this.create("potted_pomeg_berry", BlocksInvoker.createFlowerPotBlock(POMEG_BERRY))
@JvmField
val POTTED_QUALOT_BERRY = this.create("potted_qualot_berry", BlocksInvoker.createFlowerPotBlock(QUALOT_BERRY))
@JvmField
val POTTED_RABUTA_BERRY = this.create("potted_rabuta_berry", BlocksInvoker.createFlowerPotBlock(RABUTA_BERRY))
@JvmField
val POTTED_RAWST_BERRY = this.create("potted_rawst_berry", BlocksInvoker.createFlowerPotBlock(RAWST_BERRY))
@JvmField
val POTTED_RAZZ_BERRY = this.create("potted_razz_berry", BlocksInvoker.createFlowerPotBlock(RAZZ_BERRY))
@JvmField
val POTTED_RINDO_BERRY = this.create("potted_rindo_berry", BlocksInvoker.createFlowerPotBlock(RINDO_BERRY))
@JvmField
val POTTED_ROSELI_BERRY = this.create("potted_roseli_berry", BlocksInvoker.createFlowerPotBlock(ROSELI_BERRY))
@JvmField
val POTTED_ROWAP_BERRY = this.create("potted_rowap_berry", BlocksInvoker.createFlowerPotBlock(ROWAP_BERRY))
@JvmField
val POTTED_SALAC_BERRY = this.create("potted_salac_berry", BlocksInvoker.createFlowerPotBlock(SALAC_BERRY))
@JvmField
val POTTED_SHUCA_BERRY = this.create("potted_shuca_berry", BlocksInvoker.createFlowerPotBlock(SHUCA_BERRY))
@JvmField
val POTTED_SITRUS_BERRY = this.create("potted_sitrus_berry", BlocksInvoker.createFlowerPotBlock(SITRUS_BERRY))
@JvmField
val POTTED_SPELON_BERRY = this.create("potted_spelon_berry", BlocksInvoker.createFlowerPotBlock(SPELON_BERRY))
@JvmField
val POTTED_STARF_BERRY = this.create("potted_starf_berry", BlocksInvoker.createFlowerPotBlock(STARF_BERRY))
@JvmField
val POTTED_TAMATO_BERRY = this.create("potted_tamato_berry", BlocksInvoker.createFlowerPotBlock(TAMATO_BERRY))
@JvmField
val POTTED_TANGA_BERRY = this.create("potted_tanga_berry", BlocksInvoker.createFlowerPotBlock(TANGA_BERRY))
@JvmField
val POTTED_TOUGA_BERRY = this.create("potted_touga_berry", BlocksInvoker.createFlowerPotBlock(TOUGA_BERRY))
@JvmField
val POTTED_WACAN_BERRY = this.create("potted_wacan_berry", BlocksInvoker.createFlowerPotBlock(WACAN_BERRY))
@JvmField
val POTTED_WATMEL_BERRY = this.create("potted_watmel_berry", BlocksInvoker.createFlowerPotBlock(WATMEL_BERRY))
@JvmField
val POTTED_WEPEAR_BERRY = this.create("potted_wepear_berry", BlocksInvoker.createFlowerPotBlock(WEPEAR_BERRY))
@JvmField
val POTTED_WIKI_BERRY = this.create("potted_wiki_berry", BlocksInvoker.createFlowerPotBlock(WIKI_BERRY))
@JvmField
val POTTED_YACHE_BERRY = this.create("potted_yache_berry", BlocksInvoker.createFlowerPotBlock(YACHE_BERRY))
init {
/**
* Makes all blocks in array flammable by adding them to FireBlock's flammableRegistry.
@@ -1134,4 +1333,48 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
}
fun typeGemClusters() = typeGemClusters.toMap()
private fun pottedPlant(name: String, flower: Block) = this.create(name, BlocksInvoker.createFlowerPotBlock(flower))
private fun mintLitter(name: String, color: MapColor) = this.create(
name,
MintLitterBlock(
BlockBehaviour.Properties.of()
.sound(CobblemonSounds.MINT_SOUNDS)
.mapColor(color)
.noOcclusion()
.noCollission()
.pushReaction(PushReaction.DESTROY)
)
)
private fun terrainSeed(name: String, type: TerrainSeedBlock.TerrainSeedType) = this.create(
name,
TerrainSeedBlock(
type,
BlockBehaviour.Properties.of()
.pushReaction(PushReaction.DESTROY)
.ignitedByLava()
.mapColor(MapColor.PLANT)
.offsetType(BlockBehaviour.OffsetType.XZ)
.noCollission()
.randomTicks()
.instabreak()
)
)
private fun terrainPlant(name: String, lightLevel: (BlockState) -> Int) = this.create(
name,
TerrainPlantBlock(
BlockBehaviour.Properties.of()
.mapColor(MapColor.PLANT)
.noCollission()
.instabreak()
.sound(SoundType.GRASS)
.offsetType(BlockBehaviour.OffsetType.XZ)
.ignitedByLava()
.pushReaction(PushReaction.DESTROY)
.lightLevel(lightLevel)
)
)
}
@@ -748,27 +748,27 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val RED_MINT_SEEDS = mintSeed("red", MintType.RED.getCropBlock())
@JvmField
val RED_MINT_LEAF = mintLeaf("red", MintLeafItem(MintType.RED))
val RED_MINT_LEAF = compostableItemNameBlockItem("red_mint_leaf", CobblemonBlocks.RED_MINT_LEAF_LITTER, 0.50f)
@JvmField
val BLUE_MINT_SEEDS = mintSeed("blue", MintType.BLUE.getCropBlock())
@JvmField
val BLUE_MINT_LEAF = mintLeaf("blue", MintLeafItem(MintType.BLUE))
val BLUE_MINT_LEAF = compostableItemNameBlockItem("blue_mint_leaf", CobblemonBlocks.BLUE_MINT_LEAF_LITTER, 0.50f)
@JvmField
val CYAN_MINT_SEEDS = mintSeed("cyan", MintType.CYAN.getCropBlock())
@JvmField
val CYAN_MINT_LEAF = mintLeaf("cyan", MintLeafItem(MintType.CYAN))
val CYAN_MINT_LEAF = compostableItemNameBlockItem("cyan_mint_leaf", CobblemonBlocks.CYAN_MINT_LEAF_LITTER, 0.50f)
@JvmField
val PINK_MINT_SEEDS = mintSeed("pink", MintType.PINK.getCropBlock())
@JvmField
val PINK_MINT_LEAF = mintLeaf("pink", MintLeafItem(MintType.PINK))
val PINK_MINT_LEAF = compostableItemNameBlockItem("pink_mint_leaf", CobblemonBlocks.PINK_MINT_LEAF_LITTER, 0.50f)
@JvmField
val GREEN_MINT_SEEDS = mintSeed("green", MintType.GREEN.getCropBlock())
@JvmField
val GREEN_MINT_LEAF = mintLeaf("green", MintLeafItem(MintType.GREEN))
val GREEN_MINT_LEAF = compostableItemNameBlockItem("green_mint_leaf", CobblemonBlocks.GREEN_MINT_LEAF_LITTER, 0.50f)
@JvmField
val WHITE_MINT_SEEDS = mintSeed("white", MintType.WHITE.getCropBlock())
@JvmField
val WHITE_MINT_LEAF = mintLeaf("white", MintLeafItem(MintType.WHITE))
val WHITE_MINT_LEAF = compostableItemNameBlockItem("white_mint_leaf", CobblemonBlocks.WHITE_MINT_LEAF_LITTER, 0.50f)
val mints = mutableMapOf<String, MintItem>()
@@ -969,7 +969,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val EJECT_PACK = heldItem("eject_pack")
@JvmField
val ELECTRIC_SEED = heldItem("electric_seed")
val ELECTRIC_SEED = itemNameBlockItem("electric_seed", CobblemonBlocks.ELECTRIC_SEED)
@JvmField
val EVERSTONE = heldItem("everstone")
@JvmField
@@ -985,7 +985,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val FOCUS_SASH = heldItem("focus_sash")
@JvmField
val GRASSY_SEED = heldItem("grassy_seed")
val GRASSY_SEED = itemNameBlockItem("grassy_seed", CobblemonBlocks.GRASSY_SEED)
@JvmField
val GRIP_CLAW = heldItem("grip_claw")
@JvmField
@@ -1033,7 +1033,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val POWER_WEIGHT = heldItem("power_weight")
@JvmField
val PSYCHIC_SEED = heldItem("psychic_seed")
val PSYCHIC_SEED = itemNameBlockItem("psychic_seed", CobblemonBlocks.PSYCHIC_SEED)
@JvmField
val PROTECTIVE_PADS = heldItem("protective_pads")
@JvmField
@@ -1085,13 +1085,13 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val MIRROR_HERB = compostableHeldItem("mirror_herb", null, 0.85F)
@JvmField
val MISTY_SEED = heldItem("misty_seed")
val MISTY_SEED = itemNameBlockItem("misty_seed", CobblemonBlocks.MISTY_SEED)
@JvmField
val POWER_HERB = compostableHeldItem("power_herb", null, 0.85F)
@JvmField
val WHITE_HERB = compostableHeldItem("white_herb", null, 0.85F)
@JvmField
val BRIGHT_POWDER = itemNameBlockItem("bright_powder", CobblemonBlocks.BRIGHT_POWDER)
val BRIGHT_POWDER = glowItem("bright_powder", CobblemonBlocks.BRIGHT_POWDER)
@JvmField
val METAL_POWDER = itemNameBlockItem("metal_powder", CobblemonBlocks.METAL_POWDER)
@JvmField
@@ -1103,7 +1103,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val SMOOTH_ROCK = itemNameBlockItem("smooth_rock", CobblemonBlocks.SMOOTH_ROCK)
@JvmField
val ICY_ROCK = itemNameBlockItem("icy_rock", CobblemonBlocks.ICY_ROCK)
val ICY_ROCK = heldItem("icy_rock")
// Mulch
@JvmField
@@ -1558,6 +1558,25 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
//@JvmField
//val BINDING_SOIL = blockItem("binding_soil", CobblemonBlocks.BINDING_SOIL)
// Plants, Flora, and Flowers
@JvmField
val LOBAILA = compostableBlockItem("lobaila", CobblemonBlocks.LOBAILA, 0.65f)
@JvmField
val POMOHANA = compostableBlockItem("pomohana", CobblemonBlocks.POMOHANA, 0.3f)
@JvmField
val PAUVILLEA = compostableBlockItem("pauvillea", CobblemonBlocks.PAUVILLEA, 0.65f)
@JvmField
val WISTENSU = compostableBlockItem("wistensu", CobblemonBlocks.WISTENSU, 0.5f)
@JvmField
val VOLTACONIA = compostableBlockItem("voltaconia", CobblemonBlocks.VOLTACONIA, 0.85f)
@JvmField
val VERDROOT = compostableBlockItem("verdroot", CobblemonBlocks.VERDROOT, 0.85f)
@JvmField
val MISTLEAF = compostableBlockItem("mistleaf", CobblemonBlocks.MISTLEAF, 0.85f)
@JvmField
val LUCIBELL = compostableBlockItem("lucibell", CobblemonBlocks.LUCIBELL, 0.85f)
private fun blockItem(name: String, block: Block, rarity: Rarity = Rarity.COMMON): BlockItem = this.create(name, BlockItem(block, Item.Properties().rarity(rarity)))
private fun itemNameBlockItem(name: String, block: Block, rarity: Rarity = Rarity.COMMON): ItemNameBlockItem = this.create(name, ItemNameBlockItem(block, Item.Properties().rarity(rarity)))
@@ -1760,4 +1779,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
private fun foodItem(nutrition: Int, saturationModifier: Float): Item {
return CobblemonItem(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
}
private fun glowItem(name: String, block: Block): GlowItem = this.create(name, GlowItem(block, Item.Properties()))
}
@@ -148,6 +148,9 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
@JvmField
val MONITOR_GLITCHING = this.create("block.monitor.glitching")
@JvmField
val BRIGHT_POWDER_USE = this.create("block.bright_powder.use")
@JvmField
val FOSSIL_MACHINE_ACTIVATE = this.create("block.fossil_machine.activate")
@JvmField
@@ -103,15 +103,15 @@ class MintBlock(private val mintType: MintType, settings: Properties) : CropBloc
GREEN -> CobblemonItems.GREEN_MINT_SEEDS
WHITE -> CobblemonItems.WHITE_MINT_SEEDS
}
fun getLeaf(): MintLeafItem = when (this) {
RED -> CobblemonItems.RED_MINT_LEAF
BLUE -> CobblemonItems.BLUE_MINT_LEAF
CYAN -> CobblemonItems.CYAN_MINT_LEAF
PINK -> CobblemonItems.PINK_MINT_LEAF
GREEN -> CobblemonItems.GREEN_MINT_LEAF
WHITE -> CobblemonItems.WHITE_MINT_LEAF
}
// These don't seem to get called to anywhere besides the direct item, and since I'm trying to do funny stuff there, just commenting this out
// fun getLeaf(): MintLeafItem = when (this) {
// RED -> CobblemonItems.RED_MINT_LEAF
// BLUE -> CobblemonItems.BLUE_MINT_LEAF
// CYAN -> CobblemonItems.CYAN_MINT_LEAF
// PINK -> CobblemonItems.PINK_MINT_LEAF
// GREEN -> CobblemonItems.GREEN_MINT_LEAF
// WHITE -> CobblemonItems.WHITE_MINT_LEAF
// }
fun getCropBlock(): MintBlock = when (this) {
RED -> CobblemonBlocks.RED_MINT
@@ -0,0 +1,59 @@
/*
* 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.decor
import net.minecraft.core.BlockPos
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.SimpleWaterloggedBlock
import net.minecraft.world.level.block.TallFlowerBlock
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf
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
class LobailaFlowerBlock(properties: Properties?) : TallFlowerBlock(properties), SimpleWaterloggedBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(HALF, DoubleBlockHalf.LOWER)
.setValue(WATERLOGGED, false))
}
override fun getFluidState(blockState: BlockState): FluidState? {
return if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState);
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HALF, WATERLOGGED)
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
val fluidState = context.level.getFluidState(context.clickedPos)
return this.defaultBlockState()
.setValue(
WATERLOGGED,
fluidState.type === Fluids.WATER
)
}
override fun getShape(state: BlockState, world: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape = AABB
companion object {
private val AABB = Shapes.box(0.125, 0.0, 0.125, 0.875, 1.0, 0.875)
}
}
@@ -0,0 +1,87 @@
/*
* 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.decor
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.block.entity.MistleafFlowerBlockEntity
import net.minecraft.core.BlockPos
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelReader
import net.minecraft.world.level.block.BaseEntityBlock
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.SoundType
import net.minecraft.world.level.block.TallFlowerBlock
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.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.DoubleBlockHalf
import net.minecraft.world.level.block.state.properties.IntegerProperty
import net.minecraft.world.level.material.MapColor
import net.minecraft.world.level.material.PushReaction
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class MistleafFlowerBlock(lightLevel: (BlockState) -> Int) :
EntityBlock,
TallFlowerBlock(
Properties.of()
.mapColor(MapColor.PLANT)
.noCollission()
.instabreak()
.sound(SoundType.GRASS)
.offsetType(OffsetType.XZ)
.ignitedByLava()
.pushReaction(PushReaction.DESTROY)
.lightLevel(lightLevel)
) {
init {
registerDefaultState(stateDefinition.any()
.setValue(HALF, DoubleBlockHalf.LOWER)
.setValue(GLOWING, 0))
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HALF, GLOWING)
}
override fun isValidBonemealTarget(level: LevelReader, pos: BlockPos, state: BlockState): Boolean {
return false
}
override fun getShape(state: BlockState, world: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape = AABB
override fun newBlockEntity(pos: BlockPos, state: BlockState): BlockEntity? {
return MistleafFlowerBlockEntity(pos, state)
}
override fun <T : BlockEntity?> getTicker(
level: Level,
state: BlockState,
blockEntityType: BlockEntityType<T?>
): BlockEntityTicker<T?>? {
return if (level.isClientSide) null else BaseEntityBlock.createTickerHelper(blockEntityType as BlockEntityType<*>,
CobblemonBlockEntities.MISTLEAF_FLOWER, MistleafFlowerBlockEntity::serverTick) as BlockEntityTicker<T?>?
}
companion object {
private val AABB = Shapes.box(0.125, 0.0, 0.125, 0.875, 1.0, 0.875)
val GLOWING = IntegerProperty.create("glowing", 0, 8)
}
override fun hasAnalogOutputSignal(state: BlockState): Boolean { return true }
override fun getAnalogOutputSignal(state: BlockState, level: Level, pos: BlockPos): Int {
return state.getValue(GLOWING) as Int
}
}
@@ -0,0 +1,104 @@
/*
* 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.decor
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.util.RandomSource
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.LevelReader
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.BonemealableBlock
import net.minecraft.world.level.block.DirectionalBlock
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class PauvilleaFlowerBlock(properties: Properties?) : DirectionalBlock(properties), BonemealableBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(FACING, Direction.DOWN))
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(FACING)
}
override fun getStateForPlacement(ctx: BlockPlaceContext): BlockState? {
var blockState = defaultBlockState()
val worldView = ctx.level
val blockPos = ctx.clickedPos
blockState = blockState.setValue(FACING, ctx.clickedFace) as BlockState
if (blockState.canSurvive(worldView, blockPos)) {
return blockState
}
return null
}
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, level: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
val facing = state.getValue(FACING)
if (direction == facing.opposite && !canSurvive(state, level, pos)) {
return Blocks.AIR.defaultBlockState()
}
return super.updateShape(state, direction, neighborState, level, pos, neighborPos)
}
override fun canSurvive(state: BlockState, level: LevelReader, pos: BlockPos): Boolean {
val direction = state.getValue(FACING) as Direction
val blockState = level.getBlockState(pos.relative(direction.opposite))
return blockState.isCollisionShapeFullBlock(level, pos) or blockState.canOcclude()
}
override fun codec(): MapCodec<PauvilleaFlowerBlock> = CODEC
override fun getShape(state: BlockState, blockGetter: BlockGetter, pos: BlockPos, collisionContext: CollisionContext): VoxelShape {
return when (state.getValue(FACING)) {
Direction.DOWN -> CEILING
Direction.NORTH -> WALL_NORTH
Direction.EAST -> WALL_EAST
Direction.SOUTH -> WALL_SOUTH
Direction.WEST -> WALL_WEST
Direction.UP -> FLOOR
}
}
companion object {
val CODEC: MapCodec<PauvilleaFlowerBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::PauvilleaFlowerBlock)
}
val FLOOR = Shapes.box(0.075, 0.0, 0.075, 0.925, 0.4375, 0.925)
val WALL_NORTH = Shapes.box(0.0, 0.0, 0.8125, 1.0, 1.0, 1.0)
val WALL_EAST = Shapes.box(0.0, 0.0, 0.0, 0.1875, 1.0, 1.0)
val WALL_SOUTH = Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.1875)
val WALL_WEST = Shapes.box(0.8125, 0.0, 0.0, 1.0, 1.0, 1.0)
val CEILING = Shapes.box(0.075, 0.0, 0.075, 0.925, 1.0, 0.925)
}
override fun isValidBonemealTarget(level: LevelReader?, pos: BlockPos?, state: BlockState?): Boolean {
return true
}
override fun isBonemealSuccess(level: Level?, random: RandomSource?, pos: BlockPos?, state: BlockState?): Boolean {
return true
}
override fun performBonemeal(level: ServerLevel, random: RandomSource?, pos: BlockPos, state: BlockState?) {
popResource(level, pos, ItemStack(this))
}
}
@@ -0,0 +1,29 @@
/*
* 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.decor
import net.minecraft.core.BlockPos
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.block.PinkPetalsBlock
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class PomohanaFlowerBlock(properties: Properties?) : PinkPetalsBlock(properties) {
override fun getShape(state: BlockState, world: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape = AABB
companion object {
private val AABB = Shapes.box(0.125, 0.0, 0.125, 0.875, 1.0, 0.875)
}
}
@@ -0,0 +1,105 @@
/*
* 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.decor
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.block.entity.TerrainPlantBlockEntity
import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.world.entity.Entity
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelReader
import net.minecraft.world.level.block.BaseEntityBlock
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.TallFlowerBlock
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.BooleanProperty
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class TerrainPlantBlock(properties: Properties) : TallFlowerBlock(properties), EntityBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(HALF, DoubleBlockHalf.LOWER)
.setValue(GLOWING, false))
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HALF, GLOWING)
}
override fun isValidBonemealTarget(level: LevelReader, pos: BlockPos, state: BlockState): Boolean {
return false
}
override fun tick(state: BlockState, level: ServerLevel, pos: BlockPos, random: RandomSource) {
if (state.`is`(CobblemonBlocks.LUCIBELL)) { this.checkInside(level, pos, state) }
}
private fun checkInside(level: Level, pos: BlockPos, state: BlockState) {
// Only lower will handle this
val upperState = level.getBlockState(pos.above()).takeIf { it.`is`(CobblemonBlocks.LUCIBELL) && it.getValue(HALF) == DoubleBlockHalf.UPPER }
val entityInside = level.getEntities(null, state.getShape(level, pos).bounds().move(pos)).isNotEmpty()
|| upperState?.let { level.getEntities(null, it.getShape(level, pos.above()).bounds().move(pos.above())).isNotEmpty() } ?: false
val glowingState = state.getValue(GLOWING)
if (glowingState != entityInside) {
level.setBlock(pos, state.setValue(GLOWING, entityInside), UPDATE_CLIENTS)
upperState?.let { level.setBlock(pos.above(), it.setValue(GLOWING, entityInside), UPDATE_CLIENTS) }
}
if (entityInside) level.scheduleTick(pos, this, 30) // tick occasionally to check if player inside
}
override fun entityInside(state: BlockState, level: Level, pos: BlockPos, entity: Entity) {
// Lucibell lower block will be our 'driver'
if (!level.isClientSide && !state.getValue(GLOWING) && state.`is`(CobblemonBlocks.LUCIBELL)) {
val halfState = state.getValue(HALF)
if (halfState == DoubleBlockHalf.UPPER) {
val lowerState = level.getBlockState(pos.below())
.takeIf { it.`is`(CobblemonBlocks.LUCIBELL) && it.getValue(HALF) == DoubleBlockHalf.LOWER }
?: return
(lowerState.block as TerrainPlantBlock).checkInside(level, pos.below(), lowerState)
} else {
checkInside(level, pos, state)
}
}
}
override fun getShape(state: BlockState, world: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape = AABB
override fun newBlockEntity(pos: BlockPos, state: BlockState): BlockEntity {
return TerrainPlantBlockEntity(pos, state)
}
override fun <T : BlockEntity> getTicker(
level: Level,
state: BlockState,
blockEntityType: BlockEntityType<T?>
): BlockEntityTicker<T?>? {
return if (level.isClientSide) null else BaseEntityBlock.createTickerHelper(blockEntityType as BlockEntityType<*>,
CobblemonBlockEntities.TERRAIN_PLANT, TerrainPlantBlockEntity::serverTick) as BlockEntityTicker<T?>?
}
companion object {
private val AABB = Shapes.box(0.125, 0.0, 0.125, 0.875, 1.0, 0.875)
val GLOWING = BooleanProperty.create("glowing")
}
}
@@ -0,0 +1,273 @@
/*
* 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.decor
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.CobblemonSounds
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.util.RandomSource
import net.minecraft.util.StringRepresentable
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.*
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
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf
import net.minecraft.world.level.block.state.properties.EnumProperty
import net.minecraft.world.level.block.state.properties.IntegerProperty
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape
@Suppress("OVERRIDE_DEPRECATION")
class TerrainSeedBlock(private val terrainSeedType: TerrainSeedType, settings: Properties) : CropBlock(settings) {
companion object {
val CODEC: MapCodec<TerrainSeedBlock> = RecordCodecBuilder.mapCodec { it.group(
TerrainSeedType.CODEC.fieldOf("terrainSeedType").forGetter(TerrainSeedBlock::terrainSeedType),
propertiesCodec()
).apply(it, ::TerrainSeedBlock) }
const val MATURE_AGE = 4
val AGE: IntegerProperty = IntegerProperty.create("age", 0, MATURE_AGE)
val HALF: EnumProperty<DoubleBlockHalf> = BlockStateProperties.DOUBLE_BLOCK_HALF
val AGE_TO_SHAPE = arrayOf(
box(2.0, 0.0, 2.0, 14.0, 6.0, 14.0), // Stage 0
box(2.0, 0.0, 2.0, 14.0, 16.0, 14.0), // Stage 1
box(2.0, 0.0, 2.0, 14.0, 16.0, 14.0), // Stage 2
box(2.0, 0.0, 2.0, 14.0, 16.0, 14.0), // Stage 3
box(2.0, 0.0, 2.0, 14.0, 16.0, 14.0), // Stage 4
)
val AGE_TO_SHAPE_TOP = arrayOf(
box(2.0, 0.0, 2.0, 14.0, 1.0, 14.0), // Stage 0
box(2.0, 0.0, 2.0, 14.0, 1.0, 14.0), // Stage 1
box(2.0, 0.0, 2.0, 14.0, 8.0, 14.0), // Stage 2
box(2.0, 0.0, 2.0, 14.0, 16.0, 14.0), // Stage 3
box(2.0, 0.0, 2.0, 14.0, 16.0, 14.0), // Stage 4
)
}
override fun codec(): MapCodec<out CropBlock> {
return CODEC
}
init {
this.registerDefaultState(
this.stateDefinition.any()
.setValue(AGE, 0)
.setValue(HALF, DoubleBlockHalf.LOWER)
)
}
override fun getAgeProperty(): IntegerProperty = AGE
override fun getMaxAge(): Int = MATURE_AGE
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(AGE, HALF)
}
override fun getBaseSeedId(): ItemLike = this.terrainSeedType.getSeed()
override fun getShape(state: BlockState, world: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape =
if (state.getValue(HALF) == DoubleBlockHalf.UPPER) AGE_TO_SHAPE_TOP[getAge(state)] else AGE_TO_SHAPE[this.getAge(state)]
override fun randomTick(state: BlockState, world: ServerLevel, pos: BlockPos, random: RandomSource) {
if (state.getValue(HALF) == DoubleBlockHalf.UPPER || !canGrow(world, pos, state)) return
if (hasSufficientLight(world, pos) && random.nextInt(32) == 0) {
grow(world, pos, state, 1)
}
}
private fun canGrow(world: LevelReader, pos: BlockPos, state: BlockState): Boolean {
return !this.isMaxAge(state) && canSurvive(state, world, pos) && !(!canGrowInto(world, pos.above()) && state.getValue(AGE) >= 4)
}
private fun canGrowInto(world: LevelReader, pos: BlockPos): Boolean {
val blockState = world.getBlockState(pos)
return blockState.isAir || blockState.`is`(this.terrainSeedType.getCropBlock())
}
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, world: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
return if (state.getValue(AGE) >= 2) {
super.updateShape(state, direction, neighborState, world, pos, neighborPos)
} else {
if (state.canSurvive(world, pos)) state else Blocks.AIR.defaultBlockState()
}
}
override fun isValidBonemealTarget(level: LevelReader, pos: BlockPos, state: BlockState): Boolean {
val posAndState = getLowerHalf(level, pos, state)
return if (posAndState == null) false else this.canGrow(
level,
posAndState.first,
posAndState.second
)
}
override fun performBonemeal(level: ServerLevel, random: RandomSource, pos: BlockPos, state: BlockState) {
val posAndState = getLowerHalf(level, pos, state)
if (posAndState != null) {
grow(level, posAndState.first, posAndState.second, getBonemealAgeIncrease(level))
}
}
fun grow(world: Level, pos: BlockPos, state: BlockState, increment: Int) {
if (!canGrow(world, pos, state)) return
val newAge = (this.getAge(state) + increment).coerceAtMost(this.maxAge)
world.setBlock(pos, state.setValue(this.ageProperty, newAge), UPDATE_CLIENTS)
val abovePos = pos.above()
val stateAbove = world.getBlockState(abovePos)
// Set top half depending on age
if (newAge >= (2)) {
if (stateAbove.isAir) {
world.setBlock(
abovePos,
this.defaultBlockState().setValue(AGE, newAge).setValue(HALF, DoubleBlockHalf.UPPER),
UPDATE_CLIENTS
)
}
else if (stateAbove.hasProperty(HALF) && stateAbove.getValue(HALF) == DoubleBlockHalf.UPPER) {
world.setBlock(
abovePos,
stateAbove.setValue(AGE, newAge),
UPDATE_CLIENTS
)
}
}
// Swaps blocks to the actual Flower when fully grown
if (newAge == this.maxAge) {
val nextStateLower = this.terrainSeedType.getFlowerBlock().defaultBlockState().setValue(HALF, DoubleBlockHalf.LOWER)
val nextStateUpper = this.terrainSeedType.getFlowerBlock().defaultBlockState().setValue(HALF, DoubleBlockHalf.UPPER)
world.setBlock(abovePos, nextStateUpper, UPDATE_CLIENTS)
world.setBlock(pos, nextStateLower, UPDATE_CLIENTS)
}
}
override fun getBonemealAgeIncrease(level: Level): Int {
return 1
}
override fun canSurvive(state: BlockState, world: LevelReader, pos: BlockPos): Boolean {
return when (state.getValue(HALF)) {
DoubleBlockHalf.LOWER -> {
val floorBlock = pos.below()
val floor = world.getBlockState(floorBlock)
floor.`is`(Blocks.FARMLAND)
}
DoubleBlockHalf.UPPER -> {
getLowerHalf(world, pos, state) != null
// Upper part survives only if the lower part is valid
}
}
}
private fun getLowerHalf(level: LevelReader, pos: BlockPos, state: BlockState): Pair<BlockPos, BlockState>? {
if (isLower(state)) {
return Pair(pos, state)
} else {
val blockPos = pos.below()
val blockState = level.getBlockState(blockPos)
return if (isLower(blockState)) Pair(
blockPos,
blockState
) else null
}
}
private fun isLower(state: BlockState): Boolean =
state.`is`(this.terrainSeedType.getCropBlock()) && state.getValue(HALF) == DoubleBlockHalf.LOWER
override fun getSoundType(state: BlockState): SoundType {
return CobblemonSounds.HEARTY_GRAINS_SOUNDS
}
@Suppress("unused")
enum class TerrainSeedType : StringRepresentable {
ELECTRIC,
PSYCHIC,
MISTY,
GRASSY;
fun getSeed(): Item = when (this) {
ELECTRIC -> CobblemonItems.ELECTRIC_SEED
PSYCHIC -> CobblemonItems.PSYCHIC_SEED
MISTY -> CobblemonItems.MISTY_SEED
GRASSY -> CobblemonItems.GRASSY_SEED
}
fun getCropBlock(): TerrainSeedBlock = when (this) {
ELECTRIC -> CobblemonBlocks.ELECTRIC_SEED
PSYCHIC -> CobblemonBlocks.PSYCHIC_SEED
MISTY -> CobblemonBlocks.MISTY_SEED
GRASSY -> CobblemonBlocks.GRASSY_SEED
}
fun getFlowerBlock(): Block = when (this) {
ELECTRIC -> CobblemonBlocks.VOLTACONIA
PSYCHIC -> CobblemonBlocks.LUCIBELL
MISTY -> CobblemonBlocks.MISTLEAF
GRASSY -> CobblemonBlocks.VERDROOT
}
override fun getSerializedName(): String = this.name.lowercase()
companion object {
val CODEC = StringRepresentable.fromEnum(::values)
}
}
override fun playerWillDestroy(level: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
if (!level.isClientSide) {
if (player.isCreative()) {
preventDropFromBottomPart(level, pos, state, player)
} else {
dropResources(state, level, pos, null as BlockEntity?, player, player.getMainHandItem())
}
}
return super.playerWillDestroy(level, pos, state, player)
}
override fun playerDestroy(
level: Level,
player: Player,
pos: BlockPos,
state: BlockState,
blockEntity: BlockEntity?,
tool: ItemStack
) {
super.playerDestroy(level, player, pos, Blocks.AIR.defaultBlockState(), blockEntity, tool)
}
fun preventDropFromBottomPart(level: Level, pos: BlockPos, state: BlockState, player: Player?) {
val doubleblockhalf = state.getValue<DoubleBlockHalf?>(DoublePlantBlock.HALF) as DoubleBlockHalf
if (doubleblockhalf == DoubleBlockHalf.UPPER) {
val blockpos = pos.below()
val blockstate = level.getBlockState(blockpos)
if (blockstate.`is`(state.getBlock()) && blockstate.getValue<DoubleBlockHalf?>(DoublePlantBlock.HALF) == DoubleBlockHalf.LOWER) {
val blockstate1 = if (blockstate.getFluidState()
.`is`(Fluids.WATER)
) Blocks.WATER.defaultBlockState() else Blocks.AIR.defaultBlockState()
level.setBlock(blockpos, blockstate1, 35)
level.levelEvent(player, 2001, blockpos, getId(blockstate))
}
}
}
}
@@ -0,0 +1,80 @@
/*
* 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.decor
import com.cobblemon.mod.common.CobblemonBlocks
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.LevelReader
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.BooleanProperty
interface WistensuFlowerBlock {
fun additionalBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(BlockStateProperties.FACING)
builder.add(ROOT)
}
fun adjustStateForPlacement(context: BlockPlaceContext, defaultState: BlockState): BlockState {
val upperBlock = context.level.getBlockState(context.clickedPos.relative(Direction.UP))
if (upperBlock.`is`(CobblemonBlocks.WISTENSU) || upperBlock.`is`(CobblemonBlocks.WISTENSU_VINE)) {
return defaultState
.setValue(BlockStateProperties.FACING, Direction.DOWN)
.setValue(ROOT, false)
} else {
var placeDirection = context.clickedFace
if (placeDirection == Direction.UP) placeDirection = Direction.DOWN
return defaultState
.setValue(BlockStateProperties.FACING, placeDirection)
.setValue(ROOT, true)
}
}
fun copyStateValues(target: BlockState, source: BlockState): BlockState {
return target
.setValue(ROOT, source.getValue(ROOT))
.setValue(BlockStateProperties.FACING, source.getValue(BlockStateProperties.FACING))
}
fun wisternCanSurvive(state: BlockState, level: LevelReader, pos: BlockPos): Boolean {
if (state.getValue(ROOT)) {
val facing = state.getValue(BlockStateProperties.FACING)
val targetPos = pos.relative(facing.opposite)
val directionState = level.getBlockState(targetPos)
return directionState.isFaceSturdy(level, targetPos, facing)
} else {
val topState = level.getBlockState(pos.relative(Direction.UP))
return topState.`is`(CobblemonBlocks.WISTENSU) || topState.`is`(CobblemonBlocks.WISTENSU_VINE)
}
}
fun wisternUpdateShape(state: BlockState, direction: Direction, neighborState: BlockState, level: LevelAccessor, pos: BlockPos, neighborPos: BlockPos, block: Block): BlockState? {
if (!wisternCanSurvive(state, level, pos)) {
level.scheduleTick(pos, block, 1)
}
if (direction == Direction.UP &&
(neighborState.`is`(CobblemonBlocks.WISTENSU) || neighborState.`is`(CobblemonBlocks.WISTENSU_VINE))) {
return state
.setValue(ROOT, false)
.setValue(BlockStateProperties.FACING, Direction.DOWN)
}
return null
}
companion object {
val ROOT = BooleanProperty.create("root")
}
}
@@ -0,0 +1,114 @@
/*
* 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.decor
import com.cobblemon.mod.common.CobblemonBlocks
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.util.RandomSource
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.LevelReader
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.GrowingPlantHeadBlock
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.phys.shapes.VoxelShape
import kotlin.math.min
//TODO: Root/connection shit
class WistensuFlowerHeadBlock(properties: Properties?) : GrowingPlantHeadBlock(properties, Direction.DOWN, SHAPE, false, 0.1), WistensuFlowerBlock {
companion object {
val CODEC: MapCodec<WistensuFlowerHeadBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::WistensuFlowerHeadBlock)
}
val SHAPE: VoxelShape = box(1.0, 2.0, 1.0, 15.0, 16.0, 15.0)
}
override fun codec(): MapCodec<WistensuFlowerHeadBlock> = CODEC
override fun getBlocksToGrowWhenBonemealed(random: RandomSource): Int {
var d = 1.0
var i = 0
while (random.nextDouble() < d) {
d *= 0.826
++i
}
return i
}
override fun canGrowInto(state: BlockState): Boolean {
return state.isAir
}
override fun getBodyBlock(): Block {
return CobblemonBlocks.WISTENSU_VINE
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
super.createBlockStateDefinition(builder)
additionalBlockStateDefinition(builder)
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
level: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
val updateState = wisternUpdateShape(state, direction, neighborState, level, pos, neighborPos, this)
if (updateState != null) return updateState
if (direction == Direction.DOWN &&
(neighborState.`is`(CobblemonBlocks.WISTENSU) || neighborState.`is`(CobblemonBlocks.WISTENSU_VINE))) {
return updateBodyAfterConvertedFromHead(state, bodyBlock.defaultBlockState())
}
return state
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState {
val defaultState = super.getStateForPlacement(context)!!
return adjustStateForPlacement(context, defaultState)
}
override fun getGrowIntoState(state: BlockState, random: RandomSource): BlockState {
return super.getGrowIntoState(state, random)
.setValue(WistensuFlowerBlock.ROOT, false)
.setValue(BlockStateProperties.FACING, Direction.DOWN)
}
override fun updateBodyAfterConvertedFromHead(head: BlockState, body: BlockState): BlockState {
return copyStateValues(body, head)
}
override fun performBonemeal(level: ServerLevel, random: RandomSource, pos: BlockPos, state: BlockState) {
var blockPos = pos.relative(growthDirection)
var i = min(state.getValue(AGE), MAX_AGE)
val j = getBlocksToGrowWhenBonemealed(random)
var currentState = state
for (k in 0..<j) {
if (!canGrowInto(level.getBlockState(blockPos))) break
level.setBlockAndUpdate(blockPos, getGrowIntoState(currentState, random))
currentState = level.getBlockState(blockPos)
blockPos = blockPos.relative(growthDirection)
i = min(i + 1, MAX_AGE)
}
}
override fun canSurvive(state: BlockState, level: LevelReader, pos: BlockPos): Boolean {
return wisternCanSurvive(state, level, pos)
}
}
@@ -0,0 +1,77 @@
/*
* 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.decor
import com.cobblemon.mod.common.CobblemonBlocks
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.LevelReader
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.GrowingPlantBodyBlock
import net.minecraft.world.level.block.GrowingPlantHeadBlock
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.phys.shapes.VoxelShape
//TODO: Root/connection shit
class WistensuFlowerVineBlock(properties: Properties?) : GrowingPlantBodyBlock(properties, Direction.DOWN, SHAPE, false), WistensuFlowerBlock
{
companion object {
val CODEC: MapCodec<WistensuFlowerVineBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::WistensuFlowerVineBlock)
}
val SHAPE: VoxelShape = box(1.0, 0.0, 1.0, 15.0, 16.0, 15.0)
}
override fun codec(): MapCodec<WistensuFlowerVineBlock> = CODEC
override fun getHeadBlock(): GrowingPlantHeadBlock {
return CobblemonBlocks.WISTENSU
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
super.createBlockStateDefinition(builder)
additionalBlockStateDefinition(builder)
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
level: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
val updateState = wisternUpdateShape(state, direction, neighborState, level, pos, neighborPos, this)
if (updateState != null) return updateState
if (direction == Direction.DOWN &&
!neighborState.`is`(CobblemonBlocks.WISTENSU) && !neighborState.`is`(CobblemonBlocks.WISTENSU_VINE)) {
return updateHeadAfterConvertedFromBody(state, headBlock.getStateForPlacement(level))
}
return state
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState {
val defaultState = super.getStateForPlacement(context)!!
return adjustStateForPlacement(context, defaultState)
}
override fun updateHeadAfterConvertedFromBody(head: BlockState, body: BlockState): BlockState {
return copyStateValues(body, head)
}
override fun canSurvive(state: BlockState, level: LevelReader, pos: BlockPos): Boolean {
return wisternCanSurvive(state, level, pos)
}
}
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.entity
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.block.decor.MistleafFlowerBlock
import net.minecraft.core.BlockPos
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState
class MistleafFlowerBlockEntity(pos: BlockPos, state: BlockState): BlockEntity(CobblemonBlockEntities.MISTLEAF_FLOWER, pos, state) {
companion object {
fun serverTick(level: Level, pos: BlockPos, state: BlockState, mistleafFlowerBlockEntity: MistleafFlowerBlockEntity) {
if (level.isClientSide) return
if (state.block !is MistleafFlowerBlock) return
val glowing = state.getValue(MistleafFlowerBlock.GLOWING)
val wantedState = when (state.`is`(CobblemonBlocks.MISTLEAF)) {
//The light level and comparator output increases on odds from New to Full, and decreases on the evens from Full to New
((level.dayTime().toInt().mod(24000) in 12542..23459) && level.moonPhase == 4) -> 1 //New Moon
((level.dayTime().toInt().mod(24000) in 12542..23459) && level.moonPhase == 5) -> 3 //Waxing Crescent
((level.dayTime().toInt().mod(24000) in 12542..23459) && level.moonPhase == 6) -> 5 //First Quarter
((level.dayTime().toInt().mod(24000) in 12542..23459) && level.moonPhase == 7) -> 7 //Waxing Gibbous
((level.dayTime().toInt().mod(24000) in 12542..23459) && level.moonPhase == 0) -> 8 //Full Moon
((level.dayTime().toInt().mod(24000) in 12542..23459) && level.moonPhase == 1) -> 6 //Waning Gibbous
((level.dayTime().toInt().mod(24000) in 12542..23459) && level.moonPhase == 2) -> 4 // Third Quarter
((level.dayTime().toInt().mod(24000) in 12542..23459) && level.moonPhase == 3) -> 2 //Waning Crescent
else -> 0 //Daytime, and likely dimensions with no concept of day/night cycle or moon phase
}
if (glowing != wantedState) {
level.setBlock(pos, state.setValue(MistleafFlowerBlock.GLOWING, wantedState), Block.UPDATE_ALL)
}
}
}
}
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.entity
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.block.decor.TerrainPlantBlock
import net.minecraft.core.BlockPos
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState
class TerrainPlantBlockEntity(pos: BlockPos, state: BlockState): BlockEntity(CobblemonBlockEntities.TERRAIN_PLANT, pos, state) {
companion object {
fun serverTick(level: Level, pos: BlockPos, state: BlockState, terrainPlantBlockEntity: TerrainPlantBlockEntity) {
if (level.isClientSide) return
if (state.block !is TerrainPlantBlock) return
val glowing = state.getValue(TerrainPlantBlock.GLOWING)
val wantedState = if (state.`is`(CobblemonBlocks.VOLTACONIA)) level.isThundering
else if (state.`is`(CobblemonBlocks.VERDROOT)) level.isRaining && !level.isThundering
else null // We dont control glowing here
if (wantedState != null && glowing != wantedState) {
level.setBlock(pos, state.setValue(TerrainPlantBlock.GLOWING, wantedState), Block.UPDATE_CLIENTS)
}
}
}
}
@@ -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.general
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.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.LevelReader
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
import net.minecraft.world.level.block.state.properties.IntegerProperty
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
import kotlin.math.min
class MintLitterBlock(properties: Properties?) : Block(properties) {
init {
registerDefaultState(stateDefinition.any()
.setValue(FACING, Direction.NORTH)
.setValue(AMOUNT, 1))
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
val blockState = context.getLevel().getBlockState(context.getClickedPos())
return if (blockState.`is`(this)) blockState.setValue<Int?, Int?>(
AMOUNT,
min(4, blockState.getValue<Int?>(AMOUNT) as Int + 1)
) as BlockState else this.defaultBlockState().setValue<Direction?, Direction?>(
FACING,
context.getHorizontalDirection().getOpposite()
) as BlockState
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(FACING)
builder.add(AMOUNT)
}
override fun updateShape(
state: BlockState,
direction: Direction?,
neighborState: BlockState?,
level: LevelAccessor?,
pos: BlockPos?,
neighborPos: BlockPos?
): BlockState {
return if (!state.canSurvive(level, pos)) Blocks.AIR.defaultBlockState() else super.updateShape(
state,
direction,
neighborState,
level,
pos,
neighborPos
)
}
override fun canSurvive(state: BlockState?, level: LevelReader, pos: BlockPos): Boolean {
val posBelow = pos.below()
return level.getBlockState(posBelow).isFaceSturdy(level, posBelow, Direction.UP)
}
override fun propagatesSkylightDown(state: BlockState, level: BlockGetter?, pos: BlockPos?): Boolean {
return state.getFluidState().isEmpty()
}
public override fun canBeReplaced(state: BlockState, useContext: BlockPlaceContext): Boolean {
return if (!useContext.isSecondaryUseActive && useContext.itemInHand.`is`(this.asItem()) && state.getValue(
AMOUNT
) <= MAX_AMOUNT
) true else super.canBeReplaced(state, useContext)
}
@Deprecated("Deprecated in Java")
override fun rotate(state: BlockState, rotation: Rotation): BlockState {
return state.setValue(HORIZONTAL_FACING, rotation.rotate(state.getValue(HORIZONTAL_FACING)))
}
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape? {
val litterBoxes = when (state.getValue(FACING)) {
Direction.SOUTH -> SOUTH_SHAPES
Direction.WEST -> WEST_SHAPES
Direction.EAST -> EAST_SHAPES
else -> NORTH_SHAPES
}
var litterBox = litterBoxes[state.getValue(AMOUNT)]
return litterBox
}
companion object {
val CODEC: MapCodec<MintLitterBlock> = RecordCodecBuilder.mapCodec {
it.group(
propertiesCodec()
).apply(it, ::MintLitterBlock) }
val AMOUNT = IntegerProperty.create("amount", 1, 4)
const val MAX_AMOUNT: Int = 4
private val NORTH_SHAPES = listOf(
Shapes.box(0.0, 0.0, 0.0, 1.0, 0.125, 1.0),
Shapes.box(0.0, 0.0, 0.0, 0.5, 0.0625, 0.5),
Shapes.box(0.0, 0.0, 0.0, 0.5, 0.0625, 1.0),
Shapes.or(
Shapes.box(0.0, 0.0, 0.0, 0.5, 0.0625, 1.0),
Shapes.box(0.5, 0.0, 0.5, 1.0, 0.0625, 1.0)
),
Shapes.box(0.0, 0.0, 0.0, 1.0, 0.0625, 1.0)
)
private val SOUTH_SHAPES = createShapes(Direction.SOUTH)
private val WEST_SHAPES = createShapes(Direction.WEST)
private val EAST_SHAPES = createShapes(Direction.EAST)
private fun createShapes(to: Direction): List<VoxelShape> {
return NORTH_SHAPES.map { rotateShape(Direction.NORTH, to, it) }
}
}
}
@@ -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,
@@ -415,7 +415,105 @@ object CobblemonClient {
CobblemonBlocks.NEVER_MELT_ICE,
CobblemonBlocks.WIDE_LENS,
CobblemonBlocks.ZOOM_LENS,
CobblemonBlocks.SCOPE_LENS
CobblemonBlocks.SCOPE_LENS,
CobblemonBlocks.RED_MINT_LEAF_LITTER,
CobblemonBlocks.POTTED_RED_MINT,
CobblemonBlocks.BLUE_MINT_LEAF_LITTER,
CobblemonBlocks.POTTED_BLUE_MINT,
CobblemonBlocks.CYAN_MINT_LEAF_LITTER,
CobblemonBlocks.POTTED_CYAN_MINT,
CobblemonBlocks.PINK_MINT_LEAF_LITTER,
CobblemonBlocks.POTTED_PINK_MINT,
CobblemonBlocks.GREEN_MINT_LEAF_LITTER,
CobblemonBlocks.POTTED_GREEN_MINT,
CobblemonBlocks.WHITE_MINT_LEAF_LITTER,
CobblemonBlocks.POTTED_WHITE_MINT,
CobblemonBlocks.LOBAILA,
CobblemonBlocks.POMOHANA,
CobblemonBlocks.PAUVILLEA,
CobblemonBlocks.WISTENSU,
CobblemonBlocks.WISTENSU_VINE,
CobblemonBlocks.ELECTRIC_SEED,
CobblemonBlocks.VOLTACONIA,
CobblemonBlocks.GRASSY_SEED,
CobblemonBlocks.VERDROOT,
CobblemonBlocks.MISTY_SEED,
CobblemonBlocks.MISTLEAF,
CobblemonBlocks.PSYCHIC_SEED,
CobblemonBlocks.LUCIBELL,
CobblemonBlocks.POTTED_AGUAV_BERRY,
CobblemonBlocks.POTTED_APICOT_BERRY,
CobblemonBlocks.POTTED_ASPEAR_BERRY,
CobblemonBlocks.POTTED_BABIRI_BERRY,
CobblemonBlocks.POTTED_BELUE_BERRY,
CobblemonBlocks.POTTED_BLUK_BERRY,
CobblemonBlocks.POTTED_CHARTI_BERRY,
CobblemonBlocks.POTTED_CHERI_BERRY,
CobblemonBlocks.POTTED_CHESTO_BERRY,
CobblemonBlocks.POTTED_CHILAN_BERRY,
CobblemonBlocks.POTTED_CHOPLE_BERRY,
CobblemonBlocks.POTTED_COBA_BERRY,
CobblemonBlocks.POTTED_COLBUR_BERRY,
CobblemonBlocks.POTTED_CORNN_BERRY,
CobblemonBlocks.POTTED_CUSTAP_BERRY,
CobblemonBlocks.POTTED_DURIN_BERRY,
CobblemonBlocks.POTTED_EGGANT_BERRY,
CobblemonBlocks.POTTED_ENIGMA_BERRY,
CobblemonBlocks.POTTED_FIGY_BERRY,
CobblemonBlocks.POTTED_GANLON_BERRY,
CobblemonBlocks.POTTED_GREPA_BERRY,
CobblemonBlocks.POTTED_HABAN_BERRY,
CobblemonBlocks.POTTED_HONDEW_BERRY,
CobblemonBlocks.POTTED_HOPO_BERRY,
CobblemonBlocks.POTTED_IAPAPA_BERRY,
CobblemonBlocks.POTTED_JABOCA_BERRY,
CobblemonBlocks.POTTED_KASIB_BERRY,
CobblemonBlocks.POTTED_KEBIA_BERRY,
CobblemonBlocks.POTTED_KEE_BERRY,
CobblemonBlocks.POTTED_KELPSY_BERRY,
CobblemonBlocks.POTTED_LANSAT_BERRY,
CobblemonBlocks.POTTED_LEPPA_BERRY,
CobblemonBlocks.POTTED_LIECHI_BERRY,
CobblemonBlocks.POTTED_LUM_BERRY,
CobblemonBlocks.POTTED_MAGOST_BERRY,
CobblemonBlocks.POTTED_MAGO_BERRY,
CobblemonBlocks.POTTED_MARANGA_BERRY,
CobblemonBlocks.POTTED_MICLE_BERRY,
CobblemonBlocks.POTTED_NANAB_BERRY,
CobblemonBlocks.POTTED_NOMEL_BERRY,
CobblemonBlocks.POTTED_OCCA_BERRY,
CobblemonBlocks.POTTED_ORAN_BERRY,
CobblemonBlocks.POTTED_PAMTRE_BERRY,
CobblemonBlocks.POTTED_PASSHO_BERRY,
CobblemonBlocks.POTTED_PAYAPA_BERRY,
CobblemonBlocks.POTTED_PECHA_BERRY,
CobblemonBlocks.POTTED_PERSIM_BERRY,
CobblemonBlocks.POTTED_PETAYA_BERRY,
CobblemonBlocks.POTTED_PINAP_BERRY,
CobblemonBlocks.POTTED_POMEG_BERRY,
CobblemonBlocks.POTTED_QUALOT_BERRY,
CobblemonBlocks.POTTED_RABUTA_BERRY,
CobblemonBlocks.POTTED_RAWST_BERRY,
CobblemonBlocks.POTTED_RAZZ_BERRY,
CobblemonBlocks.POTTED_RINDO_BERRY,
CobblemonBlocks.POTTED_ROSELI_BERRY,
CobblemonBlocks.POTTED_ROWAP_BERRY,
CobblemonBlocks.POTTED_SALAC_BERRY,
CobblemonBlocks.POTTED_SHUCA_BERRY,
CobblemonBlocks.POTTED_SITRUS_BERRY,
CobblemonBlocks.POTTED_SPELON_BERRY,
CobblemonBlocks.POTTED_STARF_BERRY,
CobblemonBlocks.POTTED_TAMATO_BERRY,
CobblemonBlocks.POTTED_TANGA_BERRY,
CobblemonBlocks.POTTED_TOUGA_BERRY,
CobblemonBlocks.POTTED_WACAN_BERRY,
CobblemonBlocks.POTTED_WATMEL_BERRY,
CobblemonBlocks.POTTED_WEPEAR_BERRY,
CobblemonBlocks.POTTED_WIKI_BERRY,
CobblemonBlocks.POTTED_YACHE_BERRY
)
this.createBoatModelLayers()
@@ -0,0 +1,39 @@
/*
* 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.item
import com.cobblemon.mod.common.CobblemonSounds
import net.minecraft.sounds.SoundSource
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemNameBlockItem
import net.minecraft.world.item.SignApplicator
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.entity.SignBlockEntity
import net.minecraft.world.level.block.entity.SignText
class GlowItem(block: Block, settings: Properties) : ItemNameBlockItem(block, settings), SignApplicator {
override fun tryApplyToSign(level: Level, sign: SignBlockEntity, isFront: Boolean, player: Player?): Boolean {
if (sign.updateText({ signText: SignText? -> signText!!.setHasGlowingText(true) }, isFront)) {
level.playSound(
null as Player?,
sign.blockPos,
CobblemonSounds.BRIGHT_POWDER_USE,
SoundSource.BLOCKS,
1.0f,
1.0f
)
return true
} else {
return false
}
}
}
@@ -198,6 +198,14 @@ object CobblemonItemGroups {
entries.accept(CobblemonItems.GALARICA_NUTS)
entries.accept(CobblemonItems.HEARTY_GRAINS)
entries.accept(CobblemonItems.TASTY_TAIL)
entries.accept(CobblemonItems.POMOHANA)
entries.accept(CobblemonItems.PAUVILLEA)
entries.accept(CobblemonItems.LOBAILA)
entries.accept(CobblemonItems.WISTENSU)
entries.accept(CobblemonItems.VOLTACONIA)
entries.accept(CobblemonItems.VERDROOT)
entries.accept(CobblemonItems.MISTLEAF)
entries.accept(CobblemonItems.LUCIBELL)
// entries.accept(CobblemonItems.BUGWORT) // TODO after 1.7
entries.accept(CobblemonItems.RED_APRICORN)
@@ -0,0 +1,160 @@
{
"multipart": [
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_1"
},
"when": {
"facing": "north",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_1",
"y": 90
},
"when": {
"facing": "east",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_1",
"y": 180
},
"when": {
"facing": "south",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_1",
"y": 270
},
"when": {
"facing": "west",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_2"
},
"when": {
"facing": "north",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_2",
"y": 90
},
"when": {
"facing": "east",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_2",
"y": 180
},
"when": {
"facing": "south",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_2",
"y": 270
},
"when": {
"facing": "west",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_3"
},
"when": {
"facing": "north",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_3",
"y": 90
},
"when": {
"facing": "east",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_3",
"y": 180
},
"when": {
"facing": "south",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_3",
"y": 270
},
"when": {
"facing": "west",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_4"
},
"when": {
"facing": "north",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_4",
"y": 90
},
"when": {
"facing": "east",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_4",
"y": 180
},
"when": {
"facing": "south",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/blue_mint_leaf_litter_4",
"y": 270
},
"when": {
"facing": "west",
"amount": "4"
}
}
]
}
@@ -0,0 +1,160 @@
{
"multipart": [
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_1"
},
"when": {
"facing": "north",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_1",
"y": 90
},
"when": {
"facing": "east",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_1",
"y": 180
},
"when": {
"facing": "south",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_1",
"y": 270
},
"when": {
"facing": "west",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_2"
},
"when": {
"facing": "north",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_2",
"y": 90
},
"when": {
"facing": "east",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_2",
"y": 180
},
"when": {
"facing": "south",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_2",
"y": 270
},
"when": {
"facing": "west",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_3"
},
"when": {
"facing": "north",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_3",
"y": 90
},
"when": {
"facing": "east",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_3",
"y": 180
},
"when": {
"facing": "south",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_3",
"y": 270
},
"when": {
"facing": "west",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_4"
},
"when": {
"facing": "north",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_4",
"y": 90
},
"when": {
"facing": "east",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_4",
"y": 180
},
"when": {
"facing": "south",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/cyan_mint_leaf_litter_4",
"y": 270
},
"when": {
"facing": "west",
"amount": "4"
}
}
]
}
@@ -0,0 +1,14 @@
{
"variants": {
"age=0,half=lower": { "model": "cobblemon:block/electric_seed_stage0" },
"age=0,half=upper": { "model": "cobblemon:block/electric_seed_stage0" },
"age=1,half=lower": { "model": "cobblemon:block/electric_seed_stage1" },
"age=1,half=upper": { "model": "cobblemon:block/electric_seed_stage1" },
"age=2,half=lower": { "model": "cobblemon:block/electric_seed_bottom_stage2" },
"age=2,half=upper": { "model": "cobblemon:block/electric_seed_top_stage2" },
"age=3,half=lower": { "model": "cobblemon:block/electric_seed_bottom_stage3" },
"age=3,half=upper": { "model": "cobblemon:block/electric_seed_top_stage3" },
"age=4,half=lower": { "model": "cobblemon:block/voltaconia_bottom" },
"age=4,half=upper": { "model": "cobblemon:block/voltaconia_top" }
}
}
@@ -0,0 +1,14 @@
{
"variants": {
"age=0,half=lower": { "model": "cobblemon:block/grassy_seed_stage0" },
"age=0,half=upper": { "model": "cobblemon:block/grassy_seed_stage0" },
"age=1,half=lower": { "model": "cobblemon:block/grassy_seed_stage1" },
"age=1,half=upper": { "model": "cobblemon:block/grassy_seed_stage1" },
"age=2,half=lower": { "model": "cobblemon:block/grassy_seed_bottom_stage2" },
"age=2,half=upper": { "model": "cobblemon:block/grassy_seed_top_stage2" },
"age=3,half=lower": { "model": "cobblemon:block/grassy_seed_bottom_stage3" },
"age=3,half=upper": { "model": "cobblemon:block/grassy_seed_top_stage3" },
"age=4,half=lower": { "model": "cobblemon:block/verdroot_bottom" },
"age=4,half=upper": { "model": "cobblemon:block/verdroot_top" }
}
}
@@ -0,0 +1,160 @@
{
"multipart": [
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_1"
},
"when": {
"facing": "north",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_1",
"y": 90
},
"when": {
"facing": "east",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_1",
"y": 180
},
"when": {
"facing": "south",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_1",
"y": 270
},
"when": {
"facing": "west",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_2"
},
"when": {
"facing": "north",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_2",
"y": 90
},
"when": {
"facing": "east",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_2",
"y": 180
},
"when": {
"facing": "south",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_2",
"y": 270
},
"when": {
"facing": "west",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_3"
},
"when": {
"facing": "north",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_3",
"y": 90
},
"when": {
"facing": "east",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_3",
"y": 180
},
"when": {
"facing": "south",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_3",
"y": 270
},
"when": {
"facing": "west",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_4"
},
"when": {
"facing": "north",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_4",
"y": 90
},
"when": {
"facing": "east",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_4",
"y": 180
},
"when": {
"facing": "south",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/green_mint_leaf_litter_4",
"y": 270
},
"when": {
"facing": "west",
"amount": "4"
}
}
]
}
@@ -0,0 +1,10 @@
{
"variants": {
"half=lower": {
"model": "cobblemon:block/lobaila_bottom"
},
"half=upper": {
"model": "cobblemon:block/lobaila_top"
}
}
}
@@ -0,0 +1,8 @@
{
"variants": {
"half=lower,glowing=false": { "model": "cobblemon:block/lucibell_bottom" },
"half=upper,glowing=false": { "model": "cobblemon:block/lucibell_top" },
"half=lower,glowing=true": { "model": "cobblemon:block/lucibell_bottom_glowing" },
"half=upper,glowing=true": { "model": "cobblemon:block/lucibell_top_glowing" }
}
}
@@ -0,0 +1,22 @@
{
"variants": {
"half=lower,glowing=0": { "model": "cobblemon:block/mistleaf_bottom" },
"half=upper,glowing=0": { "model": "cobblemon:block/mistleaf_top" },
"half=lower,glowing=1": { "model": "cobblemon:block/mistleaf_bottom_glowing" },
"half=upper,glowing=1": { "model": "cobblemon:block/mistleaf_top_glowing" },
"half=lower,glowing=2": { "model": "cobblemon:block/mistleaf_bottom_glowing" },
"half=upper,glowing=2": { "model": "cobblemon:block/mistleaf_top_glowing" },
"half=lower,glowing=3": { "model": "cobblemon:block/mistleaf_bottom_glowing" },
"half=upper,glowing=3": { "model": "cobblemon:block/mistleaf_top_glowing" },
"half=lower,glowing=4": { "model": "cobblemon:block/mistleaf_bottom_glowing" },
"half=upper,glowing=4": { "model": "cobblemon:block/mistleaf_top_glowing" },
"half=lower,glowing=5": { "model": "cobblemon:block/mistleaf_bottom_glowing" },
"half=upper,glowing=5": { "model": "cobblemon:block/mistleaf_top_glowing" },
"half=lower,glowing=6": { "model": "cobblemon:block/mistleaf_bottom_glowing" },
"half=upper,glowing=6": { "model": "cobblemon:block/mistleaf_top_glowing" },
"half=lower,glowing=7": { "model": "cobblemon:block/mistleaf_bottom_glowing" },
"half=upper,glowing=7": { "model": "cobblemon:block/mistleaf_top_glowing" },
"half=lower,glowing=8": { "model": "cobblemon:block/mistleaf_bottom_glowing" },
"half=upper,glowing=8": { "model": "cobblemon:block/mistleaf_top_glowing" }
}
}
@@ -0,0 +1,14 @@
{
"variants": {
"age=0,half=lower": { "model": "cobblemon:block/misty_seed_stage0" },
"age=0,half=upper": { "model": "cobblemon:block/misty_seed_stage0" },
"age=1,half=lower": { "model": "cobblemon:block/misty_seed_stage1" },
"age=1,half=upper": { "model": "cobblemon:block/misty_seed_stage1" },
"age=2,half=lower": { "model": "cobblemon:block/misty_seed_bottom_stage2" },
"age=2,half=upper": { "model": "cobblemon:block/misty_seed_top_stage2" },
"age=3,half=lower": { "model": "cobblemon:block/misty_seed_bottom_stage3" },
"age=3,half=upper": { "model": "cobblemon:block/misty_seed_top_stage3" },
"age=4,half=lower": { "model": "cobblemon:block/mistleaf_bottom" },
"age=4,half=upper": { "model": "cobblemon:block/mistleaf_top" }
}
}
@@ -0,0 +1,25 @@
{
"variants": {
"facing=down": {
"model": "cobblemon:block/pauvillea_hanging"
},
"facing=east": {
"model": "cobblemon:block/pauvillea_wall",
"y": 90
},
"facing=north": {
"model": "cobblemon:block/pauvillea_wall"
},
"facing=south": {
"model": "cobblemon:block/pauvillea_wall",
"y": 180
},
"facing=up": {
"model": "cobblemon:block/pauvillea_floor"
},
"facing=west": {
"model": "cobblemon:block/pauvillea_wall",
"y": 270
}
}
}
@@ -0,0 +1,160 @@
{
"multipart": [
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_1"
},
"when": {
"facing": "north",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_1",
"y": 90
},
"when": {
"facing": "east",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_1",
"y": 180
},
"when": {
"facing": "south",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_1",
"y": 270
},
"when": {
"facing": "west",
"amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_2"
},
"when": {
"facing": "north",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_2",
"y": 90
},
"when": {
"facing": "east",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_2",
"y": 180
},
"when": {
"facing": "south",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_2",
"y": 270
},
"when": {
"facing": "west",
"amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_3"
},
"when": {
"facing": "north",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_3",
"y": 90
},
"when": {
"facing": "east",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_3",
"y": 180
},
"when": {
"facing": "south",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_3",
"y": 270
},
"when": {
"facing": "west",
"amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_4"
},
"when": {
"facing": "north",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_4",
"y": 90
},
"when": {
"facing": "east",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_4",
"y": 180
},
"when": {
"facing": "south",
"amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/pink_mint_leaf_litter_4",
"y": 270
},
"when": {
"facing": "west",
"amount": "4"
}
}
]
}
@@ -0,0 +1,160 @@
{
"multipart": [
{
"apply": {
"model": "cobblemon:block/pomohana_1"
},
"when": {
"facing": "north",
"flower_amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_1",
"y": 90
},
"when": {
"facing": "east",
"flower_amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_1",
"y": 180
},
"when": {
"facing": "south",
"flower_amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_1",
"y": 270
},
"when": {
"facing": "west",
"flower_amount": "1|2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_2"
},
"when": {
"facing": "north",
"flower_amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_2",
"y": 90
},
"when": {
"facing": "east",
"flower_amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_2",
"y": 180
},
"when": {
"facing": "south",
"flower_amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_2",
"y": 270
},
"when": {
"facing": "west",
"flower_amount": "2|3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_3"
},
"when": {
"facing": "north",
"flower_amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_3",
"y": 90
},
"when": {
"facing": "east",
"flower_amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_3",
"y": 180
},
"when": {
"facing": "south",
"flower_amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_3",
"y": 270
},
"when": {
"facing": "west",
"flower_amount": "3|4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_4"
},
"when": {
"facing": "north",
"flower_amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_4",
"y": 90
},
"when": {
"facing": "east",
"flower_amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_4",
"y": 180
},
"when": {
"facing": "south",
"flower_amount": "4"
}
},
{
"apply": {
"model": "cobblemon:block/pomohana_4",
"y": 270
},
"when": {
"facing": "west",
"flower_amount": "4"
}
}
]
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_aguav_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_apicot_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_aspear_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_babiri_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_belue_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/potted_blue_mint"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_bluk_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_charti_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_cheri_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_chesto_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_chilan_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_chople_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_coba_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_colbur_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_cornn_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_custap_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/potted_cyan_mint"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_durin_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_eggant_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_enigma_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_figy_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_ganlon_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/potted_green_mint"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_grepa_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_haban_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_hondew_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_hopo_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_iapapa_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_jaboca_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_kasib_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_kebia_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_kee_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_kelpsy_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_lansat_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_leppa_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_liechi_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_lum_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_mago_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_magost_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_maranga_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_micle_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_nanab_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_nomel_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_occa_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_oran_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_pamtre_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_passho_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_payapa_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_pecha_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_persim_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_petaya_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_pinap_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/potted_pink_mint"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_pomeg_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_qualot_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_rabuta_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_rawst_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_razz_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/potted_red_mint"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_rindo_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_roseli_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_rowap_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_salac_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_shuca_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_sitrus_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_spelon_berry"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/berries/potted_starf_berry"
}
}
}

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