Compare commits

...
Author SHA1 Message Date
dhi_holo ada7f0faf8 Missed some
should be all clean now
2025-06-07 16:11:43 +10:00
dhi_holo e1eff89259 Update en_us.json 2025-06-07 15:36:24 +10:00
dhi_holo cc149a0ff2 They're made of Copper!
We decided that the set name should be copper, so I renamed it all.
2025-06-07 15:35:10 +10:00
dhi_holo 3fea718766 Merge branch 'main' into mechanical-hands 2025-06-07 14:10:34 +10:00
dhi_holo 4a41060533 Merge branch 'main' into mechanical-hands 2025-06-04 09:36:07 +10:00
dhi_holo 78daec9c7b Merge branch 'main' into mechanical-hands 2025-06-03 17:50:15 +10:00
dhi_holo 07f087c35c Merge branch 'cleanup' into mechanical-hands 2025-06-03 14:39:02 +10:00
dhi_holo 19f0bc29f4 Merge branch 'main' into mechanical-hands 2025-06-03 11:38:31 +10:00
dhi_holo 531f64394a Name Change Part 1
We know what they are now, what the series is called is still to be determined
2025-06-03 11:38:13 +10:00
dhi_holo 7044cb35b2 jsons go grrr 2025-06-02 14:08:29 +10:00
dhi_holo e258d6439f Tops and Recipes 2025-06-02 13:53:06 +10:00
dhi_holo 221e51b023 Drops and Spin
Containers drop, fridge faces properly, new fridge texture
2025-06-02 12:20:29 +10:00
dhi_holo c9fe117916 Cool
Fridge pseudo-working (visually, not functionally)
2025-06-01 21:13:20 +10:00
dhi_holo af3b6e3f2a Goes Brrr 2025-06-01 16:57:52 +10:00
dhi_holo 1b7759b77d Tweaks and fix ups 2025-06-01 13:05:09 +10:00
dhi_holo 698c07f0b8 Oven and Washer Work!
Yippee!!

