diff --git a/assets/opencomputers/lang/de_DE.lang b/assets/opencomputers/lang/de_DE.lang index fb472408f..1d2aec421 100644 --- a/assets/opencomputers/lang/de_DE.lang +++ b/assets/opencomputers/lang/de_DE.lang @@ -75,6 +75,8 @@ oc:gui.Robot.TurnOn=Einschalten oc:container.Adapter=Adapter oc:container.Case=Computer oc:container.DiskDrive=Diskettenlaufwerk +oc:container.Server=Server +oc:container.ServerRack=Serverschrank # Item / Block Tooltips oc:tooltip.Acid=Eine hochgiftige Möchtegernflüssigkeit, wird üblicherweise nur von gewissen Piraten konsumiert. Dank ihrer korrosiven Eigenschaften ideal zum Bedrucken von Leiterplatten geeignet. diff --git a/assets/opencomputers/lang/en_US.lang b/assets/opencomputers/lang/en_US.lang index 1e8933334..f2ed85192 100644 --- a/assets/opencomputers/lang/en_US.lang +++ b/assets/opencomputers/lang/en_US.lang @@ -75,6 +75,8 @@ oc:gui.Robot.TurnOn=Turn on oc:container.Adapter=Adapter oc:container.Case=Computer oc:container.DiskDrive=Disk Drive +oc:container.Server=Server +oc:container.ServerRack=Server Rack # Item / Block Tooltips oc:tooltip.Acid=A highly toxic pseudo-liquid, usually only consumed by certain pirates. Thanks to its corrosive nature it is perfectly suited for etching circuit boards. diff --git a/assets/opencomputers/textures/gui/server.png b/assets/opencomputers/textures/gui/server.png new file mode 100644 index 000000000..71604995a Binary files /dev/null and b/assets/opencomputers/textures/gui/server.png differ diff --git a/li/cil/oc/api/driver/Slot.java b/li/cil/oc/api/driver/Slot.java index 2c7112c2b..dfa015077 100644 --- a/li/cil/oc/api/driver/Slot.java +++ b/li/cil/oc/api/driver/Slot.java @@ -42,6 +42,15 @@ public enum Slot { */ Memory, + /** + * CPU slots, used in servers. + *
+ * Components should usually not implement this slot type, unless you want + * to provide an alternative CPU (that will have the same effect as the + * default one, so I don't think that would make a lot of sense). + */ + Processor, + /** * Tool slot in robots (equipment slot). * diff --git a/li/cil/oc/client/GuiHandler.scala b/li/cil/oc/client/GuiHandler.scala index 00d9cd6b7..9ccffc4c6 100644 --- a/li/cil/oc/client/GuiHandler.scala +++ b/li/cil/oc/client/GuiHandler.scala @@ -1,7 +1,8 @@ package li.cil.oc.client -import li.cil.oc.common.tileentity -import li.cil.oc.common.{GuiHandler => CommonGuiHandler, GuiType} +import li.cil.oc.Items +import li.cil.oc.common.inventory.ServerInventory +import li.cil.oc.common.{GuiHandler => CommonGuiHandler, item, tileentity, GuiType} import net.minecraft.entity.player.EntityPlayer import net.minecraft.world.World @@ -20,6 +21,12 @@ object GuiHandler extends CommonGuiHandler { new gui.Rack(player.inventory, rack) case screen: tileentity.Screen if id == GuiType.Screen.id => new gui.Screen(screen) - case _ => null + case _ => Items.multi.subItem(player.getCurrentEquippedItem) match { + case Some(server: item.Server) if id == GuiType.Server.id => + new gui.Server(player.inventory, new ServerInventory(player)) + case Some(terminal: item.Terminal) if id == GuiType.Terminal.id => + null // TODO + case _ => null + } } } diff --git a/li/cil/oc/client/gui/Adapter.scala b/li/cil/oc/client/gui/Adapter.scala index aeed32f60..885d82e0e 100644 --- a/li/cil/oc/client/gui/Adapter.scala +++ b/li/cil/oc/client/gui/Adapter.scala @@ -1,6 +1,5 @@ package li.cil.oc.client.gui -import li.cil.oc.Settings import li.cil.oc.common.container import li.cil.oc.common.tileentity import net.minecraft.entity.player.InventoryPlayer @@ -10,7 +9,7 @@ class Adapter(playerInventory: InventoryPlayer, val adapter: tileentity.Adapter) override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = { super.drawGuiContainerForegroundLayer(mouseX, mouseY) fontRenderer.drawString( - StatCollector.translateToLocal(Settings.namespace + "container.Adapter"), + StatCollector.translateToLocal(adapter.getInvName), 8, 6, 0x404040) } } diff --git a/li/cil/oc/client/gui/Case.scala b/li/cil/oc/client/gui/Case.scala index 9358ec98c..62f81297f 100644 --- a/li/cil/oc/client/gui/Case.scala +++ b/li/cil/oc/client/gui/Case.scala @@ -39,7 +39,7 @@ class Case(playerInventory: InventoryPlayer, val computer: tileentity.Case) exte super.drawGuiContainerForegroundLayer(mouseX, mouseY) GL11.glPushAttrib(0xFFFFFFFF) // Me lazy... prevents NEI render glitch. fontRenderer.drawString( - StatCollector.translateToLocal(Settings.namespace + "container.Case"), + StatCollector.translateToLocal(computer.getInvName), 8, 6, 0x404040) if (powerButton.func_82252_a) { val tooltip = new java.util.ArrayList[String] diff --git a/li/cil/oc/client/gui/DiskDrive.scala b/li/cil/oc/client/gui/DiskDrive.scala index 3ed4506d6..f5f427c9c 100644 --- a/li/cil/oc/client/gui/DiskDrive.scala +++ b/li/cil/oc/client/gui/DiskDrive.scala @@ -1,6 +1,5 @@ package li.cil.oc.client.gui -import li.cil.oc.Settings import li.cil.oc.common.container import li.cil.oc.common.tileentity import net.minecraft.entity.player.InventoryPlayer @@ -10,7 +9,7 @@ class DiskDrive(playerInventory: InventoryPlayer, val drive: tileentity.DiskDriv override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = { super.drawGuiContainerForegroundLayer(mouseX, mouseY) fontRenderer.drawString( - StatCollector.translateToLocal(Settings.namespace + "container.DiskDrive"), + StatCollector.translateToLocal(drive.getInvName), 8, 6, 0x404040) } } diff --git a/li/cil/oc/client/gui/DynamicGuiContainer.scala b/li/cil/oc/client/gui/DynamicGuiContainer.scala index 8088688d6..601186d7e 100644 --- a/li/cil/oc/client/gui/DynamicGuiContainer.scala +++ b/li/cil/oc/client/gui/DynamicGuiContainer.scala @@ -32,14 +32,14 @@ abstract class DynamicGuiContainer(container: Container) extends GuiContainer(co GL11.glEnable(GL11.GL_LIGHTING) } RenderState.makeItBlend() - GL11.glDepthMask(false) super.drawSlotInventory(slot) - GL11.glDepthMask(true) GL11.glDisable(GL11.GL_BLEND) if (!slot.getHasStack) slot match { case component: ComponentSlot if component.tierIcon != null => mc.getTextureManager.bindTexture(TextureMap.locationItemsTexture) + GL11.glDisable(GL11.GL_DEPTH_TEST) drawTexturedModelRectFromIcon(slot.xDisplayPosition, slot.yDisplayPosition, component.tierIcon, 16, 16) + GL11.glEnable(GL11.GL_DEPTH_TEST) case _ => } } diff --git a/li/cil/oc/client/gui/Rack.scala b/li/cil/oc/client/gui/Rack.scala index 894257951..80e3a87fb 100644 --- a/li/cil/oc/client/gui/Rack.scala +++ b/li/cil/oc/client/gui/Rack.scala @@ -1,6 +1,5 @@ package li.cil.oc.client.gui -import li.cil.oc.Settings import li.cil.oc.common.container import li.cil.oc.common.tileentity import net.minecraft.entity.player.InventoryPlayer @@ -10,7 +9,7 @@ class Rack(playerInventory: InventoryPlayer, val rack: tileentity.Rack) extends override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = { super.drawGuiContainerForegroundLayer(mouseX, mouseY) fontRenderer.drawString( - StatCollector.translateToLocal(Settings.namespace + "container.ServerRack"), + StatCollector.translateToLocal(rack.getInvName), 8, 6, 0x404040) } } diff --git a/li/cil/oc/client/gui/Robot.scala b/li/cil/oc/client/gui/Robot.scala index 0e26e78f6..e89ae1c41 100644 --- a/li/cil/oc/client/gui/Robot.scala +++ b/li/cil/oc/client/gui/Robot.scala @@ -6,19 +6,19 @@ import li.cil.oc.client.renderer.MonospaceFontRenderer import li.cil.oc.client.renderer.gui.BufferRenderer import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.container +import li.cil.oc.common.container.ComponentSlot import li.cil.oc.common.tileentity import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft import net.minecraft.client.gui.GuiButton import net.minecraft.client.gui.inventory.GuiContainer import net.minecraft.client.renderer.Tessellator +import net.minecraft.client.renderer.texture.TextureMap import net.minecraft.entity.player.InventoryPlayer import net.minecraft.inventory.Slot import net.minecraft.util.{StatCollector, ResourceLocation} import org.lwjgl.input.Keyboard import org.lwjgl.opengl.GL11 -import li.cil.oc.common.container.ComponentSlot -import net.minecraft.client.renderer.texture.TextureMap class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) extends GuiContainer(new container.Robot(playerInventory, robot)) with Buffer { xSize = 256 @@ -70,14 +70,14 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten override def drawSlotInventory(slot: Slot) { RenderState.makeItBlend() - GL11.glDepthMask(false) super.drawSlotInventory(slot) - GL11.glDepthMask(true) GL11.glDisable(GL11.GL_BLEND) if (!slot.getHasStack) slot match { case component: ComponentSlot if component.tierIcon != null => mc.getTextureManager.bindTexture(TextureMap.locationItemsTexture) + GL11.glDisable(GL11.GL_DEPTH_TEST) drawTexturedModelRectFromIcon(slot.xDisplayPosition, slot.yDisplayPosition, component.tierIcon, 16, 16) + GL11.glEnable(GL11.GL_DEPTH_TEST) case _ => } } diff --git a/li/cil/oc/client/gui/Server.scala b/li/cil/oc/client/gui/Server.scala new file mode 100644 index 000000000..11b375224 --- /dev/null +++ b/li/cil/oc/client/gui/Server.scala @@ -0,0 +1,28 @@ +package li.cil.oc.client.gui + +import li.cil.oc.Settings +import li.cil.oc.common.container +import li.cil.oc.common.inventory.ServerInventory +import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.util.{ResourceLocation, StatCollector} +import org.lwjgl.opengl.GL11 + +class Server(playerInventory: InventoryPlayer, serverInventory: ServerInventory) extends DynamicGuiContainer(new container.Server(playerInventory, serverInventory)) { + protected val serverBackground = new ResourceLocation(Settings.resourceDomain, "textures/gui/server.png") + + override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = { + super.drawGuiContainerForegroundLayer(mouseX, mouseY) + fontRenderer.drawString( + StatCollector.translateToLocal(serverInventory.getInvName), + 8, 6, 0x404040) + } + + override def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) { + GL11.glColor3f(1, 1, 1) // Required under Linux. + super.drawGuiContainerBackgroundLayer(dt, mouseX, mouseY) + mc.renderEngine.bindTexture(serverBackground) + drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) + } + + override def doesGuiPauseGame = false +} \ No newline at end of file diff --git a/li/cil/oc/common/GuiHandler.scala b/li/cil/oc/common/GuiHandler.scala index 54a0ce7a8..650b9934c 100644 --- a/li/cil/oc/common/GuiHandler.scala +++ b/li/cil/oc/common/GuiHandler.scala @@ -1,6 +1,8 @@ package li.cil.oc.common import cpw.mods.fml.common.network.IGuiHandler +import li.cil.oc.Items +import li.cil.oc.common.inventory.ServerInventory import net.minecraft.entity.player.EntityPlayer import net.minecraft.world.World @@ -17,6 +19,12 @@ abstract class GuiHandler extends IGuiHandler { new container.Robot(player.inventory, proxy.robot) case rack: tileentity.Rack if id == GuiType.Rack.id => new container.Rack(player.inventory, rack) - case _ => null + case _ => Items.multi.subItem(player.getCurrentEquippedItem) match { + case Some(server: item.Server) if id == GuiType.Server.id => + new container.Server(player.inventory, new ServerInventory(player)) + case Some(terminal: item.Terminal) if id == GuiType.Terminal.id => + null // TODO + case _ => null + } } } \ No newline at end of file diff --git a/li/cil/oc/common/container/Server.scala b/li/cil/oc/common/container/Server.scala new file mode 100644 index 000000000..3ed7fb800 --- /dev/null +++ b/li/cil/oc/common/container/Server.scala @@ -0,0 +1,29 @@ +package li.cil.oc.common.container + +import li.cil.oc.api +import li.cil.oc.common.inventory.ServerInventory +import net.minecraft.entity.player.{EntityPlayer, InventoryPlayer} + +class Server(playerInventory: InventoryPlayer, serverInventory: ServerInventory) extends Player(playerInventory, serverInventory) { + for (i <- 0 to 1) { + addSlotToContainer(76, 7 + i * slotSize, api.driver.Slot.Card, 1) + } + + for (i <- 0 to 3) { + addSlotToContainer(100, 7 + i * slotSize, api.driver.Slot.Processor) + } + + for (i <- 0 to 3) { + addSlotToContainer(124, 7 + i * slotSize, api.driver.Slot.Memory, 2) + } + + for (i <- 0 to 3) { + addSlotToContainer(148, 7 + i * slotSize, api.driver.Slot.HardDiskDrive, 2) + } + + // Show the player's inventory. + addPlayerInventorySlots(8, 84) + + override def canInteractWith(player: EntityPlayer) = player == playerInventory.player +} + diff --git a/li/cil/oc/common/inventory/ItemStackInventory.scala b/li/cil/oc/common/inventory/ItemStackInventory.scala new file mode 100644 index 000000000..3566abd08 --- /dev/null +++ b/li/cil/oc/common/inventory/ItemStackInventory.scala @@ -0,0 +1,85 @@ +package li.cil.oc.common.inventory + +import li.cil.oc.Settings +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.inventory.IInventory +import net.minecraft.item.ItemStack +import net.minecraft.nbt.{NBTTagList, NBTTagCompound} + +abstract class ItemStackInventory extends IInventory { + // The item stack that provides the inventory. + def container: ItemStack + + protected val items = Array.fill[Option[ItemStack]](getSizeInventory)(None) + + // Load items from tag. + { + if (!container.hasTagCompound) { + container.setTagCompound(new NBTTagCompound("tag")) + } + if (container.getTagCompound.hasKey(Settings.namespace + "items")) { + val list = container.getTagCompound.getTagList(Settings.namespace + "items") + for (i <- 0 until (list.tagCount min items.length)) { + val tag = list.tagAt(i).asInstanceOf[NBTTagCompound] + if (!tag.hasNoTags) { + items(i) = Option(ItemStack.loadItemStackFromNBT(tag)) + } + } + } + } + + def getStackInSlot(slot: Int) = items(slot).orNull + + def decrStackSize(slot: Int, amount: Int) = items(slot) match { + case Some(stack) if stack.stackSize - amount < 1 => + setInventorySlotContents(slot, null) + stack + case Some(stack) => + val result = stack.splitStack(amount) + onInventoryChanged() + result + case _ => null + } + + def getStackInSlotOnClosing(slot: Int) = null + + def setInventorySlotContents(slot: Int, stack: ItemStack) = { + if (stack == null || stack.stackSize < 1) { + items(slot) = None + } + else { + items(slot) = Some(stack) + } + if (stack != null && stack.stackSize > getInventoryStackLimit) { + stack.stackSize = getInventoryStackLimit + } + + onInventoryChanged() + } + + def isInvNameLocalized = false + + def getInventoryStackLimit = 64 + + def onInventoryChanged() { + // Write items back to tag. + val list = new NBTTagList() + for (i <- 0 until items.length) { + val tag = new NBTTagCompound() + items(i) match { + case Some(stack) => stack.writeToNBT(tag) + case _ => + } + list.appendTag(tag) + } + container.getTagCompound.setTag(Settings.namespace + "items", list) + } + + def isUseableByPlayer(player: EntityPlayer) = true + + def openChest() {} + + def closeChest() {} + + def isItemValidForSlot(slot: Int, stack: ItemStack) = true +} diff --git a/li/cil/oc/common/inventory/ServerInventory.scala b/li/cil/oc/common/inventory/ServerInventory.scala new file mode 100644 index 000000000..8a4378cf2 --- /dev/null +++ b/li/cil/oc/common/inventory/ServerInventory.scala @@ -0,0 +1,27 @@ +package li.cil.oc.common.inventory + +import li.cil.oc.Settings +import li.cil.oc.api.driver.Slot +import li.cil.oc.server.driver.Registry +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemStack + +class ServerInventory(player: EntityPlayer) extends ItemStackInventory { + def container = player.getCurrentEquippedItem + + def getSizeInventory = 14 + + def getInvName = Settings.namespace + "container.Server" + + override def getInventoryStackLimit = 1 + + override def isItemValidForSlot(slot: Int, stack: ItemStack) = + (slot, Registry.itemDriverFor(stack)) match { + case (_, None) => false // Invalid item. + case (0 | 1, Some(driver)) => driver.slot(stack) == Slot.Card && driver.tier(stack) <= 1 + case (2 | 3 | 4 | 5, Some(driver)) => driver.slot(stack) == Slot.Processor && driver.tier(stack) <= 2 + case (6 | 7 | 8 | 9, Some(driver)) => driver.slot(stack) == Slot.Memory && driver.tier(stack) <= 2 + case (10 | 11 | 12 | 13, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive && driver.tier(stack) <= 2 + case _ => false // Invalid slot. + } +} diff --git a/li/cil/oc/common/item/Server.scala b/li/cil/oc/common/item/Server.scala index ed73bf0f8..794ae2c2c 100644 --- a/li/cil/oc/common/item/Server.scala +++ b/li/cil/oc/common/item/Server.scala @@ -1,5 +1,21 @@ package li.cil.oc.common.item +import li.cil.oc.OpenComputers +import li.cil.oc.common.GuiType +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemStack +import net.minecraft.world.World + class Server(val parent: Delegator) extends Delegate { val unlocalizedName = "Server" + + override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = { + if (!player.isSneaking) { + if (!world.isRemote) { + player.openGui(OpenComputers, GuiType.Server.id, world, 0, 0, 0) + } + player.swingItem() + } + stack + } }