Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8

Conflicts:
	src/main/scala/li/cil/oc/common/item/Tablet.scala
	src/main/scala/li/cil/oc/common/item/UpgradeBattery.scala
	src/main/scala/li/cil/oc/common/tileentity/Charger.scala
	src/main/scala/li/cil/oc/common/tileentity/Robot.scala
	src/main/scala/li/cil/oc/integration/cofh/energy/EventHandlerRedstoneFlux.scala
	src/main/scala/li/cil/oc/integration/ic2/EventHandlerIndustrialCraft2.scala
This commit is contained in:
Florian Nücke 2015-04-24 17:39:04 +02:00
commit 8ee8309cb7
21 changed files with 296 additions and 66 deletions

View File

@ -16,7 +16,7 @@ import li.cil.oc.api.detail.NetworkAPI;
*/ */
public class API { public class API {
public static final String ID_OWNER = "OpenComputers|Core"; public static final String ID_OWNER = "OpenComputers|Core";
public static final String VERSION = "5.2.1"; public static final String VERSION = "5.2.2";
public static DriverAPI driver = null; public static DriverAPI driver = null;
public static FileSystemAPI fileSystem = null; public static FileSystemAPI fileSystem = null;

View File

@ -0,0 +1,34 @@
package li.cil.oc.api.driver.item;
import net.minecraft.item.ItemStack;
/**
* This interface can be implemented on items that go into a charger.
* <p/>
* This provides a generic way of charging items, even such that are not
* components. Doing it this way enables items to provide another environment,
* that is unrelated to charging, such as tablets providing their file system,
* while in the charger.
*/
public interface Chargeable {
/**
* Whether the specified item stack can be charged.
* <p/>
* This is primarily meant to filter meta item subitems that are not meant
* to be chargeable.
*
* @param stack the stack to check for.
* @return whether the specified item stack is chargeable.
*/
boolean canCharge(ItemStack stack);
/**
* Called when checking if an item can be charged or should be charged.
*
* @param stack the item to charge.
* @param amount the amount to inject into the item.
* @param simulate whether to only simulate injection.
* @return the remainder of the energy that could not be injected.
*/
double charge(ItemStack stack, double amount, boolean simulate);
}

View File

@ -8,6 +8,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.common.template.DisassemblerTemplates import li.cil.oc.common.template.DisassemblerTemplates
import li.cil.oc.integration.util.ItemCharge
import li.cil.oc.integration.util.Wrench import li.cil.oc.integration.util.Wrench
import li.cil.oc.server.driver.Registry import li.cil.oc.server.driver.Registry
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
@ -57,6 +58,15 @@ object IMC {
case t: Throwable => OpenComputers.log.warn("Failed registering wrench tool.", t) case t: Throwable => OpenComputers.log.warn("Failed registering wrench tool.", t)
} }
} }
else if (message.key == "registerItemCharge" && message.isNBTMessage) {
OpenComputers.log.info(s"Registering new item charge implementation '${message.getNBTValue.getString("name")}' from mod ${message.getSender}.")
try ItemCharge.add(
getStaticMethod(message.getNBTValue.getString("canCharge"), classOf[ItemStack]),
getStaticMethod(message.getNBTValue.getString("charge"), classOf[ItemStack], classOf[Double], classOf[Boolean])
) catch {
case t: Throwable => OpenComputers.log.warn("Failed registering item charge implementation.", t)
}
}
else if (message.key == "blacklistPeripheral" && message.isStringMessage) { else if (message.key == "blacklistPeripheral" && message.isStringMessage) {
OpenComputers.log.info(s"Blacklisting CC peripheral '${message.getStringValue}' as requested by mod ${message.getSender}.") OpenComputers.log.info(s"Blacklisting CC peripheral '${message.getStringValue}' as requested by mod ${message.getSender}.")
if (!Settings.get.peripheralBlacklist.contains(message.getStringValue)) { if (!Settings.get.peripheralBlacklist.contains(message.getStringValue)) {

View File

@ -247,9 +247,9 @@ object Items extends ItemAPI {
Option(get(Constants.ItemName.RAMTier6).createItemStack(1)), Option(get(Constants.ItemName.RAMTier6).createItemStack(1)),
Option(createLuaBios()), Option(createLuaBios()),
Option(createOpenOS()),
Option(get(Constants.ItemName.HDDTier3).createItemStack(1)) Option(get(Constants.ItemName.HDDTier3).createItemStack(1))
) ).padTo(32, None)
data.items(31) = Option(createOpenOS())
data.container = Option(get(Constants.BlockName.DiskDrive).createItemStack(1)) data.container = Option(get(Constants.BlockName.DiskDrive).createItemStack(1))
val stack = get(Constants.ItemName.Tablet).createItemStack(1) val stack = get(Constants.ItemName.Tablet).createItemStack(1)

View File

@ -38,7 +38,7 @@ trait ComponentInventory extends Inventory with network.Environment {
def connectComponents() { def connectComponents() {
for (slot <- 0 until getSizeInventory if slot >= 0 && slot < components.length) { for (slot <- 0 until getSizeInventory if slot >= 0 && slot < components.length) {
val stack = getStackInSlot(slot) val stack = getStackInSlot(slot)
if (stack != null && components(slot).isEmpty && isComponentSlot(slot)) { if (stack != null && components(slot).isEmpty && isComponentSlot(slot, stack)) {
components(slot) = Option(Driver.driverFor(stack)) match { components(slot) = Option(Driver.driverFor(stack)) match {
case Some(driver) => case Some(driver) =>
Option(driver.createEnvironment(stack, host)) match { Option(driver.createEnvironment(stack, host)) match {
@ -98,7 +98,7 @@ trait ComponentInventory extends Inventory with network.Environment {
override def getInventoryStackLimit = 1 override def getInventoryStackLimit = 1
override protected def onItemAdded(slot: Int, stack: ItemStack) = if (isComponentSlot(slot)) { override protected def onItemAdded(slot: Int, stack: ItemStack) = if (isComponentSlot(slot, stack)) {
Option(Driver.driverFor(stack)).foreach(driver => Option(Driver.driverFor(stack)).foreach(driver =>
Option(driver.createEnvironment(stack, host)) match { Option(driver.createEnvironment(stack, host)) match {
case Some(component) => this.synchronized { case Some(component) => this.synchronized {
@ -140,7 +140,7 @@ trait ComponentInventory extends Inventory with network.Environment {
} }
} }
def isComponentSlot(slot: Int) = true def isComponentSlot(slot: Int, stack: ItemStack) = true
protected def connectItemNode(node: Node) { protected def connectItemNode(node: Node) {
if (this.node != null && node != null) { if (this.node != null && node != null) {

View File

@ -6,6 +6,7 @@ import java.util.Random
import li.cil.oc.CreativeTab import li.cil.oc.CreativeTab
import li.cil.oc.OpenComputers import li.cil.oc.OpenComputers
import li.cil.oc.api.driver import li.cil.oc.api.driver
import li.cil.oc.api.driver.item.Chargeable
import li.cil.oc.api.event.RobotRenderEvent.MountPoint import li.cil.oc.api.event.RobotRenderEvent.MountPoint
import li.cil.oc.api.internal.Robot import li.cil.oc.api.internal.Robot
import li.cil.oc.client.renderer.item.UpgradeRenderer import li.cil.oc.client.renderer.item.UpgradeRenderer
@ -38,7 +39,7 @@ object Delegator {
else None else None
} }
class Delegator extends Item with driver.item.UpgradeRenderer { class Delegator extends Item with driver.item.UpgradeRenderer with Chargeable {
setHasSubtypes(true) setHasSubtypes(true)
setCreativeTab(CreativeTab) setCreativeTab(CreativeTab)
@ -217,6 +218,20 @@ class Delegator extends Item with driver.item.UpgradeRenderer {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
def canCharge(stack: ItemStack): Boolean =
Delegator.subItem(stack) match {
case Some(subItem: Chargeable) => true
case _ => false
}
def charge(stack: ItemStack, amount: Double, simulate: Boolean): Double =
Delegator.subItem(stack) match {
case Some(subItem: Chargeable) => subItem.charge(stack, amount, simulate)
case _ => 0.0
}
// ----------------------------------------------------------------------- //
override def computePreferredMountPoint(stack: ItemStack, robot: Robot, availableMountPoints: util.Set[String]): String = UpgradeRenderer.preferredMountPoint(stack, availableMountPoints) override def computePreferredMountPoint(stack: ItemStack, robot: Robot, availableMountPoints: util.Set[String]): String = UpgradeRenderer.preferredMountPoint(stack, availableMountPoints)
override def render(stack: ItemStack, mountPoint: MountPoint, robot: Robot, pt: Float): Unit = UpgradeRenderer.render(stack, mountPoint) override def render(stack: ItemStack, mountPoint: MountPoint, robot: Robot, pt: Float): Unit = UpgradeRenderer.render(stack, mountPoint)

View File

@ -16,6 +16,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.Chargeable
import li.cil.oc.api.driver.item.Container import li.cil.oc.api.driver.item.Container
import li.cil.oc.api.internal import li.cil.oc.api.internal
import li.cil.oc.api.machine.MachineHost import li.cil.oc.api.machine.MachineHost
@ -53,7 +54,7 @@ import net.minecraftforge.fml.relauncher.SideOnly
import scala.collection.convert.WrapAsJava._ import scala.collection.convert.WrapAsJava._
import scala.collection.convert.WrapAsScala._ import scala.collection.convert.WrapAsScala._
class Tablet(val parent: Delegator) extends Delegate with CustomModel { class Tablet(val parent: Delegator) extends Delegate with CustomModel with Chargeable {
final val TimeToAnalyze = 10 final val TimeToAnalyze = 10
// Must be assembled to be usable so we hide it in the item list. // Must be assembled to be usable so we hide it in the item list.
@ -120,6 +121,20 @@ class Tablet(val parent: Delegator) extends Delegate with CustomModel {
} }
} }
def canCharge(stack: ItemStack): Boolean = true
def charge(stack: ItemStack, amount: Double, simulate: Boolean): Double = {
val data = new TabletData(stack)
val charge = math.min(data.maxEnergy - data.energy, amount)
if (!simulate) {
data.energy += charge
data.save(stack)
}
amount - charge
}
// ----------------------------------------------------------------------- //
override def update(stack: ItemStack, world: World, entity: Entity, slot: Int, selected: Boolean) = override def update(stack: ItemStack, world: World, entity: Entity, slot: Int, selected: Boolean) =
entity match { entity match {
case player: EntityPlayer => case player: EntityPlayer =>
@ -344,7 +359,7 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp
}) })
override def internalComponents(): Iterable[ItemStack] = (0 until getSizeInventory).collect { override def internalComponents(): Iterable[ItemStack] = (0 until getSizeInventory).collect {
case slot if isComponentSlot(slot) && getStackInSlot(slot) != null => getStackInSlot(slot) case slot if getStackInSlot(slot) != null && isComponentSlot(slot, getStackInSlot(slot)) => getStackInSlot(slot)
} }
override def componentSlot(address: String) = components.indexWhere(_.exists(env => env.node != null && env.node.address == address)) override def componentSlot(address: String) = components.indexWhere(_.exists(env => env.node != null && env.node.address == address))

View File

@ -1,9 +1,11 @@
package li.cil.oc.common.item package li.cil.oc.common.item
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.api.driver.item.Chargeable
import li.cil.oc.common.item.data.NodeData
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
class UpgradeBattery(val parent: Delegator, val tier: Int) extends Delegate with ItemTier { class UpgradeBattery(val parent: Delegator, val tier: Int) extends Delegate with ItemTier with Chargeable {
override val unlocalizedName = super.unlocalizedName + tier override val unlocalizedName = super.unlocalizedName + tier
override protected def tooltipName = Option(super.unlocalizedName) override protected def tooltipName = Option(super.unlocalizedName)
@ -13,10 +15,25 @@ class UpgradeBattery(val parent: Delegator, val tier: Int) extends Delegate with
override def showDurabilityBar(stack: ItemStack) = true override def showDurabilityBar(stack: ItemStack) = true
override def durability(stack: ItemStack) = { override def durability(stack: ItemStack) = {
if (stack.hasTagCompound) { val data = new NodeData(stack)
val stored = stack.getTagCompound.getCompoundTag(Settings.namespace + "data").getCompoundTag("node").getDouble("buffer") 1 - data.buffer.getOrElse(0.0) / Settings.get.bufferCapacitorUpgrades(tier)
1 - stored / Settings.get.bufferCapacitorUpgrades(tier) }
// ----------------------------------------------------------------------- //
def canCharge(stack: ItemStack): Boolean = true
def charge(stack: ItemStack, amount: Double, simulate: Boolean): Double = {
val data = new NodeData(stack)
val buffer = data.buffer match {
case Some(value) => value
case _ => 0.0
} }
else 1.0 val charge = math.min(amount, Settings.get.bufferCapacitorUpgrades(tier).toInt - buffer)
if (!simulate) {
data.buffer = Option(buffer + charge)
data.save(stack)
}
amount - charge
} }
} }

View File

@ -0,0 +1,45 @@
package li.cil.oc.common.item.data
import li.cil.oc.Settings
import li.cil.oc.api.network.Visibility
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
// Generic one for items that are used as components; gets the items node info.
class NodeData extends ItemData {
def this(stack: ItemStack) {
this()
load(stack)
}
var address: Option[String] = None
var buffer: Option[Double] = None
var visibility: Option[Visibility] = None
override def load(nbt: NBTTagCompound): Unit = {
val nodeNbt = nbt.getCompoundTag(Settings.namespace + "data").getCompoundTag("node")
if (nodeNbt.hasKey("address")) {
address = Option(nodeNbt.getString("address"))
}
if (nodeNbt.hasKey("buffer")) {
buffer = Option(nodeNbt.getDouble("buffer"))
}
if (nodeNbt.hasKey("visibility")) {
visibility = Option(Visibility.values()(nodeNbt.getInteger("visibility")))
}
}
override def save(nbt: NBTTagCompound): Unit = {
if (!nbt.hasKey(Settings.namespace + "data")) {
nbt.setTag(Settings.namespace + "data", new NBTTagCompound())
}
val dataNbt = nbt.getCompoundTag(Settings.namespace + "data")
if (!dataNbt.hasKey("node")) {
dataNbt.setTag("node", new NBTTagCompound())
}
val nodeNbt = dataNbt.getCompoundTag("node")
address.foreach(nodeNbt.setString("address", _))
buffer.foreach(nodeNbt.setDouble("buffer", _))
visibility.map(_.ordinal()).foreach(nodeNbt.setInteger("visibility", _))
}
}

View File

@ -9,8 +9,7 @@ import li.cil.oc.api.Driver
import li.cil.oc.api.network._ import li.cil.oc.api.network._
import li.cil.oc.common.Slot import li.cil.oc.common.Slot
import li.cil.oc.common.entity.Drone import li.cil.oc.common.entity.Drone
import li.cil.oc.common.item.Tablet import li.cil.oc.integration.util.ItemCharge
import li.cil.oc.common.item.data.TabletData
import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.BlockPosition import li.cil.oc.util.BlockPosition
import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.ExtendedWorld._
@ -75,8 +74,32 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
} }
if (isServer && world.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0) { if (isServer && world.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0) {
val charge = Settings.get.chargeRateExternal * chargeSpeed * Settings.get.tickFrequency var canCharge = Settings.get.ignorePower
val canCharge = charge > 0 && (node.globalBuffer >= charge * 0.5 || Settings.get.ignorePower)
// Charging of external devices.
{
val charge = Settings.get.chargeRateExternal * chargeSpeed * Settings.get.tickFrequency
canCharge ||= charge > 0 && node.globalBuffer >= charge * 0.5
if (canCharge) {
connectors.foreach {
case (_, connector) => node.changeBuffer(connector.changeBuffer(charge + node.changeBuffer(-charge)))
}
}
}
// Charging of internal devices.
{
val charge = Settings.get.chargeRateTablet * chargeSpeed * Settings.get.tickFrequency
canCharge ||= charge > 0 && node.globalBuffer >= charge * 0.5
if (canCharge) {
(0 until getSizeInventory).map(getStackInSlot).foreach(stack => if (stack != null) {
val offered = charge + node.changeBuffer(-charge)
val surplus = ItemCharge.charge(stack, offered)
node.changeBuffer(surplus)
})
}
}
if (hasPower && !canCharge) { if (hasPower && !canCharge) {
hasPower = false hasPower = false
ServerPacketSender.sendChargerState(this) ServerPacketSender.sendChargerState(this)
@ -85,28 +108,6 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
hasPower = true hasPower = true
ServerPacketSender.sendChargerState(this) ServerPacketSender.sendChargerState(this)
} }
if (canCharge) {
connectors.foreach {
case (_, connector) => node.changeBuffer(connector.changeBuffer(charge + node.changeBuffer(-charge)))
}
}
// Charge tablet if present.
val stack = getStackInSlot(0)
if (stack != null && chargeSpeed > 0) {
def tryCharge(energy: Double, maxEnergy: Double, handler: (Double) => Unit) {
if (energy < maxEnergy) {
val itemCharge = math.min(maxEnergy - energy, Settings.get.chargeRateTablet * chargeSpeed * Settings.get.tickFrequency)
if (node.tryChangeBuffer(-itemCharge))
handler(itemCharge)
}
}
val data = new TabletData(stack)
tryCharge(data.energy, data.maxEnergy, (amount) => {
data.energy = math.min(data.maxEnergy, data.energy + amount)
data.save(stack)
})
}
} }
if (isClient && chargeSpeed > 0 && hasPower && world.getWorldInfo.getWorldTotalTime % 10 == 0) { if (isClient && chargeSpeed > 0 && hasPower && world.getWorldInfo.getWorldTotalTime % 10 == 0) {
@ -160,22 +161,17 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def isComponentSlot(slot: Int, stack: ItemStack): Boolean =
super.isComponentSlot(slot, stack) && (Option(Driver.driverFor(stack, getClass)) match {
case Some(driver) => driver.slot(stack) == Slot.Tablet
case _ => false
})
override def getSizeInventory = 1 override def getSizeInventory = 1
override def isItemValidForSlot(slot: Int, stack: ItemStack) = (slot, Option(Driver.driverFor(stack, getClass))) 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 (0, Some(driver)) if driver.slot(stack) == Slot.Tablet => true
case _ => false case _ => ItemCharge.canCharge(stack)
}
override protected def onItemAdded(slot: Int, stack: ItemStack) {
super.onItemAdded(slot, stack)
Tablet.Server.cache.invalidate(Tablet.getId(stack))
components(slot) match {
case Some(environment) => environment.node match {
case component: Component => component.setVisibility(Visibility.Network)
}
case _ =>
}
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //

View File

@ -594,7 +594,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
if (isFloppySlot(slot)) { if (isFloppySlot(slot)) {
common.Sound.playDiskInsert(this) common.Sound.playDiskInsert(this)
} }
if (isComponentSlot(slot)) { if (isComponentSlot(slot, stack)) {
super.onItemAdded(slot, stack) super.onItemAdded(slot, stack)
world.notifyBlocksOfNeighborChange(position, getBlockType) world.notifyBlocksOfNeighborChange(position, getBlockType)
} }
@ -620,7 +620,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
if (isInventorySlot(slot)) { if (isInventorySlot(slot)) {
machine.signal("inventory_changed", Int.box(slot - equipmentInventory.getSizeInventory + 1)) machine.signal("inventory_changed", Int.box(slot - equipmentInventory.getSizeInventory + 1))
} }
if (isComponentSlot(slot)) { if (isComponentSlot(slot, stack)) {
world.notifyBlocksOfNeighborChange(position, getBlockType) world.notifyBlocksOfNeighborChange(position, getBlockType)
} }
} }
@ -666,7 +666,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
} }
} }
override def isComponentSlot(slot: Int) = (containerSlots ++ componentSlots) contains slot override def isComponentSlot(slot: Int, stack: ItemStack) = (containerSlots ++ componentSlots) contains slot
def containerSlotType(slot: Int) = if (containerSlots contains slot) { def containerSlotType(slot: Int) = if (containerSlots contains slot) {
val stack = info.containers(slot - 1) val stack = info.containers(slot - 1)
@ -692,13 +692,13 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
def isInventorySlot(slot: Int) = inventorySlots contains slot def isInventorySlot(slot: Int) = inventorySlots contains slot
def isFloppySlot(slot: Int) = isComponentSlot(slot) && (Option(getStackInSlot(slot)) match { def isFloppySlot(slot: Int) = getStackInSlot(slot) != null && isComponentSlot(slot, getStackInSlot(slot)) && {
case Some(stack) => Option(Driver.driverFor(stack, getClass)) match { val stack = getStackInSlot(slot)
Option(Driver.driverFor(stack, getClass)) match {
case Some(driver) => driver.slot(stack) == Slot.Floppy case Some(driver) => driver.slot(stack) == Slot.Floppy
case _ => false case _ => false
} }
case _ => false }
})
def isUpgradeSlot(slot: Int) = containerSlotType(slot) == Slot.Upgrade def isUpgradeSlot(slot: Int) = containerSlotType(slot) == Slot.Upgrade
@ -766,7 +766,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
override def setInventorySlotContents(slot: Int, stack: ItemStack) { override def setInventorySlotContents(slot: Int, stack: ItemStack) {
if (slot < getSizeInventory - componentCount && (isItemValidForSlot(slot, stack) || stack == null)) { if (slot < getSizeInventory - componentCount && (isItemValidForSlot(slot, stack) || stack == null)) {
if (stack != null && stack.stackSize > 1 && isComponentSlot(slot)) { if (stack != null && stack.stackSize > 1 && isComponentSlot(slot, stack)) {
super.setInventorySlotContents(slot, stack.splitStack(1)) super.setInventorySlotContents(slot, stack.splitStack(1))
if (stack.stackSize > 0 && isServer) { if (stack.stackSize > 0 && isServer) {
player().inventory.addItemStackToInventory(stack) player().inventory.addItemStackToInventory(stack)
@ -886,5 +886,5 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
override def getTankInfo(from: EnumFacing) = override def getTankInfo(from: EnumFacing) =
components.collect { components.collect {
case Some(t: IFluidTank) => t.getInfo case Some(t: IFluidTank) => t.getInfo
}.toArray }
} }

View File

@ -2,6 +2,7 @@ package li.cil.oc.common.tileentity.traits
import li.cil.oc.api.network.Node import li.cil.oc.api.network.Node
import li.cil.oc.common.inventory import li.cil.oc.common.inventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.fml.relauncher.Side import net.minecraftforge.fml.relauncher.Side
import net.minecraftforge.fml.relauncher.SideOnly import net.minecraftforge.fml.relauncher.SideOnly
@ -9,7 +10,7 @@ import net.minecraftforge.fml.relauncher.SideOnly
trait ComponentInventory extends Environment with Inventory with inventory.ComponentInventory { trait ComponentInventory extends Environment with Inventory with inventory.ComponentInventory {
override def host = this override def host = this
override def isComponentSlot(slot: Int) = isServer override def isComponentSlot(slot: Int, stack: ItemStack) = isServer
override def onConnect(node: Node) { override def onConnect(node: Node) {
super.onConnect(node) super.onConnect(node)

View File

@ -73,7 +73,7 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def internalComponents(): lang.Iterable[ItemStack] = (0 until getSizeInventory).collect { override def internalComponents(): lang.Iterable[ItemStack] = (0 until getSizeInventory).collect {
case i if isComponentSlot(i) && getStackInSlot(i) != null => getStackInSlot(i) case slot if getStackInSlot(slot) != null && isComponentSlot(slot, getStackInSlot(slot)) => getStackInSlot(slot)
} }

View File

@ -1,5 +1,6 @@
package li.cil.oc.integration.cofh.energy package li.cil.oc.integration.cofh.energy
import li.cil.oc.Settings
import li.cil.oc.api.event.RobotUsedToolEvent import li.cil.oc.api.event.RobotUsedToolEvent
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
@ -28,4 +29,16 @@ object EventHandlerRedstoneFlux {
case _ => Double.NaN case _ => Double.NaN
} }
} }
def canCharge(stack: ItemStack): Boolean = stack.getItem match {
case chargeable: IEnergyContainerItem => chargeable.getMaxEnergyStored(stack) > 0
case _ => false
}
def charge(stack: ItemStack, amount: Double, simulate: Boolean): Double = {
stack.getItem match {
case item: IEnergyContainerItem => amount - item.receiveEnergy(stack, (amount * Settings.get.ratioRedstoneFlux).toInt, simulate) / Settings.get.ratioRedstoneFlux
case _ => amount
}
}
} }

View File

@ -6,6 +6,7 @@ import cpw.mods.fml.common.versioning.VersionRange
import li.cil.oc.api.Driver import li.cil.oc.api.Driver
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 net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.MinecraftForge
import scala.collection.convert.WrapAsScala._ import scala.collection.convert.WrapAsScala._
@ -17,6 +18,11 @@ object ModCoFHEnergy extends ModProxy {
override def initialize() { override def initialize() {
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerToolDurabilityProvider", "li.cil.oc.integration.cofh.energy.EventHandlerRedstoneFlux.getDurability") FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerToolDurabilityProvider", "li.cil.oc.integration.cofh.energy.EventHandlerRedstoneFlux.getDurability")
val chargerNbt = new NBTTagCompound()
chargerNbt.setString("name", "RedstoneFlux")
chargerNbt.setString("canCharge", "li.cil.oc.integration.cofh.energy.EventHandlerRedstoneFlux.canCharge")
chargerNbt.setString("charge", "li.cil.oc.integration.cofh.energy.EventHandlerRedstoneFlux.charge")
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerItemCharge", chargerNbt)
MinecraftForge.EVENT_BUS.register(EventHandlerRedstoneFlux) MinecraftForge.EVENT_BUS.register(EventHandlerRedstoneFlux)

View File

@ -1,5 +1,6 @@
package li.cil.oc.integration.ic2 package li.cil.oc.integration.ic2
import li.cil.oc.Settings
import li.cil.oc.api.event.RobotUsedToolEvent import li.cil.oc.api.event.RobotUsedToolEvent
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
@ -52,4 +53,20 @@ object EventHandlerIndustrialCraft2 {
case _ => false case _ => false
} }
} }
def canCharge(stack: ItemStack): Boolean = stack.getItem match {
case chargeable: IElectricItem => chargeable.getMaxCharge(stack) > 0
case _ => false
}
def charge(stack: ItemStack, amount: Double, simulate: Boolean): Double = {
(stack.getItem match {
case item: ISpecialElectricItem => Option(item.getManager(stack))
case item: IElectricItem => Option(ElectricItem.manager)
case _ => None
}) match {
case Some(manager) => amount - manager.charge(stack, amount * Settings.get.ratioIndustrialCraft2, Int.MaxValue, true, false) / Settings.get.ratioIndustrialCraft2
case _ => amount
}
}
} }

View File

@ -4,6 +4,7 @@ import cpw.mods.fml.common.event.FMLInterModComms
import li.cil.oc.api.Driver import li.cil.oc.api.Driver
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 net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.MinecraftForge
object ModIndustrialCraft2 extends ModProxy { object ModIndustrialCraft2 extends ModProxy {
@ -12,6 +13,11 @@ object ModIndustrialCraft2 extends ModProxy {
override def initialize() { override def initialize() {
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerToolDurabilityProvider", "li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.getDurability") FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerToolDurabilityProvider", "li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.getDurability")
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerWrenchTool", "li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.useWrench") FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerWrenchTool", "li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.useWrench")
val chargerNbt = new NBTTagCompound()
chargerNbt.setString("name", "IndustrialCraft2")
chargerNbt.setString("canCharge", "li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.canCharge")
chargerNbt.setString("charge", "li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.charge")
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerItemCharge", chargerNbt)
MinecraftForge.EVENT_BUS.register(EventHandlerIndustrialCraft2) MinecraftForge.EVENT_BUS.register(EventHandlerIndustrialCraft2)

View File

@ -4,7 +4,10 @@ import li.cil.oc.Constants
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.api.driver.EnvironmentHost import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.api.network.Component
import li.cil.oc.api.network.Visibility
import li.cil.oc.common.Slot import li.cil.oc.common.Slot
import li.cil.oc.common.item.Tablet
import li.cil.oc.common.item.data.TabletData import li.cil.oc.common.item.data.TabletData
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
@ -15,10 +18,20 @@ object DriverTablet extends Item {
api.Items.get(Constants.ItemName.Tablet)) api.Items.get(Constants.ItemName.Tablet))
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = { override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = {
Tablet.Server.cache.invalidate(Tablet.getId(stack))
val data = new TabletData(stack) val data = new TabletData(stack)
data.items.collect { data.items.collect {
case Some(fs) if DriverFileSystem.worksWith(fs) => fs case Some(fs) if DriverFileSystem.worksWith(fs) => fs
}.headOption.map(DriverFileSystem.createEnvironment(_, host)).orNull }.headOption.map(DriverFileSystem.createEnvironment(_, host)) match {
case Some(environment) => environment.node match {
case component: Component =>
component.setVisibility(Visibility.Network)
environment.save(dataTag(stack))
environment
case _ => null
}
case _ => null
}
} }
override def slot(stack: ItemStack) = Slot.Tablet override def slot(stack: ItemStack) = Slot.Tablet

View File

@ -5,6 +5,7 @@ import li.cil.oc.OpenComputers
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.api.detail.ItemInfo import li.cil.oc.api.detail.ItemInfo
import li.cil.oc.api.driver.item.Chargeable
import li.cil.oc.api.internal import li.cil.oc.api.internal
import li.cil.oc.api.internal.Wrench import li.cil.oc.api.internal.Wrench
import li.cil.oc.api.manual.PathProvider import li.cil.oc.api.manual.PathProvider
@ -56,6 +57,11 @@ object ModOpenComputers extends ModProxy {
TemplateBlacklist.register() TemplateBlacklist.register()
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerWrenchTool", "li.cil.oc.integration.opencomputers.ModOpenComputers.useWrench") FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerWrenchTool", "li.cil.oc.integration.opencomputers.ModOpenComputers.useWrench")
val chargerNbt = new NBTTagCompound()
chargerNbt.setString("name", "OpenComputers")
chargerNbt.setString("canCharge", "li.cil.oc.integration.opencomputers.ModOpenComputers.canCharge")
chargerNbt.setString("charge", "li.cil.oc.integration.opencomputers.ModOpenComputers.charge")
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerItemCharge", chargerNbt)
ForgeChunkManager.setForcedChunkLoadingCallback(OpenComputers, ChunkloaderUpgradeHandler) ForgeChunkManager.setForcedChunkLoadingCallback(OpenComputers, ChunkloaderUpgradeHandler)
@ -227,6 +233,18 @@ object ModOpenComputers extends ModProxy {
} }
} }
def canCharge(stack: ItemStack): Boolean = stack.getItem match {
case chargeable: Chargeable => chargeable.canCharge(stack)
case _ => false
}
def charge(stack: ItemStack, amount: Double, simulate: Boolean): Double = {
stack.getItem match {
case chargeable: Chargeable => chargeable.charge(stack, amount, simulate)
case _ => 0.0
}
}
private def blacklistHost(host: Class[_], itemNames: String*) { private def blacklistHost(host: Class[_], itemNames: String*) {
for (itemName <- itemNames) { for (itemName <- itemNames) {
val nbt = new NBTTagCompound() val nbt = new NBTTagCompound()

View File

@ -0,0 +1,24 @@
package li.cil.oc.integration.util
import java.lang.reflect.Method
import li.cil.oc.common.IMC
import net.minecraft.item.ItemStack
import scala.collection.mutable
object ItemCharge {
private val chargers = mutable.LinkedHashSet.empty[(Method, Method)]
def add(canCharge: Method, charge: Method): Unit = chargers += ((canCharge, charge))
def canCharge(stack: ItemStack): Boolean = stack != null && chargers.exists(charger => IMC.tryInvokeStatic(charger._1, stack)(false))
def charge(stack: ItemStack, amount: Double): Double = {
if (stack != null) chargers.find(charger => IMC.tryInvokeStatic(charger._1, stack)(false)) match {
case Some(charger) => IMC.tryInvokeStatic(charger._2, stack, double2Double(amount), java.lang.Boolean.FALSE)(0.0)
case _ => 0.0
}
else 0.0
}
}

View File

@ -39,7 +39,7 @@ class Server(val rack: tileentity.ServerRack, val slot: Int) extends Environment
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def internalComponents(): Iterable[ItemStack] = (0 until inventory.getSizeInventory).collect { override def internalComponents(): Iterable[ItemStack] = (0 until inventory.getSizeInventory).collect {
case i if inventory.isComponentSlot(i) && inventory.getStackInSlot(i) != null => inventory.getStackInSlot(i) case i if inventory.getStackInSlot(i) != null && inventory.isComponentSlot(i, inventory.getStackInSlot(i)) => inventory.getStackInSlot(i)
} }
override def componentSlot(address: String) = inventory.components.indexWhere(_.exists(env => env.node != null && env.node.address == address)) override def componentSlot(address: String) = inventory.components.indexWhere(_.exists(env => env.node != null && env.node.address == address))