Reworked component blacklisting logic to use IMC now, allowing other mods to tell OC components not to work in their blocks (e.g. for custom assembler templates).

Only revalidating templates when a slot changed now.
Inventory upgrades properly work in drones now.
Can set status text from drone scripts now.
This commit is contained in:
Florian Nücke 2014-12-15 15:50:22 +01:00
parent 95e2feef65
commit 006935ba06
34 changed files with 198 additions and 138 deletions

View File

@ -12,14 +12,30 @@ import li.cil.oc.common.template.AssemblerTemplates
import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity
import net.minecraft.client.gui.GuiButton import net.minecraft.client.gui.GuiButton
import net.minecraft.entity.player.InventoryPlayer import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.inventory.Slot
import net.minecraft.util.IChatComponent
import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.GL11
import scala.collection.convert.WrapAsJava._ import scala.collection.convert.WrapAsJava._
import scala.collection.convert.WrapAsScala._
class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Assembler) extends DynamicGuiContainer(new container.Assembler(playerInventory, assembler)) { class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Assembler) extends DynamicGuiContainer(new container.Assembler(playerInventory, assembler)) {
xSize = 176 xSize = 176
ySize = 192 ySize = 192
for (slot <- inventorySlots.inventorySlots) slot match {
case component: ComponentSlot => component.changeListener = Option(onSlotChanged)
case _ =>
}
private def onSlotChanged(slot: Slot) {
runButton.enabled = canBuild
runButton.toggled = !runButton.enabled
info = validate
}
var info: Option[(Boolean, IChatComponent, Array[IChatComponent])] = None
private def assemblerContainer = inventorySlots.asInstanceOf[container.Assembler] private def assemblerContainer = inventorySlots.asInstanceOf[container.Assembler]
protected var runButton: ImageButton = _ protected var runButton: ImageButton = _
@ -38,12 +54,6 @@ class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Asse
} }
} }
override def drawScreen(mouseX: Int, mouseY: Int, dt: Float) {
runButton.enabled = canBuild
runButton.toggled = !runButton.enabled
super.drawScreen(mouseX, mouseY, dt)
}
override def initGui() { override def initGui() {
super.initGui() super.initGui()
runButton = new ImageButton(0, guiLeft + 7, guiTop + 89, 18, 18, Textures.guiButtonRun, canToggle = true) runButton = new ImageButton(0, guiLeft + 7, guiTop + 89, 18, 18, Textures.guiButtonRun, canToggle = true)
@ -53,7 +63,6 @@ class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Asse
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = { override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
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) { if (!assemblerContainer.isAssembling) {
val info = validate
val message = val message =
if (!assemblerContainer.getSlot(0).getHasStack) { if (!assemblerContainer.getSlot(0).getHasStack) {
Localization.Assembler.InsertTemplate Localization.Assembler.InsertTemplate

View File

@ -26,7 +26,7 @@ class Drone(playerInventory: InventoryPlayer, val drone: entity.Drone) extends D
protected var powerButton: ImageButton = _ protected var powerButton: ImageButton = _
private val buffer = new TextBuffer(20, 2, PackedColor.SingleBitFormat) private val buffer = new TextBuffer(20, 2, new PackedColor.SingleBitFormat(0x33FF33))
private val bufferRenderer = new TextBufferRenderData { private val bufferRenderer = new TextBufferRenderData {
private var _dirty = true private var _dirty = true

View File

@ -9,6 +9,7 @@ import li.cil.oc.OpenComputers
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.common.template.AssemblerTemplates import li.cil.oc.common.template.AssemblerTemplates
import li.cil.oc.integration.util.Wrench import li.cil.oc.integration.util.Wrench
import li.cil.oc.server.driver.Registry
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraftforge.common.util.Constants.NBT import net.minecraftforge.common.util.Constants.NBT
@ -51,6 +52,12 @@ object IMC {
Settings.get.peripheralBlacklist.add(message.getStringValue) Settings.get.peripheralBlacklist.add(message.getStringValue)
} }
} }
else if (message.key == "blacklistHost" && message.isNBTMessage) {
OpenComputers.log.info(s"Blacklisting component '${message.getNBTValue.getString("name")}' for host '${message.getNBTValue.getString("host")}' as requested by mod ${message.getSender}.")
try Registry.blacklistHost(message.getNBTValue.getCompoundTag("item"), Class.forName(message.getNBTValue.getString("host"))) catch {
case t: Throwable => OpenComputers.log.warn("Failed blacklisting component.", t)
}
}
} }
} }

View File

@ -19,6 +19,8 @@ trait ComponentSlot extends Slot {
def tierIcon: IIcon def tierIcon: IIcon
var changeListener: Option[Slot => Unit] = None
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@ -40,6 +42,7 @@ trait ComponentSlot extends Slot {
case dynamic: ComponentSlot => dynamic.clearIfInvalid(container.playerInventory.player) case dynamic: ComponentSlot => dynamic.clearIfInvalid(container.playerInventory.player)
case _ => case _ =>
} }
changeListener.foreach(_(this))
} }
protected def clearIfInvalid(player: EntityPlayer) {} protected def clearIfInvalid(player: EntityPlayer) {}

View File

