Materials for printing (plastic and ink).

This commit is contained in:
Florian Nücke 2015-03-23 21:02:08 +01:00
parent 1d7b6caa6f
commit 311973e33e
29 changed files with 223 additions and 89 deletions

Binary file not shown.

View File

@ -509,6 +509,10 @@ opencomputers {
# controls the speed at which items are disassembled, basically. # controls the speed at which items are disassembled, basically.
disassemblerTickAmount: 25 disassemblerTickAmount: 25
# The amount of energy the printer can apply per tick. This controls
# the speed at which prints are completed, basically.
printerTickAmount: 10
# If you don't want OpenComputers to accept power from one or more of the # If you don't want OpenComputers to accept power from one or more of the
# supported power mods, for example because it doesn't suit the vision # supported power mods, for example because it doesn't suit the vision
# of your mod pack, you can disable support for them here. To stop # of your mod pack, you can disable support for them here. To stop

View File

@ -23,6 +23,8 @@ tile.oc.microcontroller.name=Microcontroller
tile.oc.motionSensor.name=Motion Sensor tile.oc.motionSensor.name=Motion Sensor
tile.oc.powerConverter.name=Power Converter tile.oc.powerConverter.name=Power Converter
tile.oc.powerDistributor.name=Power Distributor tile.oc.powerDistributor.name=Power Distributor
tile.oc.print.name=3D Print
tile.oc.printer.name=3D Printer
tile.oc.raid.name=Raid tile.oc.raid.name=Raid
tile.oc.redstone.name=Redstone I/O tile.oc.redstone.name=Redstone I/O
tile.oc.robot.name=Robot tile.oc.robot.name=Robot
@ -66,6 +68,8 @@ item.oc.GraphicsCard2.name=Graphics Card (Tier 3)
item.oc.HardDiskDrive0.name=Hard Disk Drive (Tier 1) item.oc.HardDiskDrive0.name=Hard Disk Drive (Tier 1)
item.oc.HardDiskDrive1.name=Hard Disk Drive (Tier 2) item.oc.HardDiskDrive1.name=Hard Disk Drive (Tier 2)
item.oc.HardDiskDrive2.name=Hard Disk Drive (Tier 3) item.oc.HardDiskDrive2.name=Hard Disk Drive (Tier 3)
item.oc.InkCartridge.name=Ink Cartidge
item.oc.InkCartridgeEmpty.name=Ink Cartidge (Empty)
item.oc.InternetCard.name=Internet Card item.oc.InternetCard.name=Internet Card
item.oc.Interweb.name=Interweb item.oc.Interweb.name=Interweb
item.oc.IronNugget.name=Iron Nugget item.oc.IronNugget.name=Iron Nugget
@ -84,6 +88,7 @@ item.oc.MicrocontrollerCase1.name=Microcontroller Case (Tier 2)
item.oc.MicrocontrollerCase3.name=Microcontroller Case (Creative) item.oc.MicrocontrollerCase3.name=Microcontroller Case (Creative)
item.oc.NetworkCard.name=Network Card item.oc.NetworkCard.name=Network Card
item.oc.NumPad.name=Numeric Keypad item.oc.NumPad.name=Numeric Keypad
item.oc.Plastic.name=Plastic
item.oc.Present.name=A little something... item.oc.Present.name=A little something...
item.oc.PrintedCircuitBoard.name=Printed Circuit Board (PCB) item.oc.PrintedCircuitBoard.name=Printed Circuit Board (PCB)
item.oc.RawCircuitBoard.name=Raw Circuit Board item.oc.RawCircuitBoard.name=Raw Circuit Board
@ -197,6 +202,7 @@ oc:container.Charger=Charger
oc:container.Case=Computer oc:container.Case=Computer
oc:container.Disassembler=Disassembler oc:container.Disassembler=Disassembler
oc:container.DiskDrive=Disk Drive oc:container.DiskDrive=Disk Drive
oc:container.Printer=Printer
oc:container.Raid=Raid oc:container.Raid=Raid
oc:container.Server=Server oc:container.Server=Server
oc:container.ServerRack=Server Rack oc:container.ServerRack=Server Rack
@ -237,6 +243,8 @@ oc:tooltip.DroneCase=This casing is used to build Drones in the assembler. It ha
oc:tooltip.EEPROM=Small, programmable storage that contains the BIOS computers use to boot. oc:tooltip.EEPROM=Small, programmable storage that contains the BIOS computers use to boot.
oc:tooltip.Geolyzer=Allows scanning the surrounding area's blocks' hardness. This information can be useful for generating holograms of the area or for detecting ores. oc:tooltip.Geolyzer=Allows scanning the surrounding area's blocks' hardness. This information can be useful for generating holograms of the area or for detecting ores.
oc:tooltip.GraphicsCard=Used to change what's displayed on screens.[nl] Maximum resolution: §f%sx%s§7[nl] Maximum color depth: §f%s§7[nl] Operations/tick: §f%s§7 oc:tooltip.GraphicsCard=Used to change what's displayed on screens.[nl] Maximum resolution: §f%sx%s§7[nl] Maximum color depth: §f%s§7[nl] Operations/tick: §f%s§7
oc:tooltip.InkCartridge=Used to refill ink in 3D printers. For mysterious reasons it does not have to remain in the printer.
oc:tooltip.InkCartridgeEmpty=This ink cartridge has been sucked dry. Refill it using dyes. Or throw it away. See if I care.
oc:tooltip.InternetCard=This card allows making HTTP requests and using real TCP sockets. oc:tooltip.InternetCard=This card allows making HTTP requests and using real TCP sockets.
oc:tooltip.Interweb=Congratulations, you win one (1) interweb. You can connect to it using an Internet Card. Beware: don't feed the trolls. oc:tooltip.Interweb=Congratulations, you win one (1) interweb. You can connect to it using an Internet Card. Beware: don't feed the trolls.
oc:tooltip.IronNugget=A nugget made of iron, that's why it's called an Iron Nugget, duh... oc:tooltip.IronNugget=A nugget made of iron, that's why it's called an Iron Nugget, duh...
@ -253,6 +261,7 @@ oc:tooltip.Microcontroller=Microcontrollers are computers boiled down to the ess
oc:tooltip.MicrocontrollerCase=Base component for building microcontrollers. Place it into an assembler to add further components and assemble a microcontroller. oc:tooltip.MicrocontrollerCase=Base component for building microcontrollers. Place it into an assembler to add further components and assemble a microcontroller.
oc:tooltip.MotionSensor=Can detect movement of nearby living beings. Requires clear line-of-sight. oc:tooltip.MotionSensor=Can detect movement of nearby living beings. Requires clear line-of-sight.
oc:tooltip.NetworkCard=Allows distant computers connected by other blocks (such as cable) to communicate by sending messages to each other. oc:tooltip.NetworkCard=Allows distant computers connected by other blocks (such as cable) to communicate by sending messages to each other.
oc:tooltip.Plastic=Raw material for 3D prints. Do not swallow. Not that you could even if you wanted to.
oc:tooltip.PowerAcceptor=Energy conversion speed: §f%s/t§7 oc:tooltip.PowerAcceptor=Energy conversion speed: §f%s/t§7
oc:tooltip.PowerConverter.BuildCraft=§fBuildCraft MJ§7: §a%s:%s§7 oc:tooltip.PowerConverter.BuildCraft=§fBuildCraft MJ§7: §a%s:%s§7
oc:tooltip.PowerConverter.Factorization=§fFactorization Charge§7: §a%s:%s§7 oc:tooltip.PowerConverter.Factorization=§fFactorization Charge§7: §a%s:%s§7
@ -262,6 +271,7 @@ oc:tooltip.PowerConverter.ThermalExpansion=§fThermal Expansion RF§7: §a%s:%s
oc:tooltip.PowerConverter.ResonantEngine=§fResonant Engine Coulombs§7: §a%s:%s§7 oc:tooltip.PowerConverter.ResonantEngine=§fResonant Engine Coulombs§7: §a%s:%s§7
oc:tooltip.PowerConverter=Converts power from other mods to the internal energy type. Conversion rates: oc:tooltip.PowerConverter=Converts power from other mods to the internal energy type. Conversion rates:
oc:tooltip.PowerDistributor=Distributes energy among different networks. This is useful for sharing power fed into your system from one converter among different sub-networks that should remain separate. oc:tooltip.PowerDistributor=Distributes energy among different networks. This is useful for sharing power fed into your system from one converter among different sub-networks that should remain separate.
oc:tooltip.Printer=Allows printing blocks of user-defined shapes using plastic and ink cartridges. Must be configured using a computer. Keep away from small children. Because reasons.
oc:tooltip.PrintedCircuitBoard=The basic building block for expansion cards and memory and such. oc:tooltip.PrintedCircuitBoard=The basic building block for expansion cards and memory and such.
oc:tooltip.Present=... for your troubles. Open this present for a chance to receive some §kphat lewt§7![nl]§8Craft OpenComputers items when the time is right for a chance to receive a present.§7 oc:tooltip.Present=... for your troubles. Open this present for a chance to receive some §kphat lewt§7![nl]§8Craft OpenComputers items when the time is right for a chance to receive a present.§7
oc:tooltip.Raid=Allows combining three hard drives into one larger file system that can be used by all connected computers. oc:tooltip.Raid=Allows combining three hard drives into one larger file system that can be used by all connected computers.

View File

@ -318,6 +318,21 @@ disk {
[nuggetIron, "", nuggetIron] [nuggetIron, "", nuggetIron]
["", nuggetIron, ""]] ["", nuggetIron, ""]]
} }
plastic {
input: [[gravel, gravel, gravel],
[gravel, {item=coal, subID=1}, gravel],
[gravel, water_bucket, gravel]]
output: 8
}
inkCartridgeEmpty {
input: [[nuggetIron, dispenser, nuggetIron],
["oc:materialTransistor", bucket, "oc:materialTransistor"],
[nuggetIron, "oc:materialCircuitBoardPrinted", nuggetIron]]
}
inkCartridge {
type: shapeless
input: [dyeCyan, dyeMagenta, dyeYellow, dyeBlack, "oc:inkCartridgeEmpty"]
}
buttonGroup { buttonGroup {
input: [[button, button, button] input: [[button, button, button]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

View File

@ -139,6 +139,7 @@ class Settings(val config: Config) {
val solarGeneratorEfficiency = config.getDouble("power.solarGeneratorEfficiency") val solarGeneratorEfficiency = config.getDouble("power.solarGeneratorEfficiency")
val assemblerTickAmount = config.getDouble("power.assemblerTickAmount") max 1 val assemblerTickAmount = config.getDouble("power.assemblerTickAmount") max 1
val disassemblerTickAmount = config.getDouble("power.disassemblerTickAmount") max 1 val disassemblerTickAmount = config.getDouble("power.disassemblerTickAmount") max 1
val printerTickAmount = config.getDouble("power.printerTickAmount") max 1
val powerModBlacklist = config.getStringList("power.modBlacklist") val powerModBlacklist = config.getStringList("power.modBlacklist")
// power.buffer // power.buffer

View File

@ -52,6 +52,7 @@ object PacketHandler extends CommonPacketHandler {
case PacketType.HologramTranslation => onHologramPositionOffsetY(p) case PacketType.HologramTranslation => onHologramPositionOffsetY(p)
case PacketType.PetVisibility => onPetVisibility(p) case PacketType.PetVisibility => onPetVisibility(p)
case PacketType.PowerState => onPowerState(p) case PacketType.PowerState => onPowerState(p)
case PacketType.PrinterState => onPrinterState(p)
case PacketType.RaidStateChange => onRaidStateChange(p) case PacketType.RaidStateChange => onRaidStateChange(p)
case PacketType.RedstoneState => onRedstoneState(p) case PacketType.RedstoneState => onRedstoneState(p)
case PacketType.RobotAnimateSwing => onRobotAnimateSwing(p) case PacketType.RobotAnimateSwing => onRobotAnimateSwing(p)
@ -242,6 +243,14 @@ object PacketHandler extends CommonPacketHandler {
case _ => // Invalid packet. case _ => // Invalid packet.
} }
def onPrinterState(p: PacketParser) =
p.readTileEntity[Printer]() match {
case Some(t) =>
if (p.readBoolean()) t.requiredEnergy = 9001
else t.requiredEnergy = 0
case _ => // Invalid packet.
}
def onRaidStateChange(p: PacketParser) = def onRaidStateChange(p: PacketParser) =
p.readTileEntity[Raid]() match { p.readTileEntity[Raid]() match {
case Some(t) => case Some(t) =>

View File

@ -26,6 +26,8 @@ object Textures {
val guiDrone = new ResourceLocation(Settings.resourceDomain, "textures/gui/drone.png") val guiDrone = new ResourceLocation(Settings.resourceDomain, "textures/gui/drone.png")
val guiKeyboardMissing = new ResourceLocation(Settings.resourceDomain, "textures/gui/keyboard_missing.png") val guiKeyboardMissing = new ResourceLocation(Settings.resourceDomain, "textures/gui/keyboard_missing.png")
val guiPrinter = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer.png") val guiPrinter = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer.png")
val guiPrinterInk = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer_ink.png")
val guiPrinterPlastic = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer_plastic.png")
val guiPrinterProgress = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer_progress.png") val guiPrinterProgress = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer_progress.png")
val guiRaid = new ResourceLocation(Settings.resourceDomain, "textures/gui/raid.png") val guiRaid = new ResourceLocation(Settings.resourceDomain, "textures/gui/raid.png")
val guiRange = new ResourceLocation(Settings.resourceDomain, "textures/gui/range.png") val guiRange = new ResourceLocation(Settings.resourceDomain, "textures/gui/range.png")

View File

@ -3,19 +3,31 @@ package li.cil.oc.client.gui
import li.cil.oc.Localization import li.cil.oc.Localization
import li.cil.oc.client.Textures import li.cil.oc.client.Textures
import li.cil.oc.client.gui.widget.ProgressBar import li.cil.oc.client.gui.widget.ProgressBar
import li.cil.oc.client.{PacketSender => ClientPacketSender}
import li.cil.oc.common.container import li.cil.oc.common.container
import li.cil.oc.common.container.ComponentSlot import li.cil.oc.common.container.ComponentSlot
import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity
import net.minecraft.entity.player.InventoryPlayer import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.util.ResourceLocation
import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.GL11
class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer) extends DynamicGuiContainer(new container.Printer(playerInventory, printer)) { class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer) extends DynamicGuiContainer(new container.Printer(playerInventory, printer)) {
xSize = 176 xSize = 176
ySize = 166 ySize = 166
private val progress = addWidget(new ProgressBar(104, 21) { private val plasticBar = addWidget(new ProgressBar(40, 21) {
override def width = 62
override def height = 12
override def barTexture = Textures.guiPrinterPlastic
})
private val inkBar = addWidget(new ProgressBar(40, 53) {
override def width = 62
override def height = 12
override def barTexture = Textures.guiPrinterInk
})
private val progressBar = addWidget(new ProgressBar(105, 20) {
override def width = 46 override def width = 46
override def height = 46 override def height = 46
@ -23,7 +35,7 @@ class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer)
override def barTexture = Textures.guiPrinterProgress override def barTexture = Textures.guiPrinterProgress
}) })
private def assemblerContainer = inventorySlots.asInstanceOf[container.Printer] private def printerContainer = inventorySlots.asInstanceOf[container.Printer]
override def initGui() { override def initGui() {
super.initGui() super.initGui()
@ -35,27 +47,27 @@ class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer)
Localization.localizeImmediately(printer.getInventoryName), Localization.localizeImmediately(printer.getInventoryName),
8, 6, 0x404040) 8, 6, 0x404040)
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) // Me lazy... prevents NEI render glitch. GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) // Me lazy... prevents NEI render glitch.
if (assemblerContainer.isAssembling && func_146978_c(progress.x, progress.y, progress.width, progress.height, mouseX, mouseY)) { if (func_146978_c(plasticBar.x, plasticBar.y, plasticBar.width, plasticBar.height, mouseX, mouseY)) {
val tooltip = new java.util.ArrayList[String] val tooltip = new java.util.ArrayList[String]
val timeRemaining = formatTime(assemblerContainer.assemblyRemainingTime) tooltip.add(printerContainer.amountPlastic + "/" + printer.maxAmountPlastic)
tooltip.add(Localization.Assembler.Progress(assemblerContainer.assemblyProgress, timeRemaining)) copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRendererObj)
}
if (func_146978_c(inkBar.x, inkBar.y, inkBar.width, inkBar.height, mouseX, mouseY)) {
val tooltip = new java.util.ArrayList[String]
tooltip.add(printerContainer.amountInk + "/" + printer.maxAmountInk)
copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRendererObj) copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRendererObj)
} }
GL11.glPopAttrib() GL11.glPopAttrib()
} }
private def formatTime(seconds: Int) = {
// Assembly times should not / rarely exceed one hour, so this is good enough.
if (seconds < 60) f"0:$seconds%02d"
else f"${seconds / 60}:${seconds % 60}%02d"
}
override def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) { override def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) {
GL11.glColor3f(1, 1, 1) // Required under Linux. GL11.glColor3f(1, 1, 1) // Required under Linux.
mc.renderEngine.bindTexture(Textures.guiPrinter) mc.renderEngine.bindTexture(Textures.guiPrinter)
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize)
if (assemblerContainer.isAssembling) progress.level = assemblerContainer.assemblyProgress / 100.0 plasticBar.level = printerContainer.amountPlastic / printer.maxAmountPlastic.toDouble
else progress.level = 0 inkBar.level = printerContainer.amountInk / printer.maxAmountInk.toDouble
if (printerContainer.isPrinting) progressBar.level = (System.currentTimeMillis() % 3000) / 3000.0
else progressBar.level = 0
drawWidgets() drawWidgets()
drawInventorySlots() drawInventorySlots()
} }