They have the wrong behaviours, but it's still a major step towards these blocks being functional
2025-06-01 12:29:26 +10:00
dhi_holo b0d2df2917 This was a Triumph
I'm making a note here, thank you landon.
2025-05-31 19:18:02 +10:00
dhi_holo f6ad1ab7aa what if i
blam
2025-05-31 17:50:09 +10:00
dhi_holo 3f85ce0c81 Merge branch 'main' into mechanical-hands 2025-05-30 17:13:03 +10:00
dhi_holo e25c3c3d7c Learning
Slowly trying stuff, mmmmm
2025-05-30 17:12:44 +10:00
dhi_holo f16ec1d6d3 Backup
Is this me backing up my work or calling for backup? You'll never know, busy-body
2025-05-30 15:34:11 +10:00
dhi_holo 73e59159a0 Testable State again 2025-05-30 14:11:46 +10:00
dhi_holo 5b7b430e5f Data Start 2025-05-30 13:29:40 +10:00
dhi_holo 4e6f2973c2 Assets
Temporarily changed the mechanical oven to just be a regular block so that testing can be done, and added theoretically all needed assets for the appliances
2025-05-30 12:58:02 +10:00
dhi_holo 822794230d Help - Kobo Kanaeru
Major Struggles, so it's time to make this not local
2025-05-30 09:26:07 +10:00
dhi_holo d58603ff33 Mower
No functions at all, just a model with all the needed rotation behavior and nice decoration. No data, no lang.
2025-05-29 17:01:38 +10:00
dhi_holo 157532f372 Merge branch 'main' into mechanical-hands 2025-05-29 11:26:05 +10:00
dhi_holo 3a1c3fc934 Mechanical Fan (Simple)
Implemented a Mechanical Fan. No data files, no lang translation, no bonus functions beyond being able to turn it on and off. Still needs sound events.
2025-05-28 18:26:19 +10:00
73 changed files with 3703 additions and 8 deletions
@@ -97,6 +97,18 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
val CAMPFIRE: BlockEntityType<CampfireBlockEntity> = this.create("campfire_pot",
BlockEntityType.Builder.of(::CampfireBlockEntity, CobblemonBlocks.CAMPFIRE).build(null)
)
@JvmField
val COPPER_OVEN: BlockEntityType<CopperOvenBlockEntity> = this.create("copper_oven",
BlockEntityType.Builder.of(::CopperOvenBlockEntity, CobblemonBlocks.COPPER_OVEN).build(null)
)
@JvmField
val COPPER_WASHER: BlockEntityType<CopperWasherBlockEntity> = this.create("copper_washer",
BlockEntityType.Builder.of(::CopperWasherBlockEntity, CobblemonBlocks.COPPER_WASHER).build(null)
)
@JvmField
val COPPER_FRIDGE: BlockEntityType<CopperFridgeBlockEntity> = this.create("copper_fridge",
BlockEntityType.Builder.of(::CopperFridgeBlockEntity, CobblemonBlocks.COPPER_FRIDGE).build(null)
)
/*@JvmField
val LURE_CAKE: BlockEntityType<LureCakeBlockEntity> =
@@ -34,10 +34,8 @@ import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.valueproviders.UniformInt
import net.minecraft.world.effect.MobEffects
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.EntityType
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockBehaviour
import net.minecraft.world.level.block.state.BlockState
@@ -494,6 +492,17 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val DISPLAY_CASE = create("display_case", DisplayCaseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3F)))
@JvmField
val COPPER_FAN = create("copper_fan", CopperFanBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
@JvmField
val COPPER_MOWER = create("copper_mower", CopperMowerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
@JvmField
val COPPER_OVEN = create("copper_oven", CopperOvenBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
@JvmField
val COPPER_WASHER = this.create("copper_washer", CopperWasherBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
@JvmField
val COPPER_FRIDGE = this.create("copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
@JvmField
val INCENSE_SWEET = create("incense_sweet", SweetIncenseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3f)))
@@ -483,6 +483,17 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val INCENSE_SWEET = blockItem("incense_sweet", CobblemonBlocks.INCENSE_SWEET)
@JvmField
val COPPER_FAN = blockItem("copper_fan", CobblemonBlocks.COPPER_FAN)
@JvmField
val COPPER_MOWER = blockItem("copper_mower", CobblemonBlocks.COPPER_MOWER)
@JvmField
val COPPER_OVEN = blockItem("copper_oven", CobblemonBlocks.COPPER_OVEN)
@JvmField
val COPPER_WASHER = blockItem("copper_washer", CobblemonBlocks.COPPER_WASHER)
@JvmField
val COPPER_FRIDGE = blockItem("copper_fridge", CobblemonBlocks.COPPER_FRIDGE)
// Evolution items
@JvmField val LINK_CABLE = create("link_cable", LinkCableItem())
@@ -0,0 +1,190 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.CobblemonSounds
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.block.state.properties.BooleanProperty
import net.minecraft.world.level.gameevent.GameEvent
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class CopperFanBlock(settings: Properties) : Block(settings), SimpleWaterloggedBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH)
.setValue(ACTIVE, false)
.setValue(WATERLOGGED, false)
)
}
override fun getStateForPlacement(ctx: BlockPlaceContext): BlockState? {
var blockState = defaultBlockState().setValue(ACTIVE, false)
.setValue(WATERLOGGED, ctx.level.getFluidState(ctx.clickedPos).type == Fluids.WATER)
val worldView = ctx.level
val blockPos = ctx.clickedPos
ctx.nearestLookingDirections.forEach { direction ->
if (direction.axis.isHorizontal) {
blockState = blockState.setValue(FACING, direction.opposite) as BlockState
if (blockState.canSurvive(worldView, blockPos)) {
return blockState
}
}
}
return null
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HORIZONTAL_FACING)
builder.add(ACTIVE)
builder.add(WATERLOGGED)
}
override fun getShape(
state: BlockState,
blockGetter: BlockGetter,
pos: BlockPos,
collisionContext: CollisionContext
): VoxelShape {
return when (state.getValue(HorizontalDirectionalBlock.FACING)) {
Direction.SOUTH -> NS_AABB
Direction.WEST -> EW_AABB
Direction.EAST -> EW_AABB
else -> NS_AABB
}
}
override fun useWithoutItem(
state: BlockState,
level: Level,
pos: BlockPos,
player: Player,
hitResult: BlockHitResult
): InteractionResult {
if (level.isClientSide) {
level.setBlockAndUpdate(pos, state.cycle(ACTIVE))
return InteractionResult.SUCCESS
} else {
this.push(state, level, pos, null as Player?)
return InteractionResult.CONSUME
}
}
fun push(state: BlockState, level: Level, pos: BlockPos?, player: Player?) {
var state = state
state = state.cycle(ACTIVE)
level.setBlock(pos!!, state, 3)
level.gameEvent(player, if (state.getValue(ACTIVE)) GameEvent.BLOCK_ACTIVATE else GameEvent.BLOCK_DEACTIVATE, pos)
playSound(level, pos, state, CobblemonSounds.DISPLAY_CASE_PLACE)
}
override fun getFluidState(blockState: BlockState): FluidState? {
return if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState);
}
@Deprecated("Deprecated in Java")
override fun rotate(state: BlockState, rotation: Rotation): BlockState {
return state.setValue(HORIZONTAL_FACING, rotation.rotate(state.getValue(HORIZONTAL_FACING)))
}
@Deprecated("Deprecated in Java")
override fun isPathfindable(state: BlockState, type: PathComputationType): Boolean {
return false
}
@Deprecated("Deprecated in Java")
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
if (state.getValue(WATERLOGGED)) {
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
}
return if (direction == state.getValue(FACING) && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
companion object {
val CODEC = simpleCodec(::CopperFanBlock)
val ACTIVE = BooleanProperty.create("active")
private val NS_AABB = Shapes.or(
Shapes.box(0.125, 0.25, 0.4375, 0.875, 1.0, 0.5625),
Shapes.box(0.4375, 0.125, 0.4375, 0.5625, 0.25, 0.5625),
Shapes.box(0.3125, 0.0, 0.3125, 0.6875, 0.125, 0.6875)
)
private val EW_AABB = Shapes.or(
Shapes.box(0.4375, 0.25, 0.125, 0.5625, 1.0, 0.875),
Shapes.box(0.4375, 0.125, 0.4375, 0.5625, 0.25, 0.5625),
Shapes.box(0.3125, 0.0, 0.3125, 0.6875, 0.125, 0.6875)
)
fun playSound(world: Level, pos: BlockPos, state: BlockState, sound: SoundEvent) {
var d = pos.x.toDouble() + 0.5
val e = pos.y.toDouble() + 0.5
var f = pos.z.toDouble() + 0.5
val direction = state.getValue(BlockStateProperties.HORIZONTAL_FACING)
d += direction.stepX.toDouble() * 0.5
f += direction.stepZ.toDouble() * 0.5
world.playSound(
null,
d,
e,
f,
sound,
SoundSource.BLOCKS,
0.5f,
world.random.nextFloat() * 0.1f + 0.9f
)
}
}
//TODO Get it to be a cleanly looping sound, and get Sterr to make a proper sound for it
/* override fun animateTick(state: BlockState, level: Level, pos: BlockPos, random: RandomSource) {
if ((state.getValue(ACTIVE))) {
if (random.nextInt(6) == 0) {
level.playLocalSound(
pos.x.toDouble() + 0.5,
pos.y.toDouble() + 0.5,
pos.z.toDouble() + 0.5,
CobblemonSounds.EVOLUTION_NOTIFICATION,
SoundSource.BLOCKS,
1f,
1f,
false
)
}
}
}*/
}
@@ -0,0 +1,306 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.block.entity.CopperFridgeBlockEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.util.StringRepresentable
import net.minecraft.world.Containers
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.monster.piglin.PiglinAi
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.LevelReader
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.block.state.properties.EnumProperty
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class CopperFridgeBlock(properties: Properties): BaseEntityBlock(properties), SimpleWaterloggedBlock {
companion object {
val CODEC = simpleCodec(::CopperFridgeBlock)
val PART = EnumProperty.create("part", CopperFridgePart::class.java)
private val NORTH_AABB_TOP = Shapes.or(
Shapes.box(0.0, 0.0, 0.0625, 1.0, 1.0, 1.0),
Shapes.box(0.25, 0.125, 0.0, 0.375, 0.3125, 0.0625),
Shapes.box(0.625, 0.125, 0.0, 0.75, 0.3125, 0.0625)
)
private val SOUTH_AABB_TOP = Shapes.or(
Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.9375),
Shapes.box(0.625, 0.125, 0.9375, 0.75, 0.3125, 1.0),
Shapes.box(0.25, 0.125, 0.9375, 0.375, 0.3125, 1.0)
)
private val WEST_AABB_TOP = Shapes.or(
Shapes.box(0.0625, 0.0, 0.0, 1.0, 1.0, 1.0),
Shapes.box(0.0, 0.125, 0.625, 0.0625, 0.3125, 0.75),
Shapes.box(0.0, 0.125, 0.25, 0.0625, 0.3125, 0.375)
)
private val EAST_AABB_TOP = Shapes.or(
Shapes.box(0.0, 0.0, 0.0, 0.9375, 1.0, 1.0),
Shapes.box(0.9375, 0.125, 0.25, 1.0, 0.3125, 0.375),
Shapes.box(0.9375, 0.125, 0.625, 1.0, 0.3125, 0.75)
)
private val NORTH_AABB_BOTTOM = Shapes.or(
Shapes.box(0.0, 0.0625, 0.0625, 1.0, 1.0, 1.0),
Shapes.box(0.0625, 0.0, 0.125, 0.9375, 0.0625, 0.9375)
)
private val SOUTH_AABB_BOTTOM = Shapes.or(
Shapes.box(0.0, 0.0625, 0.0, 1.0, 1.0, 0.9375),
Shapes.box(0.0625, 0.0, 0.0625, 0.9375, 0.0625, 0.875)
)
private val WEST_AABB_BOTTOM = Shapes.or(
Shapes.box(0.0625, 0.0625, 0.0, 1.0, 1.0, 1.0),
Shapes.box(0.125, 0.0, 0.0625, 0.9375, 0.0625, 0.9375)
)
private val EAST_AABB_BOTTOM = Shapes.or(
Shapes.box(0.0, 0.0625, 0.0, 0.9375, 1.0, 1.0),
Shapes.box(0.0625, 0.0, 0.0625, 0.875, 0.0625, 0.9375)
)
}
enum class CopperFridgePart(private val label: String) : StringRepresentable {
TOP("top"),
BOTTOM("bottom");
override fun getSerializedName(): String = label
}
init {
registerDefaultState(stateDefinition.any()
.setValue(HorizontalDirectionalBlock.FACING, Direction.NORTH)
.setValue(PART, CopperFridgePart.BOTTOM)
.setValue(WATERLOGGED, false)
)
}
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState) = if (blockState.getValue(PART) == CopperFridgePart.BOTTOM) CopperFridgeBlockEntity(blockPos, blockState) else null
override fun getName(): MutableComponent {
return Component.translatable("block.cobblemon.copper_fridge")
}
override fun getShape(
blockState: BlockState,
blockGetter: BlockGetter,
blockPos: BlockPos,
collisionContext: CollisionContext
): VoxelShape {
return if (blockState.getValue(PART) == CopperFridgePart.TOP) {
when (blockState.getValue(HorizontalDirectionalBlock.FACING)) {
Direction.SOUTH -> SOUTH_AABB_TOP
Direction.WEST -> WEST_AABB_TOP
Direction.EAST -> EAST_AABB_TOP
else -> NORTH_AABB_TOP
}
} else {
when (blockState.getValue(HorizontalDirectionalBlock.FACING)) {
Direction.SOUTH -> SOUTH_AABB_BOTTOM
Direction.WEST -> WEST_AABB_BOTTOM
Direction.EAST -> EAST_AABB_BOTTOM
else -> NORTH_AABB_BOTTOM
}
}
}
fun getPositionOfOtherPart(state: BlockState, pos: BlockPos): BlockPos {
return if (state.getValue(PART) == CopperFridgePart.BOTTOM) {
pos.above()
} else {
pos.below()
}
}
fun getBasePosition(state: BlockState, pos: BlockPos): BlockPos {
return if (isBase(state)) {
pos
} else {
pos.below()
}
}
private fun isBase(state: BlockState): Boolean = state.getValue(PART) == CopperFridgePart.BOTTOM
override fun setPlacedBy(
world: Level,
pos: BlockPos,
state: BlockState,
placer: LivingEntity?,
itemStack: ItemStack
) {
world.setBlock(pos.above(),
state
.setValue(PART, CopperFridgePart.TOP)
.setValue(WATERLOGGED, world.getFluidState((pos.above())).type == Fluids.WATER)
, 3)
world.blockUpdated(pos, Blocks.AIR)
state.updateNeighbourShapes(world, pos, 3)
}
override fun getStateForPlacement(blockPlaceContext: BlockPlaceContext): BlockState? {
val abovePosition = blockPlaceContext.clickedPos.above()
val world = blockPlaceContext.level
if (world.getBlockState(abovePosition).canBeReplaced(blockPlaceContext) && !world.isOutsideBuildHeight(abovePosition)) {
return defaultBlockState()
.setValue(HorizontalDirectionalBlock.FACING, blockPlaceContext.horizontalDirection.opposite)
.setValue(PART, CopperFridgePart.BOTTOM)
.setValue(WATERLOGGED, blockPlaceContext.level.getFluidState(blockPlaceContext.clickedPos).type == Fluids.WATER)
}
return null
}
override fun canSurvive(state: BlockState, world: LevelReader, pos: BlockPos): Boolean {
val blockPos = pos.below()
val blockState = world.getBlockState(blockPos)
return if (state.getValue(PART) == CopperFridgePart.BOTTOM) blockState.isFaceSturdy(world, blockPos, Direction.UP) else blockState.`is`(this)// todo (techdaan): ensure this is the right mapping
}
override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
if (!world.isClientSide && player?.isCreative == true) {
var blockPos: BlockPos = BlockPos.ZERO
var blockState: BlockState = state
val part = state.getValue(PART)
if (part == CopperFridgePart.TOP && world.getBlockState(pos.below().also { blockPos = it }).also { blockState = it }.`is`(state.block) && blockState.getValue(PART) == CopperFridgePart.BOTTOM) {
val blockState2 = if (blockState.fluidState.`is`(Fluids.WATER)) Blocks.WATER.defaultBlockState() else Blocks.AIR.defaultBlockState()
world.setBlock(blockPos, blockState2, UPDATE_ALL or UPDATE_SUPPRESS_DROPS)
world.levelEvent(player, LevelEvent.PARTICLES_DESTROY_BLOCK, blockPos, getId(blockState))
}
}
return super.playerWillDestroy(world, pos, state, player)
}
override fun codec() = CODEC
@Deprecated("Deprecated in Java")
override fun isPathfindable(
blockState: BlockState,
pathComputationType: PathComputationType
): Boolean = false
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HorizontalDirectionalBlock.FACING)
builder.add(PART)
builder.add(WATERLOGGED)
}
@Deprecated("Deprecated in Java")
override fun rotate(blockState: BlockState, rotation: Rotation) =
blockState.setValue(
HorizontalDirectionalBlock.FACING, rotation.rotate(blockState.getValue(
HorizontalDirectionalBlock.FACING)))
override fun onRemove(state: BlockState, world: Level, pos: BlockPos, newState: BlockState, moved: Boolean) {
if (!state.`is`(newState.block)) {
Containers.dropContentsOnDestroy(state, newState, world, pos)
super.onRemove(state, world, pos, newState, moved)
}
}
override fun hasAnalogOutputSignal(state: BlockState): Boolean {
return true
}
override fun getAnalogOutputSignal(state: BlockState, world: Level, pos: BlockPos): Int {
return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos))
}
override fun useWithoutItem(
state: BlockState,
world: Level,
pos: BlockPos,
player: Player,
hit: BlockHitResult
): InteractionResult {
val basePos = getBasePosition(state, pos)
// Remove any duplicate block entities that may exist
world.getBlockEntity(basePos.above())?.setRemoved()
val baseEntity = world.getBlockEntity(basePos)
if (baseEntity !is CopperFridgeBlockEntity) return InteractionResult.SUCCESS
player.openMenu(baseEntity)
if (!player.level().isClientSide) {
PiglinAi.angerNearbyPiglins(player, true)
}
return InteractionResult.SUCCESS
}
override fun getRenderShape(state: BlockState) = RenderShape.ENTITYBLOCK_ANIMATED
override fun getFluidState(state: BlockState): FluidState? {
return if (state.getValue(WATERLOGGED)) {
Fluids.WATER.getSource(false)
} else super.getFluidState(state)
}
enum class Type(val poserId: ResourceLocation) : StringRepresentable {
RED(cobblemonResource("copper_fridge"));
override fun getSerializedName(): String = name.lowercase()
companion object {
val CODEC = StringRepresentable.fromValues(::values)
}
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
if (state.getValue(WATERLOGGED)) {
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
}
val isFridge = neighborState.`is`(this)
val part = state.getValue(PART)
if (!isFridge && part == CopperFridgePart.TOP && neighborPos == pos.below()) {
return Blocks.AIR.defaultBlockState()
} else if (!isFridge && part == CopperFridgePart.BOTTOM && neighborPos == pos.above()) {
return Blocks.AIR.defaultBlockState()
}
return state
}
override fun tick(state: BlockState, world: ServerLevel, pos: BlockPos, random: RandomSource) {
val blockEntity = world.getBlockEntity(pos) as? CopperFridgeBlockEntity ?: return
blockEntity.tick()
}
}
@@ -0,0 +1,133 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING
import net.minecraft.world.level.block.Rotation
import net.minecraft.world.level.block.SimpleWaterloggedBlock
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
class CopperMowerBlock(settings: Properties) : Block(settings), SimpleWaterloggedBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.NORTH)
.setValue(WATERLOGGED, false)
)
}
override fun getStateForPlacement(ctx: BlockPlaceContext): BlockState? {
var blockState = defaultBlockState()
.setValue(WATERLOGGED, ctx.level.getFluidState(ctx.clickedPos).type == Fluids.WATER)
val worldView = ctx.level
val blockPos = ctx.clickedPos
ctx.nearestLookingDirections.forEach { direction ->
if (direction.axis.isHorizontal) {
blockState = blockState.setValue(FACING, direction.opposite) as BlockState
if (blockState.canSurvive(worldView, blockPos)) {
return blockState
}
}
}
return null
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(HORIZONTAL_FACING)
builder.add(WATERLOGGED)
}
override fun getShape(
state: BlockState,
blockGetter: BlockGetter,
pos: BlockPos,
collisionContext: CollisionContext
): VoxelShape {
return when (state.getValue(FACING)) {
Direction.EAST -> EAST_OUTLINE
Direction.SOUTH -> SOUTH_OUTLINE
Direction.WEST -> WEST_OUTLINE
else -> NORTH_OUTLINE
}
}
override fun getFluidState(blockState: BlockState): FluidState? {
return if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState);
}
@Deprecated("Deprecated in Java")
override fun rotate(state: BlockState, rotation: Rotation): BlockState {
return state.setValue(HORIZONTAL_FACING, rotation.rotate(state.getValue(HORIZONTAL_FACING)))
}
@Deprecated("Deprecated in Java")
override fun isPathfindable(state: BlockState, type: PathComputationType): Boolean {
return false
}
@Deprecated("Deprecated in Java")
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
if (state.getValue(WATERLOGGED)) {
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
}
return if (direction == state.getValue(FACING) && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
companion object {
val CODEC = simpleCodec(::CopperMowerBlock)
val SOUTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.0, 0.9375, 0.625, 0.375),
Shapes.box(0.1875, 0.0, 0.375, 0.8125, 0.375, 1.0),
Shapes.box(0.8125, 0.0, 0.5, 0.875, 0.3125, 0.8125),
Shapes.box(0.125, 0.0, 0.5, 0.1875, 0.3125, 0.8125)
)
val NORTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.625, 0.9375, 0.625, 1.0),
Shapes.box(0.1875, 0.0, 0.0, 0.8125, 0.375, 0.625),
Shapes.box(0.125, 0.0, 0.1875, 0.1875, 0.3125, 0.5),
Shapes.box(0.8125, 0.0, 0.1875, 0.875, 0.3125, 0.5)
)
val WEST_OUTLINE = Shapes.or(
Shapes.box(0.625, 0.0, 0.0625, 1.0, 0.625, 0.9375),
Shapes.box(0.0, 0.0, 0.1875, 0.625, 0.375, 0.8125),
Shapes.box(0.1875, 0.0, 0.8125, 0.5, 0.3125, 0.875),
Shapes.box(0.1875, 0.0, 0.125, 0.5, 0.3125, 0.1875),
)
val EAST_OUTLINE = Shapes.or(
Shapes.box(0.0, 0.0, 0.0625, 0.375, 0.625, 0.9375),
Shapes.box(0.375, 0.0, 0.1875, 1.0, 0.375, 0.8125),
Shapes.box(0.5, 0.0, 0.125, 0.8125, 0.3125, 0.1875),
Shapes.box(0.5, 0.0, 0.8125, 0.8125, 0.3125, 0.875)
)
}
}
@@ -0,0 +1,227 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.block.entity.CopperOvenBlockEntity
import com.cobblemon.mod.common.util.cobblemonResource
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.util.StringRepresentable
import net.minecraft.world.Containers
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.monster.piglin.PiglinAi
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
@Suppress("OVERRIDE_DEPRECATION")
class CopperOvenBlock(settings: Properties) : BaseEntityBlock(settings),
SimpleWaterloggedBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.SOUTH)
.setValue(WATERLOGGED, false))
}
companion object {
val CODEC: MapCodec<CopperOvenBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::CopperOvenBlock)
}
val SOUTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.125, 0.9375, 0.625, 0.8125)
)
val NORTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.1875, 0.9375, 0.625, 0.875)
)
val WEST_OUTLINE = Shapes.or(
Shapes.box(0.1875, 0.0, 0.0625, 0.875, 0.625, 0.9375)
)
val EAST_OUTLINE = Shapes.or(
Shapes.box(0.125, 0.0, 0.0625, 0.8125, 0.625, 0.9375)
)
}
override fun getShape(
state: BlockState,
world: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
return when (state.getValue(HorizontalDirectionalBlock.FACING)) {
Direction.NORTH -> NORTH_OUTLINE
Direction.EAST -> EAST_OUTLINE
Direction.WEST -> WEST_OUTLINE
else -> SOUTH_OUTLINE
}
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
if (state.getValue(WATERLOGGED)) world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
return super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
override fun getFluidState(state: BlockState): FluidState {
return if (state.getValue(WATERLOGGED)) {
Fluids.WATER.getSource(false)
} else super.getFluidState(state)
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
super.createBlockStateDefinition(builder)
builder.add(HORIZONTAL_FACING)
builder.add(WATERLOGGED)
}
override fun newBlockEntity(pos: BlockPos, state: BlockState) = CopperOvenBlockEntity(pos, state)
private val facingToYaw: HashMap<Direction, Float> = hashMapOf(
Direction.NORTH to -179.0F,
Direction.WEST to 90.0F,
Direction.SOUTH to 0.0F,
Direction.EAST to -90.0F
)
override fun getName(): MutableComponent {
return Component.translatable("block.cobblemon.copper_oven")
}
override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
if (!world.isClientSide) {}
return super.playerWillDestroy(world, pos, state, player)
}
override fun onRemove(
state: BlockState,
world: Level,
pos: BlockPos,
newState: BlockState,
moved: Boolean
) {
Containers.dropContentsOnDestroy(state, newState, world, pos)
super.onRemove(state, world, pos, newState, moved)
}
override fun useWithoutItem(
state: BlockState,
world: Level,
pos: BlockPos,
player: Player,
hit: BlockHitResult
): InteractionResult {
val entity = world.getBlockEntity(pos) as? CopperOvenBlockEntity ?: return InteractionResult.FAIL
player.openMenu(entity)
if (!player.level().isClientSide) {
PiglinAi.angerNearbyPiglins(player, true)
}
return InteractionResult.SUCCESS
}
override fun getRenderShape(state: BlockState) = RenderShape.ENTITYBLOCK_ANIMATED
override fun getStateForPlacement(blockPlaceContext: BlockPlaceContext): BlockState {
return defaultBlockState()
.setValue(HorizontalDirectionalBlock.FACING, blockPlaceContext.horizontalDirection.opposite)
.setValue(WATERLOGGED, blockPlaceContext.level.getFluidState(blockPlaceContext.clickedPos).type == Fluids.WATER)
}
@Deprecated("Deprecated in Java")
override fun rotate(state: BlockState, rotation: Rotation): BlockState {
return state.setValue(
HORIZONTAL_FACING, rotation.rotate(
state.getValue(HORIZONTAL_FACING) as Direction
)
) as BlockState
}
override fun hasAnalogOutputSignal(state: BlockState): Boolean {
return true
}
override fun getAnalogOutputSignal(state: BlockState, world: Level, pos: BlockPos): Int {
return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos))
}
override fun mirror(state: BlockState, mirror: Mirror): BlockState {
return state.rotate(mirror.getRotation(state.getValue(HORIZONTAL_FACING) as Direction))
}
enum class Type(val poserId: ResourceLocation) : StringRepresentable {
RED(cobblemonResource("copper_oven"));
override fun getSerializedName(): String = name.lowercase()
companion object {
val CODEC = StringRepresentable.fromValues(::values)
}
}
@Deprecated("Deprecated in Java")
override fun isPathfindable(state: BlockState, type: PathComputationType): Boolean {
return false
}
override fun codec(): MapCodec<out BaseEntityBlock> {
return CODEC
}
override fun setPlacedBy(
world: Level,
pos: BlockPos,
state: BlockState,
placer: LivingEntity?,
itemStack: ItemStack
) {
//Theoretically this is no longer needed according to https://fabricmc.net/2024/04/19/1205.html
/*
val blockEntity = world.getBlockEntity(pos)
if (itemStack.get(DataComponentTypes.CUSTOM_NAME) != && blockEntity is GildedChestBlockEntity) {
blockEntity.customName = itemStack.name
}
*/
}
override fun tick(state: BlockState, world: ServerLevel, pos: BlockPos, random: RandomSource) {
val blockEntity = world.getBlockEntity(pos) as? CopperOvenBlockEntity ?: return
blockEntity.tick()
}
}
@@ -0,0 +1,235 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.block.entity.CopperWasherBlockEntity
import com.cobblemon.mod.common.util.cobblemonResource
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource
import net.minecraft.util.StringRepresentable
import net.minecraft.world.Containers
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.monster.piglin.PiglinAi
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.material.FluidState
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
@Suppress("OVERRIDE_DEPRECATION")
class CopperWasherBlock(settings: Properties) : BaseEntityBlock(settings),
SimpleWaterloggedBlock {
init {
registerDefaultState(stateDefinition.any()
.setValue(HORIZONTAL_FACING, Direction.SOUTH)
.setValue(WATERLOGGED, false))
}
companion object {
val CODEC: MapCodec<CopperWasherBlock> = RecordCodecBuilder.mapCodec {
it.group(propertiesCodec()).apply(it, ::CopperWasherBlock)
}
private val NORTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.125, 0.9375, 0.875, 1.0),
Shapes.box(0.25, 0.125, 0.0625, 0.75, 0.625, 0.125),
Shapes.box(0.9375, 0.125, 0.6875, 1.0, 0.375, 0.9375)
)
private val SOUTH_OUTLINE = Shapes.or(
Shapes.box(0.0625, 0.0, 0.0, 0.9375, 0.875, 0.875),
Shapes.box(0.25, 0.125, 0.875, 0.75, 0.625, 0.9375),
Shapes.box(0.0, 0.125, 0.0625, 0.0625, 0.375, 0.3125)
)
private val WEST_OUTLINE = Shapes.or(
Shapes.box(0.125, 0.0, 0.0625, 1.0, 0.875, 0.9375),
Shapes.box(0.0625, 0.125, 0.25, 0.125, 0.625, 0.75),
Shapes.box(0.6875, 0.125, 0.0, 0.9375, 0.375, 0.0625)
)
private val EAST_OUTLINE = Shapes.or(
Shapes.box(0.0, 0.0, 0.0625, 0.875, 0.875, 0.9375),
Shapes.box(0.875, 0.125, 0.25, 0.9375, 0.625, 0.75),
Shapes.box(0.0625, 0.125, 0.9375, 0.3125, 0.375, 1.0)
)
}
override fun getShape(
state: BlockState,
world: BlockGetter,
pos: BlockPos,
context: CollisionContext
): VoxelShape {
return when (state.getValue(HorizontalDirectionalBlock.FACING)) {
Direction.NORTH -> NORTH_OUTLINE
Direction.EAST -> EAST_OUTLINE
Direction.WEST -> WEST_OUTLINE
else -> SOUTH_OUTLINE
}
}
override fun updateShape(
state: BlockState,
direction: Direction,
neighborState: BlockState,
world: LevelAccessor,
pos: BlockPos,
neighborPos: BlockPos
): BlockState {
if (state.getValue(WATERLOGGED)) world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
return super.updateShape(state, direction, neighborState, world, pos, neighborPos)
}
override fun getFluidState(state: BlockState): FluidState {
return if (state.getValue(WATERLOGGED)) {
Fluids.WATER.getSource(false)
} else super.getFluidState(state)
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
super.createBlockStateDefinition(builder)
builder.add(HORIZONTAL_FACING)
builder.add(WATERLOGGED)
}
override fun newBlockEntity(pos: BlockPos, state: BlockState) = CopperWasherBlockEntity(pos, state)
private val facingToYaw: HashMap<Direction, Float> = hashMapOf(
Direction.NORTH to -179.0F,
Direction.WEST to 90.0F,
Direction.SOUTH to 0.0F,
Direction.EAST to -90.0F
)
override fun getName(): MutableComponent {
return Component.translatable("block.cobblemon.copper_washer")
}
override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
if (!world.isClientSide) {}
return super.playerWillDestroy(world, pos, state, player)
}
override fun onRemove(
state: BlockState,
world: Level,
pos: BlockPos,
newState: BlockState,
moved: Boolean
) {
Containers.dropContentsOnDestroy(state, newState, world, pos)
super.onRemove(state, world, pos, newState, moved)
}
override fun useWithoutItem(
state: BlockState,
world: Level,
pos: BlockPos,
player: Player,
hit: BlockHitResult
): InteractionResult {
val entity = world.getBlockEntity(pos) as? CopperWasherBlockEntity ?: return InteractionResult.FAIL
player.openMenu(entity)
if (!player.level().isClientSide) {
PiglinAi.angerNearbyPiglins(player, true)
}
return InteractionResult.SUCCESS
}
override fun getRenderShape(state: BlockState) = RenderShape.ENTITYBLOCK_ANIMATED
override fun getStateForPlacement(blockPlaceContext: BlockPlaceContext): BlockState {
return defaultBlockState()
.setValue(HorizontalDirectionalBlock.FACING, blockPlaceContext.horizontalDirection.opposite)
.setValue(WATERLOGGED, blockPlaceContext.level.getFluidState(blockPlaceContext.clickedPos).type == Fluids.WATER)
}
@Deprecated("Deprecated in Java")
override fun rotate(state: BlockState, rotation: Rotation): BlockState {
return state.setValue(
HORIZONTAL_FACING, rotation.rotate(
state.getValue(HORIZONTAL_FACING) as Direction
)
) as BlockState
}
override fun hasAnalogOutputSignal(state: BlockState): Boolean {
return true
}
override fun getAnalogOutputSignal(state: BlockState, world: Level, pos: BlockPos): Int {
return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos))
}
override fun mirror(state: BlockState, mirror: Mirror): BlockState {
return state.rotate(mirror.getRotation(state.getValue(HORIZONTAL_FACING) as Direction))
}
enum class Type(val poserId: ResourceLocation) : StringRepresentable {
RED(cobblemonResource("copper_washer"));
override fun getSerializedName(): String = name.lowercase()
companion object {
val CODEC = StringRepresentable.fromValues(::values)
}
}
@Deprecated("Deprecated in Java")
override fun isPathfindable(state: BlockState, type: PathComputationType): Boolean {
return false
}
override fun codec(): MapCodec<out BaseEntityBlock> {
return CODEC
}
override fun setPlacedBy(
world: Level,
pos: BlockPos,
state: BlockState,
placer: LivingEntity?,
itemStack: ItemStack
) {
//Theoretically this is no longer needed according to https://fabricmc.net/2024/04/19/1205.html
/*
val blockEntity = world.getBlockEntity(pos)
if (itemStack.get(DataComponentTypes.CUSTOM_NAME) != && blockEntity is GildedChestBlockEntity) {
blockEntity.customName = itemStack.name
}
*/
}
override fun tick(state: BlockState, world: ServerLevel, pos: BlockPos, random: RandomSource) {
val blockEntity = world.getBlockEntity(pos) as? CopperWasherBlockEntity ?: return
blockEntity.tick()
}
}
@@ -0,0 +1,168 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.entity
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.block.chest.GildedState
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup
import net.minecraft.core.NonNullList
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
import net.minecraft.world.ContainerHelper
import net.minecraft.world.WorldlyContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.ChestMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.ContainerOpenersCounter
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperFridgeBlockEntity(pos: BlockPos, state: BlockState) : RandomizableContainerBlockEntity(CobblemonBlockEntities.COPPER_FRIDGE, pos, state), WorldlyContainer {
var inventoryContents: NonNullList<ItemStack> = NonNullList.withSize(NUM_SLOTS, ItemStack.EMPTY)
val posableState: GildedState = GildedState()
private val stateManager: ContainerOpenersCounter = object : ContainerOpenersCounter() {
override fun onOpen(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_OPEN)
}
override fun onClose(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_CLOSE)
}
override fun openerCountChanged(
world: Level,
pos: BlockPos,
state: BlockState,
oldViewerCount: Int,
newViewerCount: Int
) {
this@CopperFridgeBlockEntity.onViewerCountUpdate(world, pos, state, oldViewerCount, newViewerCount)
}
override fun isOwnContainer(player: Player): Boolean {
if (player.containerMenu is ChestMenu) {
val inventory = (player.containerMenu as ChestMenu).container
return inventory === this@CopperFridgeBlockEntity
}
return false
}
}
override fun getContainerSize() = NUM_SLOTS
override fun getDefaultName() = Component.translatable("block.cobblemon.copper_fridge")
override fun createMenu(syncId: Int, playerInventory: Inventory): AbstractContainerMenu =
ChestMenu.sixRows(syncId, playerInventory, this)
override fun getItems() = inventoryContents
override fun startOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.incrementOpeners(player, level, blockPos, blockState)
}
}
override fun stopOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.decrementOpeners(player, level, blockPos, blockState)
}
}
override fun getSlotsForFace(side: Direction): IntArray {
return IntArray(NUM_SLOTS) { it }
}
override fun canPlaceItemThroughFace(slot: Int, stack: ItemStack, dir: Direction?): Boolean {
return dir != Direction.DOWN
}
override fun canTakeItemThroughFace(slot: Int, stack: ItemStack, dir: Direction): Boolean {
return dir == Direction.DOWN
}
override fun stillValid(player: Player) = !player.isSpectator
override fun setItems(inventory: NonNullList<ItemStack>) {
inventoryContents = inventory
}
companion object {
val NUM_SLOTS = 54
fun playSound(world: Level, pos: BlockPos, state: BlockState, sound: SoundEvent) {
var d = pos.x.toDouble() + 0.5
val e = pos.y.toDouble() + 0.5
var f = pos.z.toDouble() + 0.5
val direction = state.getValue(BlockStateProperties.HORIZONTAL_FACING)
d += direction.stepX.toDouble() * 0.5
f += direction.stepZ.toDouble() * 0.5
world.playSound(
null,
d,
e,
f,
sound,
SoundSource.BLOCKS,
0.5f,
world.random.nextFloat() * 0.1f + 0.9f
)
}
}
override fun triggerEvent(type: Int, data: Int): Boolean {
if (type == 1) {
val isNowOpen = data > 0
val wasOpen = posableState.currentPose == "open"
val model = posableState.currentModel ?: return true
if (isNowOpen && !wasOpen) {
model.moveToPose(posableState, model.poses["open"]!!)
} else if (!isNowOpen && wasOpen) {
model.moveToPose(posableState, model.poses["closed"]!!)
}
return true
}
return super.triggerEvent(type, data)
}
fun onViewerCountUpdate(world: Level, pos: BlockPos, state: BlockState, oldViewerCount: Int, newViewerCount: Int) {
val block = state.block
world.blockEvent(pos, block, 1, newViewerCount)
}
override fun saveAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.saveAdditional(nbt, registryLookup)
if (!trySaveLootTable(nbt)) {
ContainerHelper.saveAllItems(nbt, inventoryContents, registryLookup)
}
}
override fun loadAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.loadAdditional(nbt, registryLookup)
inventoryContents= NonNullList.withSize(containerSize, ItemStack.EMPTY)
if (!tryLoadLootTable(nbt)) {
ContainerHelper.loadAllItems(nbt, inventoryContents, registryLookup)
}
}
fun tick() {
if (!this.remove) {
stateManager.recheckOpeners(level, blockPos, this.blockState)
}
}
}
@@ -0,0 +1,168 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.entity
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.block.chest.GildedState
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup
import net.minecraft.core.NonNullList
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
import net.minecraft.world.ContainerHelper
import net.minecraft.world.WorldlyContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.ChestMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.ContainerOpenersCounter
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperOvenBlockEntity(pos: BlockPos, state: BlockState) : RandomizableContainerBlockEntity(CobblemonBlockEntities.COPPER_OVEN, pos, state), WorldlyContainer {
var inventoryContents: NonNullList<ItemStack> = NonNullList.withSize(NUM_SLOTS, ItemStack.EMPTY)
val posableState: GildedState = GildedState()
private val stateManager: ContainerOpenersCounter = object : ContainerOpenersCounter() {
override fun onOpen(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_OPEN)
}
override fun onClose(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_CLOSE)
}
override fun openerCountChanged(
world: Level,
pos: BlockPos,
state: BlockState,
oldViewerCount: Int,
newViewerCount: Int
) {
this@CopperOvenBlockEntity.onViewerCountUpdate(world, pos, state, oldViewerCount, newViewerCount)
}
override fun isOwnContainer(player: Player): Boolean {
if (player.containerMenu is ChestMenu) {
val inventory = (player.containerMenu as ChestMenu).container
return inventory === this@CopperOvenBlockEntity
}
return false
}
}
override fun getContainerSize() = NUM_SLOTS
override fun getDefaultName() = Component.translatable("block.cobblemon.copper_oven")
override fun createMenu(syncId: Int, playerInventory: Inventory): AbstractContainerMenu =
ChestMenu.threeRows(syncId, playerInventory, this)
override fun getItems() = inventoryContents
override fun startOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.incrementOpeners(player, level, blockPos, blockState)
}
}
override fun stopOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.decrementOpeners(player, level, blockPos, blockState)
}
}
override fun getSlotsForFace(side: Direction): IntArray {
return IntArray(NUM_SLOTS) { it }
}
override fun canPlaceItemThroughFace(slot: Int, stack: ItemStack, dir: Direction?): Boolean {
return dir != Direction.DOWN
}
override fun canTakeItemThroughFace(slot: Int, stack: ItemStack, dir: Direction): Boolean {
return dir == Direction.DOWN
}
override fun stillValid(player: Player) = !player.isSpectator
override fun setItems(inventory: NonNullList<ItemStack>) {
inventoryContents = inventory
}
companion object {
val NUM_SLOTS = 27
fun playSound(world: Level, pos: BlockPos, state: BlockState, sound: SoundEvent) {
var d = pos.x.toDouble() + 0.5
val e = pos.y.toDouble() + 0.5
var f = pos.z.toDouble() + 0.5
val direction = state.getValue(BlockStateProperties.HORIZONTAL_FACING)
d += direction.stepX.toDouble() * 0.5
f += direction.stepZ.toDouble() * 0.5
world.playSound(
null,
d,
e,
f,
sound,
SoundSource.BLOCKS,
0.5f,
world.random.nextFloat() * 0.1f + 0.9f
)
}
}
override fun triggerEvent(type: Int, data: Int): Boolean {
if (type == 1) {
val isNowOpen = data > 0
val wasOpen = posableState.currentPose == "open"
val model = posableState.currentModel ?: return true
if (isNowOpen && !wasOpen) {
model.moveToPose(posableState, model.poses["open"]!!)
} else if (!isNowOpen && wasOpen) {
model.moveToPose(posableState, model.poses["closed"]!!)
}
return true
}
return super.triggerEvent(type, data)
}
fun onViewerCountUpdate(world: Level, pos: BlockPos, state: BlockState, oldViewerCount: Int, newViewerCount: Int) {
val block = state.block
world.blockEvent(pos, block, 1, newViewerCount)
}
override fun saveAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.saveAdditional(nbt, registryLookup)
if (!trySaveLootTable(nbt)) {
ContainerHelper.saveAllItems(nbt, inventoryContents, registryLookup)
}
}
override fun loadAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.loadAdditional(nbt, registryLookup)
inventoryContents= NonNullList.withSize(containerSize, ItemStack.EMPTY)
if (!tryLoadLootTable(nbt)) {
ContainerHelper.loadAllItems(nbt, inventoryContents, registryLookup)
}
}
fun tick() {
if (!this.remove) {
stateManager.recheckOpeners(level, blockPos, this.blockState)
}
}
}
@@ -0,0 +1,168 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.entity
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.block.chest.GildedState
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup
import net.minecraft.core.NonNullList
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
import net.minecraft.world.ContainerHelper
import net.minecraft.world.WorldlyContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.ChestMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.ContainerOpenersCounter
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperWasherBlockEntity(pos: BlockPos, state: BlockState) : RandomizableContainerBlockEntity(CobblemonBlockEntities.COPPER_WASHER, pos, state), WorldlyContainer {
var inventoryContents: NonNullList<ItemStack> = NonNullList.withSize(NUM_SLOTS, ItemStack.EMPTY)
val posableState: GildedState = GildedState()
private val stateManager: ContainerOpenersCounter = object : ContainerOpenersCounter() {
override fun onOpen(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_OPEN)
}
override fun onClose(world: Level, pos: BlockPos, state: BlockState) {
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_CLOSE)
}
override fun openerCountChanged(
world: Level,
pos: BlockPos,
state: BlockState,
oldViewerCount: Int,
newViewerCount: Int
) {
this@CopperWasherBlockEntity.onViewerCountUpdate(world, pos, state, oldViewerCount, newViewerCount)
}
override fun isOwnContainer(player: Player): Boolean {
if (player.containerMenu is ChestMenu) {
val inventory = (player.containerMenu as ChestMenu).container
return inventory === this@CopperWasherBlockEntity
}
return false
}
}
override fun getContainerSize() = NUM_SLOTS
override fun getDefaultName() = Component.translatable("block.cobblemon.copper_washer")
override fun createMenu(syncId: Int, playerInventory: Inventory): AbstractContainerMenu =
ChestMenu.threeRows(syncId, playerInventory, this)
override fun getItems() = inventoryContents
override fun startOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.incrementOpeners(player, level, blockPos, blockState)
}
}
override fun stopOpen(player: Player) {
if (!this.remove && !player.isSpectator) {
stateManager.decrementOpeners(player, level, blockPos, blockState)
}
}
override fun getSlotsForFace(side: Direction): IntArray {
return IntArray(NUM_SLOTS) { it }
}
override fun canPlaceItemThroughFace(slot: Int, stack: ItemStack, dir: Direction?): Boolean {
return dir != Direction.DOWN
}
override fun canTakeItemThroughFace(slot: Int, stack: ItemStack, dir: Direction): Boolean {
return dir == Direction.DOWN
}
override fun stillValid(player: Player) = !player.isSpectator
override fun setItems(inventory: NonNullList<ItemStack>) {
inventoryContents = inventory
}
companion object {
val NUM_SLOTS = 27
fun playSound(world: Level, pos: BlockPos, state: BlockState, sound: SoundEvent) {
var d = pos.x.toDouble() + 0.5
val e = pos.y.toDouble() + 0.5
var f = pos.z.toDouble() + 0.5
val direction = state.getValue(BlockStateProperties.HORIZONTAL_FACING)
d += direction.stepX.toDouble() * 0.5
f += direction.stepZ.toDouble() * 0.5
world.playSound(
null,
d,
e,
f,
sound,
SoundSource.BLOCKS,
0.5f,
world.random.nextFloat() * 0.1f + 0.9f
)
}
}
override fun triggerEvent(type: Int, data: Int): Boolean {
if (type == 1) {
val isNowOpen = data > 0
val wasOpen = posableState.currentPose == "open"
val model = posableState.currentModel ?: return true
if (isNowOpen && !wasOpen) {
model.moveToPose(posableState, model.poses["open"]!!)
} else if (!isNowOpen && wasOpen) {
model.moveToPose(posableState, model.poses["closed"]!!)
}
return true
}
return super.triggerEvent(type, data)
}
fun onViewerCountUpdate(world: Level, pos: BlockPos, state: BlockState, oldViewerCount: Int, newViewerCount: Int) {
val block = state.block
world.blockEvent(pos, block, 1, newViewerCount)
}
override fun saveAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.saveAdditional(nbt, registryLookup)
if (!trySaveLootTable(nbt)) {
ContainerHelper.saveAllItems(nbt, inventoryContents, registryLookup)
}
}
override fun loadAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider) {
super.loadAdditional(nbt, registryLookup)
inventoryContents= NonNullList.withSize(containerSize, ItemStack.EMPTY)
if (!tryLoadLootTable(nbt)) {
ContainerHelper.loadAllItems(nbt, inventoryContents, registryLookup)
}
}
fun tick() {
if (!this.remove) {
stateManager.recheckOpeners(level, blockPos, this.blockState)
}
}
}
@@ -53,7 +53,6 @@ import com.cobblemon.mod.common.client.trade.ClientTrade
import com.cobblemon.mod.common.data.CobblemonDataProvider
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.item.food.SinisterTeaItem
import com.cobblemon.mod.common.platform.events.PlatformEvents
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext
import com.cobblemon.mod.common.util.isLookingAt
@@ -289,8 +288,8 @@ object CobblemonClient {
CobblemonBlocks.PINK_CAMPFIRE_POT,
CobblemonBlocks.RED_CAMPFIRE_POT,
CobblemonBlocks.WHITE_CAMPFIRE_POT,
CobblemonBlocks.YELLOW_CAMPFIRE_POT
CobblemonBlocks.YELLOW_CAMPFIRE_POT,
CobblemonBlocks.COPPER_FAN
)
this.createBoatModelLayers()
@@ -345,6 +344,9 @@ object CobblemonClient {
CobblemonBlockEntities.CANDLE_POKE_CAKE,
::CandlePokeCakeBlockEntityRenderer
)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.COPPER_OVEN, ::CopperOvenBlockRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.COPPER_WASHER, ::CopperWasherBlockRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.COPPER_FRIDGE, ::CopperFridgeBlockRenderer)
}
private fun registerEntityRenderers() {
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.block
import com.cobblemon.mod.common.block.CopperFridgeBlock.Type
import com.cobblemon.mod.common.block.entity.CopperFridgeBlockEntity
import com.cobblemon.mod.common.client.render.models.blockbench.blockentity.BlockEntityModel
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperFridgeBlockRenderer(context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<CopperFridgeBlockEntity> {
val context = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.BLOCK)
it.put(RenderContext.DO_QUIRKS, true)
}
override fun render(
entity: CopperFridgeBlockEntity,
tickDelta: Float,
matrices: PoseStack,
vertexConsumers: MultiBufferSource,
light: Int,
overlay: Int
) {
val aspects = emptySet<String>()
val state = entity.posableState
state.currentAspects = aspects
state.updatePartialTicks(tickDelta)
val poserId = Type.RED.poserId
val model = VaryingModelRepository.getPoser(poserId, state) as BlockEntityModel
model.context = context
val texture = VaryingModelRepository.getTexture(poserId, state)
val vertexConsumer = vertexConsumers.getBuffer(RenderType.entityCutout(texture))
model.bufferProvider = vertexConsumers
state.currentModel = model
context.put(RenderContext.ASPECTS, aspects)
context.put(RenderContext.TEXTURE, texture)
context.put(RenderContext.SPECIES, poserId)
context.put(RenderContext.POSABLE_STATE, state)
matrices.pushPose()
matrices.mulPose(Axis.ZP.rotationDegrees(180f))
matrices.translate(-0.5, 0.0, 0.5)
matrices.mulPose(Axis.YP.rotationDegrees(entity.blockState.getValue(BlockStateProperties.HORIZONTAL_FACING).toYRot()))
matrices.mulPose(Axis.YP.rotationDegrees(180f))
model.applyAnimations(
entity = null,
state = state,
headYaw = 0F,
headPitch = 0F,
limbSwing = 0F,
limbSwingAmount = 0F,
ageInTicks = state.animationSeconds * 20
)
model.render(context, matrices, vertexConsumer, light, overlay, -0x1)
model.withLayerContext(vertexConsumers, state, VaryingModelRepository.getLayers(poserId, state)) {
model.render(context, matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, -0x1)
}
model.setDefault()
matrices.popPose()
}
}
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.block
import com.cobblemon.mod.common.block.entity.CopperOvenBlockEntity
import com.cobblemon.mod.common.block.CopperOvenBlock.Type
import com.cobblemon.mod.common.client.render.models.blockbench.blockentity.BlockEntityModel
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperOvenBlockRenderer(context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<CopperOvenBlockEntity> {
val context = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.BLOCK)
it.put(RenderContext.DO_QUIRKS, true)
}
override fun render(
entity: CopperOvenBlockEntity,
tickDelta: Float,
matrices: PoseStack,
vertexConsumers: MultiBufferSource,
light: Int,
overlay: Int
) {
val aspects = emptySet<String>()
val state = entity.posableState
state.currentAspects = aspects
state.updatePartialTicks(tickDelta)
val poserId = Type.RED.poserId
val model = VaryingModelRepository.getPoser(poserId, state) as BlockEntityModel
model.context = context
val texture = VaryingModelRepository.getTexture(poserId, state)
val vertexConsumer = vertexConsumers.getBuffer(RenderType.entityCutout(texture))
model.bufferProvider = vertexConsumers
state.currentModel = model
context.put(RenderContext.ASPECTS, aspects)
context.put(RenderContext.TEXTURE, texture)
context.put(RenderContext.SPECIES, poserId)
context.put(RenderContext.POSABLE_STATE, state)
matrices.pushPose()
matrices.mulPose(Axis.ZP.rotationDegrees(180f))
matrices.translate(-0.5, 0.0, 0.5)
matrices.mulPose(Axis.YP.rotationDegrees(entity.blockState.getValue(BlockStateProperties.HORIZONTAL_FACING).toYRot()))
matrices.mulPose(Axis.YP.rotationDegrees(180f))
model.applyAnimations(
entity = null,
state = state,
headYaw = 0F,
headPitch = 0F,
limbSwing = 0F,
limbSwingAmount = 0F,
ageInTicks = state.animationSeconds * 20
)
model.render(context, matrices, vertexConsumer, light, overlay, -0x1)
model.withLayerContext(vertexConsumers, state, VaryingModelRepository.getLayers(poserId, state)) {
model.render(context, matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, -0x1)
}
model.setDefault()
matrices.popPose()
}
}
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.block
import com.cobblemon.mod.common.block.CopperWasherBlock.Type
import com.cobblemon.mod.common.block.entity.CopperWasherBlockEntity
import com.cobblemon.mod.common.client.render.models.blockbench.blockentity.BlockEntityModel
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.world.level.block.state.properties.BlockStateProperties
class CopperWasherBlockRenderer(context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<CopperWasherBlockEntity> {
val context = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.BLOCK)
it.put(RenderContext.DO_QUIRKS, true)
}
override fun render(
entity: CopperWasherBlockEntity,
tickDelta: Float,
matrices: PoseStack,
vertexConsumers: MultiBufferSource,
light: Int,
overlay: Int
) {
val aspects = emptySet<String>()
val state = entity.posableState
state.currentAspects = aspects
state.updatePartialTicks(tickDelta)
val poserId = Type.RED.poserId
val model = VaryingModelRepository.getPoser(poserId, state) as BlockEntityModel
model.context = context
val texture = VaryingModelRepository.getTexture(poserId, state)
val vertexConsumer = vertexConsumers.getBuffer(RenderType.entityCutout(texture))
model.bufferProvider = vertexConsumers
state.currentModel = model
context.put(RenderContext.ASPECTS, aspects)
context.put(RenderContext.TEXTURE, texture)
context.put(RenderContext.SPECIES, poserId)
context.put(RenderContext.POSABLE_STATE, state)
matrices.pushPose()
matrices.mulPose(Axis.ZP.rotationDegrees(180f))
matrices.translate(-0.5, 0.0, 0.5)
matrices.mulPose(Axis.YP.rotationDegrees(entity.blockState.getValue(BlockStateProperties.HORIZONTAL_FACING).toYRot()))
matrices.mulPose(Axis.YP.rotationDegrees(180f))
model.applyAnimations(
entity = null,
state = state,
headYaw = 0F,
headPitch = 0F,
limbSwing = 0F,
limbSwingAmount = 0F,
ageInTicks = state.animationSeconds * 20
)
model.render(context, matrices, vertexConsumer, light, overlay, -0x1)
model.withLayerContext(vertexConsumers, state, VaryingModelRepository.getLayers(poserId, state)) {
model.render(context, matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, -0x1)
}
model.setDefault()
matrices.popPose()
}
}
@@ -244,6 +244,12 @@ object CobblemonItemGroups {
entries.accept(CobblemonItems.HEALING_MACHINE)
entries.accept(CobblemonItems.PASTURE)
entries.accept(CobblemonItems.COPPER_OVEN)
entries.accept(CobblemonItems.COPPER_FAN)
entries.accept(CobblemonItems.COPPER_FRIDGE)
entries.accept(CobblemonItems.COPPER_WASHER)
entries.accept(CobblemonItems.COPPER_MOWER)
entries.accept(CobblemonItems.GILDED_CHEST)
entries.accept(CobblemonItems.YELLOW_GILDED_CHEST)
entries.accept(CobblemonItems.GREEN_GILDED_CHEST)
@@ -0,0 +1,97 @@
{
"format_version": "1.8.0",
"animations": {
"animation.copper_fridge.opening": {
"loop": "hold_on_last_frame",
"animation_length": 0.25,
"bones": {
"door_west2": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [0, -105, 0]
}
},
"door_east2": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [0, 105, 0]
}
},
"door_west": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [0, -105, 0]
}
},
"door_east": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [0, 105, 0]
}
},
"drawer": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, 0, -6]
}
}
}
},
"animation.copper_fridge.open": {
"loop": "hold_on_last_frame",
"bones": {
"door_west2": {
"rotation": [0, -105, 0]
},
"door_east2": {
"rotation": [0, 105, 0]
},
"door_west": {
"rotation": [0, -105, 0]
},
"door_east": {
"rotation": [0, 105, 0]
},
"drawer": {
"position": [0, 0, -6]
}
}
},
"animation.copper_fridge.closing": {
"loop": "hold_on_last_frame",
"animation_length": 0.25,
"bones": {
"door_west2": {
"rotation": {
"0.0": [0, -105, 0],
"0.25": [0, 0, 0]
}
},
"door_east2": {
"rotation": {
"0.0": [0, 105, 0],
"0.25": [0, 0, 0]
}
},
"door_west": {
"rotation": {
"0.0": [0, -105, 0],
"0.25": [0, 0, 0]
}
},
"door_east": {
"rotation": {
"0.0": [0, 105, 0],
"0.25": [0, 0, 0]
}
},
"drawer": {
"position": {
"0.0": [0, 0, -6],
"0.25": [0, 0, 0]
}
}
}
}
}
}
@@ -0,0 +1,37 @@
{
"format_version": "1.8.0",
"animations": {
"animation.copper_oven.opening": {
"loop": "hold_on_last_frame",
"animation_length": 0.25,
"bones": {
"oven_door": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [97.5, 0, 0]
}
}
}
},
"animation.copper_oven.open": {
"loop": "hold_on_last_frame",
"bones": {
"oven_door": {
"rotation": [97.5, 0, 0]
}
}
},
"animation.copper_oven.closing": {
"loop": "hold_on_last_frame",
"animation_length": 0.25,
"bones": {
"oven_door": {
"rotation": {
"0.0": [97.5, 0, 0],
"0.25": [0, 0, 0]
}
}
}
}
}
}
@@ -0,0 +1,37 @@
{
"format_version": "1.8.0",
"animations": {
"animation.copper_washer.opening": {
"loop": "hold_on_last_frame",
"animation_length": 0.25,
"bones": {
"door": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [0, 105, 0]
}
}
}
},
"animation.copper_washer.open": {
"loop": "hold_on_last_frame",
"bones": {
"door": {
"rotation": [0, 105, 0]
}
}
},
"animation.copper_washer.closing": {
"loop": "hold_on_last_frame",
"animation_length": 0.25,
"bones": {
"door": {
"rotation": {
"0.0": [0, 105, 0],
"0.25": [0, 0, 0]
}
}
}
}
}
}
@@ -0,0 +1,87 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.copper_fridge",
"texture_width": 128,
"texture_height": 128,
"visible_bounds_width": 2,
"visible_bounds_height": 3.5,
"visible_bounds_offset": [0, 1.25, 0]
},
"bones": [
{
"name": "fridge",
"pivot": [0, 0, 0]
},
{
"name": "body",
"parent": "fridge",
"pivot": [0, 0, 0]
},
{
"name": "fridge_bottom",
"parent": "body",
"pivot": [0, 8, 0],
"cubes": [
{"origin": [-8, 1, -3], "size": [16, 15, 11], "uv": [0, 27]},
{"origin": [-7, 0, -6], "size": [14, 1, 13], "uv": [45, 44]}
]
},
{
"name": "drawer",
"parent": "fridge_bottom",
"pivot": [0, 8, 0],
"cubes": [
{"origin": [-8, 1, -7], "size": [16, 10, 4], "uv": [7, 69]},
{"origin": [-7, 2, -5], "size": [14, 8, 8], "uv": [5, 53]}
]
},
{
"name": "door_west2",
"parent": "fridge_bottom",
"pivot": [8, 16, -3],
"cubes": [
{"origin": [0, 11, -7], "size": [8, 5, 4], "uv": [78, 25]}
]
},
{
"name": "door_east2",
"parent": "fridge_bottom",
"pivot": [-8, 16, -3],
"cubes": [
{"origin": [-8, 11, -7], "size": [8, 5, 4], "uv": [54, 25]}
]
},
{
"name": "fridge_top",
"parent": "body",
"pivot": [0, 8, 0],
"cubes": [
{"origin": [-8, 24, -7], "size": [16, 8, 4], "uv": [54, 1]},
{"origin": [-8, 16, -3], "size": [16, 16, 11], "uv": [0, 0]}
]
},
{
"name": "door_west",
"parent": "fridge_top",
"pivot": [8, 16, -3],
"cubes": [
{"origin": [0, 16, -7], "size": [8, 8, 4], "uv": [78, 13]},
{"origin": [2, 18, -8], "size": [2, 3, 1], "uv": [82, 34]}
]
},
{
"name": "door_east",
"parent": "fridge_top",
"pivot": [-8, 16, -3],
"cubes": [
{"origin": [-8, 16, -7], "size": [8, 8, 4], "uv": [54, 13]},
{"origin": [-4, 18, -8], "size": [2, 3, 1], "uv": [60, 34]}
]
}
]
}
]
}
@@ -0,0 +1,54 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.copper_oven",
"texture_width": 64,
"texture_height": 32,
"visible_bounds_width": 2,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "oven",
"pivot": [0, 0, 0]
},
{
"name": "body",
"parent": "oven",
"pivot": [0, 0, 0]
},
{
"name": "shell",
"parent": "body",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [-7, 0, -5], "size": [14, 10, 11], "uv": [0, 0]}
]
},
{
"name": "void",
"parent": "body",
"pivot": [0, 8, -4.5],
"cubes": [
{"origin": [-6, 1, -5], "size": [0, 7, 1], "uv": [0, -1]},
{"origin": [-6, 1, -4], "size": [12, 7, 0], "uv": [40, 0]},
{"origin": [6, 1, -5], "size": [0, 7, 1], "uv": [0, -1]},
{"origin": [-6, 1, -5], "size": [12, 0, 1], "uv": [39, 8]},
{"origin": [-6, 8, -5], "size": [12, 0, 1], "uv": [39, 8]}
]
},
{
"name": "oven_door",
"parent": "body",
"pivot": [0, 1, -5],
"cubes": [
{"origin": [-6, 1, -5], "size": [12, 7, 1], "uv": [0, 21]}
]
}
]
}
]
}
@@ -0,0 +1,43 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.copper_washer",
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 2,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "wash",
"pivot": [0, 0, 0]
},
{
"name": "body",
"parent": "wash",
"pivot": [0, 0, 0]
},
{
"name": "shell",
"parent": "body",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [-7, 0, -6], "size": [14, 14, 14], "uv": [0, 0]},
{"origin": [-8, 2, 3], "size": [1, 4, 4], "uv": [0, 0]}
]
},
{
"name": "door",
"parent": "body",
"pivot": [-4, 6, -6],
"cubes": [
{"origin": [-4, 2, -7], "size": [8, 8, 1], "uv": [0, 28]}
]
}
]
}
]
}
@@ -0,0 +1,21 @@
{
"maxScale": 1.0,
"yTranslation": 0.0,
"poses": {
"closed": {
"allPoseTypes": true,
"transitions": {
"open": "q.bedrock_stateful('copper_fridge', 'opening')"
}
},
"open": {
"allPoseTypes": true,
"animations": [
"q.bedrock('copper_fridge', 'open')"
],
"transitions": {
"closed": "q.bedrock_stateful('copper_fridge', 'closing')"
}
}
}
}
@@ -0,0 +1,21 @@
{
"maxScale": 1.0,
"yTranslation": 0.0,
"poses": {
"closed": {
"allPoseTypes": true,
"transitions": {
"open": "q.bedrock_stateful('copper_oven', 'opening')"
}
},
"open": {
"allPoseTypes": true,
"animations": [
"q.bedrock('copper_oven', 'open')"
],
"transitions": {
"closed": "q.bedrock_stateful('copper_oven', 'closing')"
}
}
}
}
@@ -0,0 +1,21 @@
{
"maxScale": 1.0,
"yTranslation": 0.0,
"poses": {
"closed": {
"allPoseTypes": true,
"transitions": {
"open": "q.bedrock_stateful('copper_washer', 'opening')"
}
},
"open": {
"allPoseTypes": true,
"animations": [
"q.bedrock('copper_washer', 'open')"
],
"transitions": {
"closed": "q.bedrock_stateful('copper_washer', 'closing')"
}
}
}
}
@@ -0,0 +1,13 @@
{
"name": "cobblemon:copper_fridge",
"order": 0,
"variations": [
{
"aspects": [],
"poser": "cobblemon:copper_fridge",
"model": "cobblemon:copper_fridge.geo",
"texture": "cobblemon:textures/block/copper_fridge.png",
"layers": []
}
]
}
@@ -0,0 +1,13 @@
{
"name": "cobblemon:copper_oven",
"order": 0,
"variations": [
{
"aspects": [],
"poser": "cobblemon:copper_oven",
"model": "cobblemon:copper_oven.geo",
"texture": "cobblemon:textures/block/copper_oven.png",
"layers": []
}
]
}
@@ -0,0 +1,13 @@
{
"name": "cobblemon:copper_washer",
"order": 0,
"variations": [
{
"aspects": [],
"poser": "cobblemon:copper_washer",
"model": "cobblemon:copper_washer.geo",
"texture": "cobblemon:textures/block/copper_washer.png",
"layers": []
}
]
}
@@ -0,0 +1,34 @@
{
"variants": {
"facing=east,active=false": {
"model": "cobblemon:block/copper_fan",
"y": 90
},
"facing=east,active=true": {
"model": "cobblemon:block/copper_fan_on",
"y": 90
},
"facing=north,active=false": {
"model": "cobblemon:block/copper_fan"
},
"facing=north,active=true": {
"model": "cobblemon:block/copper_fan_on"
},
"facing=south,active=false": {
"model": "cobblemon:block/copper_fan",
"y": 180
},
"facing=south,active=true": {
"model": "cobblemon:block/copper_fan_on",
"y": 180
},
"facing=west,active=false": {
"model": "cobblemon:block/copper_fan",
"y": 270
},
"facing=west,active=true": {
"model": "cobblemon:block/copper_fan_on",
"y": 270
}
}
}
@@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "cobblemon:block/copper_fridge" }
}
}
@@ -0,0 +1,19 @@
{
"variants": {
"facing=east": {
"model": "cobblemon:block/copper_mower",
"y": 90
},
"facing=north": {
"model": "cobblemon:block/copper_mower"
},
"facing=south": {
"model": "cobblemon:block/copper_mower",
"y": 180
},
"facing=west": {
"model": "cobblemon:block/copper_mower",
"y": 270
}
}
}
@@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "cobblemon:block/copper_oven" }
}
}
@@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "cobblemon:block/copper_washer" }
}
}
@@ -952,6 +952,11 @@
"block.cobblemon.hearty_grain_bale": "Hearty Grain Bale",
"block.cobblemon.tatami_block": "Tatami",
"block.cobblemon.tatami_mat": "Tatami Mat",
"block.cobblemon.copper_fan": "Copper Fan",
"block.cobblemon.copper_fridge": "Copper Fridge",
"block.cobblemon.copper_mower": "Copper Mower",
"block.cobblemon.copper_oven": "Copper Oven",
"block.cobblemon.copper_washer": "Copper Washer",
"block.cobblemon.small_budding_tumblestone": "Small Tumblestone Bud",
"block.cobblemon.medium_budding_tumblestone": "Medium Tumblestone Bud",
@@ -3504,6 +3509,7 @@
"tag.item.cobblemon.aprijuices": "Aprijuices",
"tag.item.cobblemon.mochis": "Mochis",
"tag.item.cobblemon.poke_food": "Poké Foods",
"tag.item.cobblemon.rotom_appliances": "Rotom Appliances",
"tag.item.cobblemon.full_heal_bottles": "Full Heal Bottles",
@@ -0,0 +1,154 @@
{
"texture_size": [32, 32],
"textures": {
"0": "cobblemon:block/copper_fan",
"1": "cobblemon:block/copper_fan_blades",
"particle": "block/copper_block"
},
"elements": [
{
"name": "fanblades",
"from": [4, 6, 8],
"to": [12, 14, 8],
"rotation": {"angle": 0, "axis": "y", "origin": [3.5, 0, 5]},
"faces": {
"north": {"uv": [0, 0, 8, 8], "texture": "#1"},
"south": {"uv": [8, 0, 16, 8], "texture": "#1"}
}
},
{
"name": "core",
"from": [7, 9, 7.5],
"to": [9, 11, 8.5],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 0, 7.5]},
"faces": {
"north": {"uv": [3.5, 3.5, 4.5, 4.5], "texture": "#0"},
"east": {"uv": [3, 3.5, 3.5, 4.5], "texture": "#0"},
"south": {"uv": [10.5, 3.5, 11.5, 4.5], "texture": "#0"},
"west": {"uv": [4.5, 3.5, 5, 4.5], "texture": "#0"},
"up": {"uv": [4.5, 3.5, 3.5, 3], "texture": "#0"},
"down": {"uv": [4.5, 4.5, 3.5, 5], "texture": "#0"}
}
},
{
"name": "frame_top",
"from": [2, 14, 7],
"to": [14, 16, 9],
"rotation": {"angle": 0, "axis": "y", "origin": [2, 0, 7]},
"faces": {
"north": {"uv": [1, 1, 7, 2], "texture": "#0"},
"east": {"uv": [0, 1, 1, 2], "texture": "#0"},
"south": {"uv": [8, 1, 14, 2], "texture": "#0"},
"west": {"uv": [7, 1, 8, 2], "texture": "#0"},
"up": {"uv": [7, 1, 1, 0], "texture": "#0"},
"down": {"uv": [14, 7, 8, 8], "texture": "#0"}
}
},
{
"name": "frame_west",
"from": [12, 6, 7],
"to": [14, 14, 9],
"rotation": {"angle": 0, "axis": "y", "origin": [2, 0, 7]},
"faces": {
"north": {"uv": [1, 2, 2, 6], "texture": "#0"},
"east": {"uv": [0, 2, 1, 6], "texture": "#0"},
"south": {"uv": [13, 2, 14, 6], "texture": "#0"},
"west": {"uv": [12, 2, 13, 6], "texture": "#0"}
}
},
{
"name": "frame_east",
"from": [2, 6, 7],
"to": [4, 14, 9],
"rotation": {"angle": 0, "axis": "y", "origin": [2, 0, 7]},
"faces": {
"north": {"uv": [6, 2, 7, 6], "texture": "#0"},
"east": {"uv": [9, 2, 10, 6], "texture": "#0"},
"south": {"uv": [8, 2, 9, 6], "texture": "#0"},
"west": {"uv": [7, 2, 8, 6], "texture": "#0"}
}
},
{
"name": "frame_bottom",
"from": [2, 4, 7],
"to": [14, 6, 9],
"rotation": {"angle": 0, "axis": "y", "origin": [2, 0, 7]},
"faces": {
"north": {"uv": [1, 6, 7, 7], "texture": "#0"},
"east": {"uv": [0, 6, 1, 7], "texture": "#0"},
"south": {"uv": [8, 6, 14, 7], "texture": "#0"},
"west": {"uv": [7, 6, 8, 7], "texture": "#0"},
"up": {"uv": [14, 1, 8, 0], "texture": "#0"},
"down": {"uv": [7, 7, 1, 8], "texture": "#0"}
}
},
{
"name": "leg",
"from": [7, 2, 7],
"to": [9, 4, 9],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 0, 7]},
"faces": {
"north": {"uv": [7, 8, 8, 9], "texture": "#0"},
"east": {"uv": [6, 8, 7, 9], "texture": "#0"},
"south": {"uv": [9, 8, 10, 9], "texture": "#0"},
"west": {"uv": [8, 8, 9, 9], "texture": "#0"}
}
},
{
"name": "base",
"from": [5, 0, 5],
"to": [11, 2, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [5, 0, 5]},
"faces": {
"north": {"uv": [0, 14, 6, 16], "texture": "#1"},
"east": {"uv": [6, 11, 9, 12], "texture": "#0"},
"south": {"uv": [3, 11, 6, 12], "texture": "#0"},
"west": {"uv": [0, 11, 3, 12], "texture": "#0"},
"up": {"uv": [0, 8, 6, 14], "rotation": 180, "texture": "#1"},
"down": {"uv": [3, 8, 6, 11], "texture": "#0"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"thirdperson_lefthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"firstperson_righthand": {
"rotation": [0, 45, 0],
"scale": [0.5, 0.5, 0.5]
},
"firstperson_lefthand": {
"rotation": [0, 45, 0],
"scale": [0.5, 0.5, 0.5]
},
"ground": {
"translation": [0, 3, 0],
"scale": [0.25, 0.25, 0.25]
},
"gui": {
"rotation": [30, 225, 0],
"scale": [0.625, 0.625, 0.625]
},
"head": {
"translation": [0, 14.5, 0]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
},
"groups": [
{
"name": "fan",
"origin": [8, 8, 8],
"color": 0,
"children": [0, 1, 2, 3, 4, 5, 6, 7]
}
]
}
@@ -0,0 +1,8 @@
{
"parent": "cobblemon:block/copper_fan",
"textures": {
"0": "cobblemon:block/copper_fan",
"1": "cobblemon:block/copper_fan_blades_anim",
"particle": "block/copper_block"
}
}
@@ -0,0 +1,5 @@
{
"textures": {
"particle": "block/copper_block"
}
}
@@ -0,0 +1,157 @@
{
"texture_size": [64, 32],
"textures": {
"0": "cobblemon:block/copper_mower",
"particle": "block/copper_block"
},
"elements": [
{
"from": [1, 0, 10],
"to": [15, 10, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [2, 0, 11]},
"faces": {
"north": {"uv": [1.5, 3, 5, 8], "texture": "#0"},
"east": {"uv": [0, 3, 1.5, 8], "texture": "#0"},
"south": {"uv": [6.5, 3, 10, 8], "texture": "#0"},
"west": {"uv": [5, 3, 6.5, 8], "texture": "#0"},
"up": {"uv": [5, 3, 1.5, 0], "texture": "#0"},
"down": {"uv": [8.5, 0, 5, 3], "texture": "#0"}
}
},
{
"from": [3, 0, 0],
"to": [13, 6, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [4, 0, 1]},
"faces": {
"north": {"uv": [2.5, 13, 5, 16], "texture": "#0"},
"east": {"uv": [0, 13, 2.5, 16], "texture": "#0"},
"south": {"uv": [7.5, 13, 10, 16], "texture": "#0"},
"west": {"uv": [5, 13, 7.5, 16], "texture": "#0"},
"up": {"uv": [5, 13, 2.5, 8], "texture": "#0"},
"down": {"uv": [7.5, 8, 5, 13], "texture": "#0"}
}
},
{
"from": [2, 0, 3],
"to": [3, 5, 8],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 2.5, 5.5]},
"faces": {
"north": {"uv": [14.25, 3, 14.5, 5.5], "texture": "#0"},
"east": {"uv": [13, 3, 14.25, 5.5], "texture": "#0"},
"south": {"uv": [15.75, 3, 16, 5.5], "texture": "#0"},
"west": {"uv": [14.5, 3, 15.75, 5.5], "texture": "#0"},
"up": {"uv": [14.5, 3, 14.25, 0.5], "texture": "#0"},
"down": {"uv": [14.75, 0.5, 14.5, 3], "texture": "#0"}
}
},
{
"from": [13, 0, 3],
"to": [14, 5, 8],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 2.5, 5.5]},
"faces": {
"north": {"uv": [11.25, 3, 11.5, 5.5], "texture": "#0"},
"east": {"uv": [10, 3, 11.25, 5.5], "texture": "#0"},
"south": {"uv": [12.75, 3, 13, 5.5], "texture": "#0"},
"west": {"uv": [11.5, 3, 12.75, 5.5], "texture": "#0"},
"up": {"uv": [11.5, 3, 11.25, 0.5], "texture": "#0"},
"down": {"uv": [11.75, 0.5, 11.5, 3], "texture": "#0"}
}
},
{
"from": [6.5, 6, 4.5],
"to": [9.5, 10, 7.5],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 6, 4.5]},
"faces": {
"north": {"uv": [12.25, 13, 13, 15], "texture": "#0"},
"east": {"uv": [11.5, 13, 12.25, 15], "texture": "#0"},
"south": {"uv": [13.75, 13, 14.5, 15], "texture": "#0"},
"west": {"uv": [13, 13, 13.75, 15], "texture": "#0"},
"up": {"uv": [13, 13, 12.25, 11.5], "texture": "#0"},
"down": {"uv": [13.75, 11.5, 13, 13], "texture": "#0"}
}
},
{
"from": [7, 10, 5],
"to": [9, 15, 7],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 6, 4.5]},
"faces": {
"north": {"uv": [12.5, 9, 13, 11.5], "texture": "#0"},
"east": {"uv": [12, 9, 12.5, 11.5], "texture": "#0"},
"south": {"uv": [13.5, 9, 14, 11.5], "texture": "#0"},
"west": {"uv": [13, 9, 13.5, 11.5], "texture": "#0"},
"up": {"uv": [13, 9, 12.5, 8], "texture": "#0"},
"down": {"uv": [13.5, 8, 13, 9], "texture": "#0"}
}
},
{
"from": [4, 15, 5],
"to": [12, 17, 7],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 6, 4.5]},
"faces": {
"north": {"uv": [11, 7, 13, 8], "texture": "#0"},
"east": {"uv": [10.5, 7, 11, 8], "texture": "#0"},
"south": {"uv": [13.5, 7, 15.5, 8], "texture": "#0"},
"west": {"uv": [13, 7, 13.5, 8], "texture": "#0"},
"up": {"uv": [13, 7, 11, 6], "texture": "#0"},
"down": {"uv": [15, 6, 13, 7], "texture": "#0"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"thirdperson_lefthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"firstperson_righthand": {
"rotation": [0, 45, 0],
"scale": [0.4, 0.4, 0.4]
},
"firstperson_lefthand": {
"rotation": [0, 45, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 3, 0],
"scale": [0.25, 0.25, 0.25]
},
"gui": {
"rotation": [30, 225, 0],
"scale": [0.625, 0.625, 0.625]
},
"head": {
"translation": [0, 14.25, 0]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
},
"groups": [
{
"name": "mower",
"origin": [8, 0, 8],
"color": 0,
"children": [
0,
1,
{
"name": "wheels",
"origin": [8, 2, 6],
"color": 4,
"children": [2, 3]
},
{
"name": "handle",
"origin": [8, 6, 4.5],
"color": 1,
"children": [4, 5, 6]
}
]
}
]
}
@@ -0,0 +1,5 @@
{
"textures": {
"particle": "block/copper_block"
}
}
@@ -0,0 +1,5 @@
{
"textures": {
"particle": "block/copper_block"
}
}
@@ -0,0 +1,8 @@
{
"parent": "cobblemon:block/copper_fan",
"textures": {
"0": "cobblemon:block/copper_fan",
"1": "cobblemon:block/copper_fan_blades_anim",
"particle": "block/copper_block"
}
}
@@ -0,0 +1,249 @@
{
"credit": "Made with Blockbench",
"texture_size": [128, 128],
"textures": {
"1": "cobblemon:block/copper_fridge"
},
"elements": [
{
"name": "back",
"from": [0, 1, 5],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 1, 0]},
"faces": {
"north": {"uv": [1.375, 4.75, 3.375, 6.625], "texture": "#1"},
"east": {"uv": [0, 4.75, 1.375, 6.625], "texture": "#1"},
"south": {"uv": [4.75, 4.75, 6.75, 6.625], "texture": "#1"},
"west": {"uv": [3.375, 4.75, 4.75, 6.625], "texture": "#1"},
"down": {"uv": [5.375, 3.375, 3.375, 4.75], "texture": "#1"}
}
},
{
"name": "feet",
"from": [1, 0, 2],
"to": [15, 1, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 0, 2]},
"faces": {
"north": {"uv": [7.25, 7.125, 9, 7.25], "texture": "#1"},
"east": {"uv": [5.625, 7.125, 7.25, 7.25], "texture": "#1"},
"south": {"uv": [10.625, 7.125, 12.375, 7.25], "texture": "#1"},
"west": {"uv": [9, 7.125, 10.625, 7.25], "texture": "#1"},
"up": {"uv": [9, 7.125, 7.25, 5.5], "texture": "#1"},
"down": {"uv": [10.75, 5.5, 9, 7.125], "texture": "#1"}
}
},
{
"name": "outer",
"from": [0, 1, 1],
"to": [16, 11, 5],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 6, 1]},
"faces": {
"north": {"uv": [1.375, 9.125, 3.375, 10.375], "texture": "#1"},
"east": {"uv": [0.875, 9.125, 1.375, 10.375], "texture": "#1"},
"south": {"uv": [3.875, 9.125, 5.875, 10.375], "texture": "#1"},
"west": {"uv": [3.375, 9.125, 3.875, 10.375], "texture": "#1"},
"up": {"uv": [3.375, 9.125, 1.375, 8.625], "texture": "#1"},
"down": {"uv": [5.375, 8.625, 3.375, 9.125], "texture": "#1"}
}
},
{
"from": [1, 2, 3],
"to": [15, 10, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 6, 1]},
"faces": {
"north": {"uv": [1.625, 7.625, 3.375, 8.625], "texture": "#1"},
"east": {"uv": [0.625, 7.625, 1.625, 8.625], "texture": "#1"},
"south": {"uv": [4.375, 7.625, 6.125, 8.625], "texture": "#1"},
"west": {"uv": [3.375, 7.625, 4.375, 8.625], "texture": "#1"},
"up": {"uv": [3.375, 7.625, 1.625, 6.625], "texture": "#1"},
"down": {"uv": [5.125, 6.625, 3.375, 7.625], "texture": "#1"}
}
},
{
"name": "door",
"from": [0, 11, 1],
"to": [8, 16, 5],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 16, 4]},
"faces": {
"north": {"uv": [10.25, 3.625, 11.25, 4.25], "texture": "#1"},
"east": {"uv": [9.75, 3.625, 10.25, 4.25], "texture": "#1"},
"south": {"uv": [11.75, 3.625, 12.75, 4.25], "texture": "#1"},
"west": {"uv": [11.25, 3.625, 11.75, 4.25], "texture": "#1"},
"down": {"uv": [12.25, 3.125, 11.25, 3.625], "texture": "#1"}
}
},
{
"name": "door",
"from": [8, 11, 1],
"to": [16, 16, 5],
"rotation": {"angle": 0, "axis": "y", "origin": [16, 16, 4]},
"faces": {
"north": {"uv": [7.25, 3.625, 8.25, 4.25], "texture": "#1"},
"east": {"uv": [6.75, 3.625, 7.25, 4.25], "texture": "#1"},
"south": {"uv": [8.75, 3.625, 9.75, 4.25], "texture": "#1"},
"west": {"uv": [8.25, 3.625, 8.75, 4.25], "texture": "#1"},
"down": {"uv": [9.25, 3.125, 8.25, 3.625], "texture": "#1"}
}
},
{
"from": [0, 24, 1],
"to": [16, 32, 5],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 16, 0]},
"faces": {
"north": {"uv": [7.25, 0.625, 9.25, 1.625], "texture": "#1"},
"east": {"uv": [6.75, 0.625, 7.25, 1.625], "texture": "#1"},
"west": {"uv": [9.25, 0.625, 9.75, 1.625], "texture": "#1"},
"up": {"uv": [9.25, 0.625, 7.25, 0.125], "texture": "#1"},
"down": {"uv": [11.25, 0.125, 9.25, 0.625], "texture": "#1"}
}
},
{
"from": [0, 16, 5],
"to": [16, 32, 16],
"faces": {
"north": {"uv": [1.375, 1.375, 3.375, 3.375], "texture": "#1"},
"east": {"uv": [0, 1.375, 1.375, 3.375], "texture": "#1"},
"south": {"uv": [4.75, 1.375, 6.75, 3.375], "texture": "#1"},
"west": {"uv": [3.375, 1.375, 4.75, 3.375], "texture": "#1"},
"up": {"uv": [3.375, 1.375, 1.375, 0], "texture": "#1"}
}
},
{
"name": "door",
"from": [0, 16, 1],
"to": [8, 24, 5],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 16, 4]},
"faces": {
"north": {"uv": [10.25, 2.125, 11.25, 3.125], "texture": "#1"},
"east": {"uv": [9.75, 2.125, 10.25, 3.125], "texture": "#1"},
"south": {"uv": [11.75, 2.125, 12.75, 3.125], "texture": "#1"},
"west": {"uv": [11.25, 2.125, 11.75, 3.125], "texture": "#1"},
"up": {"uv": [11.25, 2.125, 10.25, 1.625], "texture": "#1"}
}
},
{
"from": [4, 18, 0],
"to": [6, 21, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [4, 18, 0]},
"faces": {
"north": {"uv": [10.375, 4.375, 10.625, 4.75], "texture": "#1"},
"east": {"uv": [10.25, 4.375, 10.375, 4.75], "texture": "#1"},
"south": {"uv": [10.75, 4.375, 11, 4.75], "texture": "#1"},
"west": {"uv": [10.625, 4.375, 10.75, 4.75], "texture": "#1"},
"up": {"uv": [10.625, 4.375, 10.375, 4.25], "texture": "#1"},
"down": {"uv": [10.875, 4.25, 10.625, 4.375], "texture": "#1"}
}
},
{
"name": "door",
"from": [8, 16, 1],
"to": [16, 24, 5],
"rotation": {"angle": 0, "axis": "y", "origin": [16, 16, 4]},
"faces": {
"north": {"uv": [7.25, 2.125, 8.25, 3.125], "texture": "#1"},
"east": {"uv": [6.75, 2.125, 7.25, 3.125], "texture": "#1"},
"south": {"uv": [8.75, 2.125, 9.75, 3.125], "texture": "#1"},
"west": {"uv": [8.25, 2.125, 8.75, 3.125], "texture": "#1"},
"up": {"uv": [8.25, 2.125, 7.25, 1.625], "texture": "#1"}
}
},
{
"from": [10, 18, 0],
"to": [12, 21, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [10, 18, 0]},
"faces": {
"north": {"uv": [7.625, 4.375, 7.875, 4.75], "texture": "#1"},
"east": {"uv": [7.5, 4.375, 7.625, 4.75], "texture": "#1"},
"south": {"uv": [8, 4.375, 8.25, 4.75], "texture": "#1"},
"west": {"uv": [7.875, 4.375, 8, 4.75], "texture": "#1"},
"up": {"uv": [7.875, 4.375, 7.625, 4.25], "texture": "#1"},
"down": {"uv": [8.125, 4.25, 7.875, 4.375], "texture": "#1"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [75, 135, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"thirdperson_lefthand": {
"rotation": [75, 135, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"firstperson_righthand": {
"rotation": [0, 135, 0],
"translation": [0, -1, 0],
"scale": [0.4, 0.4, 0.4]
},
"firstperson_lefthand": {
"rotation": [0, 135, 0],
"translation": [0, -1, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 3, 0],
"scale": [0.25, 0.25, 0.25]
},
"gui": {
"rotation": [30, 225, 0],
"translation": [0, -3, 0],
"scale": [0.425, 0.425, 0.425]
},
"fixed": {
"translation": [0, -3.75, 0],
"scale": [0.5, 0.5, 0.5]
}
},
"groups": [
{
"name": "fridge_bottom",
"origin": [8, 8, 8],
"color": 0,
"children": [
0,
1,
{
"name": "drawer",
"origin": [8, 8, 8],
"color": 0,
"children": [2, 3]
},
{
"name": "door_west2",
"origin": [0, 16, 5],
"color": 0,
"children": [4]
},
{
"name": "door_east2",
"origin": [16, 16, 5],
"color": 0,
"children": [5]
}
]
},
{
"name": "fridge_top",
"origin": [8, 8, 8],
"color": 0,
"children": [
6,
7,
{
"name": "door_west",
"origin": [0, 16, 5],
"color": 0,
"children": [8, 9]
},
{
"name": "door_east",
"origin": [16, 16, 5],
"color": 0,
"children": [10, 11]
}
]
}
]
}
@@ -0,0 +1,3 @@
{
"parent": "cobblemon:block/copper_mower"
}
@@ -0,0 +1,162 @@
{
"credit": "Made with Blockbench",
"texture_size": [64, 32],
"textures": {
"1": "cobblemon:block/copper_oven"
},
"elements": [
{
"name": "main",
"from": [1, 0, 3],
"to": [15, 10, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]},
"faces": {
"north": {"uv": [2.75, 5.5, 6.25, 10.5], "texture": "#1"},
"east": {"uv": [0, 5.5, 2.75, 10.5], "texture": "#1"},
"south": {"uv": [9, 5.5, 12.5, 10.5], "texture": "#1"},
"west": {"uv": [6.25, 5.5, 9, 10.5], "texture": "#1"},
"up": {"uv": [6.25, 5.5, 2.75, 0], "texture": "#1"},
"down": {"uv": [9.75, 0, 6.25, 5.5], "texture": "#1"}
}
},
{
"name": "void",
"from": [2, 1, 4],
"to": [14, 8, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4.5, 4]},
"faces": {
"north": {"uv": [10, 0, 13, 3.5], "texture": "#1"},
"east": {"uv": [10, 0, 10, 3.5], "texture": "#1"},
"south": {"uv": [13, 0, 16, 3.5], "texture": "#1"},
"west": {"uv": [13, 0, 13, 3.5], "texture": "#1"},
"up": {"uv": [13, 0, 10, 0], "texture": "#1"},
"down": {"uv": [16, 0, 13, 0], "texture": "#1"}
}
},
{
"name": "inner_edge_e",
"from": [2, 1, 3],
"to": [2, 8, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [2, 4.5, 3.5]},
"faces": {
"north": {"uv": [0.25, 0, 0.25, 3.5], "texture": "#1"},
"east": {"uv": [0, 0, 0.25, 3.5], "texture": "#1"},
"south": {"uv": [0.5, 0, 0.5, 3.5], "texture": "#1"},
"west": {"uv": [0.25, 0, 0.5, 3.5], "texture": "#1"},
"up": {"uv": [0.25, 0, 0.25, -0.5], "texture": "#1"},
"down": {"uv": [0.25, -0.5, 0.25, 0], "texture": "#1"}
}
},
{
"name": "inner_edge_d",
"from": [2, 1, 3],
"to": [14, 1, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 3.5]},
"faces": {
"north": {"uv": [10, 4.5, 13, 4.5], "texture": "#1"},
"east": {"uv": [9.75, 4.5, 10, 4.5], "texture": "#1"},
"south": {"uv": [13.25, 4.5, 16.25, 4.5], "texture": "#1"},
"west": {"uv": [13, 4.5, 13.25, 4.5], "texture": "#1"},
"up": {"uv": [13, 4.5, 10, 4], "texture": "#1"},
"down": {"uv": [16, 4, 13, 4.5], "texture": "#1"}
}
},
{
"name": "inner_edge_u",
"from": [2, 8, 3],
"to": [14, 8, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 3.5]},
"faces": {
"north": {"uv": [10, 4.5, 13, 4.5], "texture": "#1"},
"east": {"uv": [9.75, 4.5, 10, 4.5], "texture": "#1"},
"south": {"uv": [13.25, 4.5, 16.25, 4.5], "texture": "#1"},
"west": {"uv": [13, 4.5, 13.25, 4.5], "texture": "#1"},
"up": {"uv": [13, 4.5, 10, 4], "texture": "#1"},
"down": {"uv": [16, 4, 13, 4.5], "texture": "#1"}
}
},
{
"name": "inner_edge_w",
"from": [14, 1, 3],
"to": [14, 8, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [14, 4.5, 3.5]},
"faces": {
"north": {"uv": [0.25, 0, 0.25, 3.5], "texture": "#1"},
"east": {"uv": [0, 0, 0.25, 3.5], "texture": "#1"},
"south": {"uv": [0.5, 0, 0.5, 3.5], "texture": "#1"},
"west": {"uv": [0.25, 0, 0.5, 3.5], "texture": "#1"},
"up": {"uv": [0.25, 0, 0.25, -0.5], "texture": "#1"},
"down": {"uv": [0.25, -0.5, 0.25, 0], "texture": "#1"}
}
},
{
"name": "door",
"from": [2, 1, 3],
"to": [14, 8, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 3]},
"faces": {
"north": {"uv": [0.25, 11, 3.25, 14.5], "texture": "#1"},
"east": {"uv": [0, 11, 0.25, 14.5], "texture": "#1"},
"south": {"uv": [3.5, 11, 6.5, 14.5], "texture": "#1"},
"west": {"uv": [3.25, 11, 3.5, 14.5], "texture": "#1"},
"up": {"uv": [3.25, 11, 0.25, 10.5], "texture": "#1"},
"down": {"uv": [6.25, 10.5, 3.25, 11], "texture": "#1"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"thirdperson_lefthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"firstperson_righthand": {
"rotation": [0, 45, 0],
"scale": [0.4, 0.4, 0.4]
},
"firstperson_lefthand": {
"rotation": [0, 45, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 3, 0],
"scale": [0.25, 0.25, 0.25]
},
"gui": {
"rotation": [30, 225, 0],
"scale": [0.625, 0.625, 0.625]
},
"head": {
"translation": [0, 14.5, 0]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
},
"groups": [
{
"name": "oven",
"origin": [8, 0, 9],
"color": 0,
"children": [
0,
1,
2,
3,
4,
5,
{
"name": "oven_door",
"origin": [8, 1, 3],
"color": 4,
"children": [6]
}
]
}
]
}
@@ -0,0 +1,103 @@
{
"credit": "Made with Blockbench",
"texture_size": [64, 64],
"textures": {
"0": "cobblemon:block/copper_washer"
},
"elements": [
{
"name": "tub",
"from": [1, 0, 2],
"to": [15, 14, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 0, 8]},
"faces": {
"north": {"uv": [3.5, 3.5, 7, 7], "texture": "#0"},
"east": {"uv": [0, 3.5, 3.5, 7], "texture": "#0"},
"south": {"uv": [10.5, 3.5, 14, 7], "texture": "#0"},
"west": {"uv": [7, 3.5, 10.5, 7], "texture": "#0"},
"up": {"uv": [7, 3.5, 3.5, 0], "texture": "#0"},
"down": {"uv": [10.5, 0, 7, 3.5], "texture": "#0"}
}
},
{
"name": "door",
"from": [4, 2, 1],
"to": [12, 10, 2],
"rotation": {"angle": 0, "axis": "y", "origin": [4, 0, 8]},
"faces": {
"north": {"uv": [0.25, 7.25, 2.25, 9.25], "texture": "#0"},
"east": {"uv": [0, 7.25, 0.25, 9.25], "texture": "#0"},
"south": {"uv": [2.5, 7.25, 4.5, 9.25], "texture": "#0"},
"west": {"uv": [2.25, 7.25, 2.5, 9.25], "texture": "#0"},
"up": {"uv": [2.25, 7.25, 0.25, 7], "texture": "#0"},
"down": {"uv": [4.25, 7, 2.25, 7.25], "texture": "#0"}
}
},
{
"name": "nozzle",
"from": [15, 2, 11],
"to": [16, 6, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]},
"faces": {
"north": {"uv": [1, 1, 1.25, 2], "texture": "#0"},
"east": {"uv": [0, 1, 1, 2], "texture": "#0"},
"south": {"uv": [2.25, 1, 2.5, 2], "texture": "#0"},
"west": {"uv": [1.25, 1, 2.25, 2], "texture": "#0"},
"up": {"uv": [1.25, 1, 1, 0], "texture": "#0"},
"down": {"uv": [1.5, 0, 1.25, 1], "texture": "#0"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"thirdperson_lefthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"firstperson_righthand": {
"rotation": [0, 45, 0],
"scale": [0.4, 0.4, 0.4]
},
"firstperson_lefthand": {
"rotation": [0, 45, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 3, 0],
"scale": [0.25, 0.25, 0.25]
},
"gui": {
"rotation": [30, 225, 0],
"scale": [0.625, 0.625, 0.625]
},
"head": {
"translation": [0, 1, -1],
"scale": [1.075, 1.075, 1.075]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
},
"groups": [
{
"name": "wash",
"origin": [8, 0, 8],
"color": 0,
"children": [
0,
{
"name": "door",
"origin": [12, 6, 2],
"color": 0,
"children": [1]
},
2
]
}
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 759 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 B

@@ -0,0 +1,5 @@
{
"animation": {
"frametime": 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 922 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,29 @@
{
"parent": "cobblemon:recipes/root",
"rewards": {
"recipes": [
"cobblemon:copper_fan"
]
},
"criteria": {
"caught_rotom": {
"trigger": "cobblemon:catch_pokemon",
"conditions": {
"count": 1,
"species": "rotom"
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "cobblemon:copper_fan"
}
}
},
"requirements": [
[
"caught_rotom",
"has_the_recipe"
]
]
}
@@ -0,0 +1,29 @@
{
"parent": "cobblemon:recipes/root",
"rewards": {
"recipes": [
"cobblemon:copper_fridge"
]
},
"criteria": {
"caught_rotom": {
"trigger": "cobblemon:catch_pokemon",
"conditions": {
"count": 1,
"species": "rotom"
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "cobblemon:copper_fridge"
}
}
},
"requirements": [
[
"caught_rotom",
"has_the_recipe"
]
]
}
@@ -0,0 +1,29 @@
{
"parent": "cobblemon:recipes/root",
"rewards": {
"recipes": [
"cobblemon:copper_mower"
]
},
"criteria": {
"caught_rotom": {
"trigger": "cobblemon:catch_pokemon",
"conditions": {
"count": 1,
"species": "rotom"
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "cobblemon:copper_mower"
}
}
},
"requirements": [
[
"caught_rotom",
"has_the_recipe"
]
]
}
@@ -0,0 +1,29 @@
{
"parent": "cobblemon:recipes/root",
"rewards": {
"recipes": [
"cobblemon:copper_oven"
]
},
"criteria": {
"caught_rotom": {
"trigger": "cobblemon:catch_pokemon",
"conditions": {
"count": 1,
"species": "rotom"
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "cobblemon:copper_oven"
}
}
},
"requirements": [
[
"caught_rotom",
"has_the_recipe"
]
]
}
@@ -0,0 +1,29 @@
{
"parent": "cobblemon:recipes/root",
"rewards": {
"recipes": [
"cobblemon:copper_washer"
]
},
"criteria": {
"caught_rotom": {
"trigger": "cobblemon:catch_pokemon",
"conditions": {
"count": 1,
"species": "rotom"
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "cobblemon:copper_washer"
}
}
},
"requirements": [
[
"caught_rotom",
"has_the_recipe"
]
]
}
@@ -0,0 +1,21 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"name": "cobblemon:copper_fan"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
],
"random_sequence": "cobblemon:blocks/copper_fan"
}
@@ -0,0 +1,28 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"name": "cobblemon:copper_fridge"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
},
{
"condition": "minecraft:block_state_property",
"block": "cobblemon:copper_fridge",
"properties": {
"part": "bottom"
}
}
]
}
],
"random_sequence": "cobblemon:blocks/copper_fridge"
}
@@ -0,0 +1,21 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"name": "cobblemon:copper_mower"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
],
"random_sequence": "cobblemon:blocks/copper_mower"
}
@@ -0,0 +1,30 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"bonus_rolls": 0,
"entries": [
{
"type": "minecraft:item",
"name": "cobblemon:copper_oven",
"functions": [
{
"function": "minecraft:copy_components",
"source": "block_entity",
"include": [
"minecraft:custom_name"
]
}
]
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
],
"random_sequence": "cobblemon:blocks/copper_oven"
}
@@ -0,0 +1,30 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"bonus_rolls": 0,
"entries": [
{
"type": "minecraft:item",
"name": "cobblemon:copper_washer",
"functions": [
{
"function": "minecraft:copy_components",
"source": "block_entity",
"include": [
"minecraft:custom_name"
]
}
]
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
],
"random_sequence": "cobblemon:blocks/copper_washer"
}
@@ -0,0 +1,25 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
" C ",
"CBC",
"bCR"
],
"key": {
"C": {
"tag": "c:ingots/copper"
},
"R": {
"tag": "c:dusts/redstone"
},
"B": {
"tag": "c:rods/breeze"
},
"b": {
"tag": "minecraft:buttons"
}
},
"result": {
"id": "cobblemon:copper_fan"
}
}
@@ -0,0 +1,30 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"CCC",
"CID",
"CRC"
],
"key": {
"C": {
"tag": "c:ingots/copper"
},
"R": {
"tag": "c:dusts/redstone"
},
"I": {
"item": "minecraft:packed_ice"
},
"D": [
{
"item": "minecraft:copper_door"
},
{
"item": "minecraft:waxed_copper_door"
}
]
},
"result": {
"id": "cobblemon:copper_fridge"
}
}
@@ -0,0 +1,25 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
" IC",
" CR",
"CMC"
],
"key": {
"C": {
"tag": "c:ingots/copper"
},
"R": {
"tag": "c:dusts/redstone"
},
"I": {
"tag": "c:ingots/iron"
},
"M": {
"item": "minecraft:minecart"
}
},
"result": {
"id": "cobblemon:copper_mower"
}
}
@@ -0,0 +1,25 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"CCC",
"CMT",
"CRC"
],
"key": {
"C": {
"tag": "c:ingots/copper"
},
"R": {
"tag": "c:dusts/redstone"
},
"M": {
"item": "minecraft:magma_cream"
},
"T": {
"tag": "c:glass_blocks/tinted"
}
},
"result": {
"id": "cobblemon:copper_oven"
}
}
@@ -0,0 +1,25 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"CRC",
"CBC",
"CcC"
],
"key": {
"C": {
"tag": "c:ingots/copper"
},
"R": {
"tag": "c:dusts/redstone"
},
"B": {
"tag": "c:buckets/water"
},
"c": {
"item": "minecraft:cauldron"
}
},
"result": {
"id": "cobblemon:copper_washer"
}
}
@@ -5,6 +5,7 @@
"cobblemon:pasture",
"cobblemon:restoration_tank",
"cobblemon:monitor",
"cobblemon:fossil_analyzer"
"cobblemon:fossil_analyzer",
"#cobblemon:rotom_appliances"
]
}
@@ -0,0 +1,10 @@
{
"replace": false,
"values": [
"cobblemon:copper_oven",
"cobblemon:copper_fan",
"cobblemon:copper_fridge",
"cobblemon:copper_washer",
"cobblemon:copper_mower"
]
}
@@ -5,6 +5,7 @@
"cobblemon:pasture",
"cobblemon:restoration_tank",
"cobblemon:monitor",
"cobblemon:fossil_analyzer"
"cobblemon:fossil_analyzer",
"#cobblemon:rotom_appliances"
]
}
@@ -0,0 +1,10 @@
{
"replace": false,
"values": [
"cobblemon:copper_oven",
"cobblemon:copper_fan",
"cobblemon:copper_fridge",
"cobblemon:copper_washer",
"cobblemon:copper_mower"
]
}
@@ -92,6 +92,7 @@
"cobblemon:shiny_stone_block",
"cobblemon:sun_stone_block",
"cobblemon:thunder_stone_block",
"cobblemon:water_stone_block"
"cobblemon:water_stone_block",
"#cobblemon:rotom_appliances"
]
}