slots in computer cases are now tiered, closing #72.

This commit is contained in:
Florian Nücke 2014-01-10 17:26:39 +01:00
parent 27102a8be1
commit 7fc04b4e4a
19 changed files with 116 additions and 26 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

View File

@ -74,6 +74,20 @@ public interface Item {
*/ */
Slot slot(ItemStack stack); Slot slot(ItemStack stack);
/**
* The tier of the specified item this driver supports.
* <p/>
* This is used to determine into which slot of a computer the components
* this driver supports may go. This will only be called if a previous call
* to {@link #worksWith} with the same stack returned true.
* <p/>
* <em>Important</em>: tiers are zero-indexed.
*
* @param stack the item stack to get the tier for.
* @return the tier of the specified item.
*/
int tier(ItemStack stack);
/** /**
* Get the tag compound based on the item stack to use for persisting the * Get the tag compound based on the item stack to use for persisting the
* environment associated with the specified item stack. * environment associated with the specified item stack.
@ -91,7 +105,7 @@ public interface Item {
* *
* @param stack the item to get the child tag from. * @param stack the item to get the child tag from.
* @return the tag to use for saving and loading, or <tt>null</tt> to use * @return the tag to use for saving and loading, or <tt>null</tt> to use
* the default tag <tt>oc:data</tt>. * the default tag <tt>oc:data</tt>.
*/ */
NBTTagCompound dataTag(ItemStack stack); NBTTagCompound dataTag(ItemStack stack);
} }

View File

@ -37,5 +37,5 @@
@cpw.mods.fml.common.API( @cpw.mods.fml.common.API(
owner = "OpenComputers", owner = "OpenComputers",
provides = "OpenComputersAPI", provides = "OpenComputersAPI",
apiVersion = "1.1.0") apiVersion = "1.2.0")
package li.cil.oc.api; package li.cil.oc.api;

View File

