diff --git a/src/main/java/net/shadowfacts/phycon/api/NetworkCable.java b/src/main/java/net/shadowfacts/phycon/api/NetworkCable.java index 53d1c6e..96521e4 100644 --- a/src/main/java/net/shadowfacts/phycon/api/NetworkCable.java +++ b/src/main/java/net/shadowfacts/phycon/api/NetworkCable.java @@ -1,17 +1,8 @@ package net.shadowfacts.phycon.api; -import net.minecraft.block.BlockState; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.world.World; - -import java.util.Set; - /** * @author shadowfacts */ public interface NetworkCable extends NetworkComponent { - Set getNetworkConnectedSides(BlockState state, World world, BlockPos pos); - } diff --git a/src/main/java/net/shadowfacts/phycon/api/NetworkComponent.java b/src/main/java/net/shadowfacts/phycon/api/NetworkComponent.java index 9bae6af..bfacdf7 100644 --- a/src/main/java/net/shadowfacts/phycon/api/NetworkComponent.java +++ b/src/main/java/net/shadowfacts/phycon/api/NetworkComponent.java @@ -1,7 +1,17 @@ package net.shadowfacts.phycon.api; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +import java.util.Collection; + /** * @author shadowfacts */ public interface NetworkComponent { + + Collection getNetworkConnectedSides(BlockState state, World world, BlockPos pos); + } diff --git a/src/main/kotlin/net/shadowfacts/phycon/network/NetworkUtil.kt b/src/main/kotlin/net/shadowfacts/phycon/network/NetworkUtil.kt index 8e3e4ce..2930e3f 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/network/NetworkUtil.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/network/NetworkUtil.kt @@ -4,6 +4,7 @@ import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import net.minecraft.world.World import net.shadowfacts.phycon.api.NetworkCable +import net.shadowfacts.phycon.api.NetworkComponent import net.shadowfacts.phycon.api.PacketSink import net.shadowfacts.phycon.api.PhyAttributes import java.util.* @@ -20,7 +21,7 @@ object NetworkUtil { if (direction != null) { queue.add(startPos.offset(direction)) } else { - addAdjacent(queue, visited, startPos) + findEdges(queue, visited, world, startPos, includeNonCables = true) } while (queue.isNotEmpty()) { @@ -39,10 +40,10 @@ object NetworkUtil { return results } - private fun findEdges(queue: MutableList, visited: Set, world: World, pos: BlockPos) { + private fun findEdges(queue: MutableList, visited: Set, world: World, pos: BlockPos, includeNonCables: Boolean = false) { val state = world.getBlockState(pos) val block = state.block - if (block is NetworkCable) { + if (block is NetworkComponent && (includeNonCables || block is NetworkCable)) { val connections = block.getNetworkConnectedSides(state, world, pos) for (side in connections) { val newPos = pos.offset(side) @@ -53,13 +54,4 @@ object NetworkUtil { } } - private fun addAdjacent(queue: MutableList, visited: Set, pos: BlockPos) { - for (dir in Direction.values()) { - val newPos = pos.offset(dir) - if (newPos !in visited) { - queue.add(newPos) - } - } - } - } diff --git a/src/main/kotlin/net/shadowfacts/phycon/network/block/cable/CableBlock.kt b/src/main/kotlin/net/shadowfacts/phycon/network/block/cable/CableBlock.kt index ede82fa..21b9e35 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/network/block/cable/CableBlock.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/network/block/cable/CableBlock.kt @@ -65,7 +65,7 @@ class CableBlock: Block(Settings.of(CABLE_MATERIAL)), NetworkCable { } } - override fun getNetworkConnectedSides(state: BlockState, world: World, pos: BlockPos): Set { + override fun getNetworkConnectedSides(state: BlockState, world: World, pos: BlockPos): Collection { val set = EnumSet.noneOf(Direction::class.java) for ((side, prop) in CONNECTIONS) { if (state[prop] == CableConnection.ON) { diff --git a/src/main/kotlin/net/shadowfacts/phycon/network/block/netinterface/InterfaceBlock.kt b/src/main/kotlin/net/shadowfacts/phycon/network/block/netinterface/InterfaceBlock.kt index 5492e08..6cbdeeb 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/network/block/netinterface/InterfaceBlock.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/network/block/netinterface/InterfaceBlock.kt @@ -5,18 +5,27 @@ import alexiil.mc.lib.attributes.AttributeProvider import net.minecraft.block.Block import net.minecraft.block.BlockState import net.minecraft.block.Material +import net.minecraft.entity.EntityContext import net.minecraft.entity.LivingEntity import net.minecraft.item.ItemPlacementContext import net.minecraft.item.ItemStack import net.minecraft.state.StateFactory +import net.minecraft.state.property.EnumProperty 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.util.shape.VoxelShapes import net.minecraft.world.BlockView +import net.minecraft.world.IWorld import net.minecraft.world.World import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.api.NetworkComponent import net.shadowfacts.phycon.block.BlockWithEntity +import net.shadowfacts.phycon.network.block.cable.CableBlock +import java.net.NoRouteToHostException +import java.util.* /** * @author shadowfacts @@ -25,18 +34,61 @@ class InterfaceBlock: BlockWithEntity(Settings.of(Material companion object { val ID = Identifier(PhysicalConnectivity.MODID, "network_interface") val FACING = Properties.FACING + val CABLE_CONNECTION = EnumProperty.of("cable_connection", Direction::class.java) + private val SIDE_SHAPES = mapOf( + Direction.DOWN to createCuboidShape(2.0, 0.0, 2.0, 14.0, 2.0, 14.0), + Direction.UP to createCuboidShape(2.0, 14.0, 2.0, 14.0, 16.0, 14.0), + Direction.NORTH to createCuboidShape(2.0, 2.0, 0.0, 14.0, 14.0, 2.0), + Direction.SOUTH to createCuboidShape(2.0, 2.0, 14.0, 14.0, 14.0, 16.0), + Direction.WEST to createCuboidShape(0.0, 2.0, 2.0, 2.0, 14.0, 14.0), + Direction.EAST to createCuboidShape(14.0, 2.0, 2.0, 16.0, 14.0, 14.0) + ) + private val CENTER_SHAPES = mapOf( + Direction.DOWN to createCuboidShape(6.0, 2.0, 6.0, 10.0, 10.0, 10.0), + Direction.UP to createCuboidShape(6.0, 6.0, 6.0, 10.0, 14.0, 10.0), + Direction.NORTH to createCuboidShape(6.0, 6.0, 2.0, 10.0, 10.0, 10.0), + Direction.SOUTH to createCuboidShape(6.0, 6.0, 6.0, 10.0, 10.0, 14.0), + Direction.WEST to createCuboidShape(2.0, 6.0, 6.0, 10.0, 10.0, 10.0), + Direction.EAST to createCuboidShape(6.0, 6.0, 6.0, 14.0, 10.0, 10.0) + ) + + private val shapeCache = mutableMapOf, VoxelShape>() + fun getShape(facing: Direction, cableConnection: Direction): VoxelShape { + return shapeCache.getOrPut(facing to cableConnection) { + VoxelShapes.union( + VoxelShapes.union(SIDE_SHAPES[facing], CENTER_SHAPES[facing]), + CableBlock.SIDE_SHAPES[cableConnection] + ) + } + } + } + + override fun getNetworkConnectedSides(state: BlockState, world: World, pos: BlockPos): Collection { + return EnumSet.of(state[CABLE_CONNECTION]) } override fun appendProperties(builder: StateFactory.Builder) { super.appendProperties(builder) builder.add(FACING) + builder.add(CABLE_CONNECTION) } override fun createBlockEntity(world: BlockView) = InterfaceBlockEntity() override fun getPlacementState(context: ItemPlacementContext): BlockState { - val facing = if (context.player?.isSneaking == true) context.playerFacing else context.playerFacing.opposite - return defaultState.with(FACING, facing) + val facing = if (context.player?.isSneaking == true) context.side.opposite else context.playerFacing.opposite + val cableConnection = getCableConnectionSide(context.world, context.blockPos) ?: facing.opposite + return defaultState.with(FACING, facing).with(CABLE_CONNECTION, cableConnection) + } + + private fun getCableConnectionSide(world: World, pos: BlockPos): Direction? { + for (side in Direction.values()) { + val offsetPos = pos.offset(side) + if (world.getBlockState(offsetPos).block is NetworkComponent) { + return side + } + } + return null } override fun onPlaced(world: World, pos: BlockPos, state: BlockState, placer: LivingEntity?, stack: ItemStack) { @@ -51,8 +103,19 @@ class InterfaceBlock: BlockWithEntity(Settings.of(Material } } + override fun getStateForNeighborUpdate(state: BlockState, side: Direction, neighborState: BlockState, world: IWorld, pos: BlockPos, neighborPos: BlockPos): BlockState { + if (neighborState.block is NetworkComponent && world.getBlockState(pos.offset(state[CABLE_CONNECTION])).block !is NetworkComponent) { + return state.with(CABLE_CONNECTION, side) + } + return state + } + override fun addAllAttributes(world: World, pos: BlockPos, state: BlockState, to: AttributeList<*>) { to.offer(getBlockEntity(world, pos)) } + override fun getOutlineShape(state: BlockState, world: BlockView, pos: BlockPos, context: EntityContext): VoxelShape { + return getShape(state[FACING], state[CABLE_CONNECTION]) + } + } diff --git a/src/main/kotlin/net/shadowfacts/phycon/network/block/netswitch/SwitchBlock.kt b/src/main/kotlin/net/shadowfacts/phycon/network/block/netswitch/SwitchBlock.kt index 790773b..6103322 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/network/block/netswitch/SwitchBlock.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/network/block/netswitch/SwitchBlock.kt @@ -6,11 +6,13 @@ import net.minecraft.block.BlockState import net.minecraft.block.Material import net.minecraft.util.Identifier import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction import net.minecraft.world.BlockView import net.minecraft.world.World import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.api.NetworkComponent import net.shadowfacts.phycon.block.BlockWithEntity +import java.util.* /** * @author shadowfacts @@ -20,6 +22,10 @@ class SwitchBlock: BlockWithEntity(Settings.of(Material.METAL val ID = Identifier(PhysicalConnectivity.MODID, "switch") } + override fun getNetworkConnectedSides(state: BlockState, world: World, pos: BlockPos): Collection { + return EnumSet.allOf(Direction::class.java) + } + override fun createBlockEntity(world: BlockView) = SwitchBlockEntity() override fun addAllAttributes(world: World, pos: BlockPos, state: BlockState, to: AttributeList<*>) { diff --git a/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlock.kt b/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlock.kt index 4acb967..8a068d7 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlock.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlock.kt @@ -9,11 +9,13 @@ import net.minecraft.util.Hand import net.minecraft.util.Identifier import net.minecraft.util.hit.BlockHitResult import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction import net.minecraft.world.BlockView import net.minecraft.world.World import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.api.NetworkComponent import net.shadowfacts.phycon.block.BlockWithEntity +import java.util.* /** * @author shadowfacts @@ -23,6 +25,10 @@ class TerminalBlock: BlockWithEntity(Settings.of(Material.M val ID = Identifier(PhysicalConnectivity.MODID, "terminal") } + override fun getNetworkConnectedSides(state: BlockState, world: World, pos: BlockPos): Collection { + return EnumSet.allOf(Direction::class.java) + } + override fun createBlockEntity(world: BlockView) = TerminalBlockEntity() override fun activate(blockState_1: BlockState?, world_1: World?, blockPos_1: BlockPos?, playerEntity_1: PlayerEntity?, hand_1: Hand?, blockHitResult_1: BlockHitResult?): Boolean { diff --git a/src/main/resources/assets/phycon/blockstates/network_interface.json b/src/main/resources/assets/phycon/blockstates/network_interface.json new file mode 100644 index 0000000..30b3300 --- /dev/null +++ b/src/main/resources/assets/phycon/blockstates/network_interface.json @@ -0,0 +1,55 @@ +{ + "multipart": [ + { + "apply": { "model": "phycon:block/cable_center" } + }, + { + "when": { "facing": "down" }, + "apply": { "model": "phycon:block/interface_side" } + }, + { + "when": { "facing": "up" }, + "apply": { "model": "phycon:block/interface_side", "x": 180 } + }, + { + "when": { "facing": "north" }, + "apply": { "model": "phycon:block/interface_side", "x": 270 } + }, + { + "when": { "facing": "south" }, + "apply": { "model": "phycon:block/interface_side", "x": 90 } + }, + { + "when": { "facing": "west" }, + "apply": { "model": "phycon:block/interface_side", "x": 90, "y": 90 } + }, + { + "when": { "facing": "east" }, + "apply": { "model": "phycon:block/interface_side", "x": 90, "y": 270 } + }, + { + "when": { "cable_connection": "down" }, + "apply": { "model": "phycon:block/cable_side" } + }, + { + "when": { "cable_connection": "up" }, + "apply": { "model": "phycon:block/cable_side", "x": 180 } + }, + { + "when": { "cable_connection": "north" }, + "apply": { "model": "phycon:block/cable_side", "x": 270 } + }, + { + "when": { "cable_connection": "south" }, + "apply": { "model": "phycon:block/cable_side", "x": 90 } + }, + { + "when": { "cable_connection": "west" }, + "apply": { "model": "phycon:block/cable_side", "x": 90, "y": 90 } + }, + { + "when": { "cable_connection": "east" }, + "apply": { "model": "phycon:block/cable_side", "x": 90, "y": 270 } + } + ] +} diff --git a/src/main/resources/assets/phycon/models/block/interface_side.json b/src/main/resources/assets/phycon/models/block/interface_side.json new file mode 100644 index 0000000..8aec4f8 --- /dev/null +++ b/src/main/resources/assets/phycon/models/block/interface_side.json @@ -0,0 +1,27 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [2, 0, 2], + "to": [14, 2, 14], + "faces": { + "down": { "texture": "phycon:block/interface_front" }, + "up": { "texture": "phycon:block/interface_back" }, + "north": { "texture": "phycon:block/interface_side" }, + "south": { "texture": "phycon:block/interface_side" }, + "west": { "texture": "phycon:block/interface_side" }, + "east": { "texture": "phycon:block/interface_side" } + } + }, + { + "from": [6, 2, 6], + "to": [10, 6, 10], + "faces": { + "north": { "texture": "phycon:block/cable_side" }, + "south": { "texture": "phycon:block/cable_side" }, + "west": { "texture": "phycon:block/cable_side" }, + "east": { "texture": "phycon:block/cable_side" } + } + } + ] +}