Materials for printing (plastic and ink).
BIN
assets/items.psd
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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]
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 189 B After Width: | Height: | Size: 189 B |
After Width: | Height: | Size: 645 B |
After Width: | Height: | Size: 636 B |
After Width: | Height: | Size: 316 B |
@ -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
|
||||
|
@ -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) =>
|
||||
|
@ -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")
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -20,6 +20,7 @@ object PacketType extends Enumeration {
|
||||
HologramTranslation,
|
||||
PetVisibility, // Goes both ways.
|
||||
PowerState,
|
||||
PrinterState,
|
||||
RaidStateChange,
|
||||
RedstoneState,
|
||||
RobotAnimateSwing,
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
5
src/main/scala/li/cil/oc/common/item/InkCartridge.scala
Normal file
@ -0,0 +1,5 @@
|
||||
package li.cil.oc.common.item
|
||||
|
||||
class InkCartridge(val parent: Delegator) extends Delegate {
|
||||
override def maxStackSize = 1
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package li.cil.oc.common.item
|
||||
|
||||
class InkCartridgeEmpty(val parent: Delegator) extends Delegate {
|
||||
override def maxStackSize = 1
|
||||
}
|
3
src/main/scala/li/cil/oc/common/item/Plastic.scala
Normal file
@ -0,0 +1,3 @@
|
||||
package li.cil.oc.common.item
|
||||
|
||||
class Plastic(val parent: Delegator) extends Delegate
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|