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.
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
# 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

View File

@ -23,6 +23,8 @@ tile.oc.microcontroller.name=Microcontroller
tile.oc.motionSensor.name=Motion Sensor
tile.oc.powerConverter.name=Power Converter
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.redstone.name=Redstone I/O
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.HardDiskDrive1.name=Hard Disk Drive (Tier 2)
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.Interweb.name=Interweb
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.NetworkCard.name=Network Card
item.oc.NumPad.name=Numeric Keypad
item.oc.Plastic.name=Plastic
item.oc.Present.name=A little something...
item.oc.PrintedCircuitBoard.name=Printed Circuit Board (PCB)
item.oc.RawCircuitBoard.name=Raw Circuit Board
@ -197,6 +202,7 @@ oc:container.Charger=Charger
oc:container.Case=Computer
oc:container.Disassembler=Disassembler
oc:container.DiskDrive=Disk Drive
oc:container.Printer=Printer
oc:container.Raid=Raid
oc:container.Server=Server
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.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.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.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...
@ -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.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.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.PowerConverter.BuildCraft=§fBuildCraft MJ§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=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.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.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.

View File

@ -318,6 +318,21 @@ disk {
[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 {
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 assemblerTickAmount = config.getDouble("power.assemblerTickAmount") max 1
val disassemblerTickAmount = config.getDouble("power.disassemblerTickAmount") max 1
val printerTickAmount = config.getDouble("power.printerTickAmount") max 1
val powerModBlacklist = config.getStringList("power.modBlacklist")
// power.buffer

View File

@ -52,6 +52,7 @@ object PacketHandler extends CommonPacketHandler {
case PacketType.HologramTranslation => onHologramPositionOffsetY(p)
case PacketType.PetVisibility => onPetVisibility(p)
case PacketType.PowerState => onPowerState(p)
case PacketType.PrinterState => onPrinterState(p)
case PacketType.RaidStateChange => onRaidStateChange(p)
case PacketType.RedstoneState => onRedstoneState(p)
case PacketType.RobotAnimateSwing => onRobotAnimateSwing(p)
@ -242,6 +243,14 @@ object PacketHandler extends CommonPacketHandler {
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) =
p.readTileEntity[Raid]() match {
case Some(t) =>

View File

@ -26,6 +26,8 @@ object Textures {
val guiDrone = new ResourceLocation(Settings.resourceDomain, "textures/gui/drone.png")
val guiKeyboardMissing = new ResourceLocation(Settings.resourceDomain, "textures/gui/keyboard_missing.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 guiRaid = new ResourceLocation(Settings.resourceDomain, "textures/gui/raid.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.client.Textures
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.ComponentSlot
import li.cil.oc.common.tileentity
import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.util.ResourceLocation
import org.lwjgl.opengl.GL11
class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer) extends DynamicGuiContainer(new container.Printer(playerInventory, printer)) {
xSize = 176
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 height = 46
@ -23,7 +35,7 @@ class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer)
override def barTexture = Textures.guiPrinterProgress
})
private def assemblerContainer = inventorySlots.asInstanceOf[container.Printer]
private def printerContainer = inventorySlots.asInstanceOf[container.Printer]
override def initGui() {
super.initGui()
@ -35,27 +47,27 @@ class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer)
Localization.localizeImmediately(printer.getInventoryName),
8, 6, 0x404040)
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 timeRemaining = formatTime(assemblerContainer.assemblyRemainingTime)
tooltip.add(Localization.Assembler.Progress(assemblerContainer.assemblyProgress, timeRemaining))
tooltip.add(printerContainer.amountPlastic + "/" + printer.maxAmountPlastic)
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)
}
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) {
GL11.glColor3f(1, 1, 1) // Required under Linux.
mc.renderEngine.bindTexture(Textures.guiPrinter)
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize)
if (assemblerContainer.isAssembling) progress.level = assemblerContainer.assemblyProgress / 100.0
else progress.level = 0
plasticBar.level = printerContainer.amountPlastic / printer.maxAmountPlastic.toDouble
inkBar.level = printerContainer.amountInk / printer.maxAmountInk.toDouble
if (printerContainer.isPrinting) progressBar.level = (System.currentTimeMillis() % 3000) / 3000.0
else progressBar.level = 0
drawWidgets()
drawInventorySlots()
}

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@ import java.util
import li.cil.oc.Settings
import li.cil.oc.api
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.tileentity
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 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 {
case simple: SimpleBlock => simple.getUnlocalizedName
case _ => Settings.namespace + "tile"

View File

@ -1,6 +1,9 @@
package li.cil.oc.common.block
import java.util
import li.cil.oc.Settings
import li.cil.oc.common.item.data.PrintData
import li.cil.oc.common.tileentity
import li.cil.oc.util.ExtendedAABB
import net.minecraft.entity.EntityLivingBase
@ -11,6 +14,7 @@ import net.minecraft.world.IBlockAccess
import net.minecraft.world.World
import net.minecraftforge.common.util.ForgeDirection
import scala.collection.convert.WrapAsJava._
import scala.reflect.ClassTag
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)
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 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.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(
None,
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 hasTileEntity(metadata: Int) = true

View File

@ -28,7 +28,7 @@ class DynamicComponentSlot(val container: Player, inventory: IInventory, index:
override def getSlotStackLimit =
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 _ => 1
}

View File

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

View File

@ -12,7 +12,7 @@ class StaticComponentSlot(val container: Player, inventory: IInventory, index: I
override def getSlotStackLimit =
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 _ => 1
}

View File

@ -470,5 +470,10 @@ object Items extends ItemAPI {
// 1.4.7
Recipes.addMultiItem(new item.TabletCase(multi, Tier.Two), "tabletCase2", "oc:tabletCase2")
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.network._
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.ExtendedNBT._
import li.cil.oc.util.ItemUtils
@ -19,18 +20,26 @@ import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.AxisAlignedBB
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).
withComponent("printer3d").
withConnector(Settings.get.bufferConverter).
create()
val maxAmountPlastic = 256000
var amountPlastic = 0
val maxAmountInk = 100000
var amountInk = 0
var data = new PrintData()
var isActive = false
var output: Option[ItemStack] = None
var totalRequiredEnergy = 0.0
var requiredEnergy = 0.0
val plasticPerItem = 2000
val inkPerCartridge = 50000
val slotPlastic = 0
val slotInk = 1
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
@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 = {
if (isAssembling) util.EnumSet.of(traits.State.IsWorking)
else if (canAssemble) util.EnumSet.of(traits.State.CanWork)
if (isPrinting) util.EnumSet.of(traits.State.IsWorking)
else if (canPrint) util.EnumSet.of(traits.State.CanWork)
else util.EnumSet.noneOf(classOf[traits.State])
}
// ----------------------------------------------------------------------- //
def canAssemble = {
def canPrint = {
val complexity = data.stateOff.size + data.stateOn.size
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
@ -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.""")
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.
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.""")
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.
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.""")
def commit(context: Context, args: Arguments): Array[Object] = {
if (!canAssemble) {
if (!canPrint) {
return result(null, "model invalid")
}
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.""")
def status(context: Context, args: Arguments): Array[Object] = {
if (isAssembling) result("busy", progress)
else if (canAssemble) result("idle", true)
if (isPrinting) result("busy", progress)
else if (canPrint) result("idle", true)
else result("idle", false)
}
@ -163,47 +167,74 @@ class Printer extends traits.Environment with traits.PowerAcceptor with traits.I
override def updateEntity() {
super.updateEntity()
if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
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 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
// TODO Consume plastic (totalVolume) and ink (totalSurface).
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 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
if (totalVolume == 0) {
isActive = false
}
else {
val plasticRequired = totalVolume
val inkRequired = (totalSurface / 6) max 1
totalRequiredEnergy = totalShapes * Settings.get.printShapeCost
requiredEnergy = totalRequiredEnergy
output = Option(data.createItemStack())
// ServerPacketSender.sendRobotAssembling(this, assembling = true)
}
if (output.isDefined) {
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 (amountPlastic >= plasticRequired && amountInk >= inkRequired) {
amountPlastic -= plasticRequired
amountInk -= inkRequired
output = Option(data.createItemStack())
ServerPacketSender.sendPrinting(this, printing = true)
}
if (requiredEnergy <= 0) {
val result = getStackInSlot(slotOutput)
if (result == null) {
setInventorySlotContents(slotOutput, output.get)
}
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
}
}
if (output.isDefined) {
val want = math.max(1, math.min(requiredEnergy, Settings.get.printerTickAmount))
val success = Settings.get.ignorePower || node.tryChangeBuffer(-want)
if (success) {
requiredEnergy -= want
}
if (requiredEnergy <= 0) {
val result = getStackInSlot(slotOutput)
if (result == null) {
setInventorySlotContents(slotOutput, output.get)
}
// 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) {
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")
if (nbt.hasKey(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) {
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)
output.foreach(stack => nbt.setNewCompoundTag(Settings.namespace + "output", stack.writeToNBT))
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) =
if (slot == 0)
true // TODO Plastic
api.Items.get(stack) == api.Items.get("plastic")
else if (slot == 1)
true // TODO Color
api.Items.get(stack) == api.Items.get("inkCartridge")
else false
}

View File

@ -226,6 +226,15 @@ object PacketSender {
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) {
val pb = new SimplePacketBuilder(PacketType.RaidStateChange)