View File

@ -16,8 +16,8 @@ class ProgressBar(val x: Int, val y: Int) extends Widget {
def draw() { def draw() {
if (level > 0) { if (level > 0) {
val u0 = 0 val u0 = 0
val u1 = width / 256.0 * level val u1 = level
val v0 = 1 - height / 256.0 val v0 = 0
val v1 = 1 val v1 = 1
val tx = owner.windowX + x val tx = owner.windowX + x
val ty = owner.windowY + y val ty = owner.windowY + y

View File

@ -20,6 +20,7 @@ object PacketType extends Enumeration {
HologramTranslation, HologramTranslation,
PetVisibility, // Goes both ways. PetVisibility, // Goes both ways.
PowerState, PowerState,
PrinterState,
RaidStateChange, RaidStateChange,
RedstoneState, RedstoneState,
RobotAnimateSwing, RobotAnimateSwing,

View File

@ -5,6 +5,7 @@ import li.cil.oc.api.driver
object Slot { object Slot {
val None = driver.item.Slot.None val None = driver.item.Slot.None
val Any = driver.item.Slot.Any val Any = driver.item.Slot.Any
val Filtered = "filtered"
val Card = driver.item.Slot.Card val Card = driver.item.Slot.Card
val ComponentBus = driver.item.Slot.ComponentBus val ComponentBus = driver.item.Slot.ComponentBus

View File

@ -5,6 +5,7 @@ import java.util
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.client.KeyBindings import li.cil.oc.client.KeyBindings
import li.cil.oc.common.item.data.PrintData
import li.cil.oc.common.item.data.RobotData import li.cil.oc.common.item.data.RobotData
import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity
import li.cil.oc.util.ItemCosts import li.cil.oc.util.ItemCosts
@ -47,6 +48,14 @@ class Item(value: Block) extends ItemBlock(value) {
override def getMetadata(itemDamage: Int) = itemDamage override def getMetadata(itemDamage: Int) = itemDamage
override def getItemStackDisplayName(stack: ItemStack): String = {
if (api.Items.get(stack) == api.Items.get("print")) {
val data = new PrintData(stack)
data.label.getOrElse(super.getItemStackDisplayName(stack))
}
else super.getItemStackDisplayName(stack)
}
override def getUnlocalizedName = block match { override def getUnlocalizedName = block match {
case simple: SimpleBlock => simple.getUnlocalizedName case simple: SimpleBlock => simple.getUnlocalizedName
case _ => Settings.namespace + "tile" case _ => Settings.namespace + "tile"

View File

@ -1,6 +1,9 @@
package li.cil.oc.common.block package li.cil.oc.common.block
import java.util
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.common.item.data.PrintData
import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity
import li.cil.oc.util.ExtendedAABB import li.cil.oc.util.ExtendedAABB
import net.minecraft.entity.EntityLivingBase import net.minecraft.entity.EntityLivingBase
@ -11,6 +14,7 @@ import net.minecraft.world.IBlockAccess
import net.minecraft.world.World import net.minecraft.world.World
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
import scala.collection.convert.WrapAsJava._
import scala.reflect.ClassTag import scala.reflect.ClassTag
class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends SimpleBlock with traits.SpecialBlock with traits.CustomDrops[tileentity.Print] { class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends SimpleBlock with traits.SpecialBlock with traits.CustomDrops[tileentity.Print] {
@ -19,6 +23,12 @@ class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends
// NEI.hide(this) // NEI.hide(this)
setBlockTextureName(Settings.resourceDomain + "GenericTop") setBlockTextureName(Settings.resourceDomain + "GenericTop")
override protected def tooltipBody(metadata: Int, stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean): Unit = {
super.tooltipBody(metadata, stack, player, tooltip, advanced)
val data = new PrintData(stack)
data.tooltip.foreach(s => tooltip.addAll(s.lines.toIterable))
}
override def shouldSideBeRendered(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = true override def shouldSideBeRendered(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = true
override def isBlockSolid(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = true override def isBlockSolid(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = true

View File

@ -9,7 +9,7 @@ import net.minecraft.world.IBlockAccess
import net.minecraft.world.World import net.minecraft.world.World
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
class Printer extends SimpleBlock with traits.SpecialBlock with traits.PowerAcceptor with traits.StateAware with traits.GUI { class Printer extends SimpleBlock with traits.SpecialBlock with traits.StateAware with traits.GUI {
override protected def customTextures = Array( override protected def customTextures = Array(
None, None,
Some("AssemblerTop"), Some("AssemblerTop"),
@ -32,8 +32,6 @@ class Printer extends SimpleBlock with traits.SpecialBlock with traits.PowerAcce
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def energyThroughput = Settings.get.assemblerRate
override def guiType = GuiType.Printer override def guiType = GuiType.Printer
override def hasTileEntity(metadata: Int) = true override def hasTileEntity(metadata: Int) = true

View File

@ -28,7 +28,7 @@ class DynamicComponentSlot(val container: Player, inventory: IInventory, index:
override def getSlotStackLimit = override def getSlotStackLimit =
slot match { slot match {
case common.Slot.Tool | common.Slot.Any => super.getSlotStackLimit case common.Slot.Tool | common.Slot.Any | common.Slot.Filtered => super.getSlotStackLimit
case common.Slot.None => 0 case common.Slot.None => 0
case _ => 1 case _ => 1
} }

View File

@ -2,51 +2,53 @@ package li.cil.oc.common.container
import cpw.mods.fml.relauncher.Side import cpw.mods.fml.relauncher.Side
import cpw.mods.fml.relauncher.SideOnly import cpw.mods.fml.relauncher.SideOnly
import li.cil.oc.common.Slot
import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity
import li.cil.oc.util.SideTracker import li.cil.oc.util.SideTracker
import net.minecraft.entity.player.InventoryPlayer import net.minecraft.entity.player.InventoryPlayer
class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer) extends Player(playerInventory, printer) { class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer) extends Player(playerInventory, printer) {
addSlotToContainer(18, 19) addSlotToContainer(18, 19, Slot.Filtered)
addSlotToContainer(18, 51) addSlotToContainer(18, 51, Slot.Filtered)
addSlotToContainer(152, 35) addSlotToContainer(152, 35)
// Show the player's inventory. // Show the player's inventory.
addPlayerInventorySlots(8, 84) addPlayerInventorySlots(8, 84)
var isAssembling = false var isPrinting = false
var assemblyProgress = 0.0 var amountPlastic = 0
var assemblyRemainingTime = 0 var amountInk = 0
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
override def updateProgressBar(id: Int, value: Int) { override def updateProgressBar(id: Int, value: Int) {
super.updateProgressBar(id, value) super.updateProgressBar(id, value)
if (id == 0) { if (id == 0) {
isAssembling = value == 1 isPrinting = value == 1
} }
if (id == 1) { if (id == 1) {
assemblyProgress = value / 5.0 amountPlastic = value
} }
if (id == 2) { if (id == 2) {
assemblyRemainingTime = value amountInk = value
} }
} }
override def detectAndSendChanges() { override def detectAndSendChanges() {
super.detectAndSendChanges() super.detectAndSendChanges()
if (SideTracker.isServer) { if (SideTracker.isServer) {
if (isAssembling != printer.isAssembling) { if (isPrinting != printer.isPrinting) {
isAssembling = printer.isAssembling isPrinting = printer.isPrinting
sendProgressBarUpdate(0, if (isAssembling) 1 else 0) sendProgressBarUpdate(0, if (isPrinting) 1 else 0)
} }
val timeRemaining = printer.timeRemaining if (amountPlastic != printer.amountPlastic) {
if (math.abs(printer.progress - assemblyProgress) > 0.2 || assemblyRemainingTime != timeRemaining) { amountPlastic = printer.amountPlastic
assemblyProgress = printer.progress sendProgressBarUpdate(1, amountPlastic)
assemblyRemainingTime = timeRemaining }
sendProgressBarUpdate(1, (assemblyProgress * 5).toInt) if (amountInk != printer.amountInk) {
sendProgressBarUpdate(2, timeRemaining) amountInk = printer.amountInk
sendProgressBarUpdate(2, amountInk)
} }
} }
} }

View File

@ -12,7 +12,7 @@ class StaticComponentSlot(val container: Player, inventory: IInventory, index: I
override def getSlotStackLimit = override def getSlotStackLimit =
slot match { slot match {
case common.Slot.Tool | common.Slot.Any => super.getSlotStackLimit case common.Slot.Tool | common.Slot.Any | common.Slot.Filtered => super.getSlotStackLimit
case common.Slot.None => 0 case common.Slot.None => 0
case _ => 1 case _ => 1
} }

View File

@ -470,5 +470,10 @@ object Items extends ItemAPI {
// 1.4.7 // 1.4.7
Recipes.addMultiItem(new item.TabletCase(multi, Tier.Two), "tabletCase2", "oc:tabletCase2") Recipes.addMultiItem(new item.TabletCase(multi, Tier.Two), "tabletCase2", "oc:tabletCase2")
registerItem(new item.TabletCase(multi, Tier.Four), "tabletCaseCreative") registerItem(new item.TabletCase(multi, Tier.Four), "tabletCaseCreative")
// 1.5.4
Recipes.addMultiItem(new item.InkCartridgeEmpty(multi), "inkCartridgeEmpty", "oc:inkCartridgeEmpty")
Recipes.addMultiItem(new item.InkCartridge(multi), "inkCartridge", "oc:inkCartridge")
Recipes.addMultiItem(new item.Plastic(multi), "plastic", "oc:plastic")
} }
} }

View File

@ -0,0 +1,5 @@
package li.cil.oc.common.item
class InkCartridge(val parent: Delegator) extends Delegate {
override def maxStackSize = 1
}

View File

@ -0,0 +1,5 @@
package li.cil.oc.common.item
class InkCartridgeEmpty(val parent: Delegator) extends Delegate {
override def maxStackSize = 1
}

View File

@ -0,0 +1,3 @@
package li.cil.oc.common.item
class Plastic(val parent: Delegator) extends Delegate

View File

@ -11,6 +11,7 @@ import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context import li.cil.oc.api.machine.Context
import li.cil.oc.api.network._ import li.cil.oc.api.network._
import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.item.data.PrintData
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedAABB._ import li.cil.oc.util.ExtendedAABB._
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils import li.cil.oc.util.ItemUtils
@ -19,18 +20,26 @@ import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.AxisAlignedBB import net.minecraft.util.AxisAlignedBB
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
class Printer extends traits.Environment with traits.PowerAcceptor with traits.Inventory with traits.Rotatable with SidedEnvironment with traits.StateAware { class Printer extends traits.Environment with traits.Inventory with traits.Rotatable with SidedEnvironment with traits.StateAware {
val node = api.Network.newNode(this, Visibility.Network). val node = api.Network.newNode(this, Visibility.Network).
withComponent("printer3d"). withComponent("printer3d").
withConnector(Settings.get.bufferConverter). withConnector(Settings.get.bufferConverter).
create() create()
val maxAmountPlastic = 256000
var amountPlastic = 0
val maxAmountInk = 100000
var amountInk = 0
var data = new PrintData() var data = new PrintData()
var isActive = false var isActive = false
var output: Option[ItemStack] = None var output: Option[ItemStack] = None
var totalRequiredEnergy = 0.0 var totalRequiredEnergy = 0.0
var requiredEnergy = 0.0 var requiredEnergy = 0.0
val plasticPerItem = 2000
val inkPerCartridge = 50000
val slotPlastic = 0 val slotPlastic = 0
val slotInk = 1 val slotInk = 1
val slotOutput = 2 val slotOutput = 2
@ -42,27 +51,22 @@ class Printer extends traits.Environment with traits.PowerAcceptor with traits.I
override def sidedNode(side: ForgeDirection) = if (side != ForgeDirection.UP) node else null override def sidedNode(side: ForgeDirection) = if (side != ForgeDirection.UP) node else null
@SideOnly(Side.CLIENT)
override protected def hasConnector(side: ForgeDirection) = canConnect(side)
override protected def connector(side: ForgeDirection) = Option(if (side != ForgeDirection.UP) node else null)
override protected def energyThroughput = Settings.get.assemblerRate
override def currentState = { override def currentState = {
if (isAssembling) util.EnumSet.of(traits.State.IsWorking) if (isPrinting) util.EnumSet.of(traits.State.IsWorking)
else if (canAssemble) util.EnumSet.of(traits.State.CanWork) else if (canPrint) util.EnumSet.of(traits.State.CanWork)
else util.EnumSet.noneOf(classOf[traits.State]) else util.EnumSet.noneOf(classOf[traits.State])
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
def canAssemble = { def canPrint = {
val complexity = data.stateOff.size + data.stateOn.size val complexity = data.stateOff.size + data.stateOn.size
complexity > 0 && complexity <= Settings.get.maxPrintComplexity complexity > 0 && complexity <= Settings.get.maxPrintComplexity
} }
def isAssembling = requiredEnergy > 0 def isPrinting = (requiredEnergy > 0 || isActive) && Option(getStackInSlot(slotOutput)).fold(true)(stack => {
stack.stackSize < stack.getMaxStackSize && output.fold(true)(ItemStack.areItemStackTagsEqual(stack, _))
})
def progress = (1 - requiredEnergy / totalRequiredEnergy) * 100 def progress = (1 - requiredEnergy / totalRequiredEnergy) * 100
@ -79,7 +83,7 @@ class Printer extends traits.Environment with traits.PowerAcceptor with traits.I
@Callback(doc = """function(value:string) -- Set a label for the block being printed.""") @Callback(doc = """function(value:string) -- Set a label for the block being printed.""")
def setLabel(context: Context, args: Arguments): Array[Object] = { def setLabel(context: Context, args: Arguments): Array[Object] = {
data.label = Option(args.optString(0, null)) data.label = Option(args.optString(0, null)).map(_.take(16))
isActive = false // Needs committing. isActive = false // Needs committing.
null null
} }
@ -91,7 +95,7 @@ class Printer extends traits.Environment with traits.PowerAcceptor with traits.I
@Callback(doc = """function(value:string) -- Set a tooltip for the block being printed.""") @Callback(doc = """function(value:string) -- Set a tooltip for the block being printed.""")
def setTooltip(context: Context, args: Arguments): Array[Object] = { def setTooltip(context: Context, args: Arguments): Array[Object] = {
data.tooltip = Option(args.optString(0, null)) data.tooltip = Option(args.optString(0, null)).map(_.take(128))
isActive = false // Needs committing. isActive = false // Needs committing.
null null
} }
@ -140,7 +144,7 @@ class Printer extends traits.Environment with traits.PowerAcceptor with traits.I
@Callback(doc = """function():boolean -- Commit and begin printing the current configuration.""") @Callback(doc = """function():boolean -- Commit and begin printing the current configuration.""")
def commit(context: Context, args: Arguments): Array[Object] = { def commit(context: Context, args: Arguments): Array[Object] = {
if (!canAssemble) { if (!canPrint) {
return result(null, "model invalid") return result(null, "model invalid")
} }
isActive = true isActive = true
@ -149,8 +153,8 @@ class Printer extends traits.Environment with traits.PowerAcceptor with traits.I
@Callback(doc = """function(): string, number or boolean -- The current state of the printer, `busy' or `idle', followed by the progress or model validity, respectively.""") @Callback(doc = """function(): string, number or boolean -- The current state of the printer, `busy' or `idle', followed by the progress or model validity, respectively.""")
def status(context: Context, args: Arguments): Array[Object] = { def status(context: Context, args: Arguments): Array[Object] = {
if (isAssembling) result("busy", progress) if (isPrinting) result("busy", progress)
else if (canAssemble) result("idle", true) else if (canPrint) result("idle", true)
else result("idle", false) else result("idle", false)
} }
@ -163,47 +167,74 @@ class Printer extends traits.Environment with traits.PowerAcceptor with traits.I
override def updateEntity() { override def updateEntity() {
super.updateEntity() super.updateEntity()
if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) { if (isActive && output.isEmpty) {
if (isActive && output.isEmpty) { val totalVolume = data.stateOn.foldLeft(0)((acc, shape) => acc + shape.bounds.volume) + data.stateOff.foldLeft(0)((acc, shape) => acc + shape.bounds.volume)
val totalVolume = data.stateOn.foldLeft(0)((acc, shape) => acc + shape.bounds.volume) + data.stateOff.foldLeft(0)((acc, shape) => acc + shape.bounds.volume) val totalSurface = data.stateOn.foldLeft(0)((acc, shape) => acc + shape.bounds.surface) + data.stateOff.foldLeft(0)((acc, shape) => acc + shape.bounds.surface)
val totalSurface = data.stateOn.foldLeft(0)((acc, shape) => acc + shape.bounds.surface) + data.stateOff.foldLeft(0)((acc, shape) => acc + shape.bounds.surface) val totalShapes = data.stateOn.size + data.stateOff.size
val totalShapes = data.stateOn.size + data.stateOff.size
// TODO Consume plastic (totalVolume) and ink (totalSurface). if (totalVolume == 0) {
isActive = false
}
else {
val plasticRequired = totalVolume
val inkRequired = (totalSurface / 6) max 1
totalRequiredEnergy = totalShapes * Settings.get.printShapeCost totalRequiredEnergy = totalShapes * Settings.get.printShapeCost
requiredEnergy = totalRequiredEnergy requiredEnergy = totalRequiredEnergy
output = Option(data.createItemStack())
// ServerPacketSender.sendRobotAssembling(this, assembling = true)
}
if (output.isDefined) { if (amountPlastic >= plasticRequired && amountInk >= inkRequired) {
val want = math.max(1, math.min(requiredEnergy, Settings.get.assemblerTickAmount * Settings.get.tickFrequency)) amountPlastic -= plasticRequired
val success = Settings.get.ignorePower || node.tryChangeBuffer(-want) amountInk -= inkRequired
if (success) { output = Option(data.createItemStack())
requiredEnergy -= want ServerPacketSender.sendPrinting(this, printing = true)
} }
if (requiredEnergy <= 0) { }
val result = getStackInSlot(slotOutput) }
if (result == null) {
setInventorySlotContents(slotOutput, output.get) if (output.isDefined) {
} val want = math.max(1, math.min(requiredEnergy, Settings.get.printerTickAmount))
else if (output.get.isItemEqual(result) && ItemStack.areItemStackTagsEqual(output.get, result) && result.stackSize < result.getMaxStackSize) { val success = Settings.get.ignorePower || node.tryChangeBuffer(-want)
result.stackSize += 1 if (success) {
markDirty() requiredEnergy -= want
} }
else { if (requiredEnergy <= 0) {
return val result = getStackInSlot(slotOutput)
} if (result == null) {
requiredEnergy = 0 setInventorySlotContents(slotOutput, output.get)
output = None
} }
// ServerPacketSender.sendRobotAssembling(this, success && output.isDefined) else if (output.get.isItemEqual(result) && ItemStack.areItemStackTagsEqual(output.get, result) && result.stackSize < result.getMaxStackSize) {
result.stackSize += 1
markDirty()
}
else {
return
}
requiredEnergy = 0
output = None
}
ServerPacketSender.sendPrinting(this, success && output.isDefined)
}
if (maxAmountPlastic - amountPlastic >= plasticPerItem) {
val plastic = decrStackSize(slotPlastic, 1)
if (plastic != null) {
amountPlastic += plasticPerItem
}
}
if (maxAmountInk - amountInk >= inkPerCartridge) {
if (api.Items.get(getStackInSlot(slotInk)) == api.Items.get("inkCartridge")) {
setInventorySlotContents(slotInk, api.Items.get("inkCartridgeEmpty").createItemStack(1))
amountInk += inkPerCartridge
} }
} }
} }
override def readFromNBTForServer(nbt: NBTTagCompound) { override def readFromNBTForServer(nbt: NBTTagCompound) {
super.readFromNBTForServer(nbt) super.readFromNBTForServer(nbt)
data.load(nbt.getCompoundTag("data")) amountPlastic = nbt.getInteger(Settings.namespace + "amountPlastic")
amountInk = nbt.getInteger(Settings.namespace + "amountInk")
data.load(nbt.getCompoundTag(Settings.namespace + "data"))
isActive = nbt.getBoolean(Settings.namespace + "active") isActive = nbt.getBoolean(Settings.namespace + "active")
if (nbt.hasKey(Settings.namespace + "output")) { if (nbt.hasKey(Settings.namespace + "output")) {
output = Option(ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "output"))) output = Option(ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "output")))
@ -214,7 +245,9 @@ class Printer extends traits.Environment with traits.PowerAcceptor with traits.I
override def writeToNBTForServer(nbt: NBTTagCompound) { override def writeToNBTForServer(nbt: NBTTagCompound) {
super.writeToNBTForServer(nbt) super.writeToNBTForServer(nbt)
nbt.setNewCompoundTag("data", data.save) nbt.setInteger(Settings.namespace + "amountPlastic", amountPlastic)
nbt.setInteger(Settings.namespace + "amountInk", amountInk)
nbt.setNewCompoundTag(Settings.namespace + "data", data.save)
nbt.setBoolean(Settings.namespace + "active", isActive) nbt.setBoolean(Settings.namespace + "active", isActive)
output.foreach(stack => nbt.setNewCompoundTag(Settings.namespace + "output", stack.writeToNBT)) output.foreach(stack => nbt.setNewCompoundTag(Settings.namespace + "output", stack.writeToNBT))
nbt.setDouble(Settings.namespace + "total", totalRequiredEnergy) nbt.setDouble(Settings.namespace + "total", totalRequiredEnergy)
@ -240,8 +273,8 @@ class Printer extends traits.Environment with traits.PowerAcceptor with traits.I
override def isItemValidForSlot(slot: Int, stack: ItemStack) = override def isItemValidForSlot(slot: Int, stack: ItemStack) =
if (slot == 0) if (slot == 0)
true // TODO Plastic api.Items.get(stack) == api.Items.get("plastic")
else if (slot == 1) else if (slot == 1)
true // TODO Color api.Items.get(stack) == api.Items.get("inkCartridge")
else false else false
} }

View File

@ -226,6 +226,15 @@ object PacketSender {
pb.sendToPlayersNearTileEntity(t) pb.sendToPlayersNearTileEntity(t)
} }
def sendPrinting(t: tileentity.Printer, printing: Boolean) {
val pb = new SimplePacketBuilder(PacketType.PrinterState)
pb.writeTileEntity(t)
pb.writeBoolean(printing)
pb.sendToPlayersNearHost(t)
}
def sendRaidChange(t: tileentity.Raid) { def sendRaidChange(t: tileentity.Raid) {
val pb = new SimplePacketBuilder(PacketType.RaidStateChange) val pb = new SimplePacketBuilder(PacketType.RaidStateChange)