PhysicalConnectivity/src/main/kotlin/net/shadowfacts/phycon/item/ScrewdriverItem.kt

113 lines
4.1 KiB
Kotlin

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
}
}