ExtraHoppers/src/main/kotlin/net/shadowfacts/extrahoppers/block/grate/GrateBlock.kt

122 lines
4.2 KiB
Kotlin

package net.shadowfacts.extrahoppers.block.grate
import net.fabricmc.fabric.api.block.FabricBlockSettings
import net.minecraft.block.*
import net.minecraft.block.enums.BlockHalf
import net.minecraft.entity.EntityContext
import net.minecraft.fluid.Fluid
import net.minecraft.fluid.FluidState
import net.minecraft.fluid.Fluids
import net.minecraft.item.ItemPlacementContext
import net.minecraft.sound.BlockSoundGroup
import net.minecraft.state.StateManager
import net.minecraft.state.property.Properties
import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.util.shape.VoxelShape
import net.minecraft.world.BlockView
import net.minecraft.world.IWorld
import net.shadowfacts.extrahoppers.block.base.BlockWithEntity
import net.shadowfacts.extrahoppers.util.FluidFlowControllable
import net.shadowfacts.extrahoppers.util.PositionedFluidStateProvider
/**
* @author shadowfacts
*/
class GrateBlock: BlockWithEntity<GrateBlockEntity>(
FabricBlockSettings.of(Material.METAL, MaterialColor.AIR)
.strength(5f, 6f)
.sounds(BlockSoundGroup.METAL)
.nonOpaque()
.build()
), PositionedFluidStateProvider, FluidFlowControllable, FluidFillable, FluidDrainable {
companion object {
val ID = Identifier("extrahoppers", "grate")
val HALF = Properties.BLOCK_HALF
val TOP_SHAPE = createCuboidShape(0.0, 15.0, 0.0, 16.0, 16.0, 16.0)
val BOTTOM_SHAPE = createCuboidShape(0.0, 0.0, 0.0, 16.0, 1.0, 16.0)
}
init {
defaultState = stateManager.defaultState.with(HALF, BlockHalf.BOTTOM)
}
override fun appendProperties(builder: StateManager.Builder<Block, BlockState>) {
builder.add(HALF)
}
override fun getOutlineShape(state: BlockState, world: BlockView, pos: BlockPos, entityContext: EntityContext): VoxelShape {
return when (state.get(HALF)) {
BlockHalf.TOP -> TOP_SHAPE
BlockHalf.BOTTOM -> BOTTOM_SHAPE
}
}
override fun getRayTraceShape(state: BlockState, world: BlockView, pos: BlockPos): VoxelShape {
return when (state.get(HALF)) {
BlockHalf.TOP -> TOP_SHAPE
BlockHalf.BOTTOM -> BOTTOM_SHAPE
}
}
override fun getPlacementState(context: ItemPlacementContext): BlockState {
val half = when (context.side) {
Direction.DOWN -> BlockHalf.TOP
Direction.UP -> BlockHalf.BOTTOM
else -> if (context.hitPos.y - context.blockPos.y > 0.5) BlockHalf.TOP else BlockHalf.BOTTOM
}
return defaultState.with(HALF, half)
}
override fun createBlockEntity(world: BlockView) = GrateBlockEntity()
override fun getFluidState(state: BlockState, world: BlockView, pos: BlockPos): FluidState {
return getBlockEntity(world, pos)?.fluidState ?: Fluids.EMPTY.defaultState
}
override fun allowsFlow(toSide: Direction, state: BlockState, world: BlockView, pos: BlockPos): FluidFlowControllable.Result {
return FluidFlowControllable.Result.ALLOW
}
// Fluid Fillable
override fun canFillWithFluid(world: BlockView, pos: BlockPos, state: BlockState, fluid: Fluid): Boolean {
val be = getBlockEntity(world, pos)
return be != null && be.fluidState == null
}
override fun tryFillWithFluid(world: IWorld, pos: BlockPos, state: BlockState, fluidState: FluidState): Boolean {
val be = getBlockEntity(world, pos)
return if (be != null) {
if (!world.isClient) {
be.fluidState = fluidState
world.fluidTickScheduler.schedule(pos, fluidState.fluid, fluidState.fluid.getTickRate(world))
be.sync()
}
true
} else {
false
}
}
override fun tryDrainFluid(world: IWorld, pos: BlockPos, state: BlockState): Fluid {
val be = getBlockEntity(world, pos) ?: return Fluids.EMPTY
val fluidState = be.fluidState ?: return Fluids.EMPTY
return if (fluidState.isStill) {
if (!world.isClient) {
be.fluidState = null
be.sync()
}
fluidState.fluid
} else {
Fluids.EMPTY
}
}
}