diff --git a/src/main/java/li/cil/oc/client/PacketSender.scala b/src/main/java/li/cil/oc/client/PacketSender.scala index 7dbc5240c..273d95621 100644 --- a/src/main/java/li/cil/oc/client/PacketSender.scala +++ b/src/main/java/li/cil/oc/client/PacketSender.scala @@ -108,6 +108,11 @@ object PacketSender { pb.sendToServer() } + def sendMultiPlace() { + val pb = new PacketBuilder(PacketType.MultiPartPlace) + pb.sendToServer() + } + def sendRobotStateRequest(dimension: Int, x: Int, y: Int, z: Int) { val pb = new PacketBuilder(PacketType.RobotStateRequest) diff --git a/src/main/java/li/cil/oc/common/PacketType.scala b/src/main/java/li/cil/oc/common/PacketType.scala index 4e535099d..6670fde48 100644 --- a/src/main/java/li/cil/oc/common/PacketType.scala +++ b/src/main/java/li/cil/oc/common/PacketType.scala @@ -38,6 +38,7 @@ object PacketType extends Enumeration { Clipboard, MouseClickOrDrag, MouseScroll, + MultiPartPlace, RobotStateRequest, ServerSide, ServerRange = Value diff --git a/src/main/java/li/cil/oc/common/multipart/EventHandler.scala b/src/main/java/li/cil/oc/common/multipart/EventHandler.scala index 41db3b952..052d0607b 100644 --- a/src/main/java/li/cil/oc/common/multipart/EventHandler.scala +++ b/src/main/java/li/cil/oc/common/multipart/EventHandler.scala @@ -1,8 +1,92 @@ package li.cil.oc.common.multipart -/** - * Created by lordjoda on 02.03.14. - */ -class EventHandler { +import net.minecraftforge.event.entity.player.{PlayerDestroyItemEvent, PlayerInteractEvent} +import net.minecraftforge.event.ForgeSubscribe +import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.world.World +import codechicken.lib.raytracer.RayTracer +import codechicken.lib.vec.{Vector3, BlockCoord} +import net.minecraft.block.Block +import li.cil.oc.Blocks +import codechicken.multipart.{TileMultipart, TMultiPart} +import codechicken.lib.packet.PacketCustom +import net.minecraft.network.packet.Packet15Place +import net.minecraftforge.common.MinecraftForge +import li.cil.oc.common.block.Delegator +import li.cil.oc.client.PacketSender + +object EventHandler { + + @ForgeSubscribe + def playerInteract(event: PlayerInteractEvent) { + if (event.action == Action.RIGHT_CLICK_BLOCK && event.entityPlayer.worldObj.isRemote) { + if (place(event.entityPlayer)) + event.setCanceled(true) + + } + } + + def place(player: EntityPlayer): Boolean = { + val world = player.getEntityWorld + val hit = RayTracer.reTrace(world, player) + if (hit == null) + return false + + val pos = new BlockCoord(hit.blockX, hit.blockY, hit.blockZ) + val held = player.getHeldItem + var part: TMultiPart = null + if (held == null) + return false + + Delegator.subBlock(held) match { + case Some(subBlock) if subBlock == Blocks.cable => + part = new CablePart() + case _ => + } + + if (part == null) + return false + + //attempt to use block activated like normal and tell the server the right stuff + if (world.isRemote && !player.isSneaking) { + val f = new Vector3(hit.hitVec).add(-hit.blockX, -hit.blockY, -hit.blockZ) + val block = Block.blocksList(world.getBlockId(hit.blockX, hit.blockY, hit.blockZ)) + if (block != null && block.onBlockActivated(world, hit.blockX, hit.blockY, hit.blockZ, player, hit.sideHit, f.x.toFloat, f.y.toFloat, f.z.toFloat)) { + player.swingItem() + PacketCustom.sendToServer(new Packet15Place( + hit.blockX, hit.blockY, hit.blockZ, hit.sideHit, + player.inventory.getCurrentItem, + f.x.toFloat, f.y.toFloat, f.z.toFloat)) + return false + } + } + + val tile = TileMultipart.getOrConvertTile(world, pos) + if (tile == null || !tile.canAddPart(part)) + return false + + if (!world.isRemote) { + TileMultipart.addPart(world, pos, part) + world.playSoundEffect(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, + Blocks.cable.parent.stepSound.getPlaceSound, + (Blocks.cable.parent.stepSound.getVolume + 1.0F) / 2.0F, + Blocks.cable.parent.stepSound.getPitch * 0.8F) + if (!player.capabilities.isCreativeMode) { + held.stackSize -= 1 + if (held.stackSize == 0) { + player.inventory.mainInventory(player.inventory.currentItem) = null + MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(player, held)) + } + } + } + else { + player.swingItem() + //TODO + PacketSender.sendMultiPlace() + } + true + } + } diff --git a/src/main/java/li/cil/oc/common/multipart/Multipart.scala b/src/main/java/li/cil/oc/common/multipart/Multipart.scala index e19e88e30..3c83cad05 100644 --- a/src/main/java/li/cil/oc/common/multipart/Multipart.scala +++ b/src/main/java/li/cil/oc/common/multipart/Multipart.scala @@ -12,7 +12,7 @@ object MultiPart extends IPartFactory with IPartConverter { def init() { MultiPartRegistry.registerConverter(this) MultiPartRegistry.registerParts(this, Array("oc:cable")) - MinecraftForge.EVENT_BUS.register(new EventHandler()) + MinecraftForge.EVENT_BUS.register(EventHandler) } override def createPart(name: String, client: Boolean): TMultiPart = { diff --git a/src/main/java/li/cil/oc/server/PacketHandler.scala b/src/main/java/li/cil/oc/server/PacketHandler.scala index 84b3b80c0..682a41889 100644 --- a/src/main/java/li/cil/oc/server/PacketHandler.scala +++ b/src/main/java/li/cil/oc/server/PacketHandler.scala @@ -9,6 +9,7 @@ import li.cil.oc.server.component.machine.Machine import net.minecraft.entity.player.EntityPlayerMP import net.minecraft.util.ChatMessageComponent import net.minecraftforge.common.{ForgeDirection, DimensionManager} +import li.cil.oc.common.multipart.{EventHandler, MultiPart} class PacketHandler extends CommonPacketHandler { override protected def world(player: Player, dimension: Int) = @@ -22,6 +23,7 @@ class PacketHandler extends CommonPacketHandler { case PacketType.Clipboard => onClipboard(p) case PacketType.MouseClickOrDrag => onMouseClick(p) case PacketType.MouseScroll => onMouseScroll(p) + case PacketType.MultiPartPlace => onMultiPartPlace(p) case PacketType.RobotStateRequest => onRobotStateRequest(p) case PacketType.ServerRange => onServerRange(p) case PacketType.ServerSide => onServerSide(p) @@ -134,6 +136,14 @@ class PacketHandler extends CommonPacketHandler { } } + def onMultiPartPlace(p: PacketParser) { + p.player match { + case player: EntityPlayerMP => EventHandler.place(player) + case _ => // Invalid packet. + } + + } + def onRobotStateRequest(p: PacketParser) = p.readTileEntity[RobotProxy]() match { case Some(proxy) => proxy.world.markBlockForUpdate(proxy.x, proxy.y, proxy.z)