Progress bar for robot assembly, blocking slot in assembler while assembling.

Some checks for robot inventory slots in GUI if there are fewer than 16 inventory slots.
Not showing item costs prompt for uncraftable items and blocks.
Some tier icon related rendering fixes.
Fixed analyzer costs not showing in tooltip.
This commit is contained in:
Florian Nücke 2014-05-15 23:46:15 +02:00
parent 43566955a2
commit 48b50c9d27
26 changed files with 245 additions and 45 deletions

View File

@ -23,4 +23,15 @@ public interface UpgradeContainer extends Item {
* @return the slot type provided by that dynamic slot upgrade.
*/
Slot providedSlot(ItemStack stack);
/**
* The maximum item tier of the items that can be placed into the slot
* provided by the specified container.
* <p/>
* This will usually be equal to the container's tier.
*
* @param stack the item stack to the the supported tier for.
* @return the maximum tier supported by that dynamic slot upgrade.
*/
int providedTier(ItemStack stack);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 742 B

After

Width:  |  Height:  |  Size: 651 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -38,6 +38,7 @@ class PacketHandler extends CommonPacketHandler {
case PacketType.RedstoneState => onRedstoneState(p)
case PacketType.RobotAnimateSwing => onRobotAnimateSwing(p)
case PacketType.RobotAnimateTurn => onRobotAnimateTurn(p)
case PacketType.RobotAssemblingState => onRobotAssemblingState(p)
case PacketType.RobotEquippedItemChange => onRobotEquippedItemChange(p)
case PacketType.RobotEquippedUpgradeChange => onRobotEquippedUpgradeChange(p)
case PacketType.RobotMove => onRobotMove(p)
@ -197,6 +198,14 @@ class PacketHandler extends CommonPacketHandler {
case _ => // Invalid packet.
}
def onRobotAssemblingState(p: PacketParser) =
p.readTileEntity[RobotAssembler]() match {
case Some(t) =>
if (p.readBoolean()) t.requiredEnergy = 9001
else t.requiredEnergy = 0
case _ => // Invalid packet.
}
def onRobotEquippedItemChange(p: PacketParser) =
p.readTileEntity[RobotProxy]() match {
case Some(t) => t.robot.equippedItem = Option(p.readItemStack())

View File

@ -13,6 +13,7 @@ object Textures extends ResourceManagerReloadListener {
val guiButtonPower = new ResourceLocation(Settings.resourceDomain, "textures/gui/button_power.png")
val guiButtonRange = new ResourceLocation(Settings.resourceDomain, "textures/gui/button_range.png")
val guiButtonRun = new ResourceLocation(Settings.resourceDomain, "textures/gui/button_run.png")
val guiButtonScroll = new ResourceLocation(Settings.resourceDomain, "textures/gui/button_scroll.png")
val guiButtonSide = new ResourceLocation(Settings.resourceDomain, "textures/gui/button_side.png")
val guiComputer = new ResourceLocation(Settings.resourceDomain, "textures/gui/computer.png")
val guiRange = new ResourceLocation(Settings.resourceDomain, "textures/gui/range.png")

View File

@ -39,7 +39,9 @@ abstract class DynamicGuiContainer(container: Container) extends GuiContainer(co
case component: ComponentSlot if component.tierIcon != null =>
mc.getTextureManager.bindTexture(TextureMap.locationItemsTexture)
GL11.glDisable(GL11.GL_DEPTH_TEST)
GL11.glDisable(GL11.GL_LIGHTING)
drawTexturedModelRectFromIcon(slot.xDisplayPosition, slot.yDisplayPosition, component.tierIcon, 16, 16)
GL11.glEnable(GL11.GL_LIGHTING)
GL11.glEnable(GL11.GL_DEPTH_TEST)
case _ =>
}

View File

@ -27,12 +27,17 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten
protected var powerButton: ImageButton = _
protected var scrollButton: ImageButton = _
protected def buffer = {
robot.components.collect {
case Some(component: api.component.TextBuffer) => component
}.headOption.orNull
}
// Scroll offset for robot inventory.
private var inventoryOffset = 0
private val bufferWidth = 242.0
private val bufferHeight = 128.0
private val bufferMargin = BufferRenderer.innerMargin
@ -60,13 +65,16 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten
override def drawScreen(mouseX: Int, mouseY: Int, dt: Float) {
powerButton.toggled = robot.isRunning
scrollButton.enabled = robot.inventorySize > 16
super.drawScreen(mouseX, mouseY, dt)
}
override def initGui() {
super.initGui()
powerButton = new ImageButton(0, guiLeft + 5, guiTop + 139, 18, 18, Textures.guiButtonPower, canToggle = true)
scrollButton = new ImageButton(1, guiLeft + 244, guiTop + 142, 6, 13, Textures.guiButtonScroll)
add(buttonList, powerButton)
add(buttonList, scrollButton)
}
override def drawSlotInventory(slot: Slot) {
@ -77,7 +85,9 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten
case component: StaticComponentSlot if component.tierIcon != null =>
mc.getTextureManager.bindTexture(TextureMap.locationItemsTexture)
GL11.glDisable(GL11.GL_DEPTH_TEST)
GL11.glDisable(GL11.GL_LIGHTING)
drawTexturedModelRectFromIcon(slot.xDisplayPosition, slot.yDisplayPosition, component.tierIcon, 16, 16)
GL11.glEnable(GL11.GL_LIGHTING)
GL11.glEnable(GL11.GL_DEPTH_TEST)
case _ =>
}
@ -129,7 +139,9 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten
mc.renderEngine.bindTexture(Textures.guiRobot)
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize)
drawPowerLevel()
drawSelection()
if (robot.inventorySize > 0) {
drawSelection()
}
}
protected override def keyTyped(char: Char, code: Int) {

View File

@ -10,23 +10,32 @@ import net.minecraft.client.gui.GuiButton
import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.util.StatCollector
import org.lwjgl.opengl.GL11
import net.minecraft.client.renderer.Tessellator
class RobotAssembler(playerInventory: InventoryPlayer, val assembler: tileentity.RobotAssembler) extends DynamicGuiContainer(new container.RobotAssembler(playerInventory, assembler)) {
xSize = 176
ySize = 192
private def assemblerContainer = inventorySlots.asInstanceOf[container.RobotAssembler]
protected var runButton: ImageButton = _
private val progressX = 28
private val progressY = 92
private val progressWidth = 140
private val progressHeight = 12
def add[T](list: util.List[T], value: Any) = list.add(value.asInstanceOf[T])
protected override def actionPerformed(button: GuiButton) {
if (button.id == 0 && !assembler.isAssembling && assembler.complexity <= assembler.maxComplexity) {
if (button.id == 0 && !assemblerContainer.isAssembling && assembler.complexity <= assembler.maxComplexity) {
ClientPacketSender.sendRobotAssemblerStart(assembler)
}
}
override def drawScreen(mouseX: Int, mouseY: Int, dt: Float) {
runButton.enabled = assembler.complexity <= assembler.maxComplexity && !assembler.isAssembling
runButton.enabled = assembler.complexity <= assembler.maxComplexity && !assemblerContainer.isAssembling && assembler.isItemValidForSlot(0, assembler.getStackInSlot(0))
runButton.toggled = !runButton.enabled
super.drawScreen(mouseX, mouseY, dt)
}
@ -39,7 +48,7 @@ class RobotAssembler(playerInventory: InventoryPlayer, val assembler: tileentity
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
GL11.glPushAttrib(0xFFFFFFFF) // Me lazy... prevents NEI render glitch.
if (!assembler.isAssembling) {
if (!assemblerContainer.isAssembling) {
if (!inventorySlots.getSlot(0).getHasStack) {
val message =
if (api.Items.get(inventorySlots.getSlot(0).getStack) == api.Items.get("robot"))
@ -56,7 +65,7 @@ class RobotAssembler(playerInventory: InventoryPlayer, val assembler: tileentity
30, 94, if (assembler.complexity <= assembler.maxComplexity) 0x404040 else 0x804040)
}
}
if (runButton.func_82252_a && !assembler.isAssembling) {
if (runButton.func_82252_a && !assemblerContainer.isAssembling) {
val tooltip = new java.util.ArrayList[String]
tooltip.add(StatCollector.translateToLocal(Settings.namespace + "gui.RobotAssembler.Run"))
drawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer)
@ -69,7 +78,30 @@ class RobotAssembler(playerInventory: InventoryPlayer, val assembler: tileentity
super.drawGuiContainerBackgroundLayer(dt, mouseX, mouseY)
mc.renderEngine.bindTexture(Textures.guiRobotAssembler)
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize)
if (assemblerContainer.isAssembling) {
drawProgress()
}
}
override def doesGuiPauseGame = false
private def drawProgress() {
val level = assemblerContainer.assemblyProgress / 100.0
val u0 = 0
val u1 = progressWidth / 256.0 * level
val v0 = 1 - progressHeight / 256.0
val v1 = 1
val x = guiLeft + progressX
val y = guiTop + progressY
val w = progressWidth * level
val t = Tessellator.instance
t.startDrawingQuads()
t.addVertexWithUV(x, y, zLevel, u0, v0)
t.addVertexWithUV(x, y + progressHeight, zLevel, u0, v1)
t.addVertexWithUV(x + w, y + progressHeight, zLevel, u1, v1)
t.addVertexWithUV(x + w, y, zLevel, u1, v0)
t.draw()
}
}

View File

@ -69,7 +69,7 @@ object InventorySlots {
InventorySlot(Slot.Processor, Tier.One),
InventorySlot(Slot.Memory, Tier.One),
InventorySlot(Slot.Memory, Tier.One),
InventorySlot(Slot.Disk, Tier.One),
InventorySlot(Slot.Disk, Tier.Any),
InventorySlot(Slot.HardDiskDrive, Tier.One),
InventorySlot(Slot.None, Tier.None)
),
@ -94,7 +94,7 @@ object InventorySlots {
InventorySlot(Slot.Processor, Tier.Two),
InventorySlot(Slot.Memory, Tier.Two),
InventorySlot(Slot.Memory, Tier.Two),
InventorySlot(Slot.Disk, Tier.One),
InventorySlot(Slot.Disk, Tier.Any),
InventorySlot(Slot.HardDiskDrive, Tier.Two),
InventorySlot(Slot.None, Tier.None)
),
@ -119,7 +119,7 @@ object InventorySlots {
InventorySlot(Slot.Processor, Tier.Three),
InventorySlot(Slot.Memory, Tier.Three),
InventorySlot(Slot.Memory, Tier.Three),
InventorySlot(Slot.Disk, Tier.One),
InventorySlot(Slot.Disk, Tier.Any),
InventorySlot(Slot.HardDiskDrive, Tier.Three),
InventorySlot(Slot.HardDiskDrive, Tier.Two)
)

View File

@ -18,6 +18,7 @@ object PacketType extends Enumeration {
RedstoneState,
RobotAnimateSwing,
RobotAnimateTurn,
RobotAssemblingState,
RobotEquippedItemChange,
RobotEquippedUpgradeChange,
RobotMove,

View File

@ -330,13 +330,15 @@ class Delegator[Child <: Delegate](id: Int) extends Block(id, Material.iron) {
case Some(subBlock) => subBlock.tooltipLines(stack, player, tooltip, advanced)
case _ =>
}
if (KeyBindings.showMaterialCosts) {
ItemCosts.addTooltip(stack, tooltip.asInstanceOf[util.List[String]])
}
else {
tooltip.add(StatCollector.translateToLocalFormatted(
Settings.namespace + "tooltip.MaterialCosts",
input.Keyboard.getKeyName(KeyBindings.materialCosts.keyCode)))
if (ItemCosts.hasCosts(stack)) {
if (KeyBindings.showMaterialCosts) {
ItemCosts.addTooltip(stack, tooltip.asInstanceOf[util.List[String]])
}
else {
tooltip.add(StatCollector.translateToLocalFormatted(
Settings.namespace + "tooltip.MaterialCosts",
input.Keyboard.getKeyName(KeyBindings.materialCosts.keyCode)))
}
}
}

View File

@ -16,6 +16,7 @@ import net.minecraft.item.{EnumRarity, ItemStack}
import net.minecraft.util.{Icon, MovingObjectPosition, AxisAlignedBB, Vec3}
import net.minecraft.world.{IBlockAccess, World}
import net.minecraftforge.common.ForgeDirection
import li.cil.oc.client.KeyBindings
class RobotProxy(val parent: SpecialDelegator) extends RedstoneAware with SpecialDelegate {
val unlocalizedName = "Robot"
@ -33,9 +34,11 @@ class RobotProxy(val parent: SpecialDelegator) extends RedstoneAware with Specia
override def tooltipLines(stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) {
addLines(stack, tooltip)
tooltip.addAll(Tooltip.get(unlocalizedName))
val info = new ItemUtils.RobotData(stack)
for (component <- info.containers ++ info.components) {
tooltip.add(component.getDisplayName)
if (KeyBindings.showExtendedTooltips) {
val info = new ItemUtils.RobotData(stack)
for (component <- info.containers ++ info.components) {
tooltip.add("- " + component.getDisplayName)
}
}
}

View File

@ -21,7 +21,7 @@ trait ComponentSlot extends Slot {
@SideOnly(Side.CLIENT)
override def func_111238_b() = tier != Tier.None && super.func_111238_b()
override def isItemValid(stack: ItemStack) = inventory.isItemValidForSlot(slotNumber, stack)
override def isItemValid(stack: ItemStack) = inventory.isItemValidForSlot(getSlotIndex, stack)
override def onPickupFromSlot(player: EntityPlayer, stack: ItemStack) {
super.onPickupFromSlot(player, stack)

View File

@ -9,7 +9,7 @@ import net.minecraft.inventory.{Slot, IInventory}
class DynamicComponentSlot(val container: Player, inventory: IInventory, index: Int, x: Int, y: Int, val info: Array[Array[InventorySlot]], val tierGetter: () => Int) extends Slot(inventory, index, x, y) with ComponentSlot {
override def tier = {
val mainTier = tierGetter()
if (mainTier >= 0) info(mainTier)(slotNumber).tier
if (mainTier >= 0) info(mainTier)(getSlotIndex).tier
else mainTier
}
@ -17,7 +17,7 @@ class DynamicComponentSlot(val container: Player, inventory: IInventory, index:
def slot = {
val mainTier = tierGetter()
if (mainTier >= 0) info(tierGetter())(slotNumber).slot
if (mainTier >= 0) info(tierGetter())(getSlotIndex).slot
else api.driver.Slot.None
}

View File

@ -1,12 +1,13 @@
package li.cil.oc.common.container
import cpw.mods.fml.common.FMLCommonHandler
import cpw.mods.fml.relauncher.{SideOnly, Side}
import li.cil.oc.api
import li.cil.oc.client.gui.Icons
import li.cil.oc.common.tileentity
import li.cil.oc.common.InventorySlots.Tier
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import net.minecraft.entity.player.{EntityPlayer, InventoryPlayer}
import li.cil.oc.common.InventorySlots.Tier
import li.cil.oc.client.gui.Icons
class Robot(playerInventory: InventoryPlayer, robot: tileentity.Robot) extends Player(playerInventory, robot) {
addSlotToContainer(170 + 0 * slotSize, 218, api.driver.Slot.Tool)
@ -20,9 +21,19 @@ class Robot(playerInventory: InventoryPlayer, robot: tileentity.Robot) extends P
val x = 170 + j * slotSize
val index = inventorySlots.size
addSlotToContainer(new StaticComponentSlot(this, otherInventory, index, x, y, api.driver.Slot.None, Tier.Any) {
def isValid = robot.isInventorySlot(getSlotIndex)
@SideOnly(Side.CLIENT)
override def func_111238_b() = isValid && super.func_111238_b()
override def getBackgroundIconIndex = {
if (!robot.isInventorySlot(this.slotNumber)) Icons.get(Tier.None)
super.getBackgroundIconIndex
if (isValid) super.getBackgroundIconIndex
else Icons.get(Tier.None)
}
override def getStack = {
if (isValid) super.getStack
else null
}
})
}

View File

@ -1,13 +1,27 @@
package li.cil.oc.common.container
import cpw.mods.fml.relauncher.{SideOnly, Side}
import cpw.mods.fml.common.FMLCommonHandler
import li.cil.oc.common.{InventorySlots, tileentity}
import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.inventory.Slot
import li.cil.oc.util.ItemUtils
import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.inventory.{ICrafting, Slot}
import scala.collection.convert.WrapAsScala._
import li.cil.oc.api
import li.cil.oc.common.InventorySlots.Tier
import li.cil.oc.client.gui.Icons
class RobotAssembler(playerInventory: InventoryPlayer, assembler: tileentity.RobotAssembler) extends Player(playerInventory, assembler) {
// Computer case.
addSlotToContainer(12, 12)
{
val index = inventorySlots.size
addSlotToContainer(new StaticComponentSlot(this, otherInventory, index, 12, 12, api.driver.Slot.None, Tier.Any) {
@SideOnly(Side.CLIENT) override
def func_111238_b() = !isAssembling && super.func_111238_b()
override def getBackgroundIconIndex = if (isAssembling) Icons.get(Tier.None) else super.getBackgroundIconIndex
})
}
def caseTier = ItemUtils.caseTier(inventorySlots.get(0).asInstanceOf[Slot].getStack)
@ -41,4 +55,40 @@ class RobotAssembler(playerInventory: InventoryPlayer, assembler: tileentity.Rob
// Show the player's inventory.
addPlayerInventorySlots(8, 110)
var isAssembling = false
var assemblyProgress = 0
@SideOnly(Side.CLIENT)
override def updateProgressBar(id: Int, value: Int) {
super.updateProgressBar(id, value)
if (id == 0) {
isAssembling = value == 1
}
if (id == 1) {
assemblyProgress = value
}
}
override def detectAndSendChanges() {
super.detectAndSendChanges()
if (FMLCommonHandler.instance.getEffectiveSide.isServer) {
if (isAssembling != assembler.isAssembling) {
isAssembling = assembler.isAssembling
sendProgressBarUpdate(0, if (isAssembling) 1 else 0)
}
if (assemblyProgress != assembler.progress) {
assemblyProgress = assembler.progress
sendProgressBarUpdate(1, assemblyProgress)
}
}
}
private def sendProgressBarUpdate(id: Int, value: Int) {
for (entry <- crafters) entry match {
case player: ICrafting => player.sendProgressBarUpdate(this, id, value)
case _ =>
}
}
}

View File

@ -17,6 +17,7 @@ class Analyzer(val parent: Delegator) extends Delegate {
override def tooltipLines(stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) {
tooltip.addAll(Tooltip.get(unlocalizedName))
super.tooltipLines(stack, player, tooltip, advanced)
}
override def onItemUse(stack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float) = {

View File

@ -51,13 +51,15 @@ trait Delegate {
@SideOnly(Side.CLIENT)
def tooltipLines(stack: ItemStack, player: EntityPlayer, tooltip: java.util.List[String], advanced: Boolean) {
if (KeyBindings.showMaterialCosts) {
ItemCosts.addTooltip(stack, tooltip.asInstanceOf[util.List[String]])
}
else {
tooltip.add(StatCollector.translateToLocalFormatted(
Settings.namespace + "tooltip.MaterialCosts",
input.Keyboard.getKeyName(KeyBindings.materialCosts.keyCode)))
if (ItemCosts.hasCosts(stack)) {
if (KeyBindings.showMaterialCosts) {
ItemCosts.addTooltip(stack, tooltip.asInstanceOf[util.List[String]])
}
else {
tooltip.add(StatCollector.translateToLocalFormatted(
Settings.namespace + "tooltip.MaterialCosts",
input.Keyboard.getKeyName(KeyBindings.materialCosts.keyCode)))
}
}
if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "data")) {
val data = stack.getTagCompound.getCompoundTag(Settings.namespace + "data")

View File

@ -50,6 +50,8 @@ class Robot(val isRemote: Boolean) extends traits.Computer with traits.PowerInfo
var selectedSlot = actualSlot(0)
// Fixed number of containers (mostly due to GUI limitation, but also because
// I find three to be a large enough number for sufficient flexibility).
override def containerCount = 3
override def componentCount = info.components.length
@ -303,7 +305,9 @@ class Robot(val isRemote: Boolean) extends traits.Computer with traits.PowerInfo
if (nbt.hasKey(Settings.namespace + "owner")) {
owner = nbt.getString(Settings.namespace + "owner")
}
selectedSlot = nbt.getInteger(Settings.namespace + "selectedSlot") max inventorySlots.min min inventorySlots.max
if (inventorySize > 0) {
selectedSlot = nbt.getInteger(Settings.namespace + "selectedSlot") max inventorySlots.min min inventorySlots.max
}
animationTicksTotal = nbt.getInteger(Settings.namespace + "animationTicksTotal")
animationTicksLeft = nbt.getInteger(Settings.namespace + "animationTicksLeft")
if (animationTicksLeft > 0) {
@ -509,7 +513,7 @@ class Robot(val isRemote: Boolean) extends traits.Computer with traits.PowerInfo
def containerSlotTier(slot: Int) = if (containerSlots contains slot) {
val stack = info.containers(slot - 1)
Option(Driver.driverFor(stack)) match {
case Some(driver: api.driver.UpgradeContainer) => driver.tier(stack)
case Some(driver: api.driver.UpgradeContainer) => driver.providedTier(stack)
case _ => Tier.None
}
}
@ -517,7 +521,7 @@ class Robot(val isRemote: Boolean) extends traits.Computer with traits.PowerInfo
def isToolSlot(slot: Int) = slot == 0
def isInventorySlot(slot: Int) = !isToolSlot(slot) && !isComponentSlot(slot)
def isInventorySlot(slot: Int) = slot >= 0 && slot < getSizeInventory && !isToolSlot(slot) && !isComponentSlot(slot)
def isFloppySlot(slot: Int) = isComponentSlot(slot) && (Option(getStackInSlot(slot)) match {
case Some(stack) => Option(Driver.driverFor(stack)) match {
@ -572,7 +576,7 @@ class Robot(val isRemote: Boolean) extends traits.Computer with traits.PowerInfo
}
Array.copy(components, getSizeInventory - componentCount, components, realSize, componentCount)
getSizeInventory = realSize + componentCount
if (world != null) {
if (world != null && isServer) {
val p = player()
for (stack <- removed) {
p.inventory.addItemStackToInventory(stack)

View File

@ -1,13 +1,17 @@
package li.cil.oc.common.tileentity
import li.cil.oc.api.network.Visibility
import li.cil.oc.{Settings, api}
import net.minecraft.item.ItemStack
import li.cil.oc.api.Driver
import li.cil.oc.common.InventorySlots.Tier
import li.cil.oc.common.InventorySlots
import li.cil.oc.util.ItemUtils
import li.cil.oc.api.driver.{Slot, UpgradeContainer}
import li.cil.oc.api.network.Visibility
import li.cil.oc.common.InventorySlots
import li.cil.oc.common.InventorySlots.Tier
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ItemUtils
import li.cil.oc.util.ExtendedNBT._
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import cpw.mods.fml.relauncher.{Side, SideOnly}
class RobotAssembler extends traits.Environment with traits.Inventory with traits.Rotatable {
val node = api.Network.newNode(this, Visibility.None).
@ -16,8 +20,12 @@ class RobotAssembler extends traits.Environment with traits.Inventory with trait
def isAssembling = requiredEnergy > 0
def progress = ((1 - requiredEnergy / totalRequiredEnergy) * 100).toInt
var robot: Option[ItemStack] = None
var totalRequiredEnergy = 0.0
var requiredEnergy = 0.0
def complexity = items.drop(1).foldLeft(0)((acc, stack) => acc + (Option(api.Driver.driverFor(stack.orNull)) match {
@ -35,6 +43,7 @@ class RobotAssembler extends traits.Environment with traits.Inventory with trait
if (!isAssembling && robot.isEmpty && complexity <= maxComplexity) {
// TODO validate all slots, just in case. never trust a client. never trust minecraft.
val data = new ItemUtils.RobotData()
data.name = ItemUtils.RobotData.randomName
data.energy = 50000
data.containers = items.take(4).drop(1).collect {
case Some(item) => item
@ -45,7 +54,9 @@ class RobotAssembler extends traits.Environment with traits.Inventory with trait
val stack = api.Items.get("robot").createItemStack(1)
data.save(stack)
robot = Some(stack)
requiredEnergy = Settings.get.robotBaseCost + complexity * Settings.get.robotComplexityCost
totalRequiredEnergy = math.max(1, Settings.get.robotBaseCost + complexity * Settings.get.robotComplexityCost)
requiredEnergy = totalRequiredEnergy
ServerPacketSender.sendRobotAssembling(this, assembling = true)
for (slot <- 0 until getSizeInventory) items(slot) = None
onInventoryChanged()
@ -64,10 +75,38 @@ class RobotAssembler extends traits.Environment with traits.Inventory with trait
setInventorySlotContents(0, robot.get)
robot = None
requiredEnergy = 0
ServerPacketSender.sendRobotAssembling(this, assembling = false)
}
}
}
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
if (nbt.hasKey(Settings.namespace + "robot")) {
robot = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "robot")))
}
totalRequiredEnergy = nbt.getDouble(Settings.namespace + "total")
requiredEnergy = nbt.getDouble(Settings.namespace + "remaining")
}
override def writeToNBT(nbt: NBTTagCompound) {
super.writeToNBT(nbt)
robot.foreach(stack => nbt.setNewCompoundTag(Settings.namespace + "robot", stack.writeToNBT))
nbt.setDouble(Settings.namespace + "total", totalRequiredEnergy)
nbt.setDouble(Settings.namespace + "remaining", requiredEnergy)
}
@SideOnly(Side.CLIENT) override
def readFromNBTForClient(nbt: NBTTagCompound) {
super.readFromNBTForClient(nbt)
requiredEnergy = nbt.getDouble("remaining")
}
override def writeToNBTForClient(nbt: NBTTagCompound) {
super.writeToNBTForClient(nbt)
nbt.setDouble("remaining", requiredEnergy)
}
// ----------------------------------------------------------------------- //
override def getInvName = Settings.namespace + "container.RobotAssembler"

View File

@ -142,6 +142,15 @@ object PacketSender {
pb.sendToNearbyPlayers(t)
}
def sendRobotAssembling(t: tileentity.RobotAssembler, assembling: Boolean) {
val pb = new PacketBuilder(PacketType.RobotAssemblingState)
pb.writeTileEntity(t)
pb.writeBoolean(assembling)
pb.sendToNearbyPlayers(t)
}
def sendRobotMove(t: tileentity.Robot, ox: Int, oy: Int, oz: Int, direction: ForgeDirection) {
val pb = new PacketBuilder(PacketType.RobotMove)

View File

@ -15,6 +15,8 @@ object UpgradeContainerCard extends Item with UpgradeContainer {
override def providedSlot(stack: ItemStack) = Slot.Card
override def providedTier(stack: ItemStack) = tier(stack)
override def tier(stack: ItemStack) =
Items.multi.subItem(stack) match {
case Some(container: item.UpgradeContainerCard) => container.tier

View File

@ -13,4 +13,6 @@ object UpgradeContainerFloppy extends Item with UpgradeContainer {
override def slot(stack: ItemStack) = Slot.UpgradeContainer
override def providedSlot(stack: ItemStack) = Slot.Disk
override def providedTier(stack: ItemStack) = -1 // Any
}

View File

@ -15,6 +15,8 @@ object UpgradeContainerUpgrade extends Item with UpgradeContainer {
override def providedSlot(stack: ItemStack) = Slot.Upgrade
override def providedTier(stack: ItemStack) = tier(stack)
override def tier(stack: ItemStack) =
Items.multi.subItem(stack) match {
case Some(container: item.UpgradeContainerUpgrade) => container.tier

View File

@ -46,6 +46,11 @@ object ItemCosts {
terminate(Item.slimeBall)
terminate(Item.stick)
def hasCosts(stack: ItemStack) = {
val ingredients = computeIngredients(stack)
ingredients.size > 0 && (ingredients.size > 1 || !ItemStack.areItemStacksEqual(ingredients.head._1, stack))
}
def addTooltip(stack: ItemStack, tooltip: util.List[String]) {
tooltip.add(StatCollector.translateToLocal(Settings.namespace + "tooltip.Materials"))
for ((ingredient, count) <- computeIngredients(stack)) {