2021-02-28 18:48:39 +00:00
|
|
|
package net.shadowfacts.phycon.block
|
2021-02-21 20:35:20 +00:00
|
|
|
|
|
|
|
import net.minecraft.block.Block
|
|
|
|
import net.minecraft.block.BlockState
|
|
|
|
import net.minecraft.block.ShapeContext
|
|
|
|
import net.minecraft.item.ItemPlacementContext
|
|
|
|
import net.minecraft.state.StateManager
|
|
|
|
import net.minecraft.state.property.EnumProperty
|
|
|
|
import net.minecraft.state.property.Properties
|
|
|
|
import net.minecraft.util.math.BlockPos
|
|
|
|
import net.minecraft.util.math.Direction
|
|
|
|
import net.minecraft.util.shape.VoxelShape
|
|
|
|
import net.minecraft.util.shape.VoxelShapes
|
|
|
|
import net.minecraft.world.BlockView
|
|
|
|
import net.minecraft.world.World
|
|
|
|
import net.minecraft.world.WorldAccess
|
|
|
|
import net.shadowfacts.phycon.api.Interface
|
|
|
|
import net.shadowfacts.phycon.api.NetworkComponentBlock
|
2021-02-28 18:48:39 +00:00
|
|
|
import net.shadowfacts.phycon.block.cable.CableBlock
|
2021-02-21 20:35:20 +00:00
|
|
|
import java.util.*
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author shadowfacts
|
|
|
|
*/
|
|
|
|
abstract class FaceDeviceBlock<T: DeviceBlockEntity>(settings: Settings): DeviceBlock<T>(settings) {
|
|
|
|
companion object {
|
|
|
|
val FACING = Properties.FACING
|
|
|
|
val CABLE_CONNECTION = EnumProperty.of("cable_connection", Direction::class.java)
|
|
|
|
}
|
|
|
|
|
|
|
|
protected abstract val faceThickness: Double
|
|
|
|
protected abstract val faceShapes: Map<Direction, VoxelShape>
|
|
|
|
private val centerShapes: Map<Direction, VoxelShape> by lazy {
|
|
|
|
mapOf(
|
|
|
|
Direction.DOWN to createCuboidShape(6.0, faceThickness, 6.0, 10.0, 10.0, 10.0),
|
|
|
|
Direction.UP to createCuboidShape(6.0, 6.0, 6.0, 10.0, 16.0 - faceThickness, 10.0),
|
|
|
|
Direction.NORTH to createCuboidShape(6.0, 6.0, faceThickness, 10.0, 10.0, 10.0),
|
|
|
|
Direction.SOUTH to createCuboidShape(6.0, 6.0, 6.0, 10.0, 10.0, 16.0 - faceThickness),
|
|
|
|
Direction.WEST to createCuboidShape(faceThickness, 6.0, 6.0, 10.0, 10.0, 10.0),
|
|
|
|
Direction.EAST to createCuboidShape(6.0, 6.0, 6.0, 16.0 - faceThickness, 10.0, 10.0)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
private val shapeCache = mutableMapOf<Pair<Direction, Direction>, VoxelShape>()
|
|
|
|
|
|
|
|
fun getShape(facing: Direction, cableConnection: Direction): VoxelShape {
|
|
|
|
return shapeCache.getOrPut(facing to cableConnection) {
|
|
|
|
VoxelShapes.union(
|
|
|
|
faceShapes[facing],
|
|
|
|
centerShapes[facing],
|
|
|
|
CableBlock.SIDE_SHAPES[cableConnection]
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getNetworkConnectedSides(state: BlockState, world: WorldAccess, pos: BlockPos): Collection<Direction> {
|
|
|
|
return EnumSet.of(state[CABLE_CONNECTION])
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getNetworkInterfaceForSide(side: Direction, state: BlockState, world: WorldAccess, pos: BlockPos): Interface? {
|
|
|
|
return if (side == state[FACING]) {
|
|
|
|
null
|
|
|
|
} else {
|
|
|
|
getBlockEntity(world, pos)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun appendProperties(builder: StateManager.Builder<Block, BlockState>) {
|
|
|
|
super.appendProperties(builder)
|
|
|
|
builder.add(FACING)
|
|
|
|
builder.add(CABLE_CONNECTION)
|
|
|
|
}
|
|
|
|
|
2021-02-24 03:05:05 +00:00
|
|
|
override fun getPlacementState(context: ItemPlacementContext): BlockState {
|
|
|
|
val facing = if (context.player?.isSneaking == true) context.side.opposite else context.playerLookDirection.opposite
|
|
|
|
val cableConnection = getCableConnectedSide(context.world, context.blockPos, facing) ?: facing.opposite
|
2021-02-21 20:35:20 +00:00
|
|
|
return defaultState
|
|
|
|
.with(FACING, facing)
|
|
|
|
.with(CABLE_CONNECTION, cableConnection)
|
|
|
|
}
|
|
|
|
|
2021-02-24 03:05:05 +00:00
|
|
|
protected fun getCableConnectedSide(world: World, pos: BlockPos, facing: Direction): Direction? {
|
2021-02-21 20:35:20 +00:00
|
|
|
for (side in Direction.values()) {
|
2021-02-24 03:05:05 +00:00
|
|
|
if (side == facing) {
|
|
|
|
continue
|
|
|
|
}
|
2021-02-21 20:35:20 +00:00
|
|
|
val offsetPos = pos.offset(side)
|
2021-02-24 03:05:05 +00:00
|
|
|
val state = world.getBlockState(offsetPos)
|
|
|
|
val block = state.block
|
|
|
|
if (block is NetworkComponentBlock && block.getNetworkConnectedSides(state, world, offsetPos).contains(side.opposite)) {
|
2021-02-21 20:35:20 +00:00
|
|
|
return side
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getStateForNeighborUpdate(state: BlockState, side: Direction, neighborState: BlockState, world: WorldAccess, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
|
|
|
if (neighborState.block is NetworkComponentBlock && world.getBlockState(pos.offset(state[CABLE_CONNECTION])).block !is NetworkComponentBlock) {
|
|
|
|
return state.with(CABLE_CONNECTION, side)
|
|
|
|
}
|
|
|
|
return state
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getOutlineShape(state: BlockState, world: BlockView, pos: BlockPos, context: ShapeContext): VoxelShape {
|
|
|
|
return getShape(state[FACING], state[CABLE_CONNECTION])
|
|
|
|
}
|
2021-02-24 03:05:05 +00:00
|
|
|
}
|