mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-17 11:15:12 -04:00
Merge branch 'master' of github.com:MightyPirates/OpenComputers into master-MC1.7.10
Conflicts: src/main/scala/li/cil/oc/OpenComputers.scala src/main/scala/li/cil/oc/client/gui/RobotAssembler.scala src/main/scala/li/cil/oc/common/tileentity/RobotAssembler.scala
This commit is contained in:
commit
9a8109b3f3
@ -24,7 +24,7 @@ oc:tile.PowerDistributor.name=Stromverteiler
|
||||
oc:tile.Redstone.name=Redstone-I/O
|
||||
oc:tile.Robot.name=Roboter
|
||||
oc:tile.RobotAfterimage.name=Roboter
|
||||
oc:tile.RobotAssembler.name=Roboter-Werkbank
|
||||
oc:tile.RobotAssembler.name=Elektronik-Werkbank
|
||||
oc:tile.Screen0.name=Bildschirm (Stufe 1)
|
||||
oc:tile.Screen1.name=Bildschirm (Stufe 2)
|
||||
oc:tile.Screen2.name=Bildschirm (Stufe 3)
|
||||
@ -132,9 +132,9 @@ oc:gui.Error.OutOfMemory=Nicht genug Arbeitsspeicher.
|
||||
oc:gui.Robot.Power=Energie
|
||||
oc:gui.Robot.TurnOff=Ausschalten
|
||||
oc:gui.Robot.TurnOn=Einschalten
|
||||
oc:gui.RobotAssembler.CollectRobot=Roboter entnehmen
|
||||
oc:gui.RobotAssembler.CollectRobot=Ergebnis entnehmen
|
||||
oc:gui.RobotAssembler.Complexity=Komplexität: %s/%s
|
||||
oc:gui.RobotAssembler.InsertCase=Computergehäuse einlegen
|
||||
oc:gui.RobotAssembler.InsertCase=Grundbaustein einlegen
|
||||
oc:gui.RobotAssembler.InsertCPU=CPU benötigt
|
||||
oc:gui.RobotAssembler.InsertRAM=RAM benötigt
|
||||
oc:gui.RobotAssembler.Progress=Fortschritt: %s%% (%s)
|
||||
@ -232,7 +232,7 @@ oc:tooltip.Robot=Im Gegensatz zu normalen Computern können sich Roboter in der
|
||||
# The underscore makes sure this isn't hidden with the rest of the tooltip.
|
||||
oc:tooltip.Robot_Level=§fStufe§7: §a%s§7.
|
||||
oc:tooltip.Robot_StoredEnergy=§fGespeicherte Energie§7: §a%s§7.
|
||||
oc:tooltip.RobotAssembler=Erlaubt die Fertigung von Robotern aus diversen anderen Computerteilen.
|
||||
oc:tooltip.RobotAssembler=Erlaubt die Fertigung von Robotern und weiteren Geräten aus diversen anderen Computerteilen.
|
||||
oc:tooltip.Screen=Zeigt Text an, gesteuert von Grafikkarten in Computern.[nl] Höchstauflösung: §f%sx%s§7.[nl] Maximale Farbtiefe: §f%s§7.
|
||||
oc:tooltip.Server=Ein Server kann wie ein gewöhnliches Computergehäuse mit Komponenten verbessert werden. Um den Server zu starten, muss er in einem Servergehäuse installiert werden.[nl] Anzahl unterstützter Fernbedienungen: §f%s§7.
|
||||
oc:tooltip.Server.Components=Installierte Komponenten:
|
||||
|
@ -24,7 +24,7 @@ oc:tile.PowerDistributor.name=Power Distributor
|
||||
oc:tile.Redstone.name=Redstone I/O
|
||||
oc:tile.Robot.name=Robot
|
||||
oc:tile.RobotAfterimage.name=Robot
|
||||
oc:tile.RobotAssembler.name=Robot Assembler
|
||||
oc:tile.RobotAssembler.name=Electronics Assembler
|
||||
oc:tile.Screen0.name=Screen (Tier 1)
|
||||
oc:tile.Screen1.name=Screen (Tier 2)
|
||||
oc:tile.Screen2.name=Screen (Tier 3)
|
||||
@ -133,9 +133,9 @@ oc:gui.Error.OutOfMemory=Out of memory.
|
||||
oc:gui.Robot.Power=Energy
|
||||
oc:gui.Robot.TurnOff=Turn off
|
||||
oc:gui.Robot.TurnOn=Turn on
|
||||
oc:gui.RobotAssembler.CollectRobot=Collect robot
|
||||
oc:gui.RobotAssembler.CollectRobot=Collect output
|
||||
oc:gui.RobotAssembler.Complexity=Complexity: %s/%s
|
||||
oc:gui.RobotAssembler.InsertCase=Insert a Computer Case
|
||||
oc:gui.RobotAssembler.InsertCase=Insert a base part
|
||||
oc:gui.RobotAssembler.InsertCPU=Insert a CPU
|
||||
oc:gui.RobotAssembler.InsertRAM=Insert some RAM
|
||||
oc:gui.RobotAssembler.Progress=Progress: %s%% (%s)
|
||||
@ -233,7 +233,7 @@ oc:tooltip.Robot=Unlike computers, robots can move around and interact with the
|
||||
# The underscore makes sure this isn't hidden with the rest of the tooltip.
|
||||
oc:tooltip.Robot_Level=§fLevel§7: §a%s§7.
|
||||
oc:tooltip.Robot_StoredEnergy=§fStored energy§7: §a%s§7.
|
||||
oc:tooltip.RobotAssembler=Allows constructing robots from a number of different computer parts.
|
||||
oc:tooltip.RobotAssembler=Allows constructing robots and other devices from a number of different computer parts.
|
||||
oc:tooltip.Screen=Display text, controlled by a Graphics Card in a Case.[nl] Maximum resolution: §f%sx%s§7.[nl] Maximum color depth: §f%s§7.
|
||||
oc:tooltip.Server=This is a server, there are many like it, but this one can be upgraded with components much like a computer case can be. It can be run by inserting it into a server rack.[nl] Number of supported terminals: §f%s§7.
|
||||
oc:tooltip.Server.Components=Installed components:
|
||||
|
@ -62,24 +62,28 @@ object Localization {
|
||||
def Power = localizeImmediately("gui.Robot.Power")
|
||||
}
|
||||
|
||||
object RobotAssembler {
|
||||
def InsertCase = localizeImmediately("gui.RobotAssembler.InsertCase")
|
||||
object Assembler {
|
||||
def InsertTemplate = localizeImmediately("gui.RobotAssembler.InsertCase")
|
||||
|
||||
def InsertCPU = localizeImmediately("gui.RobotAssembler.InsertCPU")
|
||||
def CollectResult = localizeImmediately("gui.RobotAssembler.CollectRobot")
|
||||
|
||||
def InsertRAM = localizeImmediately("gui.RobotAssembler.InsertRAM")
|
||||
def InsertCPU = localizeLater("gui.RobotAssembler.InsertCPU")
|
||||
|
||||
def Complexity(complexity: Int, maxComplexity: Int) = localizeImmediately("gui.RobotAssembler.Complexity", complexity.toString, maxComplexity.toString)
|
||||
def InsertRAM = localizeLater("gui.RobotAssembler.InsertRAM")
|
||||
|
||||
def Complexity(complexity: Int, maxComplexity: Int) = {
|
||||
val message = localizeLater("gui.RobotAssembler.Complexity", complexity.toString, maxComplexity.toString)
|
||||
if (complexity > maxComplexity) new ChatComponentText("§4").appendSibling(message)
|
||||
else message
|
||||
}
|
||||
|
||||
def Run = localizeImmediately("gui.RobotAssembler.Run")
|
||||
|
||||
def CollectRobot = localizeImmediately("gui.RobotAssembler.CollectRobot")
|
||||
|
||||
def Progress(progress: Double, timeRemaining: String) = localizeImmediately("gui.RobotAssembler.Progress", progress.toInt.toString, timeRemaining)
|
||||
|
||||
def Warning(name: String) = "§7- " + localizeImmediately("gui.RobotAssembler.Warning." + name)
|
||||
def Warning(name: String) = new ChatComponentText("§7- ").appendSibling(localizeLater("gui.RobotAssembler.Warning." + name))
|
||||
|
||||
def Warnings = localizeImmediately("gui.RobotAssembler.Warnings")
|
||||
def Warnings = localizeLater("gui.RobotAssembler.Warnings")
|
||||
}
|
||||
|
||||
object ServerRack {
|
||||
|
@ -1,13 +1,17 @@
|
||||
package li.cil.oc
|
||||
|
||||
import cpw.mods.fml.common.Mod.EventHandler
|
||||
import cpw.mods.fml.common.event.FMLInterModComms.IMCEvent
|
||||
import cpw.mods.fml.common.event._
|
||||
import cpw.mods.fml.common.network.FMLEventChannel
|
||||
import cpw.mods.fml.common.{Mod, SidedProxy}
|
||||
import li.cil.oc.common.Proxy
|
||||
import li.cil.oc.common.template.AssemblerTemplates
|
||||
import li.cil.oc.server.CommandHandler
|
||||
import org.apache.logging.log4j.LogManager
|
||||
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
@Mod(modid = OpenComputers.ID, name = OpenComputers.Name,
|
||||
version = OpenComputers.Version, /* certificateFingerprint = OpenComputers.Fingerprint, */
|
||||
modLanguage = "scala", useMetadata = true)
|
||||
@ -49,4 +53,14 @@ object OpenComputers {
|
||||
|
||||
@EventHandler
|
||||
def serverStart(e: FMLServerStartingEvent) = CommandHandler.register(e)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
def imc(e: IMCEvent) = {
|
||||
for (message <- e.getMessages) {
|
||||
if (message.key == "registerAssemblerTemplate" && message.isNBTMessage) {
|
||||
log.info(s"Registering new assembler template from mod ${message.getSender}.")
|
||||
AssemblerTemplates.add(message.getNBTValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,17 +2,16 @@ package li.cil.oc.client.gui
|
||||
|
||||
import java.util
|
||||
|
||||
import li.cil.oc.api.driver.{Inventory, Memory, Processor}
|
||||
import li.cil.oc.Localization
|
||||
import li.cil.oc.client.gui.widget.ProgressBar
|
||||
import li.cil.oc.client.{Textures, PacketSender => ClientPacketSender}
|
||||
import li.cil.oc.common.{Slot, container, tileentity}
|
||||
import li.cil.oc.{Localization, api}
|
||||
import li.cil.oc.common.template.AssemblerTemplates
|
||||
import li.cil.oc.common.{container, tileentity}
|
||||
import net.minecraft.client.gui.GuiButton
|
||||
import net.minecraft.entity.player.InventoryPlayer
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
import scala.collection.convert.WrapAsJava._
|
||||
import scala.collection.mutable
|
||||
|
||||
class RobotAssembler(playerInventory: InventoryPlayer, val assembler: tileentity.RobotAssembler) extends DynamicGuiContainer(new container.RobotAssembler(playerInventory, assembler)) {
|
||||
xSize = 176
|
||||
@ -24,60 +23,11 @@ class RobotAssembler(playerInventory: InventoryPlayer, val assembler: tileentity
|
||||
|
||||
private val progress = addWidget(new ProgressBar(28, 92))
|
||||
|
||||
val suggestedComponents = Array(
|
||||
"Screen" -> (() => hasComponent("screen1")),
|
||||
"Keyboard" -> (() => hasComponent("keyboard")),
|
||||
"GraphicsCard" -> (() => Array("graphicsCard1", "graphicsCard2", "graphicsCard3").exists(hasComponent)),
|
||||
"Inventory" -> (() => hasInventory),
|
||||
"OS" -> (() => hasFileSystem))
|
||||
|
||||
def add[T](list: util.List[T], value: Any) = list.add(value.asInstanceOf[T])
|
||||
|
||||
private def hasCase = assembler.isItemValidForSlot(0, assembler.getStackInSlot(0))
|
||||
private def validate = AssemblerTemplates.select(assemblerContainer.getSlot(0).getStack).map(_.validate(assemblerContainer.otherInventory))
|
||||
|
||||
private def hasCPU = assembler.items.exists {
|
||||
case Some(stack) => api.Driver.driverFor(stack) match {
|
||||
case _: Processor => true
|
||||
case _ => false
|
||||
}
|
||||
case _ => false
|
||||
}
|
||||
|
||||
private def hasRAM = assembler.items.exists {
|
||||
case Some(stack) => api.Driver.driverFor(stack) match {
|
||||
case _: Memory => true
|
||||
case _ => false
|
||||
}
|
||||
case _ => false
|
||||
}
|
||||
|
||||
private def hasComponent(name: String) = assembler.items.exists {
|
||||
case Some(stack) => Option(api.Items.get(stack)) match {
|
||||
case Some(descriptor) => descriptor.name == name
|
||||
case _ => false
|
||||
}
|
||||
case _ => false
|
||||
}
|
||||
|
||||
private def hasInventory = assembler.items.exists {
|
||||
case Some(stack) => api.Driver.driverFor(stack) match {
|
||||
case _: Inventory => true
|
||||
case _ => false
|
||||
}
|
||||
case _ => false
|
||||
}
|
||||
|
||||
private def hasFileSystem = assembler.items.exists {
|
||||
case Some(stack) => Option(api.Driver.driverFor(stack)) match {
|
||||
case Some(driver) => Slot.fromApi(driver.slot(stack)) == Slot.Floppy || Slot.fromApi(driver.slot(stack)) == Slot.HDD
|
||||
case _ => false
|
||||
}
|
||||
case _ => false
|
||||
}
|
||||
|
||||
private def isCapacityValid = assembler.complexity <= assembler.maxComplexity
|
||||
|
||||
private def canBuild = !assemblerContainer.isAssembling && hasCase && hasCPU && hasRAM && isCapacityValid
|
||||
private def canBuild = !assemblerContainer.isAssembling && validate.exists(_._1)
|
||||
|
||||
protected override def actionPerformed(button: GuiButton) {
|
||||
if (button.id == 0 && canBuild) {
|
||||
@ -100,37 +50,23 @@ class RobotAssembler(playerInventory: InventoryPlayer, val assembler: tileentity
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) // Me lazy... prevents NEI render glitch.
|
||||
if (!assemblerContainer.isAssembling) {
|
||||
def drawMessage(message: String) {
|
||||
fontRendererObj.drawString(message, 30, 94, 0x404040)
|
||||
}
|
||||
if (!inventorySlots.getSlot(0).getHasStack) {
|
||||
drawMessage(Localization.RobotAssembler.InsertCase)
|
||||
}
|
||||
else if (api.Items.get(inventorySlots.getSlot(0).getStack) == api.Items.get("robot")) {
|
||||
drawMessage(Localization.RobotAssembler.CollectRobot)
|
||||
}
|
||||
else if (!hasCPU) {
|
||||
drawMessage(Localization.RobotAssembler.InsertCPU)
|
||||
}
|
||||
else if (!hasRAM) {
|
||||
drawMessage(Localization.RobotAssembler.InsertRAM)
|
||||
}
|
||||
else {
|
||||
fontRendererObj.drawString(Localization.RobotAssembler.Complexity(assembler.complexity, assembler.maxComplexity), 30, 94, if (isCapacityValid) 0x404040 else 0x804040)
|
||||
}
|
||||
val info = validate
|
||||
val message =
|
||||
if (!assemblerContainer.getSlot(0).getHasStack) {
|
||||
Localization.Assembler.InsertTemplate
|
||||
}
|
||||
else info match {
|
||||
case Some((_, value, _)) if value != null => value.getUnformattedText
|
||||
case _ if assemblerContainer.getSlot(0).getHasStack => Localization.Assembler.CollectResult
|
||||
case _ => ""
|
||||
}
|
||||
fontRendererObj.drawString(message, 30, 94, 0x404040)
|
||||
if (runButton.func_146115_a) {
|
||||
val tooltip = new java.util.ArrayList[String]
|
||||
tooltip.add(Localization.RobotAssembler.Run)
|
||||
if (canBuild) {
|
||||
var warnings = mutable.ArrayBuffer.empty[String]
|
||||
for ((name, check) <- suggestedComponents) {
|
||||
if (!check()) {
|
||||
warnings += Localization.RobotAssembler.Warning(name)
|
||||
}
|
||||
}
|
||||
if (warnings.length > 0) {
|
||||
tooltip.add(Localization.RobotAssembler.Warnings)
|
||||
tooltip.addAll(warnings)
|
||||
tooltip.add(Localization.Assembler.Run)
|
||||
info.foreach {
|
||||
case (valid, _, warnings) => if (valid && warnings.length > 0) {
|
||||
tooltip.addAll(warnings.map(_.getUnformattedText).toList)
|
||||
}
|
||||
}
|
||||
drawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRendererObj)
|
||||
@ -139,7 +75,7 @@ class RobotAssembler(playerInventory: InventoryPlayer, val assembler: tileentity
|
||||
else if (func_146978_c(progress.x, progress.y, progress.width, progress.height, mouseX, mouseY)) {
|
||||
val tooltip = new java.util.ArrayList[String]
|
||||
val timeRemaining = formatTime(assemblerContainer.assemblyRemainingTime)
|
||||
tooltip.add(Localization.RobotAssembler.Progress(assemblerContainer.assemblyProgress, timeRemaining))
|
||||
tooltip.add(Localization.Assembler.Progress(assemblerContainer.assemblyProgress, timeRemaining))
|
||||
copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRendererObj)
|
||||
}
|
||||
GL11.glPopAttrib()
|
||||
|
@ -46,108 +46,6 @@ object InventorySlots {
|
||||
)
|
||||
)
|
||||
|
||||
val assembler = Array(
|
||||
Array(
|
||||
InventorySlot(Slot.None, Tier.None), // Reserved for computer case.
|
||||
InventorySlot(Slot.Container, Tier.Two),
|
||||
InventorySlot(Slot.Container, Tier.One),
|
||||
InventorySlot(Slot.Container, Tier.One),
|
||||
InventorySlot(Slot.Upgrade, Tier.One),
|
||||
InventorySlot(Slot.Upgrade, Tier.One),
|
||||
InventorySlot(Slot.Upgrade, Tier.One),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.Card, Tier.One),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.CPU, Tier.One),
|
||||
InventorySlot(Slot.Memory, Tier.One),
|
||||
InventorySlot(Slot.Memory, Tier.One),
|
||||
InventorySlot(Slot.Floppy, Tier.Any),
|
||||
InventorySlot(Slot.HDD, Tier.One),
|
||||
InventorySlot(Slot.None, Tier.None)
|
||||
),
|
||||
|
||||
Array(
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.Container, Tier.Three),
|
||||
InventorySlot(Slot.Container, Tier.Two),
|
||||
InventorySlot(Slot.Container, Tier.One),
|
||||
InventorySlot(Slot.Upgrade, Tier.Two),
|
||||
InventorySlot(Slot.Upgrade, Tier.Two),
|
||||
InventorySlot(Slot.Upgrade, Tier.Two),
|
||||
InventorySlot(Slot.Upgrade, Tier.One),
|
||||
InventorySlot(Slot.Upgrade, Tier.One),
|
||||
InventorySlot(Slot.Upgrade, Tier.One),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.Card, Tier.Two),
|
||||
InventorySlot(Slot.Card, Tier.One),
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.CPU, Tier.Two),
|
||||
InventorySlot(Slot.Memory, Tier.Two),
|
||||
InventorySlot(Slot.Memory, Tier.Two),
|
||||
InventorySlot(Slot.Floppy, Tier.Any),
|
||||
InventorySlot(Slot.HDD, Tier.Two),
|
||||
InventorySlot(Slot.None, Tier.None)
|
||||
),
|
||||
|
||||
Array(
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.Container, Tier.Three),
|
||||
InventorySlot(Slot.Container, Tier.Three),
|
||||
InventorySlot(Slot.Container, Tier.Two),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Two),
|
||||
InventorySlot(Slot.Upgrade, Tier.Two),
|
||||
InventorySlot(Slot.Upgrade, Tier.Two),
|
||||
InventorySlot(Slot.Upgrade, Tier.One),
|
||||
InventorySlot(Slot.Upgrade, Tier.One),
|
||||
InventorySlot(Slot.Upgrade, Tier.One),
|
||||
InventorySlot(Slot.Card, Tier.Three),
|
||||
InventorySlot(Slot.Card, Tier.Two),
|
||||
InventorySlot(Slot.Card, Tier.Two),
|
||||
InventorySlot(Slot.CPU, Tier.Three),
|
||||
InventorySlot(Slot.Memory, Tier.Three),
|
||||
InventorySlot(Slot.Memory, Tier.Three),
|
||||
InventorySlot(Slot.Floppy, Tier.Any),
|
||||
InventorySlot(Slot.HDD, Tier.Three),
|
||||
InventorySlot(Slot.HDD, Tier.Two)
|
||||
),
|
||||
|
||||
Array(
|
||||
InventorySlot(Slot.None, Tier.None),
|
||||
InventorySlot(Slot.Container, Tier.Three),
|
||||
InventorySlot(Slot.Container, Tier.Three),
|
||||
InventorySlot(Slot.Container, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Upgrade, Tier.Three),
|
||||
InventorySlot(Slot.Card, Tier.Three),
|
||||
InventorySlot(Slot.Card, Tier.Three),
|
||||
InventorySlot(Slot.Card, Tier.Three),
|
||||
InventorySlot(Slot.CPU, Tier.Three),
|
||||
InventorySlot(Slot.Memory, Tier.Three),
|
||||
InventorySlot(Slot.Memory, Tier.Three),
|
||||
InventorySlot(Slot.Floppy, Tier.Any),
|
||||
InventorySlot(Slot.HDD, Tier.Three),
|
||||
InventorySlot(Slot.HDD, Tier.Three)
|
||||
)
|
||||
)
|
||||
|
||||
val server = Array(
|
||||
Array(
|
||||
InventorySlot(Slot.Card, Tier.Two),
|
||||
|
@ -10,6 +10,7 @@ import li.cil.oc.common.event._
|
||||
import li.cil.oc.common.item.Tablet
|
||||
import li.cil.oc.common.multipart.MultiPart
|
||||
import li.cil.oc.common.recipe.Recipes
|
||||
import li.cil.oc.common.template.RobotTemplate
|
||||
import li.cil.oc.server._
|
||||
import li.cil.oc.server.component.machine
|
||||
import li.cil.oc.server.component.machine.{LuaJLuaArchitecture, NativeLuaArchitecture}
|
||||
@ -115,6 +116,9 @@ class Proxy {
|
||||
api.Driver.add(driver.converter.FluidTankInfo)
|
||||
api.Driver.add(driver.converter.ItemStack)
|
||||
|
||||
OpenComputers.log.info("Initializing assembler templates.")
|
||||
RobotTemplate.register()
|
||||
|
||||
OpenComputers.log.info("Initializing loot disks.")
|
||||
Loot.init()
|
||||
|
||||
|
@ -7,18 +7,18 @@ import li.cil.oc.util.SideTracker
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.{IInventory, Slot}
|
||||
|
||||
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 {
|
||||
class DynamicComponentSlot(val container: Player, inventory: IInventory, index: Int, x: Int, y: Int, val info: DynamicComponentSlot => InventorySlot, val containerTierGetter: () => Int) extends Slot(inventory, index, x, y) with ComponentSlot {
|
||||
override def tier = {
|
||||
val mainTier = tierGetter()
|
||||
if (mainTier >= 0) info(mainTier)(getSlotIndex).tier
|
||||
val mainTier = containerTierGetter()
|
||||
if (mainTier >= 0) info(this).tier
|
||||
else mainTier
|
||||
}
|
||||
|
||||
def tierIcon = Icons.get(tier)
|
||||
|
||||
def slot = {
|
||||
val mainTier = tierGetter()
|
||||
if (mainTier >= 0) info(tierGetter())(getSlotIndex).slot
|
||||
val mainTier = containerTierGetter()
|
||||
if (mainTier >= 0) info(this).slot
|
||||
else common.Slot.None
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package li.cil.oc.common.container
|
||||
|
||||
import li.cil.oc.common
|
||||
import li.cil.oc.common.InventorySlots.InventorySlot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.util.SideTracker
|
||||
import net.minecraft.entity.player.{EntityPlayer, InventoryPlayer}
|
||||
import net.minecraft.inventory.{Container, ICrafting, IInventory, Slot}
|
||||
@ -90,9 +91,14 @@ abstract class Player(val playerInventory: InventoryPlayer, val otherInventory:
|
||||
addSlotToContainer(new StaticComponentSlot(this, otherInventory, index, x, y, slot, tier))
|
||||
}
|
||||
|
||||
def addSlotToContainer(x: Int, y: Int, info: Array[Array[InventorySlot]], tierGetter: () => Int) {
|
||||
def addSlotToContainer(x: Int, y: Int, info: Array[Array[InventorySlot]], containerTierGetter: () => Int) {
|
||||
val index = inventorySlots.size
|
||||
addSlotToContainer(new DynamicComponentSlot(this, otherInventory, index, x, y, info, tierGetter))
|
||||
addSlotToContainer(new DynamicComponentSlot(this, otherInventory, index, x, y, slot => info(slot.containerTierGetter())(slot.getSlotIndex), containerTierGetter))
|
||||
}
|
||||
|
||||
def addSlotToContainer(x: Int, y: Int, info: DynamicComponentSlot => InventorySlot) {
|
||||
val index = inventorySlots.size
|
||||
addSlotToContainer(new DynamicComponentSlot(this, otherInventory, index, x, y, info, () => Tier.One))
|
||||
}
|
||||
|
||||
/** Render player inventory at the specified coordinates. */
|
||||
|
@ -2,11 +2,12 @@ package li.cil.oc.common.container
|
||||
|
||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||
import li.cil.oc.client.gui.Icons
|
||||
import li.cil.oc.common.InventorySlots.InventorySlot
|
||||
import li.cil.oc.common.template.AssemblerTemplates
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.util.SideTracker
|
||||
import li.cil.oc.{Settings, common}
|
||||
import li.cil.oc.common.{InventorySlots, tileentity}
|
||||
import li.cil.oc.util.{ItemUtils, SideTracker}
|
||||
import net.minecraft.entity.player.InventoryPlayer
|
||||
import net.minecraft.inventory.Slot
|
||||
|
||||
class RobotAssembler(playerInventory: InventoryPlayer, val assembler: tileentity.RobotAssembler) extends Player(playerInventory, assembler) {
|
||||
// Computer case.
|
||||
@ -20,34 +21,46 @@ class RobotAssembler(playerInventory: InventoryPlayer, val assembler: tileentity
|
||||
})
|
||||
}
|
||||
|
||||
def caseTier = ItemUtils.caseTier(inventorySlots.get(0).asInstanceOf[Slot].getStack)
|
||||
private def slotInfo(slot: DynamicComponentSlot) = {
|
||||
AssemblerTemplates.select(getSlot(0).getStack) match {
|
||||
case Some(template) =>
|
||||
val index = slot.getSlotIndex
|
||||
val tplSlot =
|
||||
if ((1 until 4) contains index) template.containerSlots(index - 1)
|
||||
else if ((4 until 13) contains index) template.upgradeSlots(index - 4)
|
||||
else if ((13 until 21) contains index) template.componentSlots(index - 13)
|
||||
else AssemblerTemplates.NoSlot
|
||||
new InventorySlot(tplSlot.kind, tplSlot.tier)
|
||||
case _ => new InventorySlot(common.Slot.None, common.Tier.None)
|
||||
}
|
||||
}
|
||||
|
||||
// Component containers.
|
||||
for (i <- 0 until 3) {
|
||||
addSlotToContainer(34 + i * slotSize, 70, InventorySlots.assembler, () => caseTier)
|
||||
addSlotToContainer(34 + i * slotSize, 70, slotInfo _)
|
||||
}
|
||||
|
||||
// Components.
|
||||
for (i <- 0 until 9) {
|
||||
addSlotToContainer(34 + (i % 3) * slotSize, 12 + (i / 3) * slotSize, InventorySlots.assembler, () => caseTier)
|
||||
addSlotToContainer(34 + (i % 3) * slotSize, 12 + (i / 3) * slotSize, slotInfo _)
|
||||
}
|
||||
|
||||
// Cards.
|
||||
for (i <- 0 until 3) {
|
||||
addSlotToContainer(104, 12 + i * slotSize, InventorySlots.assembler, () => caseTier)
|
||||
addSlotToContainer(104, 12 + i * slotSize, slotInfo _)
|
||||
}
|
||||
|
||||
// CPU.
|
||||
addSlotToContainer(126, 12, InventorySlots.assembler, () => caseTier)
|
||||
addSlotToContainer(126, 12, slotInfo _)
|
||||
|
||||
// RAM.
|
||||
for (i <- 0 until 2) {
|
||||
addSlotToContainer(126, 30 + i * slotSize, InventorySlots.assembler, () => caseTier)
|
||||
addSlotToContainer(126, 30 + i * slotSize, slotInfo _)
|
||||
}
|
||||
|
||||
// Floppy + HDDs.
|
||||
for (i <- 0 until 3) {
|
||||
addSlotToContainer(148, 12 + i * slotSize, InventorySlots.assembler, () => caseTier)
|
||||
addSlotToContainer(148, 12 + i * slotSize, slotInfo _)
|
||||
}
|
||||
|
||||
// Show the player's inventory.
|
||||
|
@ -0,0 +1,93 @@
|
||||
package li.cil.oc.common.template
|
||||
|
||||
import java.lang.reflect.{Method, Modifier}
|
||||
|
||||
import li.cil.oc.common.{Slot, Tier}
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.{OpenComputers, api}
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.IChatComponent
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
object AssemblerTemplates {
|
||||
val NoSlot = new Slot(Slot.None, Tier.None, None)
|
||||
|
||||
val templates = mutable.ArrayBuffer.empty[Template]
|
||||
|
||||
def add(template: NBTTagCompound): Unit = try {
|
||||
val selector = getStaticMethod(template.getString("select"), classOf[ItemStack])
|
||||
val validator = getStaticMethod(template.getString("validate"), classOf[IInventory])
|
||||
val assembler = getStaticMethod(template.getString("assemble"), classOf[IInventory])
|
||||
val containerSlots = template.getTagList("containerSlots", NBT.TAG_COMPOUND).map((list, index) => parseSlot(list.getCompoundTagAt(index), Some(Slot.Container))).take(3).padTo(3, NoSlot).toArray
|
||||
val upgradeSlots = template.getTagList("upgradeSlots", NBT.TAG_COMPOUND).map((list, index) => parseSlot(list.getCompoundTagAt(index), Some(Slot.Upgrade))).take(9).padTo(9, NoSlot).toArray
|
||||
val componentSlots = template.getTagList("componentSlots", NBT.TAG_COMPOUND).map((list, index) => parseSlot(list.getCompoundTagAt(index))).take(9).padTo(9, NoSlot).toArray
|
||||
|
||||
templates += new Template(selector, validator, assembler, containerSlots, upgradeSlots, componentSlots)
|
||||
}
|
||||
catch {
|
||||
case t: Throwable => OpenComputers.log.warn("Failed registering assembler template.", t)
|
||||
}
|
||||
|
||||
def select(stack: ItemStack) = templates.find(_.select(stack))
|
||||
|
||||
class Template(val selector: Method,
|
||||
val validator: Method,
|
||||
val assembler: Method,
|
||||
val containerSlots: Array[Slot],
|
||||
val upgradeSlots: Array[Slot],
|
||||
val componentSlots: Array[Slot]) {
|
||||
def select(stack: ItemStack) = tryInvokeStatic(selector, stack)(false)
|
||||
|
||||
def validate(inventory: IInventory) = tryInvokeStatic(validator, inventory)(null: Array[AnyRef]) match {
|
||||
case Array(valid: java.lang.Boolean, progress: IChatComponent, warnings: Array[IChatComponent]) => (valid: Boolean, progress, warnings)
|
||||
case Array(valid: java.lang.Boolean, progress: IChatComponent) => (valid: Boolean, progress, Array.empty[IChatComponent])
|
||||
case Array(valid: java.lang.Boolean) => (valid: Boolean, null, Array.empty[IChatComponent])
|
||||
case _ => (false, null, Array.empty[IChatComponent])
|
||||
}
|
||||
|
||||
def assemble(inventory: IInventory) = tryInvokeStatic(assembler, inventory)(null: Array[AnyRef]) match {
|
||||
case Array(stack: ItemStack, energy: java.lang.Double) => (stack, energy: Double)
|
||||
case Array(stack: ItemStack) => (stack, 0.0)
|
||||
case _ => (null, 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
class Slot(val kind: String, val tier: Int, val validator: Option[Method]) {
|
||||
def validate(inventory: IInventory, slot: Int, stack: ItemStack) = validator match {
|
||||
case Some(method) => tryInvokeStatic(method, inventory, slot.underlying(), stack)(false)
|
||||
case _ => Option(api.Driver.driverFor(stack)) match {
|
||||
case Some(driver) => validateInternal(stack, driver) && Slot.fromApi(driver.slot(stack)) == kind
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
protected def validateInternal(stack: ItemStack, driver: api.driver.Item) = driver.tier(stack) <= tier
|
||||
}
|
||||
|
||||
private def parseSlot(nbt: NBTTagCompound, kindOverride: Option[String] = None) = {
|
||||
val kind = kindOverride.getOrElse(if (nbt.hasKey("type")) nbt.getString("type") else Slot.None)
|
||||
val tier = if (nbt.hasKey("tier")) nbt.getInteger("tier") else Tier.None
|
||||
val validator = if (nbt.hasKey("validator")) Option(getStaticMethod(nbt.getString("validator"), classOf[ItemStack], classOf[Int], classOf[ItemStack])) else None
|
||||
new Slot(kind, tier, validator)
|
||||
}
|
||||
|
||||
private def getStaticMethod(name: String, signature: Class[_]*) = {
|
||||
val nameSplit = name.lastIndexOf('.')
|
||||
val className = name.substring(0, nameSplit)
|
||||
val methodName = name.substring(nameSplit + 1)
|
||||
val clazz = Class.forName(className)
|
||||
val method = clazz.getDeclaredMethod(methodName, signature: _*)
|
||||
if (!Modifier.isStatic(method.getModifiers)) throw new IllegalArgumentException(s"Method $name is not static.")
|
||||
method
|
||||
}
|
||||
|
||||
private def tryInvokeStatic[T](method: Method, args: AnyRef*)(default: T): T = try method.invoke(null, args: _*).asInstanceOf[T] catch {
|
||||
case t: Throwable =>
|
||||
OpenComputers.log.warn(s"Error invoking callback ${method.getDeclaringClass.getCanonicalName + "." + method.getName}.", t)
|
||||
default
|
||||
}
|
||||
}
|
286
src/main/scala/li/cil/oc/common/template/RobotTemplate.scala
Normal file
286
src/main/scala/li/cil/oc/common/template/RobotTemplate.scala
Normal file
@ -0,0 +1,286 @@
|
||||
package li.cil.oc.common.template
|
||||
|
||||
import cpw.mods.fml.common.event.FMLInterModComms
|
||||
import li.cil.oc.api.driver.{Inventory, Memory, Processor, UpgradeContainer}
|
||||
import li.cil.oc.common.{Slot, Tier}
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import li.cil.oc.{Localization, Settings, api}
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
|
||||
import net.minecraft.util.IChatComponent
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
object RobotTemplate {
|
||||
def selectTier1(stack: ItemStack) = ItemUtils.caseTier(stack) == Tier.One
|
||||
|
||||
def selectTier2(stack: ItemStack) = ItemUtils.caseTier(stack) == Tier.Two
|
||||
|
||||
def selectTier3(stack: ItemStack) = ItemUtils.caseTier(stack) == Tier.Three
|
||||
|
||||
def selectCreative(stack: ItemStack) = ItemUtils.caseTier(stack) == Tier.Four
|
||||
|
||||
def validate(inventory: IInventory): Array[AnyRef] = {
|
||||
val hasCase = ItemUtils.caseTier(inventory.getStackInSlot(0)) != Tier.None
|
||||
val hasCPU = RobotTemplate.hasCPU(inventory)
|
||||
val hasRAM = RobotTemplate.hasRAM(inventory)
|
||||
val complexity = RobotTemplate.complexity(inventory)
|
||||
val maxComplexity = RobotTemplate.maxComplexity(inventory)
|
||||
|
||||
val valid = hasCase && hasCPU && hasRAM && complexity <= maxComplexity
|
||||
|
||||
val progress =
|
||||
if (!hasCPU) Localization.Assembler.InsertCPU
|
||||
else if (!hasRAM) Localization.Assembler.InsertRAM
|
||||
else Localization.Assembler.Complexity(complexity, maxComplexity)
|
||||
|
||||
val warnings = mutable.ArrayBuffer.empty[IChatComponent]
|
||||
for ((name, check) <- suggestedComponents) {
|
||||
if (!check(inventory)) {
|
||||
warnings += Localization.Assembler.Warning(name)
|
||||
}
|
||||
}
|
||||
if (warnings.length > 0) {
|
||||
warnings.prepend(Localization.Assembler.Warnings)
|
||||
}
|
||||
|
||||
Array(valid: java.lang.Boolean, progress, warnings.toArray)
|
||||
}
|
||||
|
||||
def assemble(inventory: IInventory) = {
|
||||
val items = (0 until inventory.getSizeInventory).map(inventory.getStackInSlot)
|
||||
val data = new ItemUtils.RobotData()
|
||||
data.tier = ItemUtils.caseTier(inventory.getStackInSlot(0))
|
||||
data.name = ItemUtils.RobotData.randomName
|
||||
data.robotEnergy = 50000
|
||||
data.totalEnergy = data.robotEnergy
|
||||
data.containers = items.slice(1, 4).filter(_ != null).toArray
|
||||
data.components = items.drop(4).filter(_ != null).toArray
|
||||
val stack = api.Items.get("robot").createItemStack(1)
|
||||
data.save(stack)
|
||||
val energy = Settings.get.robotBaseCost + complexity(inventory) * Settings.get.robotComplexityCost
|
||||
|
||||
Array(stack, energy: java.lang.Double)
|
||||
}
|
||||
|
||||
def register() {
|
||||
// Tier 1
|
||||
{
|
||||
val nbt = new NBTTagCompound()
|
||||
nbt.setString("select", "li.cil.oc.common.template.RobotTemplate.selectTier1")
|
||||
nbt.setString("validate", "li.cil.oc.common.template.RobotTemplate.validate")
|
||||
nbt.setString("assemble", "li.cil.oc.common.template.RobotTemplate.assemble")
|
||||
|
||||
val containerSlots = new NBTTagList()
|
||||
containerSlots.appendTag(Map("tier" -> Tier.Two))
|
||||
containerSlots.appendTag(Map("tier" -> Tier.One))
|
||||
containerSlots.appendTag(Map("tier" -> Tier.One))
|
||||
nbt.setTag("containerSlots", containerSlots)
|
||||
|
||||
val upgradeSlots = new NBTTagList()
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.One))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.One))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.One))
|
||||
nbt.setTag("upgradeSlots", upgradeSlots)
|
||||
|
||||
val componentSlots = new NBTTagList()
|
||||
componentSlots.appendTag(Map("type" -> Slot.Card, "tier" -> Tier.One))
|
||||
componentSlots.appendTag(new NBTTagCompound())
|
||||
componentSlots.appendTag(new NBTTagCompound())
|
||||
componentSlots.appendTag(Map("type" -> Slot.CPU, "tier" -> Tier.One))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.One))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.One))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Floppy, "tier" -> Tier.Any))
|
||||
componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.One))
|
||||
nbt.setTag("componentSlots", componentSlots)
|
||||
|
||||
FMLInterModComms.sendMessage("OpenComputers", "registerAssemblerTemplate", nbt)
|
||||
}
|
||||
|
||||
// Tier 2
|
||||
{
|
||||
val nbt = new NBTTagCompound()
|
||||
nbt.setString("select", "li.cil.oc.common.template.RobotTemplate.selectTier2")
|
||||
nbt.setString("validate", "li.cil.oc.common.template.RobotTemplate.validate")
|
||||
nbt.setString("assemble", "li.cil.oc.common.template.RobotTemplate.assemble")
|
||||
|
||||
val containerSlots = new NBTTagList()
|
||||
containerSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
containerSlots.appendTag(Map("tier" -> Tier.Two))
|
||||
containerSlots.appendTag(Map("tier" -> Tier.One))
|
||||
nbt.setTag("containerSlots", containerSlots)
|
||||
|
||||
val upgradeSlots = new NBTTagList()
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Two))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Two))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Two))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.One))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.One))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.One))
|
||||
nbt.setTag("upgradeSlots", upgradeSlots)
|
||||
|
||||
val componentSlots = new NBTTagList()
|
||||
componentSlots.appendTag(Map("type" -> Slot.Card, "tier" -> Tier.Two))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Card, "tier" -> Tier.One))
|
||||
componentSlots.appendTag(new NBTTagCompound())
|
||||
componentSlots.appendTag(Map("type" -> Slot.CPU, "tier" -> Tier.Two))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Two))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Two))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Floppy, "tier" -> Tier.Any))
|
||||
componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.Two))
|
||||
nbt.setTag("componentSlots", componentSlots)
|
||||
|
||||
FMLInterModComms.sendMessage("OpenComputers", "registerAssemblerTemplate", nbt)
|
||||
}
|
||||
|
||||
// Tier 3
|
||||
{
|
||||
val nbt = new NBTTagCompound()
|
||||
nbt.setString("select", "li.cil.oc.common.template.RobotTemplate.selectTier3")
|
||||
nbt.setString("validate", "li.cil.oc.common.template.RobotTemplate.validate")
|
||||
nbt.setString("assemble", "li.cil.oc.common.template.RobotTemplate.assemble")
|
||||
|
||||
val containerSlots = new NBTTagList()
|
||||
containerSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
containerSlots.appendTag(Map("tier" -> Tier.Two))
|
||||
containerSlots.appendTag(Map("tier" -> Tier.Two))
|
||||
nbt.setTag("containerSlots", containerSlots)
|
||||
|
||||
val upgradeSlots = new NBTTagList()
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Two))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Two))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Two))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.One))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.One))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.One))
|
||||
nbt.setTag("upgradeSlots", upgradeSlots)
|
||||
|
||||
val componentSlots = new NBTTagList()
|
||||
componentSlots.appendTag(Map("type" -> Slot.Card, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Card, "tier" -> Tier.Two))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Card, "tier" -> Tier.Two))
|
||||
componentSlots.appendTag(Map("type" -> Slot.CPU, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Floppy, "tier" -> Tier.Any))
|
||||
componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.Two))
|
||||
nbt.setTag("componentSlots", componentSlots)
|
||||
|
||||
FMLInterModComms.sendMessage("OpenComputers", "registerAssemblerTemplate", nbt)
|
||||
}
|
||||
|
||||
// Creative
|
||||
{
|
||||
val nbt = new NBTTagCompound()
|
||||
nbt.setString("select", "li.cil.oc.common.template.RobotTemplate.selectCreative")
|
||||
nbt.setString("validate", "li.cil.oc.common.template.RobotTemplate.validate")
|
||||
nbt.setString("assemble", "li.cil.oc.common.template.RobotTemplate.assemble")
|
||||
|
||||
val containerSlots = new NBTTagList()
|
||||
containerSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
containerSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
containerSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
nbt.setTag("containerSlots", containerSlots)
|
||||
|
||||
val upgradeSlots = new NBTTagList()
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Three))
|
||||
nbt.setTag("upgradeSlots", upgradeSlots)
|
||||
|
||||
val componentSlots = new NBTTagList()
|
||||
componentSlots.appendTag(Map("type" -> Slot.Card, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Card, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Card, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.CPU, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Floppy, "tier" -> Tier.Any))
|
||||
componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.Three))
|
||||
componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.Three))
|
||||
nbt.setTag("componentSlots", componentSlots)
|
||||
|
||||
FMLInterModComms.sendMessage("OpenComputers", "registerAssemblerTemplate", nbt)
|
||||
}
|
||||
}
|
||||
|
||||
private val suggestedComponents = Array(
|
||||
"Screen" -> hasComponent("screen1") _,
|
||||
"Keyboard" -> hasComponent("keyboard") _,
|
||||
"GraphicsCard" -> ((inventory: IInventory) => Array("graphicsCard1", "graphicsCard2", "graphicsCard3").exists(name => hasComponent(name)(inventory))),
|
||||
"Inventory" -> hasInventory _,
|
||||
"OS" -> hasFileSystem _)
|
||||
|
||||
private def exists(inventory: IInventory, p: ItemStack => Boolean) = {
|
||||
(0 until inventory.getSizeInventory).exists(slot => Option(inventory.getStackInSlot(slot)) match {
|
||||
case Some(stack) => p(stack)
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
|
||||
private def hasCPU(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_) match {
|
||||
case _: Processor => true
|
||||
case _ => false
|
||||
})
|
||||
|
||||
private def hasRAM(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_) match {
|
||||
case _: Memory => true
|
||||
case _ => false
|
||||
})
|
||||
|
||||
private def hasComponent(name: String)(inventory: IInventory) = exists(inventory, stack => Option(api.Items.get(stack)) match {
|
||||
case Some(descriptor) => descriptor.name == name
|
||||
case _ => false
|
||||
})
|
||||
|
||||
private def hasInventory(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_) match {
|
||||
case _: Inventory => true
|
||||
case _ => false
|
||||
})
|
||||
|
||||
private def hasFileSystem(inventory: IInventory) = exists(inventory, stack => Option(api.Driver.driverFor(stack)) match {
|
||||
case Some(driver) => Slot.fromApi(driver.slot(stack)) == Slot.Floppy || Slot.fromApi(driver.slot(stack)) == Slot.HDD
|
||||
case _ => false
|
||||
})
|
||||
|
||||
private def complexity(inventory: IInventory) = {
|
||||
var acc = 0
|
||||
for (slot <- 1 until inventory.getSizeInventory) {
|
||||
val stack = inventory.getStackInSlot(slot)
|
||||
acc += (Option(api.Driver.driverFor(stack)) match {
|
||||
case Some(driver: Processor) => 0 // CPUs are exempt, since they control the limit.
|
||||
case Some(driver: UpgradeContainer) => (1 + driver.tier(stack)) * 2
|
||||
case Some(driver) => 1 + driver.tier(stack)
|
||||
case _ => 0
|
||||
})
|
||||
}
|
||||
acc
|
||||
}
|
||||
|
||||
private def maxComplexity(inventory: IInventory) = {
|
||||
val caseTier = ItemUtils.caseTier(inventory.getStackInSlot(0))
|
||||
val cpuTier = (0 until inventory.getSizeInventory).foldRight(0)((slot, acc) => {
|
||||
val stack = inventory.getStackInSlot(slot)
|
||||
acc + (api.Driver.driverFor(stack) match {
|
||||
case processor: Processor => processor.tier(stack)
|
||||
case _ => 0
|
||||
})
|
||||
})
|
||||
if (caseTier >= Tier.One && cpuTier >= Tier.One) {
|
||||
Settings.robotComplexityByTier(caseTier) - (caseTier - cpuTier) * 6
|
||||
}
|
||||
else 0
|
||||
}
|
||||
}
|
@ -1,13 +1,10 @@
|
||||
package li.cil.oc.common.tileentity
|
||||
|
||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||
import li.cil.oc.api.Driver
|
||||
import li.cil.oc.api.driver.UpgradeContainer
|
||||
import li.cil.oc.api.network._
|
||||
import li.cil.oc.common.{InventorySlots, Slot, Tier}
|
||||
import li.cil.oc.common.template.AssemblerTemplates
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import li.cil.oc.{Settings, api}
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
@ -19,7 +16,7 @@ class RobotAssembler extends traits.Environment with traits.PowerAcceptor with t
|
||||
withConnector(Settings.get.bufferConverter).
|
||||
create()
|
||||
|
||||
var robot: Option[ItemStack] = None
|
||||
var output: Option[ItemStack] = None
|
||||
|
||||
var totalRequiredEnergy = 0.0
|
||||
|
||||
@ -45,61 +42,41 @@ class RobotAssembler extends traits.Environment with traits.PowerAcceptor with t
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def complexity = items.drop(1).foldLeft(0)((acc, stack) => acc + (Option(api.Driver.driverFor(stack.orNull)) match {
|
||||
case Some(driver: UpgradeContainer) => (1 + driver.tier(stack.get)) * 2
|
||||
case Some(driver) => 1 + driver.tier(stack.get)
|
||||
case _ => 0
|
||||
}))
|
||||
|
||||
def maxComplexity = {
|
||||
val caseTier = ItemUtils.caseTier(items(0).orNull)
|
||||
if (caseTier >= 0) Settings.robotComplexityByTier(caseTier) else 0
|
||||
}
|
||||
|
||||
def start(finishImmediately: Boolean = false): Boolean = this.synchronized {
|
||||
if (!isAssembling && robot.isEmpty && complexity <= maxComplexity) {
|
||||
for (slot <- 0 until getSizeInventory) {
|
||||
val stack = getStackInSlot(slot)
|
||||
if (stack != null && !isItemValidForSlot(slot, stack)) return false
|
||||
}
|
||||
val data = new ItemUtils.RobotData()
|
||||
data.tier = ItemUtils.caseTier(items(0).get)
|
||||
data.name = ItemUtils.RobotData.randomName
|
||||
data.robotEnergy = 50000
|
||||
data.totalEnergy = data.robotEnergy
|
||||
data.containers = items.take(4).drop(1).collect {
|
||||
case Some(item) => item
|
||||
}
|
||||
data.components = items.drop(4).collect {
|
||||
case Some(item) => item
|
||||
}
|
||||
val stack = api.Items.get("robot").createItemStack(1)
|
||||
data.save(stack)
|
||||
robot = Some(stack)
|
||||
if (finishImmediately || data.tier == Tier.Four) {
|
||||
// Creative tier, finish instantly.
|
||||
totalRequiredEnergy = 0
|
||||
}
|
||||
else {
|
||||
totalRequiredEnergy = math.max(1, Settings.get.robotBaseCost + complexity * Settings.get.robotComplexityCost)
|
||||
}
|
||||
requiredEnergy = totalRequiredEnergy
|
||||
ServerPacketSender.sendRobotAssembling(this, assembling = true)
|
||||
AssemblerTemplates.select(getStackInSlot(0)) match {
|
||||
case Some(template) if !isAssembling && output.isEmpty && template.validate(this)._1 =>
|
||||
for (slot <- 0 until getSizeInventory) {
|
||||
val stack = getStackInSlot(slot)
|
||||
if (stack != null && !isItemValidForSlot(slot, stack)) return false
|
||||
}
|
||||
val (stack, energy) = template.assemble(this)
|
||||
output = Some(stack)
|
||||
if (finishImmediately) {
|
||||
totalRequiredEnergy = 0
|
||||
}
|
||||
else {
|
||||
totalRequiredEnergy = math.max(1, energy)
|
||||
}
|
||||
requiredEnergy = totalRequiredEnergy
|
||||
ServerPacketSender.sendRobotAssembling(this, assembling = true)
|
||||
|
||||
for (slot <- 0 until getSizeInventory) items(slot) = None
|
||||
markDirty()
|
||||
for (slot <- 0 until getSizeInventory) items(slot) = None
|
||||
markDirty()
|
||||
|
||||
true
|
||||
true
|
||||
case _ => false
|
||||
}
|
||||
else false
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@Callback(doc = """function(): string, number[, number] -- The current state of the assember, `busy' or `idle', followed by the progress or complexity and maximum complexity, respectively.""")
|
||||
@Callback(doc = """function(): string, number or boolean -- The current state of the assembler, `busy' or `idle', followed by the progress or template validity, respectively.""")
|
||||
def status(context: Context, args: Arguments): Array[Object] = {
|
||||
if (isAssembling) result("busy", progress)
|
||||
else result("idle", complexity, maxComplexity)
|
||||
else AssemblerTemplates.select(getStackInSlot(0)) match {
|
||||
case Some(template) if template.validate(this)._1 => result("idle", true)
|
||||
case _ => result("idle", false)
|
||||
}
|
||||
}
|
||||
|
||||
@Callback(doc = """function():boolean -- Start assembling, if possible. Returns whether assembly was started or not.""")
|
||||
@ -111,25 +88,29 @@ class RobotAssembler extends traits.Environment with traits.PowerAcceptor with t
|
||||
|
||||
override def updateEntity() {
|
||||
super.updateEntity()
|
||||
if (robot.isDefined && world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
|
||||
if (output.isDefined && world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
|
||||
val want = math.max(1, math.min(requiredEnergy, Settings.get.assemblerTickAmount * Settings.get.tickFrequency))
|
||||
val success = Settings.get.ignorePower || node.tryChangeBuffer(-want)
|
||||
if (success) {
|
||||
requiredEnergy -= want
|
||||
}
|
||||
if (requiredEnergy <= 0) {
|
||||
setInventorySlotContents(0, robot.get)
|
||||
robot = None
|
||||
setInventorySlotContents(0, output.get)
|
||||
output = None
|
||||
requiredEnergy = 0
|
||||
}
|
||||
ServerPacketSender.sendRobotAssembling(this, success && robot.isDefined)
|
||||
ServerPacketSender.sendRobotAssembling(this, success && output.isDefined)
|
||||
}
|
||||
}
|
||||
|
||||
override def readFromNBT(nbt: NBTTagCompound) {
|
||||
super.readFromNBT(nbt)
|
||||
if (nbt.hasKey(Settings.namespace + "robot")) {
|
||||
robot = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "robot")))
|
||||
if (nbt.hasKey(Settings.namespace + "output")) {
|
||||
output = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "output")))
|
||||
}
|
||||
else if (nbt.hasKey(Settings.namespace + "robot")) {
|
||||
// Backwards compatibility.
|
||||
output = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "robot")))
|
||||
}
|
||||
totalRequiredEnergy = nbt.getDouble(Settings.namespace + "total")
|
||||
requiredEnergy = nbt.getDouble(Settings.namespace + "remaining")
|
||||
@ -137,7 +118,7 @@ class RobotAssembler extends traits.Environment with traits.PowerAcceptor with t
|
||||
|
||||
override def writeToNBT(nbt: NBTTagCompound) {
|
||||
super.writeToNBT(nbt)
|
||||
robot.foreach(stack => nbt.setNewCompoundTag(Settings.namespace + "robot", stack.writeToNBT))
|
||||
output.foreach(stack => nbt.setNewCompoundTag(Settings.namespace + "output", stack.writeToNBT))
|
||||
nbt.setDouble(Settings.namespace + "total", totalRequiredEnergy)
|
||||
nbt.setDouble(Settings.namespace + "remaining", requiredEnergy)
|
||||
}
|
||||
@ -155,22 +136,22 @@ class RobotAssembler extends traits.Environment with traits.PowerAcceptor with t
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def getSizeInventory = InventorySlots.assembler(0).length
|
||||
override def getSizeInventory = 22
|
||||
|
||||
override def getInventoryStackLimit = 1
|
||||
|
||||
override def isItemValidForSlot(slot: Int, stack: ItemStack) =
|
||||
if (slot == 0) {
|
||||
!isAssembling && ItemUtils.caseTier(stack) != Tier.None
|
||||
!isAssembling && AssemblerTemplates.select(stack).isDefined
|
||||
}
|
||||
else {
|
||||
val caseTier = ItemUtils.caseTier(items(0).orNull)
|
||||
caseTier != Tier.None && {
|
||||
val info = InventorySlots.assembler(caseTier)(slot)
|
||||
Option(Driver.driverFor(stack)) match {
|
||||
case Some(driver) if info.slot != Slot.None && info.tier != Tier.None => Slot.fromApi(driver.slot(stack)) == info.slot && driver.tier(stack) <= info.tier
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
else AssemblerTemplates.select(getStackInSlot(0)) match {
|
||||
case Some(template) =>
|
||||
val tplSlot =
|
||||
if ((1 until 4) contains slot) template.containerSlots(slot - 1)
|
||||
else if ((4 until 13) contains slot) template.upgradeSlots(slot - 4)
|
||||
else if ((13 until 21) contains slot) template.componentSlots(slot - 13)
|
||||
else AssemblerTemplates.NoSlot
|
||||
tplSlot.validate(this, slot, stack)
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,24 @@ object ExtendedNBT {
|
||||
nbt
|
||||
}
|
||||
|
||||
implicit def toNbt(value: Map[String, _]): NBTTagCompound = {
|
||||
val nbt = new NBTTagCompound()
|
||||
for ((key, value) <- value) value match {
|
||||
case value: Byte => nbt.setTag(key, value)
|
||||
case value: Short => nbt.setTag(key, value)
|
||||
case value: Int => nbt.setTag(key, value)
|
||||
case value: Array[Int] => nbt.setTag(key, value)
|
||||
case value: Long => nbt.setTag(key, value)
|
||||
case value: Float => nbt.setTag(key, value)
|
||||
case value: Double => nbt.setTag(key, value)
|
||||
case value: Array[Byte] => nbt.setTag(key, value)
|
||||
case value: String => nbt.setTag(key, value)
|
||||
case value: ItemStack => nbt.setTag(key, value)
|
||||
case _ =>
|
||||
}
|
||||
nbt
|
||||
}
|
||||
|
||||
implicit def byteIterableToNbt(value: Iterable[Byte]) = value.map(toNbt)
|
||||
|
||||
implicit def shortIterableToNbt(value: Iterable[Short]) = value.map(toNbt)
|
||||
|
Loading…
x
Reference in New Issue
Block a user