2021-02-28 18:48:39 +00:00
|
|
|
package net.shadowfacts.phycon.block.cable
|
2019-10-28 15:53:47 +00:00
|
|
|
|
|
|
|
import net.minecraft.block.*
|
|
|
|
import net.minecraft.block.piston.PistonBehavior
|
2019-10-28 16:38:55 +00:00
|
|
|
import net.minecraft.entity.player.PlayerEntity
|
2019-10-28 15:53:47 +00:00
|
|
|
import net.minecraft.item.ItemPlacementContext
|
2021-02-10 23:55:49 +00:00
|
|
|
import net.minecraft.state.StateManager
|
2019-10-28 16:38:55 +00:00
|
|
|
import net.minecraft.state.property.EnumProperty
|
2021-02-10 23:55:49 +00:00
|
|
|
import net.minecraft.util.ActionResult
|
2019-10-28 16:38:55 +00:00
|
|
|
import net.minecraft.util.Hand
|
2019-10-28 15:53:47 +00:00
|
|
|
import net.minecraft.util.Identifier
|
2019-10-28 16:38:55 +00:00
|
|
|
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
|
2019-10-28 16:38:55 +00:00
|
|
|
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
|
2019-10-28 16:00:17 +00:00
|
|
|
import net.minecraft.world.World
|
2021-02-10 23:55:49 +00:00
|
|
|
import net.minecraft.world.WorldAccess
|
2019-10-28 15:53:47 +00:00
|
|
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
2021-02-13 23:24:36 +00:00
|
|
|
import net.shadowfacts.phycon.api.Interface
|
|
|
|
import net.shadowfacts.phycon.api.NetworkCableBlock
|
|
|
|
import net.shadowfacts.phycon.api.NetworkComponentBlock
|
2019-10-28 16:39:12 +00:00
|
|
|
import net.shadowfacts.phycon.init.PhyItems
|
2019-10-28 16:38:55 +00:00
|
|
|
import net.shadowfacts.phycon.util.CableConnection
|
2019-10-28 15:53:47 +00:00
|
|
|
import java.util.*
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author shadowfacts
|
|
|
|
*/
|
2021-02-10 23:55:49 +00:00
|
|
|
class CableBlock: Block(
|
|
|
|
Settings.of(CABLE_MATERIAL)
|
2021-02-28 23:56:04 +00:00
|
|
|
.strength(1f)
|
2021-02-10 23:55:49 +00:00
|
|
|
.nonOpaque()
|
2021-02-13 23:24:36 +00:00
|
|
|
), NetworkCableBlock {
|
2019-10-28 15:53:47 +00:00
|
|
|
companion object {
|
|
|
|
val ID = Identifier(PhysicalConnectivity.MODID, "cable")
|
2021-02-10 23:55:49 +00:00
|
|
|
val CABLE_MATERIAL = Material(MaterialColor.IRON, false, false, true, false, true, false, PistonBehavior.NORMAL)
|
2019-10-28 15:53:47 +00:00
|
|
|
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>()
|
2019-10-28 16:38:55 +00:00
|
|
|
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) {
|
2019-10-28 16:38:55 +00:00
|
|
|
if (state[prop] == CableConnection.ON) {
|
2019-10-28 15:53:47 +00:00
|
|
|
shape = VoxelShapes.union(shape, SIDE_SHAPES[side])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return shape
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
init {
|
2021-02-10 23:55:49 +00:00
|
|
|
defaultState = CONNECTIONS.values.fold(stateManager.defaultState) { acc, prop ->
|
2019-10-28 16:38:55 +00:00
|
|
|
acc.with(prop, CableConnection.OFF)
|
2019-10-28 15:53:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-18 03:29:18 +00:00
|
|
|
override fun getNetworkConnectedSides(state: BlockState, world: WorldAccess, pos: BlockPos): Collection<Direction> {
|
2019-10-28 16:00:17 +00:00
|
|
|
val set = EnumSet.noneOf(Direction::class.java)
|
|
|
|
for ((side, prop) in CONNECTIONS) {
|
2019-10-28 16:38:55 +00:00
|
|
|
if (state[prop] == CableConnection.ON) {
|
2019-10-28 16:00:17 +00:00
|
|
|
set.add(side)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return set
|
|
|
|
}
|
|
|
|
|
2021-02-10 23:55:49 +00:00
|
|
|
override fun appendProperties(builder: StateManager.Builder<Block, BlockState>) {
|
2019-10-28 15:53:47 +00:00
|
|
|
super.appendProperties(builder)
|
|
|
|
CONNECTIONS.values.forEach {
|
|
|
|
builder.add(it)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getPlacementState(context: ItemPlacementContext): BlockState {
|
|
|
|
return CONNECTIONS.entries.fold(defaultState, { acc, (dir, prop) ->
|
2019-10-28 16:38:55 +00:00
|
|
|
acc.with(prop, getConnectionStateInDirection(context.world, context.blockPos, dir))
|
2019-10-28 15:53:47 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-02-10 23:55:49 +00:00
|
|
|
override fun getStateForNeighborUpdate(state: BlockState, side: Direction, neighborState: BlockState, world: WorldAccess, blockPos_1: BlockPos, blockPos_2: BlockPos): BlockState {
|
2019-10-28 16:38:55 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2021-02-10 23:55:49 +00:00
|
|
|
private fun getConnectionStateInDirection(world: WorldAccess, pos: BlockPos, direction: Direction): CableConnection {
|
2021-02-18 03:29:18 +00:00
|
|
|
val offsetPos = pos.offset(direction)
|
|
|
|
val state = world.getBlockState(offsetPos)
|
|
|
|
val block = state.block
|
|
|
|
return when (block) {
|
2019-10-28 16:38:55 +00:00
|
|
|
this -> {
|
|
|
|
val prop = CONNECTIONS[direction.opposite]
|
|
|
|
when (state[prop]) {
|
|
|
|
CableConnection.DISABLED -> CableConnection.DISABLED
|
|
|
|
else -> CableConnection.ON
|
|
|
|
}
|
|
|
|
}
|
2021-02-18 03:29:18 +00:00
|
|
|
is NetworkComponentBlock -> {
|
|
|
|
if (block.getNetworkConnectedSides(state, world, offsetPos).contains(direction.opposite)) {
|
|
|
|
CableConnection.ON
|
|
|
|
} else {
|
|
|
|
CableConnection.OFF
|
|
|
|
}
|
|
|
|
}
|
2019-10-28 16:38:55 +00:00
|
|
|
else -> CableConnection.OFF
|
|
|
|
}
|
2019-10-28 15:53:47 +00:00
|
|
|
}
|
|
|
|
|
2021-02-18 03:29:18 +00:00
|
|
|
override fun getNetworkInterfaceForSide(side: Direction, state: BlockState, world: WorldAccess, pos: BlockPos): Interface? {
|
2021-02-13 23:24:36 +00:00
|
|
|
// cables don't have network interfaces
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
2021-02-10 23:55:49 +00:00
|
|
|
override fun onUse(
|
|
|
|
state: BlockState,
|
|
|
|
world: World,
|
|
|
|
pos: BlockPos,
|
|
|
|
player: PlayerEntity,
|
|
|
|
hand: Hand,
|
|
|
|
hitResult: BlockHitResult
|
|
|
|
): ActionResult {
|
2019-10-28 16:39:12 +00:00
|
|
|
if (player.getStackInHand(hand).item == PhyItems.SCREWDRIVER) {
|
|
|
|
val hitPos = Vec3d(hitResult.pos.x - pos.x, hitResult.pos.y - pos.y, hitResult.pos.z - pos.z)
|
|
|
|
val hitConnection = SIDE_SHAPES.entries.firstOrNull { (_, shape) ->
|
|
|
|
val box = shape.boundingBox
|
|
|
|
hitPos.x >= box.minX && hitPos.x <= box.maxX && hitPos.y >= box.minY && hitPos.y <= box.maxY && hitPos.z >= box.minZ && hitPos.z <= box.maxZ
|
|
|
|
}
|
|
|
|
if (hitConnection != null) {
|
|
|
|
val side = hitConnection.key
|
|
|
|
val prop = CONNECTIONS[side]
|
|
|
|
val newState = when (state[prop]) {
|
|
|
|
CableConnection.DISABLED -> {
|
|
|
|
// if the block this cable is connecting to on the side that will be re-enabled is a cable that
|
|
|
|
// is disabled on the side that connects it to us, we also re-enable that cable to make sure both
|
|
|
|
// "halves" of the connection are in the same state
|
|
|
|
val connectedToPos = pos.offset(side)
|
|
|
|
val connectedTo = world.getBlockState(connectedToPos)
|
|
|
|
if (connectedTo.block == this && connectedTo[CONNECTIONS[side.opposite]] == CableConnection.DISABLED) {
|
|
|
|
world.setBlockState(connectedToPos, connectedTo.with(CONNECTIONS[side.opposite], CableConnection.ON))
|
|
|
|
}
|
|
|
|
|
2021-02-13 23:24:36 +00:00
|
|
|
state.with(prop, if (connectedTo.block is NetworkComponentBlock) CableConnection.ON else CableConnection.OFF)
|
2019-10-28 16:39:12 +00:00
|
|
|
}
|
|
|
|
else -> state.with(prop, CableConnection.DISABLED)
|
|
|
|
}
|
|
|
|
world.setBlockState(pos, newState)
|
|
|
|
}
|
2021-02-10 23:55:49 +00:00
|
|
|
return ActionResult.SUCCESS
|
2019-10-28 16:39:12 +00:00
|
|
|
}
|
2021-02-10 23:55:49 +00:00
|
|
|
return ActionResult.PASS
|
2019-10-28 15:53:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun isTranslucent(blockState_1: BlockState?, blockView_1: BlockView?, blockPos_1: BlockPos?): Boolean {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2021-02-10 23:55:49 +00:00
|
|
|
// override fun isSimpleFullBlock(blockState_1: BlockState?, blockView_1: BlockView?, blockPos_1: BlockPos?): Boolean {
|
|
|
|
// return false
|
|
|
|
// }
|
2019-10-28 15:53:47 +00:00
|
|
|
|
2021-02-10 23:55:49 +00:00
|
|
|
override fun getOutlineShape(state: BlockState, world: BlockView, pos: BlockPos, context: ShapeContext): VoxelShape {
|
2019-10-28 15:53:47 +00:00
|
|
|
return getShape(state)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|