From fdb834adc9dc5b3e40d12e0e9ce43e13eaeedbf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sun, 14 Dec 2014 23:02:08 +0100 Subject: [PATCH] More work on drone GUI, shows up now, powering works via that, inventory works. --- .../opencomputers/textures/gui/drone.png | Bin 596 -> 596 bytes .../scala/li/cil/oc/client/GuiHandler.scala | 189 ++++++++++-------- .../scala/li/cil/oc/client/PacketSender.scala | 10 + .../scala/li/cil/oc/client/gui/Drone.scala | 13 +- .../scala/li/cil/oc/common/GuiHandler.scala | 90 +++++---- src/main/scala/li/cil/oc/common/GuiType.scala | 53 +++-- .../li/cil/oc/common/PacketBuilder.scala | 8 +- .../li/cil/oc/common/PacketHandler.scala | 20 +- .../scala/li/cil/oc/common/PacketType.scala | 1 + .../li/cil/oc/common/container/Drone.scala | 6 +- .../scala/li/cil/oc/common/entity/Drone.scala | 24 ++- .../li/cil/oc/server/PacketHandler.scala | 16 ++ src/main/scala/li/cil/oc/util/ScalaEnum.scala | 39 ++++ 13 files changed, 307 insertions(+), 162 deletions(-) create mode 100644 src/main/scala/li/cil/oc/util/ScalaEnum.scala diff --git a/src/main/resources/assets/opencomputers/textures/gui/drone.png b/src/main/resources/assets/opencomputers/textures/gui/drone.png index 669568fce008ad47f9617ea2e8525fd969de3f58..e7dd2ce5031fe2271b9bdef0d092ad382d9f043e 100644 GIT binary patch delta 75 zcmcb@a)o8X0!9@E28O7_wHy2d7#en7o6m6J_P-selYrFZ>-(9%gsI!IKDfv@`5 CommonGuiHandler} +import li.cil.oc.common.tileentity +import li.cil.oc.common.{GuiHandler => CommonGuiHandler} import net.minecraft.client.Minecraft import net.minecraft.entity.player.EntityPlayer import net.minecraft.world.World object GuiHandler extends CommonGuiHandler { - override def getClientGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef = - world.getTileEntity(x, y, z) match { - case t: tileentity.Adapter if id == GuiType.Adapter.id => - new gui.Adapter(player.inventory, t) - case t: tileentity.Assembler if id == GuiType.Assembler.id => - new gui.Assembler(player.inventory, t) - case t: tileentity.Case if id == GuiType.Case.id => - new gui.Case(player.inventory, t) - case t: tileentity.Charger if id == GuiType.Charger.id => - new gui.Charger(player.inventory, t) - case t: tileentity.Disassembler if id == GuiType.Disassembler.id => - new gui.Disassembler(player.inventory, t) - case t: tileentity.DiskDrive if id == GuiType.DiskDrive.id => - new gui.DiskDrive(player.inventory, t) - case t: tileentity.Raid if id == GuiType.Raid.id => - new gui.Raid(player.inventory, t) - case t: tileentity.RobotProxy if id == GuiType.Robot.id => - new gui.Robot(player.inventory, t.robot) - case t: tileentity.ServerRack if id == GuiType.Rack.id => - new gui.ServerRack(player.inventory, t) - case t: tileentity.Screen if id == GuiType.Screen.id => - new gui.Screen(t.origin.buffer, t.tier > 0, () => t.origin.hasKeyboard, () => t.origin.buffer.isRenderingEnabled) - case t: tileentity.Switch if id == GuiType.Switch.id => - new gui.Switch(player.inventory, t) - case _ => Items.multi.subItem(player.getCurrentEquippedItem) match { - case Some(database: item.UpgradeDatabase) if id == GuiType.Database.id => - new gui.Database(player.inventory, new DatabaseInventory { - override def tier = database.tier + override def getClientGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef = { + GuiType.Categories.get(id) match { + case Some(GuiType.Category.Block) => + world.getTileEntity(x, y, z) match { + case t: tileentity.Adapter if id == GuiType.Adapter.id => + new gui.Adapter(player.inventory, t) + case t: tileentity.Assembler if id == GuiType.Assembler.id => + new gui.Assembler(player.inventory, t) + case t: tileentity.Case if id == GuiType.Case.id => + new gui.Case(player.inventory, t) + case t: tileentity.Charger if id == GuiType.Charger.id => + new gui.Charger(player.inventory, t) + case t: tileentity.Disassembler if id == GuiType.Disassembler.id => + new gui.Disassembler(player.inventory, t) + case t: tileentity.DiskDrive if id == GuiType.DiskDrive.id => + new gui.DiskDrive(player.inventory, t) + case t: tileentity.Raid if id == GuiType.Raid.id => + new gui.Raid(player.inventory, t) + case t: tileentity.RobotProxy if id == GuiType.Robot.id => + new gui.Robot(player.inventory, t.robot) + case t: tileentity.ServerRack if id == GuiType.Rack.id => + new gui.ServerRack(player.inventory, t) + case t: tileentity.Screen if id == GuiType.Screen.id => + new gui.Screen(t.origin.buffer, t.tier > 0, () => t.origin.hasKeyboard, () => t.origin.buffer.isRenderingEnabled) + case t: tileentity.Switch if id == GuiType.Switch.id => + new gui.Switch(player.inventory, t) + case _ => null + } + case Some(GuiType.Category.Entity) => + world.getEntityByID(x) match { + case drone: entity.Drone if id == GuiType.Drone.id => + new gui.Drone(player.inventory, drone) + case _ => null + } + case Some(GuiType.Category.Item) => + Items.multi.subItem(player.getCurrentEquippedItem) match { + case Some(database: item.UpgradeDatabase) if id == GuiType.Database.id => + new gui.Database(player.inventory, new DatabaseInventory { + override def tier = database.tier - override def container = player.getCurrentEquippedItem + override def container = player.getCurrentEquippedItem - override def isUseableByPlayer(player: EntityPlayer) = player == player - }) - case Some(server: item.Server) if id == GuiType.Server.id => - new gui.Server(player.inventory, new ServerInventory { - override def tier = server.tier + override def isUseableByPlayer(player: EntityPlayer) = player == player + }) + case Some(server: item.Server) if id == GuiType.Server.id => + new gui.Server(player.inventory, new ServerInventory { + override def tier = server.tier - override def container = player.getCurrentEquippedItem + override def container = player.getCurrentEquippedItem - override def isUseableByPlayer(player: EntityPlayer) = player == player - }) - case Some(tablet: item.Tablet) if id == GuiType.Tablet.id => - val stack = player.getCurrentEquippedItem - if (stack.hasTagCompound) { - Tablet.get(stack, player).components.collect { - case Some(buffer: TextBuffer) => buffer - }.headOption match { - case Some(buffer: TextBuffer) => return new gui.Screen(buffer, true, () => true, () => true) - case _ => - } - } - null - case Some(terminal: item.Terminal) if id == GuiType.Terminal.id => - val stack = player.getCurrentEquippedItem - if (stack.hasTagCompound) { - val address = stack.getTagCompound.getString(Settings.namespace + "server") - val key = stack.getTagCompound.getString(Settings.namespace + "key") - if (key != null && !key.isEmpty && address != null && !address.isEmpty) { - tileentity.ServerRack.list.keys. - flatMap(_.terminals). - find(term => term.rack.isPresent(term.number) match { - case Some(value) => value == address - case _ => false - }) match { - case Some(term) => - def inRange = player.isEntityAlive && !term.rack.isInvalid && term.rack.getDistanceFrom(player.posX, player.posY, player.posZ) < term.rack.range * term.rack.range - if (inRange) { - if (term.keys.contains(key)) return new gui.Screen(term.buffer, true, () => true, () => { - // Check if someone else bound a term to our server. - if (stack.getTagCompound.getString(Settings.namespace + "key") != key) { - Minecraft.getMinecraft.displayGuiScreen(null) - } - // Check whether we're still in range. - if (!inRange) { - Minecraft.getMinecraft.displayGuiScreen(null) - } - true - }) - else player.addChatMessage(Localization.Terminal.InvalidKey) - } - else player.addChatMessage(Localization.Terminal.OutOfRange) - case _ => player.addChatMessage(Localization.Terminal.OutOfRange) + override def isUseableByPlayer(player: EntityPlayer) = player == player + }) + case Some(tablet: item.Tablet) if id == GuiType.Tablet.id => + val stack = player.getCurrentEquippedItem + if (stack.hasTagCompound) { + Tablet.get(stack, player).components.collect { + case Some(buffer: TextBuffer) => buffer + }.headOption match { + case Some(buffer: TextBuffer) => return new gui.Screen(buffer, true, () => true, () => true) + case _ => } } - } - null - case _ => null - } + null + case Some(terminal: item.Terminal) if id == GuiType.Terminal.id => + val stack = player.getCurrentEquippedItem + if (stack.hasTagCompound) { + val address = stack.getTagCompound.getString(Settings.namespace + "server") + val key = stack.getTagCompound.getString(Settings.namespace + "key") + if (key != null && !key.isEmpty && address != null && !address.isEmpty) { + tileentity.ServerRack.list.keys. + flatMap(_.terminals). + find(term => term.rack.isPresent(term.number) match { + case Some(value) => value == address + case _ => false + }) match { + case Some(term) => + def inRange = player.isEntityAlive && !term.rack.isInvalid && term.rack.getDistanceFrom(player.posX, player.posY, player.posZ) < term.rack.range * term.rack.range + if (inRange) { + if (term.keys.contains(key)) return new gui.Screen(term.buffer, true, () => true, () => { + // Check if someone else bound a term to our server. + if (stack.getTagCompound.getString(Settings.namespace + "key") != key) { + Minecraft.getMinecraft.displayGuiScreen(null) + } + // Check whether we're still in range. + if (!inRange) { + Minecraft.getMinecraft.displayGuiScreen(null) + } + true + }) + else player.addChatMessage(Localization.Terminal.InvalidKey) + } + else player.addChatMessage(Localization.Terminal.OutOfRange) + case _ => player.addChatMessage(Localization.Terminal.OutOfRange) + } + } + } + null + case _ => null + } + case _ => null } + } } diff --git a/src/main/scala/li/cil/oc/client/PacketSender.scala b/src/main/scala/li/cil/oc/client/PacketSender.scala index 33ac000c6..f16a4d1f8 100644 --- a/src/main/scala/li/cil/oc/client/PacketSender.scala +++ b/src/main/scala/li/cil/oc/client/PacketSender.scala @@ -4,6 +4,7 @@ import li.cil.oc.Settings import li.cil.oc.common.CompressedPacketBuilder import li.cil.oc.common.PacketType import li.cil.oc.common.SimplePacketBuilder +import li.cil.oc.common.entity.Drone import li.cil.oc.common.tileentity._ import li.cil.oc.common.tileentity.traits.Computer import net.minecraft.client.Minecraft @@ -25,6 +26,15 @@ object PacketSender { pb.sendToServer() } + def sendDronePower(e: Drone, power: Boolean) { + val pb = new SimplePacketBuilder(PacketType.DronePower) + + pb.writeEntity(e) + pb.writeBoolean(power) + + pb.sendToServer() + } + def sendKeyDown(address: String, char: Char, code: Int) { val pb = new SimplePacketBuilder(PacketType.KeyDown) diff --git a/src/main/scala/li/cil/oc/client/gui/Drone.scala b/src/main/scala/li/cil/oc/client/gui/Drone.scala index d9cb09f80..cda05537a 100644 --- a/src/main/scala/li/cil/oc/client/gui/Drone.scala +++ b/src/main/scala/li/cil/oc/client/gui/Drone.scala @@ -18,7 +18,7 @@ import org.lwjgl.opengl.GL11 class Drone(playerInventory: InventoryPlayer, val drone: entity.Drone) extends DynamicGuiContainer(new container.Drone(playerInventory, drone)) { xSize = 176 - ySize = 146 + ySize = 148 protected var powerButton: ImageButton = _ @@ -27,10 +27,10 @@ class Drone(playerInventory: InventoryPlayer, val drone: entity.Drone) extends D private val bufferX = 10 private val bufferY = 10 - private val inventoryX = 95 - private val inventoryY = 5 + private val inventoryX = 97 + private val inventoryY = 7 - private val power = addWidget(new ProgressBar(26, 48)) + private val power = addWidget(new ProgressBar(28, 48)) private val selectionSize = 20 private val selectionsStates = 17 @@ -40,7 +40,7 @@ class Drone(playerInventory: InventoryPlayer, val drone: entity.Drone) extends D protected override def actionPerformed(button: GuiButton) { if (button.id == 0) { -// ClientPacketSender.sendComputerPower(drone, !drone.isRunning) + ClientPacketSender.sendDronePower(drone, !drone.isRunning) } } @@ -51,7 +51,7 @@ class Drone(playerInventory: InventoryPlayer, val drone: entity.Drone) extends D override def initGui() { super.initGui() - powerButton = new ImageButton(0, guiLeft + 5, guiTop + 43, 18, 18, Textures.guiButtonPower, canToggle = true) + powerButton = new ImageButton(0, guiLeft + 7, guiTop + 45, 18, 18, Textures.guiButtonPower, canToggle = true) add(buttonList, powerButton) } @@ -79,6 +79,7 @@ class Drone(playerInventory: InventoryPlayer, val drone: entity.Drone) extends D mc.renderEngine.bindTexture(Textures.guiDrone) drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) // power.level = robot.globalBuffer / robot.globalBufferSize + power.level = 0.5 drawWidgets() if (drone.inventory.getSizeInventory > 0) { drawSelection() diff --git a/src/main/scala/li/cil/oc/common/GuiHandler.scala b/src/main/scala/li/cil/oc/common/GuiHandler.scala index c7764fd65..38b21432b 100644 --- a/src/main/scala/li/cil/oc/common/GuiHandler.scala +++ b/src/main/scala/li/cil/oc/common/GuiHandler.scala @@ -2,51 +2,65 @@ package li.cil.oc.common import cpw.mods.fml.common.network.IGuiHandler import li.cil.oc.common.init.Items -import li.cil.oc.common.inventory.{DatabaseInventory, ServerInventory} +import li.cil.oc.common.inventory.DatabaseInventory +import li.cil.oc.common.inventory.ServerInventory import net.minecraft.entity.player.EntityPlayer import net.minecraft.world.World abstract class GuiHandler extends IGuiHandler { - override def getServerGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int) = - world.getTileEntity(x, y, z) match { - case t: tileentity.Adapter if id == GuiType.Adapter.id => - new container.Adapter(player.inventory, t) - case t: tileentity.Assembler if id == GuiType.Assembler.id => - new container.Assembler(player.inventory, t) - case t: tileentity.Charger if id == GuiType.Charger.id => - new container.Charger(player.inventory, t) - case t: tileentity.Case if id == GuiType.Case.id => - new container.Case(player.inventory, t) - case t: tileentity.Disassembler if id == GuiType.Disassembler.id => - new container.Disassembler(player.inventory, t) - case t: tileentity.DiskDrive if id == GuiType.DiskDrive.id => - new container.DiskDrive(player.inventory, t) - case t: tileentity.Raid if id == GuiType.Raid.id => - new container.Raid(player.inventory, t) - case t: tileentity.RobotProxy if id == GuiType.Robot.id => - new container.Robot(player.inventory, t.robot) - case t: tileentity.ServerRack if id == GuiType.Rack.id => - new container.ServerRack(player.inventory, t) - case t: tileentity.Switch if id == GuiType.Switch.id => - new container.Switch(player.inventory, t) - case _ => Items.multi.subItem(player.getCurrentEquippedItem) match { - case Some(database: item.UpgradeDatabase) if id == GuiType.Database.id => - new container.Database(player.inventory, new DatabaseInventory { - override def tier = database.tier + override def getServerGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef = { + GuiType.Categories.get(id) match { + case Some(GuiType.Category.Block) => + world.getTileEntity(x, y, z) match { + case t: tileentity.Adapter if id == GuiType.Adapter.id => + new container.Adapter(player.inventory, t) + case t: tileentity.Assembler if id == GuiType.Assembler.id => + new container.Assembler(player.inventory, t) + case t: tileentity.Charger if id == GuiType.Charger.id => + new container.Charger(player.inventory, t) + case t: tileentity.Case if id == GuiType.Case.id => + new container.Case(player.inventory, t) + case t: tileentity.Disassembler if id == GuiType.Disassembler.id => + new container.Disassembler(player.inventory, t) + case t: tileentity.DiskDrive if id == GuiType.DiskDrive.id => + new container.DiskDrive(player.inventory, t) + case t: tileentity.Raid if id == GuiType.Raid.id => + new container.Raid(player.inventory, t) + case t: tileentity.RobotProxy if id == GuiType.Robot.id => + new container.Robot(player.inventory, t.robot) + case t: tileentity.ServerRack if id == GuiType.Rack.id => + new container.ServerRack(player.inventory, t) + case t: tileentity.Switch if id == GuiType.Switch.id => + new container.Switch(player.inventory, t) + case _ => null + } + case Some(GuiType.Category.Entity) => + world.getEntityByID(x) match { + case drone: entity.Drone if id == GuiType.Drone.id => + new container.Drone(player.inventory, drone) + case _ => null + } + case Some(GuiType.Category.Item) => + Items.multi.subItem(player.getCurrentEquippedItem) match { + case Some(database: item.UpgradeDatabase) if id == GuiType.Database.id => + new container.Database(player.inventory, new DatabaseInventory { + override def tier = database.tier - override def container = player.getCurrentEquippedItem + override def container = player.getCurrentEquippedItem - override def isUseableByPlayer(player: EntityPlayer) = player == player - }) - case Some(server: item.Server) if id == GuiType.Server.id => - new container.Server(player.inventory, new ServerInventory { - override def tier = server.tier + override def isUseableByPlayer(player: EntityPlayer) = player == player + }) + case Some(server: item.Server) if id == GuiType.Server.id => + new container.Server(player.inventory, new ServerInventory { + override def tier = server.tier - override def container = player.getCurrentEquippedItem + override def container = player.getCurrentEquippedItem - override def isUseableByPlayer(player: EntityPlayer) = player == player - }) - case _ => null - } + override def isUseableByPlayer(player: EntityPlayer) = player == player + }) + case _ => null + } + case _ => null } + } } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/GuiType.scala b/src/main/scala/li/cil/oc/common/GuiType.scala index e9dba2b16..3ce157f9c 100644 --- a/src/main/scala/li/cil/oc/common/GuiType.scala +++ b/src/main/scala/li/cil/oc/common/GuiType.scala @@ -1,23 +1,40 @@ package li.cil.oc.common -object GuiType extends Enumeration { - val +import li.cil.oc.util.ScalaEnum - Adapter, - Assembler, - Case, - Charger, - Database, - Disassembler, - DiskDrive, - Rack, - Raid, - Robot, - Screen, - Server, - Switch, - Tablet, - Terminal +import scala.collection.mutable - = Value +object GuiType extends ScalaEnum { + val Categories = mutable.Map.empty[Int, Category.Value] + + sealed trait EnumVal extends Value { + def id = ordinal + def subType: GuiType.Category.Value + Categories += ordinal -> subType + } + + val Adapter = new EnumVal { def name = "Adapter"; def subType = GuiType.Category.Block } + val Assembler = new EnumVal { def name = "Assembler"; def subType = GuiType.Category.Block } + val Case = new EnumVal { def name = "Case"; def subType = GuiType.Category.Block } + val Charger = new EnumVal { def name = "Charger"; def subType = GuiType.Category.Block } + val Database = new EnumVal { def name = "Database"; def subType = GuiType.Category.Item } + val Disassembler = new EnumVal { def name = "Disassembler"; def subType = GuiType.Category.Block } + val DiskDrive = new EnumVal { def name = "DiskDrive"; def subType = GuiType.Category.Block } + val Drone = new EnumVal { def name = "Drone"; def subType = GuiType.Category.Entity } + val Rack = new EnumVal { def name = "Rack"; def subType = GuiType.Category.Block } + val Raid = new EnumVal { def name = "Raid"; def subType = GuiType.Category.Block } + val Robot = new EnumVal { def name = "Robot"; def subType = GuiType.Category.Block } + val Screen = new EnumVal { def name = "Screen"; def subType = GuiType.Category.Block } + val Server = new EnumVal { def name = "Server"; def subType = GuiType.Category.Item } + val Switch = new EnumVal { def name = "Switch"; def subType = GuiType.Category.Block } + val Tablet = new EnumVal { def name = "Tablet"; def subType = GuiType.Category.Item } + val Terminal = new EnumVal { def name = "Terminal"; def subType = GuiType.Category.Item } + + object Category extends ScalaEnum { + sealed trait EnumVal extends Value + + val Block = new EnumVal { def name = "Block" } + val Entity = new EnumVal { def name = "Entity" } + val Item = new EnumVal { def name = "Item" } + } } diff --git a/src/main/scala/li/cil/oc/common/PacketBuilder.scala b/src/main/scala/li/cil/oc/common/PacketBuilder.scala index c3fccdf94..257dda10a 100644 --- a/src/main/scala/li/cil/oc/common/PacketBuilder.scala +++ b/src/main/scala/li/cil/oc/common/PacketBuilder.scala @@ -10,6 +10,7 @@ import cpw.mods.fml.common.network.internal.FMLProxyPacket import io.netty.buffer.Unpooled import li.cil.oc.OpenComputers import li.cil.oc.api.driver.EnvironmentHost +import net.minecraft.entity.Entity import net.minecraft.entity.player.EntityPlayerMP import net.minecraft.item.ItemStack import net.minecraft.nbt.CompressedStreamTools @@ -21,13 +22,18 @@ import net.minecraftforge.common.util.ForgeDirection import scala.collection.convert.WrapAsScala._ abstract class PacketBuilder(stream: OutputStream) extends DataOutputStream(stream) { - def writeTileEntity(t: TileEntity) = { + def writeTileEntity(t: TileEntity) { writeInt(t.getWorldObj.provider.dimensionId) writeInt(t.xCoord) writeInt(t.yCoord) writeInt(t.zCoord) } + def writeEntity(e: Entity) { + writeInt(e.worldObj.provider.dimensionId) + writeInt(e.getEntityId) + } + def writeDirection(d: ForgeDirection) = writeInt(d.ordinal) def writeItemStack(stack: ItemStack) = { diff --git a/src/main/scala/li/cil/oc/common/PacketHandler.scala b/src/main/scala/li/cil/oc/common/PacketHandler.scala index 644a0de71..f81abfc0a 100644 --- a/src/main/scala/li/cil/oc/common/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/common/PacketHandler.scala @@ -51,7 +51,6 @@ abstract class PacketHandler { def getTileEntity[T: ClassTag](dimension: Int, x: Int, y: Int, z: Int): Option[T] = { world(player, dimension) match { - case None => // Invalid dimension. case Some(world) if world.blockExists(x, y, z) => val t = world.getTileEntity(x, y, z) if (t != null && classTag[T].runtimeClass.isAssignableFrom(t.getClass)) { @@ -68,6 +67,19 @@ abstract class PacketHandler { } case _ => } + case _ => // Invalid dimension. + } + None + } + + def getEntity[T: ClassTag](dimension: Int, id: Int): Option[T] = { + world(player, dimension) match { + case Some(world) => + val e = world.getEntityByID(id) + if (e != null && classTag[T].runtimeClass.isAssignableFrom(e.getClass)) { + return Some(e.asInstanceOf[T]) + } + case _ => } None } @@ -80,6 +92,12 @@ abstract class PacketHandler { getTileEntity(dimension, x, y, z) } + def readEntity[T: ClassTag](): Option[T] = { + val dimension = readInt() + val id = readInt() + getEntity[T](dimension, id) + } + def readDirection() = ForgeDirection.getOrientation(readInt()) def readItemStack() = { diff --git a/src/main/scala/li/cil/oc/common/PacketType.scala b/src/main/scala/li/cil/oc/common/PacketType.scala index 78b62a3b6..fac6f4d39 100644 --- a/src/main/scala/li/cil/oc/common/PacketType.scala +++ b/src/main/scala/li/cil/oc/common/PacketType.scala @@ -47,6 +47,7 @@ object PacketType extends Enumeration { // Client -> Server ComputerPower, + DronePower, KeyDown, KeyUp, Clipboard, diff --git a/src/main/scala/li/cil/oc/common/container/Drone.scala b/src/main/scala/li/cil/oc/common/container/Drone.scala index 92f4f3b93..81c17f2cb 100644 --- a/src/main/scala/li/cil/oc/common/container/Drone.scala +++ b/src/main/scala/li/cil/oc/common/container/Drone.scala @@ -12,14 +12,14 @@ class Drone(playerInventory: InventoryPlayer, drone: entity.Drone) extends Playe val deltaY = 0 for (i <- 0 to 1) { - val y = 6 + i * slotSize - deltaY + val y = 8 + i * slotSize - deltaY for (j <- 0 to 3) { - val x = 96 + j * slotSize + val x = 98 + j * slotSize addSlotToContainer(new InventorySlot(this, otherInventory, inventorySlots.size, x, y)) } } - addPlayerInventorySlots(6, 64) + addPlayerInventorySlots(8, 66) class InventorySlot(container: Player, inventory: IInventory, index: Int, x: Int, y: Int) extends StaticComponentSlot(container, inventory, index, x, y, common.Slot.Any, common.Tier.Any) { def isValid = (0 until drone.inventory.getSizeInventory).contains(getSlotIndex) diff --git a/src/main/scala/li/cil/oc/common/entity/Drone.scala b/src/main/scala/li/cil/oc/common/entity/Drone.scala index 8dca210cd..26fec7f6f 100644 --- a/src/main/scala/li/cil/oc/common/entity/Drone.scala +++ b/src/main/scala/li/cil/oc/common/entity/Drone.scala @@ -2,6 +2,7 @@ package li.cil.oc.common.entity import cpw.mods.fml.relauncher.Side import cpw.mods.fml.relauncher.SideOnly +import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.Driver @@ -11,6 +12,7 @@ import li.cil.oc.api.driver.item.Processor import li.cil.oc.api.internal import li.cil.oc.api.machine.MachineHost import li.cil.oc.api.network._ +import li.cil.oc.common.GuiType import li.cil.oc.common.Slot import li.cil.oc.common.inventory.ComponentInventory import li.cil.oc.common.inventory.Inventory @@ -286,21 +288,23 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern stack } + def preparePowerUp() { + targetX = math.floor(posX).toFloat + 0.5f + targetY = math.floor(posY).toFloat + 0.5f + targetZ = math.floor(posZ).toFloat + 0.5f + targetAcceleration = maxAcceleration + + api.Network.joinNewNetwork(machine.node) + components.connectComponents() + machine.node.connect(control.node) + } + override def interactFirst(player: EntityPlayer) = { if (player.isSneaking) { kill() } else if (!world.isRemote) { - targetX = math.floor(posX).toFloat + 0.5f - targetY = math.floor(posY).toFloat + 0.5f - targetZ = math.floor(posZ).toFloat + 0.5f - targetAcceleration = maxAcceleration - - api.Network.joinNewNetwork(machine.node) - components.connectComponents() - machine.node.connect(control.node) - if (machine.isRunning) machine.stop() - else machine.start() + player.openGui(OpenComputers, GuiType.Drone.id, world, getEntityId, 0, 0) } true } diff --git a/src/main/scala/li/cil/oc/server/PacketHandler.scala b/src/main/scala/li/cil/oc/server/PacketHandler.scala index 78a9adccb..2883d70e3 100644 --- a/src/main/scala/li/cil/oc/server/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/server/PacketHandler.scala @@ -8,6 +8,7 @@ import li.cil.oc.api import li.cil.oc.api.machine.Machine import li.cil.oc.common.PacketType import li.cil.oc.common.component.TextBuffer +import li.cil.oc.common.entity.Drone import li.cil.oc.common.tileentity._ import li.cil.oc.common.tileentity.traits.Computer import li.cil.oc.common.tileentity.traits.TileEntity @@ -31,6 +32,7 @@ object PacketHandler extends CommonPacketHandler { override def dispatch(p: PacketParser) { p.packetType match { case PacketType.ComputerPower => onComputerPower(p) + case PacketType.DronePower => onDronePower(p) case PacketType.KeyDown => onKeyDown(p) case PacketType.KeyUp => onKeyUp(p) case PacketType.Clipboard => onClipboard(p) @@ -65,6 +67,20 @@ object PacketHandler extends CommonPacketHandler { case _ => // Invalid packet. } + def onDronePower(p: PacketParser) = + p.readEntity[Drone]() match { + case Some(drone) => p.player match { + case player: EntityPlayerMP => + val power = p.readBoolean() + if (power) { + drone.preparePowerUp() + } + trySetComputerPower(drone.machine, power, player) + case _ => + } + case _ => // Invalid packet. + } + private def trySetComputerPower(computer: Machine, value: Boolean, player: EntityPlayerMP) { if (computer.canInteract(player.getCommandSenderName)) { if (value) { diff --git a/src/main/scala/li/cil/oc/util/ScalaEnum.scala b/src/main/scala/li/cil/oc/util/ScalaEnum.scala new file mode 100644 index 000000000..1de8c008c --- /dev/null +++ b/src/main/scala/li/cil/oc/util/ScalaEnum.scala @@ -0,0 +1,39 @@ +package li.cil.oc.util + +/** + * https://gist.github.com/viktorklang/1057513 + */ +trait ScalaEnum { + import java.util.concurrent.atomic.AtomicReference //Concurrency paranoia + + type EnumVal <: Value //This is a type that needs to be found in the implementing class + + private val _values = new AtomicReference(Vector[EnumVal]()) //Stores our enum values + + //Adds an EnumVal to our storage, uses CCAS to make sure it's thread safe, returns the ordinal + private final def addEnumVal(newVal: EnumVal): Int = { + import _values.{get, compareAndSet => CAS} + val oldVec = get + val newVec = oldVec :+ newVal + if ((get eq oldVec) && CAS(oldVec, newVec)) + newVec.indexWhere(_ eq newVal) + else + addEnumVal(newVal) + } + + def values: Vector[EnumVal] = _values.get //Here you can get all the enums that exist for this type + + //This is the trait that we need to extend our EnumVal type with, it does the book-keeping for us + protected trait Value { self: EnumVal => //Enforce that no one mixes in Value in a non-EnumVal type + final val ordinal = addEnumVal(this) //Adds the EnumVal and returns the ordinal + + def name: String //All enum values should have a name + + override def toString = name //And that name is used for the toString operation + + override def equals(other: Any) = this eq other.asInstanceOf[AnyRef] + + override def hashCode = 31 * (this.getClass.## + name.## + ordinal) + } + +} \ No newline at end of file