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 import net.minecraft.item.ItemStack import net.minecraft.item.ItemUsageContext 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.block.cable.CableBlock import net.shadowfacts.phycon.init.PhyBlocks import net.shadowfacts.phycon.util.containsInclusive /** * @author shadowfacts */ class ScrewdriverItem: Item(Settings().maxCount(1)) { companion object { val ID = Identifier(PhysicalConnectivity.MODID, "screwdriver") } 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 val newState = when (block) { is DeviceBlock<*> -> screwdriverDeviceBlock(context, state, block) is CableBlock -> screwdriverCableBlock(context, state) 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 = be.createNbt() // remove x, y, z entries for stacking purposes beTag.remove("x") beTag.remove("y") beTag.remove("z") stack.setSubNbt("BlockEntityTag", beTag) 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)) { val cableBlock = PhyBlocks.CABLES[state[FaceDeviceBlock.COLOR]]!! return cableBlock.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(state.block)) context.world.spawnEntity(cable) } return Blocks.AIR.defaultState } } private fun screwdriverCableBlock(context: ItemUsageContext, state: BlockState): BlockState? { if (!context.world.isClient) { val entity = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), ItemStack(state.block)) 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 } }