@ -1,9 +1,11 @@
package li.cil.oc.client.gui package li.cil.oc.client.gui
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.common.container.ComponentSlot
import li.cil.oc.util.RenderState import li.cil.oc.util.RenderState
import net.minecraft.client.gui.inventory.GuiContainer import net.minecraft.client.gui.inventory.GuiContainer
import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.Tessellator
import net.minecraft.client.renderer.texture.TextureMap
import net.minecraft.inventory.{Container, Slot} import net.minecraft.inventory.{Container, Slot}
import net.minecraft.util.{StatCollector, ResourceLocation} import net.minecraft.util.{StatCollector, ResourceLocation}
import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.GL11
@ -30,8 +32,16 @@ abstract class DynamicGuiContainer(container: Container) extends GuiContainer(co
GL11.glEnable(GL11.GL_LIGHTING) GL11.glEnable(GL11.GL_LIGHTING)
} }
RenderState.makeItBlend() RenderState.makeItBlend()
GL11.glDepthMask(false)
super.drawSlotInventory(slot) super.drawSlotInventory(slot)
GL11.glDepthMask(true)
GL11.glDisable(GL11.GL_BLEND) GL11.glDisable(GL11.GL_BLEND)
if (!slot.getHasStack) slot match {
case component: ComponentSlot if component.tierIcon != null =>
mc.getTextureManager.bindTexture(TextureMap.locationItemsTexture)
drawTexturedModelRectFromIcon(slot.xDisplayPosition, slot.yDisplayPosition, component.tierIcon, 16, 16)
case _ =>
}
} }
private def drawSlotBackground(x: Int, y: Int) { private def drawSlotBackground(x: Int, y: Int) {

View File

@ -10,6 +10,8 @@ import scala.collection.mutable
object Icons { object Icons {
private val bySlotType = mutable.Map.empty[Slot, Icon] private val bySlotType = mutable.Map.empty[Slot, Icon]
private val byTier = mutable.Map.empty[Int, Icon]
@ForgeSubscribe @ForgeSubscribe
def onItemIconRegister(e: TextureStitchEvent.Pre) { def onItemIconRegister(e: TextureStitchEvent.Pre) {
val iconRegister = e.map val iconRegister = e.map
@ -20,8 +22,14 @@ object Icons {
bySlotType += Slot.Memory -> iconRegister.registerIcon(Settings.resourceDomain + ":icon_ram") bySlotType += Slot.Memory -> iconRegister.registerIcon(Settings.resourceDomain + ":icon_ram")
bySlotType += Slot.Tool -> iconRegister.registerIcon(Settings.resourceDomain + ":icon_tool") bySlotType += Slot.Tool -> iconRegister.registerIcon(Settings.resourceDomain + ":icon_tool")
bySlotType += Slot.Upgrade -> iconRegister.registerIcon(Settings.resourceDomain + ":icon_upgrade") bySlotType += Slot.Upgrade -> iconRegister.registerIcon(Settings.resourceDomain + ":icon_upgrade")
byTier += 0 -> iconRegister.registerIcon(Settings.resourceDomain + ":icon_tier0")
byTier += 1 -> iconRegister.registerIcon(Settings.resourceDomain + ":icon_tier1")
byTier += 2 -> iconRegister.registerIcon(Settings.resourceDomain + ":icon_tier2")
} }
} }
def get(slotType: Slot) = bySlotType.get(slotType).orNull def get(slotType: Slot) = bySlotType.get(slotType).orNull
def get(tier: Int) = byTier.get(tier).orNull
} }

View File

@ -17,6 +17,8 @@ import net.minecraft.inventory.Slot
import net.minecraft.util.{StatCollector, ResourceLocation} import net.minecraft.util.{StatCollector, ResourceLocation}
import org.lwjgl.input.Keyboard import org.lwjgl.input.Keyboard
import org.lwjgl.opengl.GL11 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 { class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) extends GuiContainer(new container.Robot(playerInventory, robot)) with Buffer {
xSize = 256 xSize = 256
@ -68,8 +70,16 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten
override def drawSlotInventory(slot: Slot) { override def drawSlotInventory(slot: Slot) {
RenderState.makeItBlend() RenderState.makeItBlend()
GL11.glDepthMask(false)
super.drawSlotInventory(slot) super.drawSlotInventory(slot)
GL11.glDepthMask(true)
GL11.glDisable(GL11.GL_BLEND) GL11.glDisable(GL11.GL_BLEND)
if (!slot.getHasStack) slot match {
case component: ComponentSlot if component.tierIcon != null =>
mc.getTextureManager.bindTexture(TextureMap.locationItemsTexture)
drawTexturedModelRectFromIcon(slot.xDisplayPosition, slot.yDisplayPosition, component.tierIcon, 16, 16)
case _ =>
}
} }
def drawBuffer() { def drawBuffer() {

View File

@ -6,15 +6,15 @@ import net.minecraft.entity.player.{EntityPlayer, InventoryPlayer}
class Case(playerInventory: InventoryPlayer, computer: tileentity.Case) extends Player(playerInventory, computer) { class Case(playerInventory: InventoryPlayer, computer: tileentity.Case) extends Player(playerInventory, computer) {
for (i <- 0 to (if (computer.tier == 2) 2 else 1)) { for (i <- 0 to (if (computer.tier == 2) 2 else 1)) {
addSlotToContainer(98, 16 + i * slotSize, api.driver.Slot.Card) addSlotToContainer(98, 16 + i * slotSize, api.driver.Slot.Card, computer.maxComponentTierForSlot(getInventory.size))
} }
for (i <- 0 to (if (computer.tier == 0) 0 else 1)) { for (i <- 0 to (if (computer.tier == 0) 0 else 1)) {
addSlotToContainer(120, 16 + i * slotSize, api.driver.Slot.Memory) addSlotToContainer(120, 16 + i * slotSize, api.driver.Slot.Memory, computer.maxComponentTierForSlot(getInventory.size))
} }
for (i <- 0 to (if (computer.tier == 0) 0 else 1)) { for (i <- 0 to (if (computer.tier == 0) 0 else 1)) {
addSlotToContainer(142, 16 + i * slotSize, api.driver.Slot.HardDiskDrive) addSlotToContainer(142, 16 + i * slotSize, api.driver.Slot.HardDiskDrive, computer.maxComponentTierForSlot(getInventory.size))
} }
if (computer.tier == 2) { if (computer.tier == 2) {

View File

@ -5,9 +5,11 @@ import li.cil.oc.client.gui.Icons
import net.minecraft.inventory.{IInventory, Slot} import net.minecraft.inventory.{IInventory, Slot}
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
class ComponentSlot(inventory: IInventory, index: Int, x: Int, y: Int, val slot: api.driver.Slot = api.driver.Slot.None) extends Slot(inventory, index, x, y) { class ComponentSlot(inventory: IInventory, index: Int, x: Int, y: Int, val slot: api.driver.Slot = api.driver.Slot.None, val tier: Int = -1) extends Slot(inventory, index, x, y) {
setBackgroundIcon(Icons.get(slot)) setBackgroundIcon(Icons.get(slot))
val tierIcon = Icons.get(tier)
override def getSlotStackLimit = override def getSlotStackLimit =
slot match { slot match {
case api.driver.Slot.Tool | api.driver.Slot.None => super.getSlotStackLimit case api.driver.Slot.Tool | api.driver.Slot.None => super.getSlotStackLimit

View File

@ -97,9 +97,9 @@ abstract class Player(protected val playerInventory: InventoryPlayer, val otherI
} }
} }
def addSlotToContainer(x: Int, y: Int, slot: api.driver.Slot = api.driver.Slot.None) { def addSlotToContainer(x: Int, y: Int, slot: api.driver.Slot = api.driver.Slot.None, tier: Int = -1) {
val index = getInventory.size val index = getInventory.size
addSlotToContainer(new ComponentSlot(otherInventory, index, x, y, slot)) addSlotToContainer(new ComponentSlot(otherInventory, index, x, y, slot, tier))
} }
/** Render player inventory at the specified coordinates. */ /** Render player inventory at the specified coordinates. */

View File

@ -7,7 +7,7 @@ import net.minecraft.entity.player.{EntityPlayer, InventoryPlayer}
class Robot(playerInventory: InventoryPlayer, robot: tileentity.Robot) extends Player(playerInventory, robot) { class Robot(playerInventory: InventoryPlayer, robot: tileentity.Robot) extends Player(playerInventory, robot) {
addSlotToContainer(178 + 0 * slotSize, 218, api.driver.Slot.Tool) addSlotToContainer(178 + 0 * slotSize, 218, api.driver.Slot.Tool)
addSlotToContainer(178 + 1 * slotSize, 218, api.driver.Slot.Card) addSlotToContainer(178 + 1 * slotSize, 218, api.driver.Slot.Card, 1)
addSlotToContainer(178 + 2 * slotSize, 218, api.driver.Slot.Disk) addSlotToContainer(178 + 2 * slotSize, 218, api.driver.Slot.Disk)
addSlotToContainer(178 + 3 * slotSize, 218, api.driver.Slot.Upgrade) addSlotToContainer(178 + 3 * slotSize, 218, api.driver.Slot.Upgrade)

View File

@ -43,26 +43,48 @@ class Case(var tier: Int, isRemote: Boolean) extends Computer(isRemote) {
def isItemValidForSlot(slot: Int, stack: ItemStack) = tier match { def isItemValidForSlot(slot: Int, stack: ItemStack) = tier match {
case 0 => (slot, Registry.itemDriverFor(stack)) match { case 0 => (slot, Registry.itemDriverFor(stack)) match {
case (_, None) => false // Invalid item. case (_, None) => false // Invalid item.
case (0 | 1, Some(driver)) => driver.slot(stack) == Slot.Card case (0 | 1, Some(driver)) => driver.slot(stack) == Slot.Card && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (2, Some(driver)) => driver.slot(stack) == Slot.Memory case (2, Some(driver)) => driver.slot(stack) == Slot.Memory && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (3, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive case (3, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive && driver.tier(stack) <= maxComponentTierForSlot(slot)
case _ => false // Invalid slot. case _ => false // Invalid slot.
} }
case 1 => (slot, Registry.itemDriverFor(stack)) match { case 1 => (slot, Registry.itemDriverFor(stack)) match {
case (_, None) => false // Invalid item. case (_, None) => false // Invalid item.
case (0 | 1, Some(driver)) => driver.slot(stack) == Slot.Card case (0 | 1, Some(driver)) => driver.slot(stack) == Slot.Card && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (2 | 3, Some(driver)) => driver.slot(stack) == Slot.Memory case (2 | 3, Some(driver)) => driver.slot(stack) == Slot.Memory && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (4 | 5, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive case (4 | 5, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive && driver.tier(stack) <= maxComponentTierForSlot(slot)
case _ => false // Invalid slot. case _ => false // Invalid slot.
} }
case 2 => (slot, Registry.itemDriverFor(stack)) match { case 2 => (slot, Registry.itemDriverFor(stack)) match {
case (_, None) => false // Invalid item. case (_, None) => false // Invalid item.
case (0 | 1 | 2, Some(driver)) => driver.slot(stack) == Slot.Card case (0 | 1 | 2, Some(driver)) => driver.slot(stack) == Slot.Card && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (3 | 4, Some(driver)) => driver.slot(stack) == Slot.Memory case (3 | 4, Some(driver)) => driver.slot(stack) == Slot.Memory && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (5 | 6, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive case (5 | 6, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (7, Some(driver)) => driver.slot(stack) == Slot.Disk case (7, Some(driver)) => driver.slot(stack) == Slot.Disk
case _ => false // Invalid slot. case _ => false // Invalid slot.
} }
case _ => false case _ => false
} }
def maxComponentTierForSlot(slot: Int) = tier match {
case 0 => 0
case 1 => slot match {
case 0 => 1
case 1 => 0
case (2 | 3) => 1
case 4 => 1
case 5 => 0
case _ => -1 // Invalid slot.
}
case 2 => slot match {
case 0 => 2
case 1 | 2 => 1
case (3 | 4) => 2
case 5 => 2
case 6 => 1
case 7 => 0
case _ => -1 // Invalid slot.
}
case _ => -1
}
} }

View File

@ -518,7 +518,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
def isItemValidForSlot(slot: Int, stack: ItemStack) = (slot, Registry.itemDriverFor(stack)) match { def isItemValidForSlot(slot: Int, stack: ItemStack) = (slot, Registry.itemDriverFor(stack)) match {
case (0, _) => true // Allow anything in the tool slot. case (0, _) => true // Allow anything in the tool slot.
case (1, Some(driver)) => driver.slot(stack) == Slot.Card case (1, Some(driver)) => driver.slot(stack) == Slot.Card && driver.tier(stack) < 2
case (2, Some(driver)) => driver.slot(stack) == Slot.Disk case (2, Some(driver)) => driver.slot(stack) == Slot.Disk
case (3, Some(driver)) => driver.slot(stack) == Slot.Upgrade case (3, Some(driver)) => driver.slot(stack) == Slot.Upgrade
case (i, _) if actualSlot(0) until getSizeInventory contains i => true // Normal inventory. case (i, _) if actualSlot(0) until getSizeInventory contains i => true // Normal inventory.

View File

@ -43,6 +43,12 @@ object FileSystem extends Item {
case _ => throw new IllegalArgumentException() case _ => throw new IllegalArgumentException()
} }
override def tier(stack: ItemStack) =
Items.multi.subItem(stack) match {
case Some(hdd: HardDiskDrive) => hdd.tier
case _ => 0
}
private def createEnvironment(stack: ItemStack, capacity: Int) = { private def createEnvironment(stack: ItemStack, capacity: Int) = {
// We have a bit of a chicken-egg problem here, because we want to use the // We have a bit of a chicken-egg problem here, because we want to use the
// node's address as the folder name... so we generate the address here, // node's address as the folder name... so we generate the address here,

View File

@ -22,4 +22,10 @@ object GraphicsCard extends Item {
} }
override def slot(stack: ItemStack) = Slot.Card override def slot(stack: ItemStack) = Slot.Card
override def tier(stack: ItemStack) =
Items.multi.subItem(stack) match {
case Some(gpu: common.item.GraphicsCard) => gpu.tier
case _ => 0
}
} }

View File

@ -1,18 +1,21 @@
package li.cil.oc.server.driver.item package li.cil.oc.server.driver.item
import li.cil.oc.api.driver
import li.cil.oc.common import li.cil.oc.common
import li.cil.oc.{Settings, Items, api} import li.cil.oc.{Settings, Items}
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
trait Item extends api.driver.Item { trait Item extends driver.Item {
def tier(stack: ItemStack) = 0
def dataTag(stack: ItemStack) = Item.dataTag(stack) def dataTag(stack: ItemStack) = Item.dataTag(stack)
protected def isOneOf(stack: ItemStack, items: common.item.Delegate*) = protected def isOneOf(stack: ItemStack, items: common.item.Delegate*) =
stack.getItem == Items.multi && (Items.multi.subItem(stack) match { Items.multi.subItem(stack) match {
case None => false case None => false
case Some(subItem) => items.contains(subItem) case Some(subItem) => items.contains(subItem)
}) }
} }
object Item { object Item {

View File

@ -3,18 +3,25 @@ package li.cil.oc.server.driver.item
import li.cil.oc.Items import li.cil.oc.Items
import li.cil.oc.api.driver import li.cil.oc.api.driver
import li.cil.oc.api.driver.Slot import li.cil.oc.api.driver.Slot
import li.cil.oc.common.item
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.tileentity.{TileEntity => MCTileEntity} import net.minecraft.tileentity.{TileEntity => MCTileEntity}
object Memory extends Item with driver.Memory { object Memory extends Item with driver.Memory {
def amount(stack: ItemStack) = if (stack.getItem == Items.multi) Items.multi.subItem(stack) match { def amount(stack: ItemStack) = Items.multi.subItem(stack) match {
case Some(memory: li.cil.oc.common.item.Memory) => memory.kiloBytes * 1024 case Some(memory: item.Memory) => memory.kiloBytes * 1024
case _ => 0 case _ => 0
} else 0 }
def worksWith(stack: ItemStack) = isOneOf(stack, Items.ram3, Items.ram1, Items.ram2) def worksWith(stack: ItemStack) = isOneOf(stack, Items.ram3, Items.ram1, Items.ram2)
def createEnvironment(stack: ItemStack, container: MCTileEntity) = null def createEnvironment(stack: ItemStack, container: MCTileEntity) = null
def slot(stack: ItemStack) = Slot.Memory def slot(stack: ItemStack) = Slot.Memory
override def tier(stack: ItemStack) =
Items.multi.subItem(stack) match {
case Some(memory: item.Memory) => memory.tier
case _ => 0
}
} }

View File

@ -13,4 +13,6 @@ object WirelessNetworkCard extends Item {
if (container != null) new component.WirelessNetworkCard(container) else null if (container != null) new component.WirelessNetworkCard(container) else null
def slot(stack: ItemStack) = Slot.Card def slot(stack: ItemStack) = Slot.Card
override def tier(stack: ItemStack) = 1
} }