@ -7,6 +7,7 @@ import li.cil.oc.Settings
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.api.Driver import li.cil.oc.api.Driver
import li.cil.oc.api.Machine import li.cil.oc.api.Machine
import li.cil.oc.api.driver.item
import li.cil.oc.api.driver.item.Memory import li.cil.oc.api.driver.item.Memory
import li.cil.oc.api.driver.item.Processor import li.cil.oc.api.driver.item.Processor
import li.cil.oc.api.internal import li.cil.oc.api.internal
@ -32,11 +33,13 @@ import net.minecraft.world.World
class Drone(val world: World) extends Entity(world) with MachineHost with internal.Drone { class Drone(val world: World) extends Entity(world) with MachineHost with internal.Drone {
// Some basic constants. // Some basic constants.
val gravity = 0.05f // low for slow fall (float down) val gravity = 0.05f
// low for slow fall (float down)
val drag = 0.8f val drag = 0.8f
val maxAcceleration = 0.1f val maxAcceleration = 0.1f
val maxVelocity = 0.4f val maxVelocity = 0.4f
setSize(1, 6/16f) val maxInventorySize = 8
setSize(1, 6 / 16f)
// Rendering stuff, purely eyecandy. // Rendering stuff, purely eyecandy.
val targetFlapAngles = Array.fill(4, 2)(0f) val targetFlapAngles = Array.fill(4, 2)(0f)
@ -73,9 +76,9 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
override def onMessage(message: Message) {} override def onMessage(message: Message) {}
} }
val inventory = new Inventory { val inventory = new Inventory {
var items = Array.fill[Option[ItemStack]](8)(None) val items = Array.fill[Option[ItemStack]](8)(None)
override def getSizeInventory = items.length override def getSizeInventory = inventorySize
override def getInventoryStackLimit = 64 override def getInventoryStackLimit = 64
@ -136,6 +139,14 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
override def onMachineDisconnect(node: Node) {} override def onMachineDisconnect(node: Node) {}
def computeInventorySize() = math.min(maxInventorySize, info.components.foldLeft(0)((acc, component) => acc + (Option(component) match {
case Some(stack) => Option(Driver.driverFor(stack, getClass)) match {
case Some(driver: item.Inventory) => math.max(1, driver.inventoryCapacity(stack) / 4)
case _ => 0
}
case _ => 0
})))
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def entityInit() { override def entityInit() {
@ -154,29 +165,68 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
dataWatcher.addObject(9, int2Integer(100)) dataWatcher.addObject(9, int2Integer(100))
// Status text. // Status text.
dataWatcher.addObject(10, "") dataWatcher.addObject(10, "")
// Inventory size for client.
dataWatcher.addObject(11, byte2Byte(0: Byte))
}
def initializeAfterPlacement(stack: ItemStack, player: EntityPlayer, x: Int, y: Int, z: Int, hitX: Float, hitY: Float, hitZ: Float) {
info.load(stack)
inventorySize = computeInventorySize()
setPosition(x + hitX * 1.1f, y + hitY * 1.1f, z + hitZ * 1.1f)
}
def preparePowerUp() {
targetX = math.floor(posX).toFloat + 0.5f
targetY = math.floor(posY).toFloat + 0.5f
targetZ = math.floor(posZ).toFloat + 0.5f
targetAcceleration = maxAcceleration
api.Network.joinNewNetwork(machine.node)
components.connectComponents()
machine.node.connect(control.node)
} }
def isRunning = dataWatcher.getWatchableObjectByte(2) != 0 def isRunning = dataWatcher.getWatchableObjectByte(2) != 0
def targetX = dataWatcher.getWatchableObjectFloat(3) def targetX = dataWatcher.getWatchableObjectFloat(3)
def targetY = dataWatcher.getWatchableObjectFloat(4) def targetY = dataWatcher.getWatchableObjectFloat(4)
def targetZ = dataWatcher.getWatchableObjectFloat(5) def targetZ = dataWatcher.getWatchableObjectFloat(5)
def targetAcceleration = dataWatcher.getWatchableObjectFloat(6) def targetAcceleration = dataWatcher.getWatchableObjectFloat(6)
def selectedSlot = dataWatcher.getWatchableObjectByte(7) & 0xFF def selectedSlot = dataWatcher.getWatchableObjectByte(7) & 0xFF
def globalBuffer = dataWatcher.getWatchableObjectInt(8) def globalBuffer = dataWatcher.getWatchableObjectInt(8)
def globalBufferSize = dataWatcher.getWatchableObjectInt(9) def globalBufferSize = dataWatcher.getWatchableObjectInt(9)
def statusText = dataWatcher.getWatchableObjectString(10) def statusText = dataWatcher.getWatchableObjectString(10)
private def setRunning(value: Boolean) = dataWatcher.updateObject(2, byte2Byte(if (value) 1: Byte else 0: Byte)) def inventorySize = dataWatcher.getWatchableObjectByte(11) & 0xFF
def setRunning(value: Boolean) = dataWatcher.updateObject(2, byte2Byte(if (value) 1: Byte else 0: Byte))
// Round target values to low accuracy to avoid floating point errors accumulating. // Round target values to low accuracy to avoid floating point errors accumulating.
def targetX_=(value: Float): Unit = dataWatcher.updateObject(3, float2Float(math.round(value * 5) / 5f)) def targetX_=(value: Float): Unit = dataWatcher.updateObject(3, float2Float(math.round(value * 5) / 5f))
def targetY_=(value: Float): Unit = dataWatcher.updateObject(4, float2Float(math.round(value * 5) / 5f)) def targetY_=(value: Float): Unit = dataWatcher.updateObject(4, float2Float(math.round(value * 5) / 5f))
def targetZ_=(value: Float): Unit = dataWatcher.updateObject(5, float2Float(math.round(value * 5) / 5f)) def targetZ_=(value: Float): Unit = dataWatcher.updateObject(5, float2Float(math.round(value * 5) / 5f))
def targetAcceleration_=(value: Float): Unit = dataWatcher.updateObject(6, float2Float(math.max(0, math.min(maxAcceleration, value)))) def targetAcceleration_=(value: Float): Unit = dataWatcher.updateObject(6, float2Float(math.max(0, math.min(maxAcceleration, value))))
def selectedSlot_=(value: Int) = dataWatcher.updateObject(7, byte2Byte(value.toByte)) def selectedSlot_=(value: Int) = dataWatcher.updateObject(7, byte2Byte(value.toByte))
private def globalBuffer_=(value: Int) = dataWatcher.updateObject(8, int2Integer(value))
private def globalBufferSize_=(value: Int) = dataWatcher.updateObject(9, int2Integer(value)) def globalBuffer_=(value: Int) = dataWatcher.updateObject(8, int2Integer(value))
def globalBufferSize_=(value: Int) = dataWatcher.updateObject(9, int2Integer(value))
def statusText_=(value: String) = dataWatcher.updateObject(10, Option(value).map(_.lines.map(_.take(10)).take(2).mkString("\n")).getOrElse("")) def statusText_=(value: String) = dataWatcher.updateObject(10, Option(value).map(_.lines.map(_.take(10)).take(2).mkString("\n")).getOrElse(""))
def inventorySize_=(value: Int) = dataWatcher.updateObject(11, byte2Byte(value.toByte))
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
override def setPositionAndRotation2(x: Double, y: Double, z: Double, yaw: Float, pitch: Float, data: Int) { override def setPositionAndRotation2(x: Double, y: Double, z: Double, yaw: Float, pitch: Float, data: Int) {
// Only set exact position if we're too far away from the server's // Only set exact position if we're too far away from the server's
@ -211,7 +261,8 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
super.onEntityUpdate() super.onEntityUpdate()
if (!world.isRemote) { if (!world.isRemote) {
if (isInWater) { // We're not water-proof! if (isInWater) {
// We're not water-proof!
machine.stop() machine.stop()
} }
machine.node.asInstanceOf[Connector].changeBuffer(100) machine.node.asInstanceOf[Connector].changeBuffer(100)
@ -219,46 +270,49 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
components.updateComponents() components.updateComponents()
setRunning(machine.isRunning) setRunning(machine.isRunning)
if (math.abs(lastEnergyUpdate - globalBuffer) > 100 || world.getTotalWorldTime % 200 == 0) { if (math.abs(lastEnergyUpdate - globalBuffer) > 50 || world.getTotalWorldTime % 200 == 0) {
globalBuffer = machine.node.asInstanceOf[Connector].globalBuffer.toInt globalBuffer = math.round(machine.node.asInstanceOf[Connector].globalBuffer / 50f).toInt * 50
globalBufferSize = machine.node.asInstanceOf[Connector].globalBufferSize.toInt globalBufferSize = machine.node.asInstanceOf[Connector].globalBufferSize.toInt
lastEnergyUpdate = globalBuffer
} }
} }
else if (isRunning) { else {
// Client side update; occasionally update wing pitch and rotation to if (isRunning) {
// make the drones look a bit more dynamic. // Client side update; occasionally update wing pitch and rotation to
val rng = world.rand // make the drones look a bit more dynamic.
nextFlapChange -= 1 val rng = world.rand
nextAngularVelocityChange -= 1 nextFlapChange -= 1
nextAngularVelocityChange -= 1
if (nextFlapChange < 0) { if (nextFlapChange < 0) {
nextFlapChange = 5 + rng.nextInt(10) nextFlapChange = 5 + rng.nextInt(10)
for (i <- 0 until 2) { for (i <- 0 until 2) {
val flap = rng.nextInt(targetFlapAngles.length) val flap = rng.nextInt(targetFlapAngles.length)
targetFlapAngles(flap)(0) = math.toRadians(rng.nextFloat() * 4 - 2).toFloat targetFlapAngles(flap)(0) = math.toRadians(rng.nextFloat() * 4 - 2).toFloat
targetFlapAngles(flap)(1) = math.toRadians(rng.nextFloat() * 4 - 2).toFloat targetFlapAngles(flap)(1) = math.toRadians(rng.nextFloat() * 4 - 2).toFloat
}
} }
if (nextAngularVelocityChange < 0) {
if (angularVelocity != 0) {
angularVelocity = 0
nextAngularVelocityChange = 20
}
else {
angularVelocity = if (rng.nextBoolean()) 0.1f else -0.1f
nextAngularVelocityChange = 100
}
}
// Interpolate wing rotations.
(flapAngles, targetFlapAngles).zipped.foreach((f, t) => {
f(0) = f(0) * 0.7f + t(0) * 0.3f
f(1) = f(1) * 0.7f + t(1) * 0.3f
})
// Update body rotation.
bodyAngle += angularVelocity
} }
if (nextAngularVelocityChange < 0) {
if (angularVelocity != 0) {
angularVelocity = 0
nextAngularVelocityChange = 20
}
else {
angularVelocity = if (rng.nextBoolean()) 0.1f else -0.1f
nextAngularVelocityChange = 100
}
}
// Interpolate wing rotations.
(flapAngles, targetFlapAngles).zipped.foreach((f, t) => {
f(0) = f(0) * 0.7f + t(0) * 0.3f
f(1) = f(1) * 0.7f + t(1) * 0.3f
})
// Update body rotation.
bodyAngle += angularVelocity
} }
if (isRunning) { if (isRunning) {
@ -306,17 +360,6 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
stack stack
} }
def preparePowerUp() {
targetX = math.floor(posX).toFloat + 0.5f
targetY = math.floor(posY).toFloat + 0.5f
targetZ = math.floor(posZ).toFloat + 0.5f
targetAcceleration = maxAcceleration
api.Network.joinNewNetwork(machine.node)
components.connectComponents()
machine.node.connect(control.node)
}
override def interactFirst(player: EntityPlayer) = { override def interactFirst(player: EntityPlayer) = {
if (player.isSneaking) { if (player.isSneaking) {
kill() kill()
@ -329,8 +372,9 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def readEntityFromNBT(nbt: NBTTagCompound): Unit = { override def readEntityFromNBT(nbt: NBTTagCompound) {
info.load(nbt.getCompoundTag("info")) info.load(nbt.getCompoundTag("info"))
inventorySize = computeInventorySize()
if (!world.isRemote) { if (!world.isRemote) {
machine.load(nbt.getCompoundTag("machine")) machine.load(nbt.getCompoundTag("machine"))
control.load(nbt.getCompoundTag("control")) control.load(nbt.getCompoundTag("control"))
@ -349,7 +393,7 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
statusText = nbt.getString("statusText") statusText = nbt.getString("statusText")
} }
override def writeEntityToNBT(nbt: NBTTagCompound): Unit = { override def writeEntityToNBT(nbt: NBTTagCompound) {
components.saveComponents() components.saveComponents()
nbt.setNewCompoundTag("info", info.save) nbt.setNewCompoundTag("info", info.save)
if (!world.isRemote) { if (!world.isRemote) {

View File

@ -9,8 +9,7 @@ class Drone(val parent: Delegator) extends Delegate {
override def onItemUse(stack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float) = { override def onItemUse(stack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float) = {
if (!world.isRemote) { if (!world.isRemote) {
val drone = new entity.Drone(world) val drone = new entity.Drone(world)
drone.info.load(stack) drone.initializeAfterPlacement(stack, player, x, y, z, hitX, hitY, hitZ)
drone.setPosition(x + hitX, y + hitY, z + hitZ)
world.spawnEntityInWorld(drone) world.spawnEntityInWorld(drone)
} }
stack.stackSize -= 1 stack.stackSize -= 1

View File

@ -35,7 +35,7 @@ trait Environment extends TileEntity with network.Environment with driver.Enviro
override def updateEntity() { override def updateEntity() {
super.updateEntity() super.updateEntity()
if (isChangeScheduled) { if (isChangeScheduled) {
markDirty() world.markTileEntityChunkModified(x, y, z, this)
isChangeScheduled = false isChangeScheduled = false
} }
} }

View File

@ -3,11 +3,12 @@ package li.cil.oc.integration.opencomputers
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.api.driver.EnvironmentAware import li.cil.oc.api.driver.EnvironmentAware
import li.cil.oc.api.driver.EnvironmentHost import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.api.driver.item.HostAware
import li.cil.oc.common.Slot import li.cil.oc.common.Slot
import li.cil.oc.server.component import li.cil.oc.server.component
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
object DriverGeolyzer extends Item with EnvironmentAware { object DriverGeolyzer extends Item with HostAware with EnvironmentAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("geolyzer")) isOneOf(stack, api.Items.get("geolyzer"))

View File

@ -15,9 +15,6 @@ object DriverGraphicsCard extends Item with HostAware with EnvironmentAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("graphicsCard1"), api.Items.get("graphicsCard2"), api.Items.get("graphicsCard3")) isOneOf(stack, api.Items.get("graphicsCard1"), api.Items.get("graphicsCard2"), api.Items.get("graphicsCard3"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && !isMicrocontroller(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
tier(stack) match { tier(stack) match {
case Tier.One => new component.GraphicsCard.Tier1() case Tier.One => new component.GraphicsCard.Tier1()

View File

@ -11,9 +11,6 @@ object DriverKeyboard extends Item with HostAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("keyboard")) isOneOf(stack, api.Items.get("keyboard"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && !isAdapter(host) && !isMicrocontroller(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.Keyboard(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.Keyboard(host)
override def slot(stack: ItemStack) = Slot.Upgrade override def slot(stack: ItemStack) = Slot.Upgrade

View File

@ -12,9 +12,6 @@ object DriverNetworkCard extends Item with HostAware with EnvironmentAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("lanCard")) isOneOf(stack, api.Items.get("lanCard"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && !isTablet(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.NetworkCard(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.NetworkCard(host)
override def slot(stack: ItemStack) = Slot.Card override def slot(stack: ItemStack) = Slot.Card

View File

@ -19,9 +19,6 @@ import net.minecraft.item.ItemStack
object DriverRedstoneCard extends Item with HostAware with EnvironmentAware { object DriverRedstoneCard extends Item with HostAware with EnvironmentAware {
override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("redstoneCard1"), api.Items.get("redstoneCard2")) override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("redstoneCard1"), api.Items.get("redstoneCard2"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && (isComputer(host) || isRobot(host) || isServer(host) || isMicrocontroller(host))
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
host match { host match {
case redstone: BundledRedstoneAware if BundledRedstone.isAvailable && tier(stack) == Tier.Two => case redstone: BundledRedstoneAware if BundledRedstone.isAvailable && tier(stack) == Tier.Two =>

View File

@ -13,9 +13,6 @@ object DriverScreen extends Item with HostAware with EnvironmentAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("screen1")) isOneOf(stack, api.Items.get("screen1"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && !isTablet(host) && !isAdapter(host) && !isMicrocontroller(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match { override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match {
case screen: tileentity.Screen if screen.tier > 0 => new component.Screen(screen) case screen: tileentity.Screen if screen.tier > 0 => new component.Screen(screen)
case _ => new component.TextBuffer(host) case _ => new component.TextBuffer(host)

View File

@ -12,9 +12,6 @@ object DriverUpgradeAngel extends Item with HostAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("angelUpgrade")) isOneOf(stack, api.Items.get("angelUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && isRobot(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeAngel() override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeAngel()
override def slot(stack: ItemStack) = Slot.Upgrade override def slot(stack: ItemStack) = Slot.Upgrade

View File

@ -14,9 +14,6 @@ object DriverUpgradeBattery extends Item with HostAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("batteryUpgrade1"), api.Items.get("batteryUpgrade2"), api.Items.get("batteryUpgrade3")) isOneOf(stack, api.Items.get("batteryUpgrade1"), api.Items.get("batteryUpgrade2"), api.Items.get("batteryUpgrade3"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && !isAdapter(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeBattery(tier(stack)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeBattery(tier(stack))
override def slot(stack: ItemStack) = Slot.Upgrade override def slot(stack: ItemStack) = Slot.Upgrade

View File

@ -13,9 +13,6 @@ object DriverUpgradeChunkloader extends Item with HostAware with EnvironmentAwar
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("chunkloaderUpgrade")) isOneOf(stack, api.Items.get("chunkloaderUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && isRobot(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeChunkloader(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeChunkloader(host)
override def slot(stack: ItemStack) = Slot.Upgrade override def slot(stack: ItemStack) = Slot.Upgrade

View File

@ -14,9 +14,6 @@ object DriverUpgradeCrafting extends Item with HostAware with EnvironmentAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("craftingUpgrade")) isOneOf(stack, api.Items.get("craftingUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && isRobot(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
host match { host match {
case robot: EnvironmentHost with Robot => new component.UpgradeCrafting(robot) case robot: EnvironmentHost with Robot => new component.UpgradeCrafting(robot)

View File

@ -3,7 +3,6 @@ package li.cil.oc.integration.opencomputers
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.api.driver import li.cil.oc.api.driver
import li.cil.oc.api.driver.EnvironmentAware import li.cil.oc.api.driver.EnvironmentAware
import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.api.driver.item.HostAware import li.cil.oc.api.driver.item.HostAware
import li.cil.oc.common.Slot import li.cil.oc.common.Slot
import li.cil.oc.common.Tier import li.cil.oc.common.Tier
@ -18,9 +17,6 @@ object DriverUpgradeDatabase extends Item with HostAware with EnvironmentAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("databaseUpgrade1"), api.Items.get("databaseUpgrade2"), api.Items.get("databaseUpgrade3")) isOneOf(stack, api.Items.get("databaseUpgrade1"), api.Items.get("databaseUpgrade2"), api.Items.get("databaseUpgrade3"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && !isMicrocontroller(host)
override def createEnvironment(stack: ItemStack, host: driver.EnvironmentHost) = override def createEnvironment(stack: ItemStack, host: driver.EnvironmentHost) =
new component.UpgradeDatabase(new DatabaseInventory { new component.UpgradeDatabase(new DatabaseInventory {
override def tier = DriverUpgradeDatabase.tier(stack) override def tier = DriverUpgradeDatabase.tier(stack)

View File

@ -13,9 +13,6 @@ object DriverUpgradeExperience extends Item with HostAware with EnvironmentAware
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("experienceUpgrade")) isOneOf(stack, api.Items.get("experienceUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && isRobot(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeExperience() override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeExperience()
override def slot(stack: ItemStack) = Slot.Upgrade override def slot(stack: ItemStack) = Slot.Upgrade

View File

@ -14,9 +14,6 @@ object DriverUpgradeGenerator extends Item with HostAware with EnvironmentAware
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("generatorUpgrade")) isOneOf(stack, api.Items.get("generatorUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && isRobot(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
host match { host match {
case robot: Robot => new component.UpgradeGenerator(robot) case robot: Robot => new component.UpgradeGenerator(robot)

View File

@ -11,9 +11,6 @@ object DriverUpgradeInventory extends Item with Inventory with HostAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("inventoryUpgrade")) isOneOf(stack, api.Items.get("inventoryUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && isRobot(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = null override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = null
override def slot(stack: ItemStack) = Slot.Upgrade override def slot(stack: ItemStack) = Slot.Upgrade

View File

@ -15,9 +15,6 @@ object DriverUpgradeInventoryController extends Item with HostAware with Environ
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("inventoryControllerUpgrade")) isOneOf(stack, api.Items.get("inventoryControllerUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && (isRobot(host) || isAdapter(host))
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match { override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match {
case robot: EnvironmentHost with Robot => new component.UpgradeInventoryControllerInRobot(robot) case robot: EnvironmentHost with Robot => new component.UpgradeInventoryControllerInRobot(robot)
case adapter: EnvironmentHost with Adapter => new component.UpgradeInventoryControllerInAdapter(adapter) case adapter: EnvironmentHost with Adapter => new component.UpgradeInventoryControllerInAdapter(adapter)

View File

@ -14,9 +14,6 @@ object DriverUpgradeNavigation extends Item with HostAware with EnvironmentAware
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("navigationUpgrade")) isOneOf(stack, api.Items.get("navigationUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && (isRotatable(host) && !isMicrocontroller(host))
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
host match { host match {
case rotatable: EnvironmentHost with Rotatable => new component.UpgradeNavigation(rotatable) case rotatable: EnvironmentHost with Rotatable => new component.UpgradeNavigation(rotatable)

View File

@ -13,9 +13,6 @@ object DriverUpgradePiston extends Item with HostAware with EnvironmentAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("pistonUpgrade")) isOneOf(stack, api.Items.get("pistonUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && isRotatable(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match { override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match {
case rotatable: Rotatable with EnvironmentHost => new component.UpgradePiston(rotatable) case rotatable: Rotatable with EnvironmentHost => new component.UpgradePiston(rotatable)
case _ => null case _ => null

View File

@ -16,9 +16,6 @@ object DriverUpgradeSign extends Item with HostAware with EnvironmentAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("signUpgrade")) isOneOf(stack, api.Items.get("signUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && (isAdapter(host) || isRotatable(host))
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
host match { host match {
case rotatable: EnvironmentHost with Rotatable => new UpgradeSignInRotatable(rotatable) case rotatable: EnvironmentHost with Rotatable => new UpgradeSignInRotatable(rotatable)

View File

@ -12,9 +12,6 @@ object DriverUpgradeSolarGenerator extends Item with HostAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("solarGeneratorUpgrade")) isOneOf(stack, api.Items.get("solarGeneratorUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && !isAdapter(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeSolarGenerator(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeSolarGenerator(host)
override def slot(stack: ItemStack) = Slot.Upgrade override def slot(stack: ItemStack) = Slot.Upgrade

View File

@ -11,9 +11,6 @@ object DriverUpgradeTank extends Item with HostAware {
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("tankUpgrade")) isOneOf(stack, api.Items.get("tankUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && isRobot(host)
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeTank(host, 16000) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeTank(host, 16000)
override def slot(stack: ItemStack) = Slot.Upgrade override def slot(stack: ItemStack) = Slot.Upgrade

View File

@ -15,9 +15,6 @@ object DriverUpgradeTankController extends Item with HostAware with EnvironmentA
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("tankControllerUpgrade")) isOneOf(stack, api.Items.get("tankControllerUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && (isRobot(host) || isAdapter(host))
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match { override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match {
case robot: EnvironmentHost with Robot => new component.UpgradeTankControllerInRobot(robot) case robot: EnvironmentHost with Robot => new component.UpgradeTankControllerInRobot(robot)
case adapter: EnvironmentHost with Adapter => new component.UpgradeTankControllerInAdapter(adapter) case adapter: EnvironmentHost with Adapter => new component.UpgradeTankControllerInAdapter(adapter)

View File

@ -15,9 +15,6 @@ object DriverUpgradeTractorBeam extends Item with HostAware with EnvironmentAwar
override def worksWith(stack: ItemStack) = override def worksWith(stack: ItemStack) =
isOneOf(stack, api.Items.get("tractorBeamUpgrade")) isOneOf(stack, api.Items.get("tractorBeamUpgrade"))
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
worksWith(stack) && (isRobot(host) || isTablet(host))
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match { override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match {
case robot: Robot => new component.UpgradeTractorBeam(host, robot.player) case robot: Robot => new component.UpgradeTractorBeam(host, robot.player)
case tablet: TabletWrapper => new component.UpgradeTractorBeam(host, () => tablet.player) case tablet: TabletWrapper => new component.UpgradeTractorBeam(host, () => tablet.player)

View File

@ -6,10 +6,23 @@ import li.cil.oc.api.driver
import li.cil.oc.api.driver.EnvironmentHost import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.api.internal import li.cil.oc.api.internal
import li.cil.oc.common.Tier import li.cil.oc.common.Tier
import li.cil.oc.server.driver.Registry
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
trait Item extends driver.Item { trait Item extends driver.Item {
def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]): Boolean =
worksWith(stack) && {
val nbt = new NBTTagCompound()
val copy = stack.copy()
copy.stackSize = 1
copy.writeToNBT(nbt)
Registry.blacklist.get(nbt) match {
case Some(hosts) => !hosts.exists(_.isAssignableFrom(host))
case _ => true
}
}
override def tier(stack: ItemStack) = Tier.One override def tier(stack: ItemStack) = Tier.One
override def dataTag(stack: ItemStack) = Item.dataTag(stack) override def dataTag(stack: ItemStack) = Item.dataTag(stack)
@ -29,6 +42,8 @@ trait Item extends driver.Item {
protected def isTablet(host: Class[_ <: EnvironmentHost]) = classOf[internal.Tablet].isAssignableFrom(host) protected def isTablet(host: Class[_ <: EnvironmentHost]) = classOf[internal.Tablet].isAssignableFrom(host)
protected def isMicrocontroller(host: Class[_ <: EnvironmentHost]) = classOf[internal.Microcontroller].isAssignableFrom(host) protected def isMicrocontroller(host: Class[_ <: EnvironmentHost]) = classOf[internal.Microcontroller].isAssignableFrom(host)
protected def isDrone(host: Class[_ <: EnvironmentHost]) = classOf[internal.Drone].isAssignableFrom(host)
} }
object Item { object Item {

View File

@ -1,9 +1,11 @@
package li.cil.oc.integration.opencomputers package li.cil.oc.integration.opencomputers
import cpw.mods.fml.common.FMLCommonHandler import cpw.mods.fml.common.FMLCommonHandler
import cpw.mods.fml.common.event.FMLInterModComms
import cpw.mods.fml.common.registry.EntityRegistry import cpw.mods.fml.common.registry.EntityRegistry
import li.cil.oc.OpenComputers import li.cil.oc.OpenComputers
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.api.internal
import li.cil.oc.common.EventHandler import li.cil.oc.common.EventHandler
import li.cil.oc.common.Loot import li.cil.oc.common.Loot
import li.cil.oc.common.SaveHandler import li.cil.oc.common.SaveHandler
@ -18,7 +20,10 @@ import li.cil.oc.common.template.RobotTemplate
import li.cil.oc.common.template.TabletTemplate import li.cil.oc.common.template.TabletTemplate
import li.cil.oc.integration.ModProxy import li.cil.oc.integration.ModProxy
import li.cil.oc.integration.Mods import li.cil.oc.integration.Mods
import li.cil.oc.integration.util.WirelessRedstone
import li.cil.oc.server.network.WirelessNetwork import li.cil.oc.server.network.WirelessNetwork
import li.cil.oc.util.ExtendedNBT._
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.ForgeChunkManager import net.minecraftforge.common.ForgeChunkManager
import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.MinecraftForge
@ -97,5 +102,25 @@ object ModOpenComputers extends ModProxy {
api.Driver.add(DriverUpgradeTank) api.Driver.add(DriverUpgradeTank)
api.Driver.add(DriverUpgradeTankController) api.Driver.add(DriverUpgradeTankController)
api.Driver.add(DriverUpgradeTractorBeam) api.Driver.add(DriverUpgradeTractorBeam)
blacklistHost(classOf[internal.Adapter], "geolyzer", "keyboard", "screen1", "angelUpgrade", "batteryUpgrade1", "batteryUpgrade2", "batteryUpgrade3", "chunkloaderUpgrade", "craftingUpgrade", "experienceUpgrade", "generatorUpgrade", "inventoryUpgrade", "navigationUpgrade", "pistonUpgrade", "solarGeneratorUpgrade", "tankUpgrade", "tractorBeamUpgrade")
blacklistHost(classOf[internal.Microcontroller], "graphicsCard1", "graphicsCard2", "graphicsCard3", "keyboard", "screen1", "angelUpgrade", "chunkloaderUpgrade", "craftingUpgrade", "databaseUpgrade1", "databaseUpgrade2", "databaseUpgrade3", "experienceUpgrade", "generatorUpgrade", "inventoryUpgrade", "inventoryControllerUpgrade", "navigationUpgrade", "tankUpgrade", "tankControllerUpgrade", "tractorBeamUpgrade")
blacklistHost(classOf[internal.Drone], "graphicsCard1", "graphicsCard2", "graphicsCard3", "keyboard", "lanCard", "redstoneCard1", "screen1", "angelUpgrade", "craftingUpgrade", "experienceUpgrade", "generatorUpgrade", "tankUpgrade", "tankControllerUpgrade")
blacklistHost(classOf[internal.Tablet], "lanCard", "redstoneCard1", "screen1", "angelUpgrade", "chunkloaderUpgrade", "craftingUpgrade", "databaseUpgrade1", "databaseUpgrade2", "databaseUpgrade3", "experienceUpgrade", "generatorUpgrade", "inventoryUpgrade", "inventoryControllerUpgrade", "tankUpgrade", "tankControllerUpgrade")
if (!WirelessRedstone.isAvailable) {
blacklistHost(classOf[internal.Drone], "redstoneCard2")
blacklistHost(classOf[internal.Tablet], "redstoneCard2")
}
}
private def blacklistHost(host: Class[_], itemNames: String*) {
for (itemName <- itemNames) {
val nbt = new NBTTagCompound()
nbt.setString("name", itemName)
nbt.setString("host", host.getName)
nbt.setNewCompoundTag("item", api.Items.get(itemName).createItemStack(1).writeToNBT)
FMLInterModComms.sendMessage("OpenComputers", "blacklistHost", nbt)
}
} }
} }

View File

@ -49,12 +49,23 @@ class Drone(val host: entity.Drone) extends prefab.ManagedEnvironment with trait
override protected def suckableItems(side: ForgeDirection) = entitiesInBlock(BlockPosition(host)) ++ super.suckableItems(side) override protected def suckableItems(side: ForgeDirection) = entitiesInBlock(BlockPosition(host)) ++ super.suckableItems(side)
override protected def onSuckCollect(entity: EntityItem) = { override protected def onSuckCollect(entity: EntityItem) = {
world.playSoundAtEntity(host, "random.pop", 0.2f, ((world.rand.nextFloat - world.rand.nextFloat) * 0.7f + 1) * 2) if (InventoryUtils.insertIntoInventory(entity.getEntityItem, inventory, slots = Option(insertionSlots))) {
InventoryUtils.insertIntoInventory(entity.getEntityItem, inventory, slots = Option(insertionSlots)) world.playSoundAtEntity(host, "random.pop", 0.2f, ((world.rand.nextFloat - world.rand.nextFloat) * 0.7f + 1) * 2)
}
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@Callback(doc = "function():string -- Get the status text currently being displayed in the GUI.")
def getStatusText(context: Context, args: Arguments): Array[AnyRef] = result(host.statusText)
@Callback(doc = "function(value:string):string -- Set the status text to display in the GUI, returns new value.")
def setStatusText(context: Context, args: Arguments): Array[AnyRef] = {
host.statusText = args.checkString(0)
context.pause(0.1)
result(host.statusText)
}
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@Callback(doc = "function(dx:number, dy:number, dz:number) -- Change the target position by the specified offset.") @Callback(doc = "function(dx:number, dy:number, dz:number) -- Change the target position by the specified offset.")

View File

@ -9,6 +9,7 @@ import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.api.driver.item.HostAware import li.cil.oc.api.driver.item.HostAware
import li.cil.oc.api.machine.Value import li.cil.oc.api.machine.Value
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.world.World import net.minecraft.world.World
import scala.collection.convert.WrapAsJava._ import scala.collection.convert.WrapAsJava._
@ -37,6 +38,9 @@ private[oc] object Registry extends api.detail.DriverAPI {
val converters = mutable.ArrayBuffer.empty[api.driver.Converter] val converters = mutable.ArrayBuffer.empty[api.driver.Converter]
// Index using NBT representation of stacks because they can be hashed properly.
val blacklist = mutable.Map.empty[NBTTagCompound, mutable.Set[Class[_]]]
/** Used to keep track of whether we're past the init phase. */ /** Used to keep track of whether we're past the init phase. */
var locked = false var locked = false
@ -55,13 +59,13 @@ private[oc] object Registry extends api.detail.DriverAPI {
if (!converters.contains(converter)) converters += converter if (!converters.contains(converter)) converters += converter
} }
def driverFor(world: World, x: Int, y: Int, z: Int) = override def driverFor(world: World, x: Int, y: Int, z: Int) =
blocks.filter(_.worksWith(world, x, y, z)) match { blocks.filter(_.worksWith(world, x, y, z)) match {
case drivers if drivers.nonEmpty => new CompoundBlockDriver(drivers: _*) case drivers if drivers.nonEmpty => new CompoundBlockDriver(drivers: _*)
case _ => null case _ => null
} }
def driverFor(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = override def driverFor(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
if (stack != null) { if (stack != null) {
val hostAware = items.collect { val hostAware = items.collect {
case driver: HostAware if driver.worksWith(stack) => driver case driver: HostAware if driver.worksWith(stack) => driver
@ -73,7 +77,7 @@ private[oc] object Registry extends api.detail.DriverAPI {
} }
else null else null
def driverFor(stack: ItemStack) = override def driverFor(stack: ItemStack) =
if (stack != null) items.find(_.worksWith(stack)).orNull if (stack != null) items.find(_.worksWith(stack)).orNull
else null else null
@ -81,6 +85,10 @@ private[oc] object Registry extends api.detail.DriverAPI {
override def itemDrivers = items.toSeq override def itemDrivers = items.toSeq
def blacklistHost(item: NBTTagCompound, host: Class[_]) {
blacklist.getOrElseUpdate(item, mutable.Set.empty) += host
}
def convert(value: Array[AnyRef]) = if (value != null) value.map(arg => convertRecursively(arg, new util.IdentityHashMap())) else null def convert(value: Array[AnyRef]) = if (value != null) value.map(arg => convertRecursively(arg, new util.IdentityHashMap())) else null
def convertRecursively(value: Any, memo: util.IdentityHashMap[AnyRef, AnyRef], force: Boolean = false): AnyRef = { def convertRecursively(value: Any, memo: util.IdentityHashMap[AnyRef, AnyRef], force: Boolean = false): AnyRef = {

View File

@ -52,16 +52,18 @@ object PackedColor {
override def save(nbt: NBTTagCompound) {} override def save(nbt: NBTTagCompound) {}
} }
object SingleBitFormat extends ColorFormat { class SingleBitFormat(val color: Int) extends ColorFormat {
override def depth = ColorDepth.OneBit override def depth = ColorDepth.OneBit
override def inflate(value: Int) = if (value == 0) 0x000000 else Settings.get.monochromeColor override def inflate(value: Int) = if (value == 0) 0x000000 else color
override def deflate(value: Color) = { override def deflate(value: Color) = {
(if (value.value == 0) 0 else 1).toByte (if (value.value == 0) 0 else 1).toByte
} }
} }
object SingleBitFormat extends SingleBitFormat(Settings.get.monochromeColor)
abstract class PaletteFormat extends ColorFormat { abstract class PaletteFormat extends ColorFormat {
override def inflate(value: Int) = palette(math.max(0, math.min(palette.length - 1, value))) override def inflate(value: Int) = palette(math.max(0, math.min(palette.length - 1, value)))