diff --git a/src/main/java/li/cil/oc/api/Driver.java b/src/main/java/li/cil/oc/api/Driver.java index fab7ee5b6..f6cacedd1 100644 --- a/src/main/java/li/cil/oc/api/Driver.java +++ b/src/main/java/li/cil/oc/api/Driver.java @@ -100,10 +100,10 @@ public final class Driver { * will be used. * * @param stack the item stack to get a driver for. - * @param host the object that will host the environment created by returned driver. + * @param host the type that will host the environment created by returned driver. * @return a driver for the item, or null if there is none. */ - public static Item driverFor(ItemStack stack, EnvironmentHost host) { + public static Item driverFor(ItemStack stack, Class host) { if (instance != null) return instance.driverFor(stack, host); return null; diff --git a/src/main/java/li/cil/oc/api/detail/DriverAPI.java b/src/main/java/li/cil/oc/api/detail/DriverAPI.java index 444ab57cb..800e2c7de 100644 --- a/src/main/java/li/cil/oc/api/detail/DriverAPI.java +++ b/src/main/java/li/cil/oc/api/detail/DriverAPI.java @@ -73,10 +73,10 @@ public interface DriverAPI { * will be used. * * @param stack the item stack to get a driver for. - * @param host the object that will host the environment created by returned driver. + * @param host the type that will host the environment created by returned driver. * @return a driver for the item, or null if there is none. */ - Item driverFor(ItemStack stack, EnvironmentHost host); + Item driverFor(ItemStack stack, Class host); /** * Looks up a driver for the specified item stack. diff --git a/src/main/java/li/cil/oc/api/driver/Item.java b/src/main/java/li/cil/oc/api/driver/Item.java index 581491c88..c4e01a977 100644 --- a/src/main/java/li/cil/oc/api/driver/Item.java +++ b/src/main/java/li/cil/oc/api/driver/Item.java @@ -32,10 +32,10 @@ public interface Item { * be ejected, since this value is only checked when adding components. * * @param stack the item to check. - * @param host the host the environment would live in. + * @param host the type of host the environment would live in. * @return true if the item is supported; false otherwise. */ - boolean worksWith(ItemStack stack, EnvironmentHost host); + boolean worksWith(ItemStack stack, Class host); /** * Used to determine the item types this driver handles. diff --git a/src/main/java/li/cil/oc/api/prefab/DriverItem.java b/src/main/java/li/cil/oc/api/prefab/DriverItem.java index 1454a34ca..cddc695c9 100644 --- a/src/main/java/li/cil/oc/api/prefab/DriverItem.java +++ b/src/main/java/li/cil/oc/api/prefab/DriverItem.java @@ -27,7 +27,12 @@ public abstract class DriverItem implements li.cil.oc.api.driver.Item { } @Override - public boolean worksWith(final ItemStack stack, final EnvironmentHost host) { + public boolean worksWith(final ItemStack stack, final Class host) { + return worksWith(stack); + } + + @Override + public boolean worksWith(final ItemStack stack) { if (stack != null) { for (ItemStack item : items) { if (item != null && item.isItemEqual(stack)) { diff --git a/src/main/scala/li/cil/oc/client/gui/Robot.scala b/src/main/scala/li/cil/oc/client/gui/Robot.scala index 0e4f57f11..0037e963a 100644 --- a/src/main/scala/li/cil/oc/client/gui/Robot.scala +++ b/src/main/scala/li/cil/oc/client/gui/Robot.scala @@ -23,7 +23,7 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten case Some(buffer: api.component.TextBuffer) => buffer }.headOption.orNull - override protected val hasKeyboard = robot.info.components.map(api.Driver.driverFor).contains(driver.item.Keyboard) + override protected val hasKeyboard = robot.info.components.map(api.Driver.driverFor(_, robot.getClass)).contains(driver.item.Keyboard) private val withScreenHeight = 256 private val noScreenHeight = 108 diff --git a/src/main/scala/li/cil/oc/common/component/Terminal.scala b/src/main/scala/li/cil/oc/common/component/Terminal.scala index 0fe64e538..fcef3f8da 100644 --- a/src/main/scala/li/cil/oc/common/component/Terminal.scala +++ b/src/main/scala/li/cil/oc/common/component/Terminal.scala @@ -15,7 +15,7 @@ import scala.collection.mutable class Terminal(val rack: tileentity.ServerRack, val number: Int) { val buffer = { val screenItem = api.Items.get("screen1").createItemStack(1) - val buffer = api.Driver.driverFor(screenItem, rack).createEnvironment(screenItem, rack).asInstanceOf[api.component.TextBuffer] + val buffer = api.Driver.driverFor(screenItem, rack.getClass).createEnvironment(screenItem, rack).asInstanceOf[api.component.TextBuffer] val (maxWidth, maxHeight) = Settings.screenResolutionsByTier(1) buffer.setMaximumResolution(maxWidth, maxHeight) buffer.setMaximumColorDepth(Settings.screenDepthsByTier(1)) @@ -24,7 +24,7 @@ class Terminal(val rack: tileentity.ServerRack, val number: Int) { val keyboard = { val keyboardItem = api.Items.get("keyboard").createItemStack(1) - val keyboard = api.Driver.driverFor(keyboardItem, rack).createEnvironment(keyboardItem, rack).asInstanceOf[api.component.Keyboard] + val keyboard = api.Driver.driverFor(keyboardItem, rack.getClass).createEnvironment(keyboardItem, rack).asInstanceOf[api.component.Keyboard] keyboard.setUsableOverride(new UsabilityChecker { override def isUsableByPlayer(keyboard: api.component.Keyboard, player: EntityPlayer) = { val stack = player.getCurrentEquippedItem diff --git a/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala b/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala index 677f2ec4f..8eda31041 100644 --- a/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala +++ b/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala @@ -35,7 +35,7 @@ trait ComponentInventory extends Inventory with network.Environment { for (slot <- 0 until getSizeInventory if slot >= 0 && slot < components.length) { val stack = getStackInSlot(slot) if (stack != null && components(slot).isEmpty && isComponentSlot(slot)) { - components(slot) = Option(Driver.driverFor(stack, host)) match { + components(slot) = Option(Driver.driverFor(stack, host.getClass)) match { case Some(driver) => Option(driver.createEnvironment(stack, host)) match { case Some(component) => @@ -81,7 +81,7 @@ trait ComponentInventory extends Inventory with network.Environment { components(slot) match { case Some(component) => // We're guaranteed to have a driver for entries. - save(component, Driver.driverFor(stack, host), stack) + save(component, Driver.driverFor(stack, host.getClass), stack) case _ => // Nothing special to save. } } @@ -93,7 +93,7 @@ trait ComponentInventory extends Inventory with network.Environment { override def getInventoryStackLimit = 1 override protected def onItemAdded(slot: Int, stack: ItemStack) = if (isComponentSlot(slot)) { - Option(Driver.driverFor(stack, host)).foreach(driver => + Option(Driver.driverFor(stack, host.getClass)).foreach(driver => Option(driver.createEnvironment(stack, host)) match { case Some(component) => this.synchronized { components(slot) = Some(component) @@ -124,7 +124,7 @@ trait ComponentInventory extends Inventory with network.Environment { components(slot) = None updatingComponents -= component Option(component.node).foreach(_.remove()) - Option(Driver.driverFor(stack, host)).foreach(save(component, _, stack)) + Option(Driver.driverFor(stack, host.getClass)).foreach(save(component, _, stack)) // However, nodes then may add themselves to a network again, to // ensure they have an address that gets sent to the client, used // for associating some components with each other. So we do it again. diff --git a/src/main/scala/li/cil/oc/common/inventory/ServerInventory.scala b/src/main/scala/li/cil/oc/common/inventory/ServerInventory.scala index 7b9dbf429..f4ab91956 100644 --- a/src/main/scala/li/cil/oc/common/inventory/ServerInventory.scala +++ b/src/main/scala/li/cil/oc/common/inventory/ServerInventory.scala @@ -1,7 +1,7 @@ package li.cil.oc.common.inventory import li.cil.oc.api.Driver -import li.cil.oc.common.InventorySlots +import li.cil.oc.common.{InventorySlots, tileentity} import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack @@ -17,7 +17,7 @@ trait ServerInventory extends ItemStackInventory { override def isUseableByPlayer(player: EntityPlayer) = false override def isItemValidForSlot(slot: Int, stack: ItemStack) = - Option(Driver.driverFor(stack)).fold(false)(driver => { + Option(Driver.driverFor(stack, classOf[tileentity.ServerRack])).fold(false)(driver => { val provided = InventorySlots.server(tier)(slot) driver.slot(stack) == provided.slot && driver.tier(stack) <= provided.tier }) diff --git a/src/main/scala/li/cil/oc/common/item/Tablet.scala b/src/main/scala/li/cil/oc/common/item/Tablet.scala index 9ebdf417b..528d11892 100644 --- a/src/main/scala/li/cil/oc/common/item/Tablet.scala +++ b/src/main/scala/li/cil/oc/common/item/Tablet.scala @@ -221,7 +221,7 @@ class TabletWrapper(var stack: ItemStack, var holder: EntityPlayer) extends Comp override def cpuArchitecture: Class[_ <: Architecture] = { for (i <- 0 until getSizeInventory if isComponentSlot(i)) Option(getStackInSlot(i)) match { - case Some(s) => Option(Driver.driverFor(s, host)) match { + case Some(s) => Option(Driver.driverFor(s, getClass)) match { case Some(driver: Processor) if driver.slot(s) == Slot.CPU => return driver.architecture(s) case _ => } @@ -231,7 +231,7 @@ class TabletWrapper(var stack: ItemStack, var holder: EntityPlayer) extends Comp } override def installedMemory = items.foldLeft(0)((acc, itemOption) => acc + (itemOption match { - case Some(item) => Option(api.Driver.driverFor(item, host)) match { + case Some(item) => Option(api.Driver.driverFor(item, getClass)) match { case Some(driver: api.driver.Memory) => driver.amount(item) case _ => 0 } diff --git a/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala b/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala index c8b3463e7..7078bc748 100644 --- a/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala +++ b/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala @@ -1,7 +1,7 @@ package li.cil.oc.common.template import cpw.mods.fml.common.event.FMLInterModComms -import li.cil.oc.common.{Slot, Tier} +import li.cil.oc.common.{Slot, Tier, tileentity} import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ItemUtils import li.cil.oc.{Settings, api} @@ -10,6 +10,8 @@ import net.minecraft.item.ItemStack import net.minecraft.nbt.{NBTTagCompound, NBTTagList} object RobotTemplate extends Template { + override protected def hostClass = classOf[tileentity.Robot] + def selectTier1(stack: ItemStack) = ItemUtils.caseTier(stack) == Tier.One def selectTier2(stack: ItemStack) = ItemUtils.caseTier(stack) == Tier.Two diff --git a/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala b/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala index c68de54e8..4286440f2 100644 --- a/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala +++ b/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala @@ -1,6 +1,7 @@ package li.cil.oc.common.template import cpw.mods.fml.common.event.FMLInterModComms +import li.cil.oc.common.item.TabletWrapper import li.cil.oc.{Settings, api} import li.cil.oc.common.{Slot, Tier} import li.cil.oc.server.driver.item @@ -17,11 +18,13 @@ object TabletTemplate extends Template { "GraphicsCard" -> ((inventory: IInventory) => Array("graphicsCard1", "graphicsCard2", "graphicsCard3").exists(name => hasComponent(name)(inventory))), "OS" -> hasFileSystem _) + override protected def hostClass = classOf[TabletWrapper] + def select(stack: ItemStack) = api.Items.get(stack) == api.Items.get("tabletCase") def validate(inventory: IInventory): Array[AnyRef] = validateComputer(inventory) - def validateUpgrade(inventory: IInventory, slot: Int, tier: Int, stack: ItemStack): Boolean = Option(api.Driver.driverFor(stack)) match { + def validateUpgrade(inventory: IInventory, slot: Int, tier: Int, stack: ItemStack): Boolean = Option(api.Driver.driverFor(stack, hostClass)) match { case Some(driver) if driver.slot(stack) == Slot.Upgrade => driver != item.Screen && driver.slot(stack) == Slot.Upgrade && driver.tier(stack) <= tier diff --git a/src/main/scala/li/cil/oc/common/template/Template.scala b/src/main/scala/li/cil/oc/common/template/Template.scala index 8eb990aec..9040675f6 100644 --- a/src/main/scala/li/cil/oc/common/template/Template.scala +++ b/src/main/scala/li/cil/oc/common/template/Template.scala @@ -1,6 +1,6 @@ package li.cil.oc.common.template -import li.cil.oc.api.driver.{Container, Inventory, Memory, Processor} +import li.cil.oc.api.driver._ import li.cil.oc.common.{Slot, Tier} import li.cil.oc.{Localization, Settings, api} import net.minecraft.inventory.IInventory @@ -17,6 +17,8 @@ abstract class Template { "Inventory" -> hasInventory _, "OS" -> hasFileSystem _) + protected def hostClass: Class[_ <: EnvironmentHost] + protected def validateComputer(inventory: IInventory): Array[AnyRef] = { val hasCase = caseTier(inventory) != Tier.None val hasCPU = this.hasCPU(inventory) @@ -51,12 +53,12 @@ abstract class Template { }) } - protected def hasCPU(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_) match { + protected def hasCPU(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_, hostClass) match { case _: Processor => true case _ => false }) - protected def hasRAM(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_) match { + protected def hasRAM(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_, hostClass) match { case _: Memory => true case _ => false }) @@ -66,12 +68,12 @@ abstract class Template { case _ => false }) - protected def hasInventory(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_) match { + protected def hasInventory(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_, hostClass) match { case _: Inventory => true case _ => false }) - protected def hasFileSystem(inventory: IInventory) = exists(inventory, stack => Option(api.Driver.driverFor(stack)) match { + protected def hasFileSystem(inventory: IInventory) = exists(inventory, stack => Option(api.Driver.driverFor(stack, hostClass)) match { case Some(driver) => driver.slot(stack) == Slot.Floppy || driver.slot(stack) == Slot.HDD case _ => false }) @@ -80,7 +82,7 @@ abstract class Template { var acc = 0 for (slot <- 1 until inventory.getSizeInventory) { val stack = inventory.getStackInSlot(slot) - acc += (Option(api.Driver.driverFor(stack)) match { + acc += (Option(api.Driver.driverFor(stack, hostClass)) match { case Some(driver: Processor) => 0 // CPUs are exempt, since they control the limit. case Some(driver: Container) => (1 + driver.tier(stack)) * 2 case Some(driver) => 1 + driver.tier(stack) @@ -94,7 +96,7 @@ abstract class Template { val caseTier = this.caseTier(inventory) val cpuTier = (0 until inventory.getSizeInventory).foldRight(0)((slot, acc) => { val stack = inventory.getStackInSlot(slot) - acc + (api.Driver.driverFor(stack) match { + acc + (api.Driver.driverFor(stack, hostClass) match { case processor: Processor => processor.tier(stack) case _ => 0 }) diff --git a/src/main/scala/li/cil/oc/common/tileentity/Case.scala b/src/main/scala/li/cil/oc/common/tileentity/Case.scala index 87c659a9a..e0df55a4e 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Case.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Case.scala @@ -33,7 +33,7 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with def recomputeMaxComponents() { maxComponents = items.foldLeft(0)((sum, stack) => sum + (stack match { - case Some(item) => Option(Driver.driverFor(item, host)) match { + case Some(item) => Option(Driver.driverFor(item, getClass)) match { case Some(driver: driver.Processor) => driver.supportedComponents(item) case _ => 0 } @@ -42,7 +42,7 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with } override def installedMemory = items.foldLeft(0)((sum, stack) => sum + (stack match { - case Some(item) => Option(Driver.driverFor(item, host)) match { + case Some(item) => Option(Driver.driverFor(item, getClass)) match { case Some(driver: driver.Memory) => driver.amount(item) case _ => 0 } @@ -114,7 +114,7 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with super.isUseableByPlayer(player) && (!isCreativeCase || player.capabilities.isCreativeMode) override def isItemValidForSlot(slot: Int, stack: ItemStack) = - Option(Driver.driverFor(stack, host)).fold(false)(driver => { + Option(Driver.driverFor(stack, getClass)).fold(false)(driver => { val provided = InventorySlots.computer(tier)(slot) driver.slot(stack) == provided.slot && driver.tier(stack) <= provided.tier }) diff --git a/src/main/scala/li/cil/oc/common/tileentity/Charger.scala b/src/main/scala/li/cil/oc/common/tileentity/Charger.scala index d5cb1296e..de4dc5b5f 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Charger.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Charger.scala @@ -140,7 +140,7 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R override def getSizeInventory = 1 - override def isItemValidForSlot(slot: Int, stack: ItemStack) = (slot, Option(Driver.driverFor(stack, host))) match { + override def isItemValidForSlot(slot: Int, stack: ItemStack) = (slot, Option(Driver.driverFor(stack, getClass))) match { case (0, Some(driver)) => driver.slot(stack) == Slot.Tablet case _ => false } diff --git a/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala b/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala index 75ff9693b..32dc47149 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala @@ -29,7 +29,7 @@ class DiskDrive extends traits.Environment with traits.ComponentInventory with t override def getSizeInventory = 1 - override def isItemValidForSlot(slot: Int, stack: ItemStack) = (slot, Option(Driver.driverFor(stack, host))) match { + override def isItemValidForSlot(slot: Int, stack: ItemStack) = (slot, Option(Driver.driverFor(stack, getClass))) match { case (0, Some(driver)) => driver.slot(stack) == Slot.Floppy case _ => false } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala b/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala index 65ed87e96..c702c29ff 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala @@ -13,7 +13,7 @@ class Keyboard extends traits.Environment with traits.Rotatable with traits.Immi val keyboard = { val keyboardItem = api.Items.get("keyboard").createItemStack(1) - api.Driver.driverFor(keyboardItem, this).createEnvironment(keyboardItem, this) + api.Driver.driverFor(keyboardItem, getClass).createEnvironment(keyboardItem, this) } override def node = keyboard.node diff --git a/src/main/scala/li/cil/oc/common/tileentity/Robot.scala b/src/main/scala/li/cil/oc/common/tileentity/Robot.scala index 620401559..3e9680351 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Robot.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Robot.scala @@ -72,7 +72,7 @@ class Robot extends traits.Computer with traits.PowerInformation with tileentity components(slot) match { case Some(component) => // We're guaranteed to have a driver for entries. - save(component, Driver.driverFor(stack, host), stack) + save(component, Driver.driverFor(stack, getClass), stack) case _ => } ServerPacketSender.sendRobotInventory(this, slot, stack) @@ -493,7 +493,7 @@ class Robot extends traits.Computer with traits.PowerInformation with tileentity def containerSlotType(slot: Int) = if (containerSlots contains slot) { val stack = info.containers(slot - 1) - Option(Driver.driverFor(stack, host)) match { + Option(Driver.driverFor(stack, getClass)) match { case Some(driver: api.driver.Container) => driver.providedSlot(stack) case _ => Slot.None } @@ -502,7 +502,7 @@ class Robot extends traits.Computer with traits.PowerInformation with tileentity def containerSlotTier(slot: Int) = if (containerSlots contains slot) { val stack = info.containers(slot - 1) - Option(Driver.driverFor(stack, host)) match { + Option(Driver.driverFor(stack, getClass)) match { case Some(driver: api.driver.Container) => driver.providedTier(stack) case _ => Tier.None } @@ -516,7 +516,7 @@ class Robot extends traits.Computer with traits.PowerInformation with tileentity def isInventorySlot(slot: Int) = inventorySlots contains slot def isFloppySlot(slot: Int) = isComponentSlot(slot) && (Option(getStackInSlot(slot)) match { - case Some(stack) => Option(Driver.driverFor(stack, host)) match { + case Some(stack) => Option(Driver.driverFor(stack, getClass)) match { case Some(driver) => driver.slot(stack) == Slot.Floppy case _ => false } @@ -528,7 +528,7 @@ class Robot extends traits.Computer with traits.PowerInformation with tileentity // ----------------------------------------------------------------------- // override def installedMemory = (containerSlots ++ componentSlots).foldLeft(0)((acc, slot) => acc + (Option(getStackInSlot(slot)) match { - case Some(stack) => Option(Driver.driverFor(stack, host)) match { + case Some(stack) => Option(Driver.driverFor(stack, getClass)) match { case Some(driver: api.driver.Memory) => driver.amount(stack) case _ => 0 } @@ -537,10 +537,10 @@ class Robot extends traits.Computer with traits.PowerInformation with tileentity override def componentSlot(address: String) = components.indexWhere(_.exists(env => env.node != null && env.node.address == address)) - override def hasRedstoneCard = (containerSlots ++ componentSlots).exists(slot => Option(getStackInSlot(slot)).fold(false)(driver.item.RedstoneCard.worksWith(_, host))) + override def hasRedstoneCard = (containerSlots ++ componentSlots).exists(slot => Option(getStackInSlot(slot)).fold(false)(driver.item.RedstoneCard.worksWith(_, getClass))) private def computeInventorySize() = math.min(maxInventorySize, (containerSlots ++ componentSlots).foldLeft(0)((acc, slot) => acc + (Option(getStackInSlot(slot)) match { - case Some(stack) => Option(Driver.driverFor(stack, host)) match { + case Some(stack) => Option(Driver.driverFor(stack, getClass)) match { case Some(driver: api.driver.Inventory) => driver.inventoryCapacity(stack) case _ => 0 } @@ -607,7 +607,7 @@ class Robot extends traits.Computer with traits.PowerInformation with tileentity } } - override def isItemValidForSlot(slot: Int, stack: ItemStack) = (slot, Option(Driver.driverFor(stack, host))) match { + override def isItemValidForSlot(slot: Int, stack: ItemStack) = (slot, Option(Driver.driverFor(stack, getClass))) match { case (0, _) => true // Allow anything in the tool slot. case (i, Some(driver)) if isContainerSlot(i) => // Yay special cases! Dynamic screens kind of work, but are pretty derpy diff --git a/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala b/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala index dbc5bbbff..4cba531de 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala @@ -93,7 +93,7 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB def hasAbstractBusCard = servers exists { case Some(server) => server.machine.isRunning && server.inventory.items.exists { - case Some(stack) => driver.item.AbstractBusCard.worksWith(stack, server.inventory.host) + case Some(stack) => driver.item.AbstractBusCard.worksWith(stack, getClass) case _ => false } case _ => false @@ -101,7 +101,7 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB def hasRedstoneCard = servers exists { case Some(server) => server.machine.isRunning && server.inventory.items.exists { - case Some(stack) => driver.item.RedstoneCard.worksWith(stack, server.inventory.host) + case Some(stack) => driver.item.RedstoneCard.worksWith(stack, getClass) case _ => false } case _ => false diff --git a/src/main/scala/li/cil/oc/common/tileentity/Switch.scala b/src/main/scala/li/cil/oc/common/tileentity/Switch.scala index b6ca564cf..5b1d5d214 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Switch.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Switch.scala @@ -134,7 +134,7 @@ class Switch extends traits.Hub with traits.NotAnalyzable with IPeripheral with } private def updateLimits(slot: Int, stack: ItemStack) { - Driver.driverFor(stack, host) match { + Driver.driverFor(stack, getClass) match { case driver if driver.slot(stack) == Slot.CPU => relayDelay = math.max(1, relayBaseDelay - ((driver.tier(stack) + 1) * relayDelayPerUpgrade)) case driver if driver.slot(stack) == Slot.Memory => @@ -149,7 +149,7 @@ class Switch extends traits.Hub with traits.NotAnalyzable with IPeripheral with override protected def onItemRemoved(slot: Int, stack: ItemStack) { super.onItemRemoved(slot, stack) - Driver.driverFor(stack, host) match { + Driver.driverFor(stack, getClass) match { case driver if driver.slot(stack) == Slot.CPU => relayDelay = relayBaseDelay case driver if driver.slot(stack) == Slot.Memory => relayAmount = relayBaseAmount case driver if driver.slot(stack) == Slot.HDD => maxQueueSize = queueBaseSize @@ -159,7 +159,7 @@ class Switch extends traits.Hub with traits.NotAnalyzable with IPeripheral with override def getSizeInventory = InventorySlots.switch.length override def isItemValidForSlot(slot: Int, stack: ItemStack) = - Option(Driver.driverFor(stack, host)).fold(false)(driver => { + Option(Driver.driverFor(stack, getClass)).fold(false)(driver => { val provided = InventorySlots.switch(slot) driver.slot(stack) == provided.slot && driver.tier(stack) <= provided.tier }) diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala index f1ee16b98..4c02ffeed 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala @@ -64,7 +64,7 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B override def cpuArchitecture: Class[_ <: Architecture] = { for (i <- 0 until getSizeInventory if isComponentSlot(i)) Option(getStackInSlot(i)) match { - case Some(s) => Option(Driver.driverFor(s, host)) match { + case Some(s) => Option(Driver.driverFor(s, getClass)) match { case Some(driver: Processor) if driver.slot(s) == Slot.CPU => return driver.architecture(s) case _ => } @@ -84,12 +84,12 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B override def onMachineDisconnect(node: Node) = this.onDisconnect(node) def hasAbstractBusCard = items.exists { - case Some(item) => machine.isRunning && driver.item.AbstractBusCard.worksWith(item, host) + case Some(item) => machine.isRunning && driver.item.AbstractBusCard.worksWith(item, getClass) case _ => false } def hasRedstoneCard = items.exists { - case Some(item) => machine.isRunning && driver.item.RedstoneCard.worksWith(item, host) + case Some(item) => machine.isRunning && driver.item.RedstoneCard.worksWith(item, getClass) case _ => false } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/TextBuffer.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/TextBuffer.scala index 1219ca1f2..1a7595ead 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/TextBuffer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/TextBuffer.scala @@ -7,7 +7,7 @@ import net.minecraft.nbt.NBTTagCompound trait TextBuffer extends Environment { lazy val buffer = { val screenItem = api.Items.get("screen1").createItemStack(1) - val buffer = api.Driver.driverFor(screenItem, this).createEnvironment(screenItem, this).asInstanceOf[api.component.TextBuffer] + val buffer = api.Driver.driverFor(screenItem, getClass).createEnvironment(screenItem, this).asInstanceOf[api.component.TextBuffer] val (maxWidth, maxHeight) = Settings.screenResolutionsByTier(tier) buffer.setMaximumResolution(maxWidth, maxHeight) buffer.setMaximumColorDepth(Settings.screenDepthsByTier(tier)) diff --git a/src/main/scala/li/cil/oc/server/component/Server.scala b/src/main/scala/li/cil/oc/server/component/Server.scala index 1cda10c94..071215ba4 100644 --- a/src/main/scala/li/cil/oc/server/component/Server.scala +++ b/src/main/scala/li/cil/oc/server/component/Server.scala @@ -25,7 +25,7 @@ class Server(val rack: tileentity.ServerRack, val number: Int) extends MachineHo override def cpuArchitecture: Class[_ <: Architecture] = { for (i <- 0 until inventory.getSizeInventory if inventory.isComponentSlot(i)) Option(inventory.getStackInSlot(i)) match { - case Some(s) => Option(Driver.driverFor(s, inventory.host)) match { + case Some(s) => Option(Driver.driverFor(s, rack.getClass)) match { case Some(driver: Processor) if driver.slot(s) == Slot.CPU => return driver.architecture(s) case _ => } @@ -35,7 +35,7 @@ class Server(val rack: tileentity.ServerRack, val number: Int) extends MachineHo } override def installedMemory = inventory.items.foldLeft(0)((sum, stack) => sum + (stack match { - case Some(item) => Option(Driver.driverFor(item, inventory.host)) match { + case Some(item) => Option(Driver.driverFor(item, rack.getClass)) match { case Some(driver: driver.Memory) => driver.amount(item) case _ => 0 } @@ -44,7 +44,7 @@ class Server(val rack: tileentity.ServerRack, val number: Int) extends MachineHo lazy val maxComponents = if (!hasCPU) 0 else inventory.items.foldLeft(0)((sum, stack) => sum + (stack match { - case Some(item) => Option(Driver.driverFor(item, inventory.host)) match { + case Some(item) => Option(Driver.driverFor(item, rack.getClass)) match { case Some(driver: driver.Processor) => driver.supportedComponents(item) case _ => 0 } @@ -54,7 +54,7 @@ class Server(val rack: tileentity.ServerRack, val number: Int) extends MachineHo override def componentSlot(address: String) = inventory.components.indexWhere(_.exists(env => env.node != null && env.node.address == address)) def hasCPU = inventory.items.exists { - case Some(stack) => Option(Driver.driverFor(stack, inventory.host)) match { + case Some(stack) => Option(Driver.driverFor(stack, rack.getClass)) match { case Some(driver) => driver.slot(stack) == Slot.CPU case _ => false } diff --git a/src/main/scala/li/cil/oc/server/driver/Registry.scala b/src/main/scala/li/cil/oc/server/driver/Registry.scala index 615b0fdb7..492169ce0 100644 --- a/src/main/scala/li/cil/oc/server/driver/Registry.scala +++ b/src/main/scala/li/cil/oc/server/driver/Registry.scala @@ -57,7 +57,7 @@ private[oc] object Registry extends api.detail.DriverAPI { case _ => null } - def driverFor(stack: ItemStack, host: EnvironmentHost) = + def driverFor(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = if (stack != null) items.find(_.worksWith(stack, host)).orNull else null diff --git a/src/main/scala/li/cil/oc/server/driver/item/AbstractBusCard.scala b/src/main/scala/li/cil/oc/server/driver/item/AbstractBusCard.scala index abfe141a3..98274dc95 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/AbstractBusCard.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/AbstractBusCard.scala @@ -12,7 +12,7 @@ object AbstractBusCard extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("abstractBusCard")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && isComputer(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = if (Mods.StargateTech2.isAvailable) host match { diff --git a/src/main/scala/li/cil/oc/server/driver/item/Item.scala b/src/main/scala/li/cil/oc/server/driver/item/Item.scala index c02fbc53f..627aef4f0 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/Item.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/Item.scala @@ -12,15 +12,17 @@ trait Item extends driver.Item { override def dataTag(stack: ItemStack) = Item.dataTag(stack) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = worksWith(stack) + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = worksWith(stack) protected def isOneOf(stack: ItemStack, items: api.detail.ItemInfo*) = items.filter(_ != null).contains(api.Items.get(stack)) - protected def isComputer(host: EnvironmentHost) = host.isInstanceOf[tileentity.traits.Computer] || host.isInstanceOf[tileentity.ServerRack] + protected def isRotatable(host: Class[_ <: EnvironmentHost]) = classOf[api.tileentity.Rotatable].isAssignableFrom(host) - protected def isRobot(host: EnvironmentHost) = host.isInstanceOf[api.tileentity.Robot] + protected def isComputer(host: Class[_ <: EnvironmentHost]) = host.isInstanceOf[tileentity.traits.Computer] || host.isInstanceOf[tileentity.ServerRack] - protected def isTablet(host: EnvironmentHost) = host.isInstanceOf[item.TabletWrapper] + protected def isRobot(host: Class[_ <: EnvironmentHost]) = host.isInstanceOf[api.tileentity.Robot] + + protected def isTablet(host: Class[_ <: EnvironmentHost]) = host.isInstanceOf[item.TabletWrapper] } object Item { diff --git a/src/main/scala/li/cil/oc/server/driver/item/NetworkCard.scala b/src/main/scala/li/cil/oc/server/driver/item/NetworkCard.scala index 0799efff1..d3213de0d 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/NetworkCard.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/NetworkCard.scala @@ -10,7 +10,7 @@ object NetworkCard extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("lanCard")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && !isTablet(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.NetworkCard() diff --git a/src/main/scala/li/cil/oc/server/driver/item/RedstoneCard.scala b/src/main/scala/li/cil/oc/server/driver/item/RedstoneCard.scala index 567bead6f..15ccd48d8 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/RedstoneCard.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/RedstoneCard.scala @@ -11,7 +11,7 @@ import net.minecraft.item.ItemStack object RedstoneCard extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("redstoneCard1"), api.Items.get("redstoneCard2")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && isComputer(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = diff --git a/src/main/scala/li/cil/oc/server/driver/item/Screen.scala b/src/main/scala/li/cil/oc/server/driver/item/Screen.scala index b3c62e3cc..9e4e180ef 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/Screen.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/Screen.scala @@ -9,7 +9,7 @@ object Screen extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("screen1")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && !isTablet(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match { diff --git a/src/main/scala/li/cil/oc/server/driver/item/Tablet.scala b/src/main/scala/li/cil/oc/server/driver/item/Tablet.scala index 04c96c759..4a780ce59 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/Tablet.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/Tablet.scala @@ -12,13 +12,13 @@ object Tablet extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("tablet")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && isTablet(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = { val data = new ItemUtils.TabletData(stack) data.items.collect { - case Some(fs) if FileSystem.worksWith(fs, host) => fs + case Some(fs) if FileSystem.worksWith(fs, host.getClass) => fs }.headOption.map(FileSystem.createEnvironment(_, host)).orNull } diff --git a/src/main/scala/li/cil/oc/server/driver/item/UpgradeAngel.scala b/src/main/scala/li/cil/oc/server/driver/item/UpgradeAngel.scala index 794db4231..92b33378b 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/UpgradeAngel.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/UpgradeAngel.scala @@ -10,7 +10,7 @@ object UpgradeAngel extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("angelUpgrade")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && isRobot(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeAngel() diff --git a/src/main/scala/li/cil/oc/server/driver/item/UpgradeChunkloader.scala b/src/main/scala/li/cil/oc/server/driver/item/UpgradeChunkloader.scala index 22e6ba5fb..2ed216eb1 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/UpgradeChunkloader.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/UpgradeChunkloader.scala @@ -10,7 +10,7 @@ object UpgradeChunkloader extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("chunkloaderUpgrade")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && isRobot(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeChunkloader(host) diff --git a/src/main/scala/li/cil/oc/server/driver/item/UpgradeCrafting.scala b/src/main/scala/li/cil/oc/server/driver/item/UpgradeCrafting.scala index 1c53a833f..2fd2c0e51 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/UpgradeCrafting.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/UpgradeCrafting.scala @@ -11,7 +11,7 @@ object UpgradeCrafting extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("craftingUpgrade")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && isRobot(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = diff --git a/src/main/scala/li/cil/oc/server/driver/item/UpgradeExperience.scala b/src/main/scala/li/cil/oc/server/driver/item/UpgradeExperience.scala index af01ee9df..29e3c4e67 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/UpgradeExperience.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/UpgradeExperience.scala @@ -10,7 +10,7 @@ object UpgradeExperience extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("experienceUpgrade")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && isRobot(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.UpgradeExperience() diff --git a/src/main/scala/li/cil/oc/server/driver/item/UpgradeGenerator.scala b/src/main/scala/li/cil/oc/server/driver/item/UpgradeGenerator.scala index cd0c19b93..11bd0e26e 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/UpgradeGenerator.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/UpgradeGenerator.scala @@ -11,7 +11,7 @@ object UpgradeGenerator extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("generatorUpgrade")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && isRobot(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = diff --git a/src/main/scala/li/cil/oc/server/driver/item/UpgradeInventory.scala b/src/main/scala/li/cil/oc/server/driver/item/UpgradeInventory.scala index 6291b57af..b2446f43a 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/UpgradeInventory.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/UpgradeInventory.scala @@ -9,7 +9,7 @@ object UpgradeInventory extends Item with Inventory { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("inventoryUpgrade")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && isRobot(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = null diff --git a/src/main/scala/li/cil/oc/server/driver/item/UpgradeInventoryController.scala b/src/main/scala/li/cil/oc/server/driver/item/UpgradeInventoryController.scala index d682d5398..3270458ce 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/UpgradeInventoryController.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/UpgradeInventoryController.scala @@ -11,7 +11,7 @@ object UpgradeInventoryController extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("inventoryControllerUpgrade")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && isRobot(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match { diff --git a/src/main/scala/li/cil/oc/server/driver/item/UpgradeNavigation.scala b/src/main/scala/li/cil/oc/server/driver/item/UpgradeNavigation.scala index 6a9febbe0..527db73e7 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/UpgradeNavigation.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/UpgradeNavigation.scala @@ -11,8 +11,8 @@ object UpgradeNavigation extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("navigationUpgrade")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = - super.worksWith(stack, host) && host.isInstanceOf[Rotatable] + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = + super.worksWith(stack, host) && isRotatable(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match { diff --git a/src/main/scala/li/cil/oc/server/driver/item/UpgradePiston.scala b/src/main/scala/li/cil/oc/server/driver/item/UpgradePiston.scala index b5b03be20..bbdb79585 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/UpgradePiston.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/UpgradePiston.scala @@ -11,8 +11,8 @@ object UpgradePiston extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("pistonUpgrade")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = - super.worksWith(stack, host) && host.isInstanceOf[Rotatable] + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = + super.worksWith(stack, host) && isRotatable(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match { case rotatable: Rotatable with EnvironmentHost => new component.UpgradePiston(rotatable) diff --git a/src/main/scala/li/cil/oc/server/driver/item/UpgradeSign.scala b/src/main/scala/li/cil/oc/server/driver/item/UpgradeSign.scala index 24da7b503..4406715a0 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/UpgradeSign.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/UpgradeSign.scala @@ -11,8 +11,8 @@ object UpgradeSign extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("signUpgrade")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = - super.worksWith(stack, host) && host.isInstanceOf[Rotatable] + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = + super.worksWith(stack, host) && isRotatable(host) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match { diff --git a/src/main/scala/li/cil/oc/server/driver/item/UpgradeTractorBeam.scala b/src/main/scala/li/cil/oc/server/driver/item/UpgradeTractorBeam.scala index 21021d0f4..a3d1be423 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/UpgradeTractorBeam.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/UpgradeTractorBeam.scala @@ -12,7 +12,7 @@ object UpgradeTractorBeam extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("tractorBeamUpgrade")) - override def worksWith(stack: ItemStack, host: EnvironmentHost) = + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = super.worksWith(stack, host) && (isRobot(host) || isTablet(host)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match {