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

161 lines
5.6 KiB
Kotlin
Raw Normal View History

2020-03-29 03:31:21 +00:00
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
2020-03-29 18:21:28 +00:00
import net.minecraft.entity.EntityType
2020-03-29 03:31:21 +00:00
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
2020-03-29 16:17:29 +00:00
import net.minecraft.world.World
2020-03-29 03:31:21 +00:00
import net.shadowfacts.extrahoppers.block.base.BlockWithEntity
2020-03-29 16:17:29 +00:00
import net.shadowfacts.extrahoppers.util.DynamicFluidStateProvider
2020-03-29 03:31:21 +00:00
/**
* @author shadowfacts
*/
class GrateBlock: BlockWithEntity<GrateBlockEntity>(
FabricBlockSettings.of(Material.METAL, MaterialColor.AIR)
.strength(5f, 6f)
.sounds(BlockSoundGroup.METAL)
.nonOpaque()
.build()
2020-03-29 16:17:29 +00:00
), DynamicFluidStateProvider, FluidFillable, FluidDrainable {
2020-03-29 03:31:21 +00:00
companion object {
val ID = Identifier("extrahoppers", "grate")
val HALF = Properties.BLOCK_HALF
2020-03-29 18:21:28 +00:00
val TOP_SHAPE = createCuboidShape(0.0, 14.0, 0.0, 16.0, 16.0, 16.0)
val BOTTOM_SHAPE = createCuboidShape(0.0, 0.0, 0.0, 16.0, 2.0, 16.0)
2020-03-29 03:31:21 +00:00
}
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()
2020-03-29 18:21:28 +00:00
override fun isTranslucent(state: BlockState, world: BlockView, pos: BlockPos): Boolean {
return true
}
override fun isSimpleFullBlock(state: BlockState, world: BlockView, pos: BlockPos): Boolean {
return false
}
override fun allowsSpawning(state: BlockState, world: BlockView, pos: BlockPos, entityType: EntityType<*>): Boolean {
return false
}
2020-03-29 03:31:21 +00:00
override fun getFluidState(state: BlockState, world: BlockView, pos: BlockPos): FluidState {
return getBlockEntity(world, pos)?.fluidState ?: Fluids.EMPTY.defaultState
}
2020-03-29 16:17:29 +00:00
override fun setEmptyFluid(world: World, pos: BlockPos) {
val be = getBlockEntity(world, pos) ?: return
be.fluidState = null
if (!world.isClient) {
be.sync()
}
triggerFluidUpdate(world, pos, world.getBlockState(pos))
}
override fun allowsFlow(toSide: Direction, state: BlockState, world: BlockView, pos: BlockPos): DynamicFluidStateProvider.FlowResult {
return DynamicFluidStateProvider.FlowResult.ALLOW
2020-03-29 03:31:21 +00:00
}
2020-03-29 16:17:29 +00:00
override fun neighborUpdate(state: BlockState, world: World, pos: BlockPos, block: Block, neighborPos: BlockPos, bl: Boolean) {
val fluidState = getFluidState(state, world, pos)
if (!fluidState.isEmpty) {
world.fluidTickScheduler.schedule(pos, fluidState.fluid, fluidState.fluid.getTickRate(world))
}
}
private fun triggerFluidUpdate(world: World, pos: BlockPos, state: BlockState) {
world.updateListeners(pos, state, state, 3)
world.updateNeighbors(pos, state.block)
}
2020-03-29 03:31:21 +00:00
// 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) {
2020-03-29 16:17:29 +00:00
be.fluidState = fluidState
2020-03-29 03:31:21 +00:00
if (!world.isClient) {
world.fluidTickScheduler.schedule(pos, fluidState.fluid, fluidState.fluid.getTickRate(world))
be.sync()
}
2020-03-29 16:17:29 +00:00
if (world is World) {
triggerFluidUpdate(world, pos, state)
}
2020-03-29 03:31:21 +00:00
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) {
2020-03-29 16:17:29 +00:00
be.fluidState = null
2020-03-29 03:31:21 +00:00
if (!world.isClient) {
be.sync()
}
2020-03-29 16:17:29 +00:00
if (world is World) {
triggerFluidUpdate(world, pos, state)
}
2020-03-29 03:31:21 +00:00
fluidState.fluid
} else {
Fluids.EMPTY
}
}
}