diff --git a/src/main/kotlin/net/shadowfacts/phycon/block/FaceDeviceBlock.kt b/src/main/kotlin/net/shadowfacts/phycon/block/FaceDeviceBlock.kt index a7f77d7..ee10508 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/block/FaceDeviceBlock.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/block/FaceDeviceBlock.kt @@ -7,6 +7,7 @@ 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.StringIdentifiable import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import net.minecraft.util.shape.VoxelShape @@ -26,7 +27,36 @@ import java.util.* abstract class FaceDeviceBlock(settings: Settings): DeviceBlock(settings) { companion object { val FACING = Properties.FACING - val CABLE_CONNECTION = EnumProperty.of("cable_connection", Direction::class.java) + val CABLE_CONNECTION = EnumProperty.of("cable_connection", FaceCableConnection::class.java) + } + + enum class FaceCableConnection : StringIdentifiable { + NONE, DOWN, UP, NORTH, SOUTH, WEST, EAST; + + companion object { + fun from(dir: Direction?) = when (dir) { + null -> NONE + Direction.DOWN -> DOWN + Direction.UP -> UP + Direction.NORTH -> NORTH + Direction.SOUTH -> SOUTH + Direction.WEST -> WEST + Direction.EAST -> EAST + } + } + + val direction: Direction? + get() = when (this) { + NONE -> null + DOWN -> Direction.DOWN + UP -> Direction.UP + NORTH -> Direction.NORTH + SOUTH -> Direction.SOUTH + WEST -> Direction.WEST + EAST -> Direction.EAST + } + + override fun asString() = name.toLowerCase() } protected abstract val faceThickness: Double @@ -41,20 +71,21 @@ abstract class FaceDeviceBlock(settings: Settings): Device Direction.EAST to createCuboidShape(6.0, 6.0, 6.0, 16.0 - faceThickness, 10.0, 10.0) ) } - private val shapeCache = mutableMapOf, VoxelShape>() + private val shapeCache = mutableMapOf, VoxelShape>() - fun getShape(facing: Direction, cableConnection: Direction): VoxelShape { + private fun getShape(facing: Direction, cableConnection: FaceCableConnection): VoxelShape { return shapeCache.getOrPut(facing to cableConnection) { - VoxelShapes.union( - faceShapes[facing], - centerShapes[facing], - CableBlock.SIDE_SHAPES[cableConnection] - ) + if (cableConnection == FaceCableConnection.NONE) { + VoxelShapes.union(faceShapes[facing], centerShapes[facing]) + } else { + VoxelShapes.union(faceShapes[facing], centerShapes[facing], CableBlock.SIDE_SHAPES[cableConnection.direction]) + } } } override fun getNetworkConnectedSides(state: BlockState, world: WorldAccess, pos: BlockPos): Collection { - return EnumSet.of(state[CABLE_CONNECTION]) + val direction = state[CABLE_CONNECTION].direction + return if (direction != null) EnumSet.of(direction) else setOf() } override fun getNetworkInterfaceForSide(side: Direction, state: BlockState, world: WorldAccess, pos: BlockPos): Interface? { @@ -73,13 +104,13 @@ abstract class FaceDeviceBlock(settings: Settings): Device 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 + val cableConnection = FaceCableConnection.from(getCableConnectedSide(context.world, context.blockPos, facing)) return defaultState .with(FACING, facing) .with(CABLE_CONNECTION, cableConnection) } - protected fun getCableConnectedSide(world: World, pos: BlockPos, facing: Direction): Direction? { + private fun getCableConnectedSide(world: WorldAccess, pos: BlockPos, facing: Direction): Direction? { for (side in Direction.values()) { if (side == facing) { continue @@ -95,10 +126,21 @@ abstract class FaceDeviceBlock(settings: Settings): Device } 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) + val current = state[CABLE_CONNECTION] + var newConnection = current + + if (current == FaceCableConnection.NONE) { + if (neighborState.block is NetworkComponentBlock) { + newConnection = FaceCableConnection.from(side) + } + } else { + val currentConnectedPos = pos.offset(current.direction) + if (neighborPos == currentConnectedPos && neighborState.block !is NetworkComponentBlock) { + // the old cable connection is no longer correct, try to find another + newConnection = FaceCableConnection.from(getCableConnectedSide(world, pos, state[FACING])) + } } - return state + return state.with(CABLE_CONNECTION, newConnection) } override fun getOutlineShape(state: BlockState, world: BlockView, pos: BlockPos, context: ShapeContext): VoxelShape { diff --git a/src/main/kotlin/net/shadowfacts/phycon/client/model/InterfaceModel.kt b/src/main/kotlin/net/shadowfacts/phycon/client/model/InterfaceModel.kt index cdd03c7..eecdb99 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/client/model/InterfaceModel.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/client/model/InterfaceModel.kt @@ -8,6 +8,7 @@ import net.minecraft.util.Identifier import net.minecraft.util.math.Direction import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.block.FaceDeviceBlock +import net.shadowfacts.phycon.block.FaceDeviceBlock.FaceCableConnection import java.util.Random import java.util.function.Function @@ -20,8 +21,10 @@ object InterfaceModel: UnbakedModel, BakedModel { private val interfaceCableStraightID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_straight") private val interfaceCableCornerID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_corner") private val interfaceCableCorner2ID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_corner_2") + private val interfaceCableCapID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_cap") private var interfaceSides = Array(6) { null } private var interfaceCableStraight = Array(6) { null } + private var interfaceCableCap = Array(6) { null } private var interfaceCableCorner = mutableMapOf() private var interfaceCableCorner2 = mutableMapOf() @@ -31,6 +34,7 @@ object InterfaceModel: UnbakedModel, BakedModel { interfaceCableStraightID, interfaceCableCornerID, interfaceCableCorner2ID, + interfaceCableCapID ) } @@ -52,6 +56,7 @@ object InterfaceModel: UnbakedModel, BakedModel { ).forEachIndexed { i, rot -> interfaceSides[i] = loader.bake(interfaceSideID, rot) interfaceCableStraight[i] = loader.bake(interfaceCableStraightID, rot) + interfaceCableCap[i] = loader.bake(interfaceCableCapID, rot) } mapOf( @@ -85,50 +90,52 @@ object InterfaceModel: UnbakedModel, BakedModel { val connection = state[FaceDeviceBlock.CABLE_CONNECTION] val sideQuads = interfaceSides[facing.ordinal]?.getQuads(state, face, random) ?: listOf() - val cableQuads = if (connection == facing.opposite) { + val cableQuads = if (connection.direction == facing.opposite) { interfaceCableStraight[facing.ordinal]?.getQuads(state, face, random) ?: listOf() + } else if (connection == FaceCableConnection.NONE) { + interfaceCableCap[facing.ordinal]?.getQuads(state, face, random) ?: listOf() } else { val model = when (facing) { Direction.DOWN -> when (connection) { - Direction.NORTH -> interfaceCableCorner[ModelRotation.X0_Y0] - Direction.EAST -> interfaceCableCorner[ModelRotation.X0_Y90] - Direction.SOUTH -> interfaceCableCorner[ModelRotation.X0_Y180] - Direction.WEST -> interfaceCableCorner[ModelRotation.X0_Y270] + FaceCableConnection.NORTH -> interfaceCableCorner[ModelRotation.X0_Y0] + FaceCableConnection.EAST -> interfaceCableCorner[ModelRotation.X0_Y90] + FaceCableConnection.SOUTH -> interfaceCableCorner[ModelRotation.X0_Y180] + FaceCableConnection.WEST -> interfaceCableCorner[ModelRotation.X0_Y270] else -> null } Direction.UP -> when (connection) { - Direction.NORTH -> interfaceCableCorner[ModelRotation.X180_Y180] - Direction.EAST -> interfaceCableCorner[ModelRotation.X180_Y270] - Direction.SOUTH -> interfaceCableCorner[ModelRotation.X180_Y0] - Direction.WEST -> interfaceCableCorner[ModelRotation.X180_Y90] + FaceCableConnection.NORTH -> interfaceCableCorner[ModelRotation.X180_Y180] + FaceCableConnection.EAST -> interfaceCableCorner[ModelRotation.X180_Y270] + FaceCableConnection.SOUTH -> interfaceCableCorner[ModelRotation.X180_Y0] + FaceCableConnection.WEST -> interfaceCableCorner[ModelRotation.X180_Y90] else -> null } Direction.NORTH -> when (connection) { - Direction.UP -> interfaceCableCorner[ModelRotation.X270_Y0] - Direction.EAST -> interfaceCableCorner2[ModelRotation.X180_Y180] - Direction.DOWN -> interfaceCableCorner[ModelRotation.X90_Y180] - Direction.WEST -> interfaceCableCorner2[ModelRotation.X0_Y0] + FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y0] + FaceCableConnection.EAST -> interfaceCableCorner2[ModelRotation.X180_Y180] + FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y180] + FaceCableConnection.WEST -> interfaceCableCorner2[ModelRotation.X0_Y0] else -> null } Direction.SOUTH -> when (connection) { - Direction.UP -> interfaceCableCorner[ModelRotation.X270_Y180] - Direction.WEST -> interfaceCableCorner2[ModelRotation.X180_Y0] - Direction.DOWN -> interfaceCableCorner[ModelRotation.X90_Y0] - Direction.EAST -> interfaceCableCorner2[ModelRotation.X0_Y180] + FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y180] + FaceCableConnection.WEST -> interfaceCableCorner2[ModelRotation.X180_Y0] + FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y0] + FaceCableConnection.EAST -> interfaceCableCorner2[ModelRotation.X0_Y180] else -> null } Direction.WEST -> when (connection) { - Direction.UP -> interfaceCableCorner[ModelRotation.X270_Y270] - Direction.NORTH -> interfaceCableCorner2[ModelRotation.X180_Y90] - Direction.DOWN -> interfaceCableCorner[ModelRotation.X90_Y90] - Direction.SOUTH -> interfaceCableCorner2[ModelRotation.X0_Y270] + FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y270] + FaceCableConnection.NORTH -> interfaceCableCorner2[ModelRotation.X180_Y90] + FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y90] + FaceCableConnection.SOUTH -> interfaceCableCorner2[ModelRotation.X0_Y270] else -> null } Direction.EAST -> when (connection) { - Direction.UP -> interfaceCableCorner[ModelRotation.X270_Y90] - Direction.SOUTH -> interfaceCableCorner2[ModelRotation.X180_Y270] - Direction.DOWN -> interfaceCableCorner[ModelRotation.X90_Y270] - Direction.NORTH -> interfaceCableCorner2[ModelRotation.X0_Y90] + FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y90] + FaceCableConnection.SOUTH -> interfaceCableCorner2[ModelRotation.X180_Y270] + FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y270] + FaceCableConnection.NORTH -> interfaceCableCorner2[ModelRotation.X0_Y90] else -> null } else -> null diff --git a/src/main/resources/assets/phycon/models/block/interface_cable_cap.json b/src/main/resources/assets/phycon/models/block/interface_cable_cap.json new file mode 100644 index 0000000..7f1ef62 --- /dev/null +++ b/src/main/resources/assets/phycon/models/block/interface_cable_cap.json @@ -0,0 +1,29 @@ +{ + "textures": { + "cap": "phycon:block/cable_cap_end", + "straight": "phycon:block/cable_straight" + }, + "elements": [ + { + "from": [6, 6, 6], + "to": [10, 9, 10], + "faces": { + "north": {"texture": "#straight"}, + "south": {"texture": "#straight"}, + "west": {"texture": "#straight"}, + "east": {"texture": "#straight"} + } + }, + { + "from": [6, 9, 6], + "to": [10, 10, 10], + "faces": { + "up": {"texture": "#cap"}, + "north": {"texture": "#cap"}, + "south": {"texture": "#cap"}, + "west": {"texture": "#cap"}, + "east": {"texture": "#cap"} + } + } + ] +}