PhysicalConnectivity/src/main/kotlin/net/shadowfacts/phycon/network/block/cable/CableBlock.kt

136 lines
4.7 KiB
Kotlin
Raw Normal View History

2019-10-28 15:53:47 +00:00
package net.shadowfacts.phycon.network.block.cable
import net.fabricmc.api.EnvType
import net.fabricmc.api.Environment
import net.minecraft.block.*
import net.minecraft.block.piston.PistonBehavior
import net.minecraft.entity.EntityContext
import net.minecraft.entity.player.PlayerEntity
2019-10-28 15:53:47 +00:00
import net.minecraft.item.ItemPlacementContext
import net.minecraft.state.StateFactory
import net.minecraft.state.property.EnumProperty
import net.minecraft.util.Hand
2019-10-28 15:53:47 +00:00
import net.minecraft.util.Identifier
import net.minecraft.util.hit.BlockHitResult
2019-10-28 15:53:47 +00:00
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.util.math.Vec3d
2019-10-28 15:53:47 +00:00
import net.minecraft.util.shape.VoxelShape
import net.minecraft.util.shape.VoxelShapes
import net.minecraft.world.BlockView
import net.minecraft.world.IWorld
import net.minecraft.world.World
2019-10-28 15:53:47 +00:00
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.api.NetworkCable
import net.shadowfacts.phycon.api.NetworkComponent
import net.shadowfacts.phycon.util.CableConnection
2019-10-28 15:53:47 +00:00
import java.util.*
/**
* @author shadowfacts
*/
class CableBlock: Block(Settings.of(CABLE_MATERIAL)), NetworkCable {
companion object {
val ID = Identifier(PhysicalConnectivity.MODID, "cable")
val CABLE_MATERIAL = Material(MaterialColor.IRON, false, false, true, false, true, false, false, PistonBehavior.NORMAL)
val CENTER_SHAPE = createCuboidShape(6.0, 6.0, 6.0, 10.0, 10.0, 10.0)
val SIDE_SHAPES = mapOf<Direction, VoxelShape>(
Direction.DOWN to createCuboidShape(6.0, 0.0, 6.0, 10.0, 6.0, 10.0),
Direction.UP to createCuboidShape(6.0, 10.0, 6.0, 10.0, 16.0, 10.0),
Direction.NORTH to createCuboidShape(6.0, 6.0, 0.0, 10.0, 10.0, 6.0),
Direction.SOUTH to createCuboidShape(6.0, 6.0, 10.0, 10.0, 10.0, 16.0),
Direction.WEST to createCuboidShape(0.0, 6.0, 6.0, 6.0, 10.0, 10.0),
Direction.EAST to createCuboidShape(10.0, 6.0, 6.0, 16.0, 10.0, 10.0)
)
private val SHAPE_CACHE = mutableMapOf<BlockState, VoxelShape>()
val CONNECTIONS: Map<Direction, EnumProperty<CableConnection>> = Direction.values().associate { it to EnumProperty.of(it.name.toLowerCase(), CableConnection::class.java) }
2019-10-28 15:53:47 +00:00
fun getShape(state: BlockState): VoxelShape {
return SHAPE_CACHE.getOrPut(state) {
var shape = CENTER_SHAPE
for ((side, prop) in CONNECTIONS) {
if (state[prop] == CableConnection.ON) {
2019-10-28 15:53:47 +00:00
shape = VoxelShapes.union(shape, SIDE_SHAPES[side])
}
}
return shape
}
}
}
init {
defaultState = CONNECTIONS.values.fold(stateFactory.defaultState) { acc, prop ->
acc.with(prop, CableConnection.OFF)
2019-10-28 15:53:47 +00:00
}
}
override fun getNetworkConnectedSides(state: BlockState, world: World, pos: BlockPos): Set<Direction> {
val set = EnumSet.noneOf(Direction::class.java)
for ((side, prop) in CONNECTIONS) {
if (state[prop] == CableConnection.ON) {
set.add(side)
}
}
return set
}
2019-10-28 15:53:47 +00:00
override fun appendProperties(builder: StateFactory.Builder<Block, BlockState>) {
super.appendProperties(builder)
CONNECTIONS.values.forEach {
builder.add(it)
}
}
override fun getPlacementState(context: ItemPlacementContext): BlockState {
return CONNECTIONS.entries.fold(defaultState, { acc, (dir, prop) ->
acc.with(prop, getConnectionStateInDirection(context.world, context.blockPos, dir))
2019-10-28 15:53:47 +00:00
})
}
override fun getStateForNeighborUpdate(state: BlockState, side: Direction, neighborState: BlockState, world: IWorld, blockPos_1: BlockPos, blockPos_2: BlockPos): BlockState {
val prop = CONNECTIONS[side]
val current = state[prop]
return when (current) {
CableConnection.DISABLED -> state
else -> state.with(prop, getConnectionStateInDirection(world, blockPos_1, side))
}
2019-10-28 15:53:47 +00:00
}
private fun getConnectionStateInDirection(world: IWorld, pos: BlockPos, direction: Direction): CableConnection {
val state = world.getBlockState(pos.offset(direction))
return when (state.block) {
this -> {
val prop = CONNECTIONS[direction.opposite]
when (state[prop]) {
CableConnection.DISABLED -> CableConnection.DISABLED
else -> CableConnection.ON
}
}
is NetworkComponent -> CableConnection.ON
else -> CableConnection.OFF
}
2019-10-28 15:53:47 +00:00
}
@Environment(EnvType.CLIENT)
override fun getRenderLayer(): BlockRenderLayer {
return BlockRenderLayer.TRANSLUCENT
}
override fun isOpaque(blockState_1: BlockState?): Boolean {
return false
}
override fun isTranslucent(blockState_1: BlockState?, blockView_1: BlockView?, blockPos_1: BlockPos?): Boolean {
return true
}
override fun isSimpleFullBlock(blockState_1: BlockState?, blockView_1: BlockView?, blockPos_1: BlockPos?): Boolean {
return false
}
override fun getOutlineShape(state: BlockState, world: BlockView, pos: BlockPos, context: EntityContext): VoxelShape {
return getShape(state)
}
}