161 lines
5.6 KiB
Kotlin
161 lines
5.6 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.entity.EntityType
|
|
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.minecraft.world.World
|
|
import net.shadowfacts.extrahoppers.block.base.BlockWithEntity
|
|
import net.shadowfacts.extrahoppers.util.DynamicFluidStateProvider
|
|
|
|
/**
|
|
* @author shadowfacts
|
|
*/
|
|
class GrateBlock: BlockWithEntity<GrateBlockEntity>(
|
|
FabricBlockSettings.of(Material.METAL, MaterialColor.AIR)
|
|
.strength(5f, 6f)
|
|
.sounds(BlockSoundGroup.METAL)
|
|
.nonOpaque()
|
|
.build()
|
|
), DynamicFluidStateProvider, FluidFillable, FluidDrainable {
|
|
|
|
companion object {
|
|
val ID = Identifier("extrahoppers", "grate")
|
|
|
|
val HALF = Properties.BLOCK_HALF
|
|
|
|
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)
|
|
}
|
|
|
|
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 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
|
|
}
|
|
|
|
override fun getFluidState(state: BlockState, world: BlockView, pos: BlockPos): FluidState {
|
|
return getBlockEntity(world, pos)?.fluidState ?: Fluids.EMPTY.defaultState
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
// 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) {
|
|
be.fluidState = fluidState
|
|
if (!world.isClient) {
|
|
world.fluidTickScheduler.schedule(pos, fluidState.fluid, fluidState.fluid.getTickRate(world))
|
|
be.sync()
|
|
}
|
|
if (world is World) {
|
|
triggerFluidUpdate(world, pos, state)
|
|
}
|
|
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) {
|
|
be.fluidState = null
|
|
if (!world.isClient) {
|
|
be.sync()
|
|
}
|
|
if (world is World) {
|
|
triggerFluidUpdate(world, pos, state)
|
|
}
|
|
fluidState.fluid
|
|
} else {
|
|
Fluids.EMPTY
|
|
}
|
|
}
|
|
}
|