From d29dcb8a69cf9092ee18282967baea5785f98fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 13 Dec 2014 21:52:40 +0100 Subject: [PATCH] Started work on drone GUI. --- .../java/li/cil/oc/api/internal/Drone.java | 2 +- .../opencomputers/textures/gui/drone.png | Bin 0 -> 596 bytes src/main/scala/li/cil/oc/Localization.scala | 2 +- .../scala/li/cil/oc/client/Textures.scala | 4 + .../scala/li/cil/oc/client/gui/Case.scala | 2 +- .../scala/li/cil/oc/client/gui/Drone.scala | 124 ++++++++++++++++++ .../scala/li/cil/oc/client/gui/Robot.scala | 4 +- .../li/cil/oc/client/gui/ServerRack.scala | 2 +- .../li/cil/oc/common/container/Drone.scala | 41 ++++++ .../scala/li/cil/oc/common/entity/Drone.scala | 81 +++++++----- 10 files changed, 220 insertions(+), 42 deletions(-) create mode 100644 src/main/resources/assets/opencomputers/textures/gui/drone.png create mode 100644 src/main/scala/li/cil/oc/client/gui/Drone.scala create mode 100644 src/main/scala/li/cil/oc/common/container/Drone.scala diff --git a/src/main/java/li/cil/oc/api/internal/Drone.java b/src/main/java/li/cil/oc/api/internal/Drone.java index 50615e7bc..75075500d 100644 --- a/src/main/java/li/cil/oc/api/internal/Drone.java +++ b/src/main/java/li/cil/oc/api/internal/Drone.java @@ -17,7 +17,7 @@ import li.cil.oc.api.network.Environment; * i.e. without having to link against internal classes. This also means * that you should not implement this. */ -public interface Drone extends Environment, EnvironmentHost { +public interface Drone extends EnvironmentHost { /** * The machine currently hosted by this drone. */ diff --git a/src/main/resources/assets/opencomputers/textures/gui/drone.png b/src/main/resources/assets/opencomputers/textures/gui/drone.png new file mode 100644 index 0000000000000000000000000000000000000000..669568fce008ad47f9617ea2e8525fd969de3f58 GIT binary patch literal 596 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5FjO4;u=vBoS#-wo>-L1;Fyx1 zl&avFo0y&&l$w}QS$Hzl2B=6hz$e7DySw|?v135q|NsBZ&CNqYLxGIQ%xS7XA@-6W zzhEF22pFWincaZ49P)H=45_&F=C-#`lYs#10mX!O^(oz#MBf-R&s=oBNNif>!SlwQ z_oC;1`Pg~ynw6(Ohu7=)>C>1ugq(bR)rdh1Xll-5;rZ&d^WtZxF!%hw@GmYhT4qz+ zY@h@xc*SsJ+U#rMlm`k)6wu)2q5K5oYE+QX zQpZq`C&0j ClientPacketSender} +import li.cil.oc.common.container +import li.cil.oc.common.entity +import li.cil.oc.util.RenderState +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.GuiButton +import net.minecraft.client.renderer.Tessellator +import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.inventory.Slot +import org.lwjgl.opengl.GL11 + +class Drone(playerInventory: InventoryPlayer, val drone: entity.Drone) extends DynamicGuiContainer(new container.Drone(playerInventory, drone)) { + xSize = 176 + ySize = 146 + + protected var powerButton: ImageButton = _ + + private val bufferWidth = 80 + private val bufferHeight = 32 + private val bufferX = 10 + private val bufferY = 10 + + private val inventoryX = 95 + private val inventoryY = 5 + + private val power = addWidget(new ProgressBar(26, 48)) + + private val selectionSize = 20 + private val selectionsStates = 17 + private val selectionStepV = 1 / selectionsStates.toDouble + + def add[T](list: util.List[T], value: Any) = list.add(value.asInstanceOf[T]) + + protected override def actionPerformed(button: GuiButton) { + if (button.id == 0) { +// ClientPacketSender.sendComputerPower(drone, !drone.isRunning) + } + } + + override def drawScreen(mouseX: Int, mouseY: Int, dt: Float) { + powerButton.toggled = drone.isRunning + super.drawScreen(mouseX, mouseY, dt) + } + + override def initGui() { + super.initGui() + powerButton = new ImageButton(0, guiLeft + 5, guiTop + 43, 18, 18, Textures.guiButtonPower, canToggle = true) + add(buttonList, powerButton) + } + + override protected def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) { + GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) // Me lazy... prevents NEI render glitch. + if (func_146978_c(power.x, power.y, power.width, power.height, mouseX, mouseY)) { + val tooltip = new java.util.ArrayList[String] + val format = Localization.Computer.Power + ": %d%% (%d/%d)" +// tooltip.add(format.format( +// ((drone.globalBuffer / drone.globalBufferSize) * 100).toInt, +// drone.globalBuffer.toInt, +// drone.globalBufferSize.toInt)) + copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRendererObj) + } + if (powerButton.func_146115_a) { + val tooltip = new java.util.ArrayList[String] + tooltip.add(if (drone.isRunning) Localization.Computer.TurnOff else Localization.Computer.TurnOn) + copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRendererObj) + } + GL11.glPopAttrib() + } + + override protected def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) { + GL11.glColor3f(1, 1, 1) // Required under Linux. + mc.renderEngine.bindTexture(Textures.guiDrone) + drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) +// power.level = robot.globalBuffer / robot.globalBufferSize + drawWidgets() + if (drone.inventory.getSizeInventory > 0) { + drawSelection() + } + + GL11.glPushMatrix() + GL11.glTranslatef(guiLeft, guiTop, 0) + for (slot <- 0 until inventorySlots.inventorySlots.size()) { + drawSlotInventory(inventorySlots.inventorySlots.get(slot).asInstanceOf[Slot]) + } + GL11.glPopMatrix() + + RenderState.makeItBlend() + } + + protected override def drawGradientRect(par1: Int, par2: Int, par3: Int, par4: Int, par5: Int, par6: Int) { + super.drawGradientRect(par1, par2, par3, par4, par5, par6) + RenderState.makeItBlend() + } + + // No custom slots, we just extend DynamicGuiContainer for the highlighting. + override protected def drawSlotBackground(x: Int, y: Int) {} + + private def drawSelection() { + val slot = drone.selectedSlot + if (slot >= 0 && slot < 16) { + RenderState.makeItBlend() + Minecraft.getMinecraft.renderEngine.bindTexture(Textures.guiRobotSelection) + val now = System.currentTimeMillis() / 1000.0 + val offsetV = ((now - now.toInt) * selectionsStates).toInt * selectionStepV + val x = guiLeft + inventoryX - 1 + (slot % 4) * (selectionSize - 2) + val y = guiTop + inventoryY - 1 + (slot / 4) * (selectionSize - 2) + + val t = Tessellator.instance + t.startDrawingQuads() + t.addVertexWithUV(x, y, zLevel, 0, offsetV) + t.addVertexWithUV(x, y + selectionSize, zLevel, 0, offsetV + selectionStepV) + t.addVertexWithUV(x + selectionSize, y + selectionSize, zLevel, 1, offsetV + selectionStepV) + t.addVertexWithUV(x + selectionSize, y, zLevel, 1, offsetV) + t.draw() + } + } +} \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/client/gui/Robot.scala b/src/main/scala/li/cil/oc/client/gui/Robot.scala index 37fb9bd4e..841837ff9 100644 --- a/src/main/scala/li/cil/oc/client/gui/Robot.scala +++ b/src/main/scala/li/cil/oc/client/gui/Robot.scala @@ -133,7 +133,7 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) // Me lazy... prevents NEI render glitch. if (func_146978_c(power.x, power.y, power.width, power.height, mouseX, mouseY)) { val tooltip = new java.util.ArrayList[String] - val format = Localization.Robot.Power + ": %d%% (%d/%d)" + val format = Localization.Computer.Power + ": %d%% (%d/%d)" tooltip.add(format.format( ((robot.globalBuffer / robot.globalBufferSize) * 100).toInt, robot.globalBuffer.toInt, @@ -142,7 +142,7 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten } if (powerButton.func_146115_a) { val tooltip = new java.util.ArrayList[String] - tooltip.add(if (robot.isRunning) Localization.Robot.TurnOff else Localization.Robot.TurnOn) + tooltip.add(if (robot.isRunning) Localization.Computer.TurnOff else Localization.Computer.TurnOn) copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRendererObj) } GL11.glPopAttrib() diff --git a/src/main/scala/li/cil/oc/client/gui/ServerRack.scala b/src/main/scala/li/cil/oc/client/gui/ServerRack.scala index 424b9feb0..6596bd8a7 100644 --- a/src/main/scala/li/cil/oc/client/gui/ServerRack.scala +++ b/src/main/scala/li/cil/oc/client/gui/ServerRack.scala @@ -130,7 +130,7 @@ class ServerRack(playerInventory: InventoryPlayer, val rack: tileentity.ServerRa for (i <- 0 to 3 if powerButtons(i).func_146115_a) { val tooltip = new java.util.ArrayList[String] - tooltip.add(if (rack.isRunning(i)) Localization.Robot.TurnOff else Localization.Robot.TurnOn) + tooltip.add(if (rack.isRunning(i)) Localization.Computer.TurnOff else Localization.Computer.TurnOn) copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRendererObj) } diff --git a/src/main/scala/li/cil/oc/common/container/Drone.scala b/src/main/scala/li/cil/oc/common/container/Drone.scala new file mode 100644 index 000000000..92f4f3b93 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/container/Drone.scala @@ -0,0 +1,41 @@ +package li.cil.oc.common.container + +import cpw.mods.fml.relauncher.Side +import cpw.mods.fml.relauncher.SideOnly +import li.cil.oc.client.gui.Icons +import li.cil.oc.common +import li.cil.oc.common.entity +import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.inventory.IInventory + +class Drone(playerInventory: InventoryPlayer, drone: entity.Drone) extends Player(playerInventory, drone.inventory) { + val deltaY = 0 + + for (i <- 0 to 1) { + val y = 6 + i * slotSize - deltaY + for (j <- 0 to 3) { + val x = 96 + j * slotSize + addSlotToContainer(new InventorySlot(this, otherInventory, inventorySlots.size, x, y)) + } + } + + addPlayerInventorySlots(6, 64) + + 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) + + @SideOnly(Side.CLIENT) + override def func_111238_b() = isValid && super.func_111238_b() + + override def getBackgroundIconIndex = { + if (isValid) super.getBackgroundIconIndex + else Icons.get(common.Tier.None) + } + + override def getStack = { + if (isValid) super.getStack + else null + } + } + +} \ No newline at end of file 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 3f7c8cdab..8dca210cd 100644 --- a/src/main/scala/li/cil/oc/common/entity/Drone.scala +++ b/src/main/scala/li/cil/oc/common/entity/Drone.scala @@ -6,7 +6,6 @@ import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.Driver import li.cil.oc.api.Machine -import li.cil.oc.api.driver.EnvironmentHost import li.cil.oc.api.driver.item.Memory import li.cil.oc.api.driver.item.Processor import li.cil.oc.api.internal @@ -14,6 +13,7 @@ import li.cil.oc.api.machine.MachineHost import li.cil.oc.api.network._ import li.cil.oc.common.Slot import li.cil.oc.common.inventory.ComponentInventory +import li.cil.oc.common.inventory.Inventory import li.cil.oc.server.component import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ItemUtils @@ -27,7 +27,7 @@ import net.minecraft.util.MovingObjectPosition import net.minecraft.util.Vec3 import net.minecraft.world.World -class Drone(val world: World) extends Entity(world) with ComponentInventory with Environment with EnvironmentHost with MachineHost with internal.Drone { +class Drone(val world: World) extends Entity(world) with MachineHost with internal.Drone { // Some basic constants. val gravity = 0.05f // low for slow fall (float down) val drag = 0.8f @@ -44,11 +44,44 @@ class Drone(val world: World) extends Entity(world) with ComponentInventory with var nextAngularVelocityChange = 0 // Logic stuff, components, machine and such. + var selectedSlot = 0 val info = new ItemUtils.MicrocontrollerData() val machine = if (!world.isRemote) Machine.create(this) else null val control = if (!world.isRemote) new component.Drone(this) else null + val components = new ComponentInventory { + override def host = Drone.this - override def node = Option(machine).map(_.node).orNull + override def items = info.components.map(Option(_)) + + override def getSizeInventory = info.components.length + + override def markDirty() {} + + override def isItemValidForSlot(slot: Int, stack: ItemStack) = true + + override def isUseableByPlayer(player: EntityPlayer) = true + + override def node = Option(machine).map(_.node).orNull + + override def onConnect(node: Node) {} + + override def onDisconnect(node: Node) {} + + override def onMessage(message: Message) {} + } + val inventory = new Inventory { + var items = Array.fill[Option[ItemStack]](8)(None) + + override def getSizeInventory = items.length + + override def getInventoryStackLimit = 64 + + override def markDirty() {} // TODO update client GUI? + + override def isItemValidForSlot(slot: Int, stack: ItemStack) = slot >= 0 && slot < getSizeInventory + + override def isUseableByPlayer(player: EntityPlayer) = player.getDistanceSqToEntity(Drone.this) < 64 + } // ----------------------------------------------------------------------- // @@ -106,26 +139,6 @@ class Drone(val world: World) extends Entity(world) with ComponentInventory with // ----------------------------------------------------------------------- // - override def host = this - - override def items = info.components.map(Option(_)) - - override def getSizeInventory = info.components.length - - override def markDirty() {} - - override def isItemValidForSlot(slot: Int, stack: ItemStack) = false - - override def isUseableByPlayer(player: EntityPlayer) = false - - // Nope. - override def setInventorySlotContents(slot: Int, stack: ItemStack) {} - - // Nope. - override def decrStackSize(slot: Int, amount: Int) = null - - // ----------------------------------------------------------------------- // - override def entityInit() { // Running, target x y z and acceleration. dataWatcher.addObject(2, byte2Byte(0: Byte)) @@ -155,7 +168,7 @@ class Drone(val world: World) extends Entity(world) with ComponentInventory with if (!world.isRemote) { machine.stop() machine.node.remove() - saveComponents() + components.saveComponents() val stack = api.Items.get("drone").createItemStack(1) info.save(stack) val entity = new EntityItem(world, posX, posY, posZ, stack) @@ -188,7 +201,7 @@ class Drone(val world: World) extends Entity(world) with ComponentInventory with } machine.node.asInstanceOf[Connector].changeBuffer(100) machine.update() - updateComponents() + components.updateComponents() setRunning(machine.isRunning) } else if (isRunning) { @@ -284,7 +297,7 @@ class Drone(val world: World) extends Entity(world) with ComponentInventory with targetAcceleration = maxAcceleration api.Network.joinNewNetwork(machine.node) - connectComponents() + components.connectComponents() machine.node.connect(control.node) if (machine.isRunning) machine.stop() else machine.start() @@ -294,22 +307,16 @@ class Drone(val world: World) extends Entity(world) with ComponentInventory with // ----------------------------------------------------------------------- // - override def onConnect(node: Node) {} - - override def onDisconnect(node: Node) {} - - override def onMessage(message: Message) {} - - // ----------------------------------------------------------------------- // - override def readEntityFromNBT(nbt: NBTTagCompound): Unit = { info.load(nbt.getCompoundTag("info")) if (!world.isRemote) { machine.load(nbt.getCompoundTag("machine")) control.load(nbt.getCompoundTag("control")) + components.load(nbt.getCompoundTag("components")) + inventory.load(nbt.getCompoundTag("inventory")) api.Network.joinNewNetwork(machine.node) - connectComponents() + components.connectComponents() machine.node.connect(control.node) } targetX = nbt.getFloat("targetX") @@ -319,11 +326,13 @@ class Drone(val world: World) extends Entity(world) with ComponentInventory with } override def writeEntityToNBT(nbt: NBTTagCompound): Unit = { - saveComponents() + components.saveComponents() nbt.setNewCompoundTag("info", info.save) if (!world.isRemote) { nbt.setNewCompoundTag("machine", machine.save) nbt.setNewCompoundTag("control", control.save) + nbt.setNewCompoundTag("components", components.save) + nbt.setNewCompoundTag("inventory", inventory.save) } nbt.setFloat("targetX", targetX) nbt.setFloat("targetY", targetY)