From e6faa343555d30e821cb606e0916c4f1c5316812 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 7 Mar 2021 10:58:28 -0500 Subject: [PATCH] Allow screwdrivering cables and switches --- .../phycon/item/ScrewdriverItem.kt | 106 ++++++++++++------ 1 file changed, 71 insertions(+), 35 deletions(-) diff --git a/src/main/kotlin/net/shadowfacts/phycon/item/ScrewdriverItem.kt b/src/main/kotlin/net/shadowfacts/phycon/item/ScrewdriverItem.kt index 97a4d65..5aa97e4 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/item/ScrewdriverItem.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/item/ScrewdriverItem.kt @@ -1,5 +1,6 @@ package net.shadowfacts.phycon.item +import net.minecraft.block.BlockState import net.minecraft.block.Blocks import net.minecraft.entity.ItemEntity import net.minecraft.item.Item @@ -25,50 +26,85 @@ class ScrewdriverItem: Item(Settings()) { } override fun useOnBlock(context: ItemUsageContext): ActionResult { + if (context.player?.isSneaking != true) return ActionResult.PASS + val state = context.world.getBlockState(context.blockPos) val block = state.block - if (block is DeviceBlock<*>) { - if (!context.world.isClient) { - val be = block.getBlockEntity(context.world, context.blockPos)!! - val stack = ItemStack(block) - val beTag = stack.getOrCreateSubTag("BlockEntityTag") - be.toTag(beTag) - // remove x, y, z entries for stacking purposes - beTag.remove("x") - beTag.remove("y") - beTag.remove("z") - - if (block === PhyBlocks.TERMINAL) { - // remove the terminal's internal buffer since it drops its items - beTag.remove("InternalBuffer") - } - - val entity = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), stack) - context.world.spawnEntity(entity) - - 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) + val newState = + when (block) { + is DeviceBlock<*> -> screwdriverDeviceBlock(context, state, block) + PhyBlocks.CABLE -> screwdriverCableBlock(context) + PhyBlocks.SWITCH -> screwdriverSwitchBlock(context) + else -> null } + if (newState != null) { + context.world.setBlockState(context.blockPos, newState) context.world.playSound(context.player, context.blockPos, SoundEvents.BLOCK_METAL_PLACE, SoundCategory.BLOCKS, 0.8f, 0.65f) - return ActionResult.SUCCESS } else { return ActionResult.PASS } } + + private fun screwdriverDeviceBlock(context: ItemUsageContext, state: BlockState, block: DeviceBlock<*>): BlockState? { + if (!context.world.isClient) { + val be = block.getBlockEntity(context.world, context.blockPos)!! + + val stack = ItemStack(block) + val beTag = stack.getOrCreateSubTag("BlockEntityTag") + be.toTag(beTag) + // remove x, y, z entries for stacking purposes + beTag.remove("x") + beTag.remove("y") + beTag.remove("z") + + if (block === PhyBlocks.TERMINAL) { + // remove the terminal's internal buffer since it drops its items + beTag.remove("InternalBuffer") + } + + val entity = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), stack) + context.world.spawnEntity(entity) + } + + return if (block is FaceDeviceBlock<*>) { + screwdriverFaceDeviceBlock(context, state, block) + } else { + Blocks.AIR.defaultState + } + } + + private fun screwdriverFaceDeviceBlock(context: ItemUsageContext, state: BlockState, block: FaceDeviceBlock<*>): BlockState? { + 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)) { + return PhyBlocks.CABLE.getInitialState(context.world, context.blockPos) + } else { + if (!context.world.isClient) { + val cable = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), ItemStack(PhyBlocks.CABLE)) + context.world.spawnEntity(cable) + } + return Blocks.AIR.defaultState + } + } + + private fun screwdriverCableBlock(context: ItemUsageContext): BlockState? { + if (!context.world.isClient) { + val entity = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), ItemStack(PhyBlocks.CABLE)) + context.world.spawnEntity(entity) + } + return Blocks.AIR.defaultState + } + + private fun screwdriverSwitchBlock(context: ItemUsageContext): BlockState? { + if (!context.world.isClient) { + val entity = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), ItemStack(PhyBlocks.SWITCH)) + context.world.spawnEntity(entity) + } + return Blocks.AIR.defaultState + } + }