diff --git a/src/main/kotlin/net/shadowfacts/phycon/block/FaceDeviceBlock.kt b/src/main/kotlin/net/shadowfacts/phycon/block/FaceDeviceBlock.kt index ee10508..47ce568 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/block/FaceDeviceBlock.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/block/FaceDeviceBlock.kt @@ -60,7 +60,7 @@ abstract class FaceDeviceBlock(settings: Settings): Device } protected abstract val faceThickness: Double - protected abstract val faceShapes: Map + abstract val faceShapes: Map private val centerShapes: Map by lazy { mapOf( Direction.DOWN to createCuboidShape(6.0, faceThickness, 6.0, 10.0, 10.0, 10.0), diff --git a/src/main/kotlin/net/shadowfacts/phycon/block/cable/CableBlock.kt b/src/main/kotlin/net/shadowfacts/phycon/block/cable/CableBlock.kt index 3aad3a9..66b1a72 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/block/cable/CableBlock.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/block/cable/CableBlock.kt @@ -24,7 +24,9 @@ import net.shadowfacts.phycon.api.Interface import net.shadowfacts.phycon.api.NetworkCableBlock import net.shadowfacts.phycon.api.NetworkComponentBlock import net.shadowfacts.phycon.init.PhyItems +import net.shadowfacts.phycon.item.FaceDeviceBlockItem import net.shadowfacts.phycon.util.CableConnection +import net.shadowfacts.phycon.util.containsInclusive import java.util.* /** @@ -87,12 +89,16 @@ class CableBlock: Block( } } - override fun getPlacementState(context: ItemPlacementContext): BlockState { + fun getInitialState(world: World, pos: BlockPos): BlockState { return CONNECTIONS.entries.fold(defaultState, { acc, (dir, prop) -> - acc.with(prop, getConnectionStateInDirection(context.world, context.blockPos, dir)) + acc.with(prop, getConnectionStateInDirection(world, pos, dir)) }) } + override fun getPlacementState(context: ItemPlacementContext): BlockState { + return getInitialState(context.world, context.blockPos) + } + override fun getStateForNeighborUpdate(state: BlockState, side: Direction, neighborState: BlockState, world: WorldAccess, blockPos_1: BlockPos, blockPos_2: BlockPos): BlockState { val prop = CONNECTIONS[side] val current = state[prop] @@ -141,8 +147,7 @@ class CableBlock: Block( 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 + shape.boundingBox.containsInclusive(hitPos) } if (hitConnection != null) { val side = hitConnection.key @@ -169,6 +174,10 @@ class CableBlock: Block( return ActionResult.PASS } + override fun canReplace(state: BlockState, context: ItemPlacementContext): Boolean { + return context.stack.item is FaceDeviceBlockItem + } + override fun isTranslucent(blockState_1: BlockState?, blockView_1: BlockView?, blockPos_1: BlockPos?): Boolean { return true } diff --git a/src/main/kotlin/net/shadowfacts/phycon/init/PhyItems.kt b/src/main/kotlin/net/shadowfacts/phycon/init/PhyItems.kt index cedfb54..704d196 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/init/PhyItems.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/init/PhyItems.kt @@ -17,21 +17,22 @@ import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlock import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterBlock import net.shadowfacts.phycon.block.terminal.TerminalBlock import net.shadowfacts.phycon.item.DeviceBlockItem +import net.shadowfacts.phycon.item.FaceDeviceBlockItem /** * @author shadowfacts */ object PhyItems { - val INTERFACE = DeviceBlockItem(PhyBlocks.INTERFACE, Item.Settings()) + val INTERFACE = FaceDeviceBlockItem(PhyBlocks.INTERFACE, Item.Settings()) val TERMINAL = DeviceBlockItem(PhyBlocks.TERMINAL, Item.Settings()) val SWITCH = BlockItem(PhyBlocks.SWITCH, Item.Settings()) val CABLE = BlockItem(PhyBlocks.CABLE, Item.Settings()) val EXTRACTOR = DeviceBlockItem(PhyBlocks.EXTRACTOR, Item.Settings()) val INSERTER = DeviceBlockItem(PhyBlocks.INSERTER, Item.Settings()) val MINER = DeviceBlockItem(PhyBlocks.MINER, Item.Settings()) - val REDSTONE_CONTROLLER = DeviceBlockItem(PhyBlocks.REDSTONE_CONTROLLER, Item.Settings()) - val REDSTONE_EMITTER = DeviceBlockItem(PhyBlocks.REDSTONE_EMITTER, Item.Settings()) + val REDSTONE_CONTROLLER = FaceDeviceBlockItem(PhyBlocks.REDSTONE_CONTROLLER, Item.Settings()) + val REDSTONE_EMITTER = FaceDeviceBlockItem(PhyBlocks.REDSTONE_EMITTER, Item.Settings()) val SCREWDRIVER = ScrewdriverItem() val CONSOLE = ConsoleItem() diff --git a/src/main/kotlin/net/shadowfacts/phycon/item/DeviceBlockItem.kt b/src/main/kotlin/net/shadowfacts/phycon/item/DeviceBlockItem.kt index 509197f..995e970 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/item/DeviceBlockItem.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/item/DeviceBlockItem.kt @@ -12,7 +12,7 @@ import net.shadowfacts.phycon.util.text /** * @author shadowfacts */ -class DeviceBlockItem(block: DeviceBlock<*>, settings: Settings = Settings()): BlockItem(block, settings) { +open class DeviceBlockItem(block: DeviceBlock<*>, settings: Settings = Settings()): BlockItem(block, settings) { override fun appendTooltip(stack: ItemStack, world: World?, list: MutableList, context: TooltipContext) { val beTag = stack.getSubTag("BlockEntityTag") diff --git a/src/main/kotlin/net/shadowfacts/phycon/item/FaceDeviceBlockItem.kt b/src/main/kotlin/net/shadowfacts/phycon/item/FaceDeviceBlockItem.kt new file mode 100644 index 0000000..f93e99b --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/item/FaceDeviceBlockItem.kt @@ -0,0 +1,40 @@ +package net.shadowfacts.phycon.item + +import net.minecraft.block.BlockState +import net.minecraft.item.ItemPlacementContext +import net.minecraft.util.math.Direction +import net.shadowfacts.phycon.block.FaceDeviceBlock +import net.shadowfacts.phycon.block.cable.CableBlock +import net.shadowfacts.phycon.init.PhyBlocks +import net.shadowfacts.phycon.util.CableConnection + +/** + * @author shadowfacts + */ +class FaceDeviceBlockItem(block: FaceDeviceBlock<*>, settings: Settings = Settings()): DeviceBlockItem(block, settings) { + + override fun getPlacementState(context: ItemPlacementContext): BlockState? { + val hitState = context.world.getBlockState(context.blockPos) + if (hitState.block == PhyBlocks.CABLE) { + val hitBlockEdge = context.hitPos.getComponentAlongAxis(context.side.axis) % 1 == 0.0 + + val placementSide = if (hitBlockEdge) context.side.opposite else context.side + + if (hitState[CableBlock.CONNECTIONS[placementSide]] != CableConnection.ON) { + var connection = FaceDeviceBlock.FaceCableConnection.NONE + for (dir in Direction.values()) { + if (hitState[CableBlock.CONNECTIONS[dir]] == CableConnection.ON) { + connection = FaceDeviceBlock.FaceCableConnection.from(dir) + break + } + } + + return block.defaultState + .with(FaceDeviceBlock.FACING, placementSide) + .with(FaceDeviceBlock.CABLE_CONNECTION, connection) + } + } + return null + } + +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/item/ScrewdriverItem.kt b/src/main/kotlin/net/shadowfacts/phycon/item/ScrewdriverItem.kt index 6168df1..97a4d65 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/item/ScrewdriverItem.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/item/ScrewdriverItem.kt @@ -9,9 +9,12 @@ import net.minecraft.sound.SoundCategory import net.minecraft.sound.SoundEvents import net.minecraft.util.ActionResult import net.minecraft.util.Identifier +import net.minecraft.util.math.Vec3d import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.block.DeviceBlock +import net.shadowfacts.phycon.block.FaceDeviceBlock import net.shadowfacts.phycon.init.PhyBlocks +import net.shadowfacts.phycon.util.containsInclusive /** * @author shadowfacts @@ -44,7 +47,21 @@ class ScrewdriverItem: Item(Settings()) { val entity = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), stack) context.world.spawnEntity(entity) - context.world.setBlockState(context.blockPos, Blocks.AIR.defaultState, 3, 512) + var newState = Blocks.AIR.defaultState + + if (block is FaceDeviceBlock<*>) { + val hitInsideBlock = Vec3d(context.hitPos.x - context.blockPos.x, context.hitPos.y - context.blockPos.y, context.hitPos.z - context.blockPos.z) + val faceShape = block.faceShapes[state[FaceDeviceBlock.FACING]]!! + // if we hit the face part of block, leave the cable behind + if (faceShape.boundingBox.containsInclusive(hitInsideBlock)) { + newState = PhyBlocks.CABLE.getInitialState(context.world, context.blockPos) + } else { + val cable = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), ItemStack(PhyBlocks.CABLE)) + context.world.spawnEntity(cable) + } + } + + context.world.setBlockState(context.blockPos, newState, 3, 512) } context.world.playSound(context.player, context.blockPos, SoundEvents.BLOCK_METAL_PLACE, SoundCategory.BLOCKS, 0.8f, 0.65f) diff --git a/src/main/kotlin/net/shadowfacts/phycon/util/Vec3d.kt b/src/main/kotlin/net/shadowfacts/phycon/util/Vec3d.kt new file mode 100644 index 0000000..752e341 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/util/Vec3d.kt @@ -0,0 +1,11 @@ +package net.shadowfacts.phycon.util + +import net.minecraft.util.math.Box +import net.minecraft.util.math.Vec3d + +/** + * @author shadowfacts + */ +fun Box.containsInclusive(point: Vec3d): Boolean { + return point.x >= minX && point.x <= maxX && point.y >= minY && point.y <= maxY && point.z >= minZ && point.z <= maxZ +} diff --git a/src/main/resources/data/phycon/loot_tables/blocks/network_interface.json b/src/main/resources/data/phycon/loot_tables/blocks/network_interface.json new file mode 100644 index 0000000..0b5821f --- /dev/null +++ b/src/main/resources/data/phycon/loot_tables/blocks/network_interface.json @@ -0,0 +1,33 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "phycon:network_interface" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "phycon:cable" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} diff --git a/src/main/resources/data/phycon/loot_tables/blocks/redstone_controller.json b/src/main/resources/data/phycon/loot_tables/blocks/redstone_controller.json index c5baf9c..64f8b7a 100644 --- a/src/main/resources/data/phycon/loot_tables/blocks/redstone_controller.json +++ b/src/main/resources/data/phycon/loot_tables/blocks/redstone_controller.json @@ -14,6 +14,20 @@ "condition": "minecraft:survives_explosion" } ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "phycon:cable" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] } ] } diff --git a/src/main/resources/data/phycon/loot_tables/blocks/redstone_emitter.json b/src/main/resources/data/phycon/loot_tables/blocks/redstone_emitter.json index f005696..ef6a425 100644 --- a/src/main/resources/data/phycon/loot_tables/blocks/redstone_emitter.json +++ b/src/main/resources/data/phycon/loot_tables/blocks/redstone_emitter.json @@ -14,6 +14,20 @@ "condition": "minecraft:survives_explosion" } ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "phycon:cable" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] } ] }