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);
/**
* 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
* environment associated with the specified item stack.
@ -91,7 +105,7 @@ public interface Item {
*
* @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
* the default tag <tt>oc:data</tt>.
* the default tag <tt>oc:data</tt>.
*/
NBTTagCompound dataTag(ItemStack stack);
}

View File

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

View File

@ -1,9 +1,11 @@
package li.cil.oc.client.gui
import li.cil.oc.Settings
import li.cil.oc.common.container.ComponentSlot
import li.cil.oc.util.RenderState
import net.minecraft.client.gui.inventory.GuiContainer
import net.minecraft.client.renderer.Tessellator
import net.minecraft.client.renderer.texture.TextureMap
import net.minecraft.inventory.{Container, Slot}
import net.minecraft.util.{StatCollector, ResourceLocation}
import org.lwjgl.opengl.GL11
@ -30,8 +32,16 @@ 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)
drawTexturedModelRectFromIcon(slot.xDisplayPosition, slot.yDisplayPosition, component.tierIcon, 16, 16)
case _ =>
}
}
private def drawSlotBackground(x: Int, y: Int) {

View File

@ -10,6 +10,8 @@ import scala.collection.mutable
object Icons {
private val bySlotType = mutable.Map.empty[Slot, Icon]
private val byTier = mutable.Map.empty[Int, Icon]
@ForgeSubscribe
def onItemIconRegister(e: TextureStitchEvent.Pre) {
val iconRegister = e.map
@ -20,8 +22,14 @@ object Icons {
bySlotType += Slot.Memory -> iconRegister.registerIcon(Settings.resourceDomain + ":icon_ram")
bySlotType += Slot.Tool -> iconRegister.registerIcon(Settings.resourceDomain + ":icon_tool")
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(tier: Int) = byTier.get(tier).orNull
}

View File

@ -17,6 +17,8 @@ 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
@ -68,8 +70,16 @@ 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)
drawTexturedModelRectFromIcon(slot.xDisplayPosition, slot.yDisplayPosition, component.tierIcon, 16, 16)
case _ =>
}
}
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) {
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)) {
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)) {
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) {

View File

@ -5,9 +5,11 @@ import li.cil.oc.client.gui.Icons
import net.minecraft.inventory.{IInventory, Slot}
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))
val tierIcon = Icons.get(tier)
override def getSlotStackLimit =
slot match {
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
addSlotToContainer(new ComponentSlot(otherInventory, index, x, y, slot))
addSlotToContainer(new ComponentSlot(otherInventory, index, x, y, slot, tier))
}
/** 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) {
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 + 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 {
case 0 => (slot, Registry.itemDriverFor(stack)) match {
case (_, None) => false // Invalid item.
case (0 | 1, Some(driver)) => driver.slot(stack) == Slot.Card
case (2, Some(driver)) => driver.slot(stack) == Slot.Memory
case (3, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive
case (0 | 1, Some(driver)) => driver.slot(stack) == Slot.Card && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (2, Some(driver)) => driver.slot(stack) == Slot.Memory && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (3, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive && driver.tier(stack) <= maxComponentTierForSlot(slot)
case _ => false // Invalid slot.
}
case 1 => (slot, Registry.itemDriverFor(stack)) match {
case (_, None) => false // Invalid item.
case (0 | 1, Some(driver)) => driver.slot(stack) == Slot.Card
case (2 | 3, Some(driver)) => driver.slot(stack) == Slot.Memory
case (4 | 5, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive
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 && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (4 | 5, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive && driver.tier(stack) <= maxComponentTierForSlot(slot)
case _ => false // Invalid slot.
}
case 2 => (slot, Registry.itemDriverFor(stack)) match {
case (_, None) => false // Invalid item.
case (0 | 1 | 2, Some(driver)) => driver.slot(stack) == Slot.Card
case (3 | 4, Some(driver)) => driver.slot(stack) == Slot.Memory
case (5 | 6, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive
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 && driver.tier(stack) <= maxComponentTierForSlot(slot)
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 _ => false // Invalid slot.
}
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 {
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 (3, Some(driver)) => driver.slot(stack) == Slot.Upgrade
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()
}
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) = {
// 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,

View File

@ -22,4 +22,10 @@ object GraphicsCard extends Item {
}
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
import li.cil.oc.api.driver
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.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)
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 Some(subItem) => items.contains(subItem)
})
}
}
object Item {

View File

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