Reworked power logic a lot. Different blocks now provide different conversion speeds, so power converters have more reason to exist. Let's see how much I broke in the process \o/

Also, access points now accept power, in return they also consume power for wireless messages sent from, say ComputerCraft.
Fixed some power related stuff not being saved (other mod's node/similar constructs) leading to minor energy losses across saves.
Re-tweaked some conversion values.
This commit is contained in:
Florian Nücke 2014-10-07 23:19:51 +02:00
parent ed81caa4ac
commit 9b99729b94
24 changed files with 323 additions and 157 deletions

View File

@ -513,6 +513,9 @@ opencomputers {
# The amount a tablet can store in its internal buffer.
tablet: 10000
# The amount of energy an access point can store.
accessPoint: 600.0
}
# Default "costs", i.e. how much energy certain operations consume.
@ -652,6 +655,22 @@ opencomputers {
pistonPush: 20
}
# The rate at which different blocks accept external power. All of these
# values are in OC energy / tick.
rate {
accessPoint: 10.0
assembler: 100.0
case: [
5.0
10.0
20.0
]
charger: 200.0
disassembler: 50.0
powerConverter: 500.0
serverRack: 50.0
}
# Power values for different power systems.
value {
AppliedEnergistics2: 100.0
@ -659,8 +678,8 @@ opencomputers {
Factorization: 6.5
Galacticraft: 24.0
IndustrialCraft2: 200.0
Mekanism: 555.55555
RedstoneFlux: 35.0
Mekanism: 700.0
RedstoneFlux: 18.0
UniversalElectricity: 1750.0
}
}

View File

@ -20,7 +20,6 @@ import scala.io.Source
class Settings(config: Config) {
// ----------------------------------------------------------------------- //
// client
val screenTextFadeStartDistance = config.getDouble("client.screenTextFadeStartDistance")
val maxScreenTextRenderDistance = config.getDouble("client.maxScreenTextRenderDistance")
val textLinearFiltering = config.getBoolean("client.textLinearFiltering")
@ -50,7 +49,6 @@ class Settings(config: Config) {
// ----------------------------------------------------------------------- //
// computer
val threads = config.getInt("computer.threads") max 1
val timeout = config.getDouble("computer.timeout") max 0
val startupDelay = config.getDouble("computer.startupDelay") max 0.05
@ -85,7 +83,6 @@ class Settings(config: Config) {
// ----------------------------------------------------------------------- //
// robot
val allowActivateBlocks = config.getBoolean("robot.allowActivateBlocks")
val allowUseItemsWithDuration = config.getBoolean("robot.allowUseItemsWithDuration")
val canAttackPlayers = config.getBoolean("robot.canAttackPlayers")
@ -95,9 +92,7 @@ class Settings(config: Config) {
val itemDamageRate = config.getDouble("robot.itemDamageRate") max 0 min 1
val nameFormat = config.getString("robot.nameFormat")
// ----------------------------------------------------------------------- //
// robot.xp
val baseXpToLevel = config.getDouble("robot.xp.baseValue") max 0
val constantXpGrowth = config.getDouble("robot.xp.constantGrowth") max 1
val exponentialXpGrowth = config.getDouble("robot.xp.exponentialGrowth") max 1
@ -124,7 +119,6 @@ class Settings(config: Config) {
// ----------------------------------------------------------------------- //
// power
val pureIgnorePower = config.getBoolean("power.ignorePower")
lazy val ignorePower = pureIgnorePower || !Mods.isPowerProvidingModPresent
val tickFrequency = config.getDouble("power.tickFrequency") max 1
@ -151,6 +145,7 @@ class Settings(config: Config) {
Array(10000.0, 15000.0, 20000.0)
}
val bufferTablet = config.getDouble("power.buffer.tablet") max 0
val bufferAccessPoint = config.getDouble("power.buffer.accessPoint") max 0
// power.cost
val computerCost = config.getDouble("power.cost.computer") max 0
@ -178,6 +173,21 @@ class Settings(config: Config) {
val chunkloaderCost = config.getDouble("power.cost.chunkloaderCost") max 0
val pistonCost = config.getDouble("power.cost.pistonPush") max 0
// power.rate
val accessPointRate = config.getDouble("power.rate.accessPoint") max 0
val assemblerRate = config.getDouble("power.rate.assembler") max 0
val caseRate = (Array(config.getDoubleList("power.rate.case"): _*) match {
case Array(tier1, tier2, tier3) =>
Array(tier1: Double, tier2: Double, tier3: Double)
case _ =>
OpenComputers.log.warn("Bad number of computer case conversion rates, ignoring.")
Array(5.0, 10.0, 20.0)
}) ++ Array(9001.0) // Creative case.
val chargerRate = config.getDouble("power.rate.charger") max 0
val disassemblerRate = config.getDouble("power.rate.disassembler") max 0
val powerConverterRate = config.getDouble("power.rate.powerConverter") max 0
val serverRackRate = config.getDouble("power.rate.serverRack") max 0
// power.value
private val valueAppliedEnergistics2 = config.getDouble("power.value.AppliedEnergistics2")
private val valueBuildCraft = config.getDouble("power.value.BuildCraft")

View File

@ -1,9 +1,10 @@
package li.cil.oc.common.block
import li.cil.oc.Settings
import li.cil.oc.common.tileentity
import net.minecraft.world.World
class AccessPoint extends Switch {
class AccessPoint extends Switch with traits.PowerAcceptor {
override protected def customTextures = Array(
None,
Some("AccessPointTop"),
@ -15,5 +16,7 @@ class AccessPoint extends Switch {
// ----------------------------------------------------------------------- //
override def energyThroughput = Settings.get.accessPointRate
override def createTileEntity(world: World, metadata: Int) = new tileentity.AccessPoint()
}

View File

@ -34,6 +34,8 @@ class Assembler extends SimpleBlock with traits.SpecialBlock with traits.PowerAc
// ----------------------------------------------------------------------- //
override def energyThroughput = Settings.get.assemblerRate
override def hasTileEntity(metadata: Int) = true
override def createTileEntity(world: World, metadata: Int) = new tileentity.RobotAssembler()

View File

@ -69,6 +69,8 @@ class Case(val tier: Int) extends RedstoneAware with traits.PowerAcceptor {
// ----------------------------------------------------------------------- //
override def energyThroughput = Settings.get.caseRate(tier)
override def createTileEntity(world: World, metadata: Int) = new tileentity.Case(tier)
// ----------------------------------------------------------------------- //

View File

@ -1,12 +1,12 @@
package li.cil.oc.common.block
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.client.Textures
import li.cil.oc.common.GuiType
import li.cil.oc.common.tileentity
import li.cil.oc.server.PacketSender
import li.cil.oc.util.mods.BuildCraft
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import net.minecraft.block.Block
import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.entity.player.EntityPlayer
@ -14,7 +14,7 @@ import net.minecraft.world.IBlockAccess
import net.minecraft.world.World
import net.minecraftforge.common.util.ForgeDirection
class Charger extends RedstoneAware {
class Charger extends RedstoneAware with traits.PowerAcceptor {
override protected def customTextures = Array(
None,
None,
@ -32,6 +32,8 @@ class Charger extends RedstoneAware {
// ----------------------------------------------------------------------- //
override def energyThroughput = Settings.get.chargerRate
override def createTileEntity(world: World, metadata: Int) = new tileentity.Charger()
// ----------------------------------------------------------------------- //

View File

@ -36,6 +36,8 @@ class Disassembler extends SimpleBlock with traits.PowerAcceptor {
// ----------------------------------------------------------------------- //
override def energyThroughput = Settings.get.disassemblerRate
override def hasTileEntity(metadata: Int) = true
override def createTileEntity(world: World, metadata: Int) = new tileentity.Disassembler()

View File

@ -64,6 +64,8 @@ class PowerConverter extends SimpleBlock with traits.PowerAcceptor {
// ----------------------------------------------------------------------- //
override def energyThroughput = Settings.get.powerConverterRate
override def hasTileEntity(metadata: Int) = true
override def createTileEntity(world: World, metadata: Int) = new tileentity.PowerConverter()

View File

@ -3,6 +3,7 @@ package li.cil.oc.common.block
import cpw.mods.fml.relauncher.Side
import cpw.mods.fml.relauncher.SideOnly
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.client.Textures
import li.cil.oc.common.GuiType
import li.cil.oc.common.tileentity
@ -44,6 +45,8 @@ class ServerRack extends RedstoneAware with traits.SpecialBlock with traits.Powe
// ----------------------------------------------------------------------- //
override def energyThroughput = Settings.get.serverRackRate
override def hasTileEntity(metadata: Int) = true
override def createTileEntity(world: World, metadata: Int) = new tileentity.ServerRack()

View File

@ -24,4 +24,6 @@ trait PowerAcceptor extends Block {
case _ =>
}
}
def energyThroughput: Double
}

View File

@ -1,14 +1,16 @@
package li.cil.oc.common.tileentity
import cpw.mods.fml.relauncher.Side
import cpw.mods.fml.relauncher.SideOnly
import li.cil.oc.Localization
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network._
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.mods.Mods
import li.cil.oc.Localization
import li.cil.oc.Settings
import li.cil.oc.api
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.Constants.NBT
@ -16,10 +18,24 @@ import net.minecraftforge.common.util.ForgeDirection
import scala.collection.convert.WrapAsScala._
class AccessPoint extends Switch with WirelessEndpoint {
class AccessPoint extends Switch with WirelessEndpoint with traits.PowerAcceptor {
var strength = Settings.get.maxWirelessRange
val componentNodes = Array.fill(6)(api.Network.newNode(this, Visibility.Network).withComponent("access_point").create())
val componentNodes = Array.fill(6)(api.Network.newNode(this, Visibility.Network).
withComponent("access_point").
create())
// ----------------------------------------------------------------------- //
@SideOnly(Side.CLIENT)
override protected def hasConnector(side: ForgeDirection) = true
override protected def connector(side: ForgeDirection) = sidedNode(side) match {
case connector: Connector => Option(connector)
case _ => None
}
override protected def energyThroughput = Settings.get.accessPointRate
// ----------------------------------------------------------------------- //
@ -54,15 +70,17 @@ class AccessPoint extends Switch with WirelessEndpoint {
override protected def relayPacket(sourceSide: ForgeDirection, packet: Packet) {
super.relayPacket(sourceSide, packet)
if (strength > 0) {
if (sourceSide == null || sourceSide == ForgeDirection.UNKNOWN || {
val cost = Settings.get.wirelessCostPerRange
val connector = plugs(sourceSide.ordinal).node.asInstanceOf[Connector]
connector.tryChangeBuffer(-strength * cost)
}) api.Network.sendWirelessPacket(this, strength, packet)
if (connector.tryChangeBuffer(-strength * cost)) {
api.Network.sendWirelessPacket(this, strength, packet)
}
}
}
override protected def createNode(plug: Plug) = api.Network.newNode(plug, Visibility.Network).withConnector().create()
override protected def createNode(plug: Plug) = api.Network.newNode(plug, Visibility.Network).
withConnector(math.round(Settings.get.bufferAccessPoint)).
create()
// ----------------------------------------------------------------------- //

View File

@ -31,6 +31,8 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with
override protected def connector(side: ForgeDirection) = Option(if (side != facing && machine != null) machine.node.asInstanceOf[Connector] else null)
override protected def energyThroughput = Settings.get.caseRate(tier)
override def getWorld = world
var maxComponents = 0

View File

@ -39,6 +39,8 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
override protected def connector(side: ForgeDirection) = Option(if (side != facing) node else null)
override protected def energyThroughput = Settings.get.chargerRate
override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = {
player.addChatMessage(Localization.Analyzer.ChargerSpeed(chargeSpeed))
null

View File

@ -54,6 +54,8 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
override protected def connector(side: ForgeDirection) = Option(if (side != ForgeDirection.UP) node else null)
override protected def energyThroughput = Settings.get.disassemblerRate
// ----------------------------------------------------------------------- //
override def canUpdate = isServer

View File

@ -17,5 +17,7 @@ class PowerConverter extends traits.PowerAcceptor with traits.Environment with t
override protected def connector(side: ForgeDirection) = Option(node)
override protected def energyThroughput = Settings.get.powerConverterRate
override def canUpdate = isServer
}

View File

@ -40,6 +40,8 @@ class RobotAssembler extends traits.Environment with traits.PowerAcceptor with t
override protected def connector(side: ForgeDirection) = Option(if (side != ForgeDirection.UP) node else null)
override protected def energyThroughput = Settings.get.assemblerRate
// ----------------------------------------------------------------------- //
def isAssembling = requiredEnergy > 0

View File

@ -61,6 +61,8 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB
override protected def connector(side: ForgeDirection) = Option(if (side != facing) sidedNode(side).asInstanceOf[Connector] else null)
override protected def energyThroughput = Settings.get.serverRackRate
override def getWorld = world
// ----------------------------------------------------------------------- //

View File

@ -34,19 +34,17 @@ trait AppliedEnergistics2 extends Common {
@Optional.Method(modid = Mods.IDs.AppliedEnergistics2)
private def updateEnergy() {
val grid = getGridNode(ForgeDirection.UNKNOWN).getGrid
tryAllSides((demand, side) => {
val grid = getGridNode(side).getGrid
if (grid != null) {
val cache = grid.getCache(classOf[IEnergyGrid]).asInstanceOf[IEnergyGrid]
if (cache != null) {
for (side <- ForgeDirection.VALID_DIRECTIONS) {
val demand = (globalBufferSize(side) - globalBuffer(side)) / Settings.get.ratioAppliedEnergistics2
if (demand > 1) {
val power = cache.extractAEPower(demand, Actionable.MODULATE, PowerMultiplier.CONFIG)
tryChangeBuffer(side, power * Settings.get.ratioAppliedEnergistics2)
}
}
cache.extractAEPower(demand, Actionable.MODULATE, PowerMultiplier.CONFIG)
}
else 0.0
}
else 0.0
}, Settings.get.ratioAppliedEnergistics2)
}
override def validate() {

View File

@ -3,10 +3,10 @@ package li.cil.oc.common.tileentity.traits.power
import buildcraft.api.power.IPowerReceptor
import buildcraft.api.power.PowerHandler
import cpw.mods.fml.common.Optional
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.mods.Mods
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.mods.Mods
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.ForgeDirection
@ -26,13 +26,7 @@ trait BuildCraft extends Common {
@Optional.Method(modid = Mods.IDs.BuildCraftPower)
private def updateEnergy() {
for (side <- ForgeDirection.VALID_DIRECTIONS) {
val demand = (globalBufferSize(side) - globalBuffer(side)) / Settings.get.ratioBuildCraft
if (demand > 1) {
val power = getPowerProvider.useEnergy(1, demand.toFloat, true)
tryChangeBuffer(side, power * Settings.get.ratioBuildCraft)
}
}
tryAllSides((demand, _) => getPowerProvider.useEnergy(1, demand.toFloat, true), Settings.get.ratioBuildCraft)
}
// ----------------------------------------------------------------------- //
@ -43,7 +37,7 @@ trait BuildCraft extends Common {
}
@Optional.Method(modid = Mods.IDs.BuildCraftPower)
private def loadHandler(nbt: NBTTagCompound): Unit = {
private def loadHandler(nbt: NBTTagCompound) {
Option(getPowerProvider).foreach(_.readFromNBT(nbt.getCompoundTag(Settings.namespace + "bcpower")))
}
@ -53,7 +47,7 @@ trait BuildCraft extends Common {
}
@Optional.Method(modid = Mods.IDs.BuildCraftPower)
private def saveHandler(nbt: NBTTagCompound): Unit = {
private def saveHandler(nbt: NBTTagCompound) {
Option(getPowerProvider).foreach(h => nbt.setNewCompoundTag(Settings.namespace + "bcpower", h.writeToNBT))
}
@ -66,7 +60,8 @@ trait BuildCraft extends Common {
case receptor: IPowerReceptor =>
val handler = new PowerHandler(receptor, PowerHandler.Type.MACHINE)
if (handler != null) {
handler.configure(1, 320, Float.MaxValue, 640)
val conversionBufferSize = energyThroughput * Settings.get.tickFrequency / Settings.get.ratioBuildCraft
handler.configure(1, conversionBufferSize, Float.MaxValue, conversionBufferSize)
handler.configurePowerPerdition(0, 0)
powerHandler = Some(handler)
}

View File

@ -15,6 +15,23 @@ trait Common extends TileEntity {
// ----------------------------------------------------------------------- //
protected def energyThroughput: Double
protected def tryAllSides(provider: (Double, ForgeDirection) => Double, ratio: Double) {
// We make sure to only call this every `Settings.get.tickFrequency` ticks,
// but our throughput is per tick, so multiply this up for actual budget.
var budget = energyThroughput * Settings.get.tickFrequency
for (side <- ForgeDirection.VALID_DIRECTIONS) {
val demand = math.min(budget, globalDemand(side)) / ratio
if (demand > 1) {
val energy = provider(demand, side) * ratio
budget -= tryChangeBuffer(side, energy)
}
}
}
// ----------------------------------------------------------------------- //
def canConnectPower(side: ForgeDirection) =
!Settings.get.ignorePower && side != null && side != ForgeDirection.UNKNOWN &&
(if (isClient) hasConnector(side) else connector(side).isDefined)
@ -23,8 +40,9 @@ trait Common extends TileEntity {
if (isClient || Settings.get.ignorePower) 0
else connector(side) match {
case Some(node) =>
if (doReceive) amount - node.changeBuffer(amount)
else math.min(amount, node.globalBufferSize - node.globalBuffer)
val cappedAmount = math.max(-energyThroughput, math.min(energyThroughput, amount))
if (doReceive) amount - node.changeBuffer(cappedAmount)
else math.min(cappedAmount, globalDemand(side))
case _ => 0
}
@ -41,4 +59,6 @@ trait Common extends TileEntity {
case Some(node) => node.globalBufferSize
case _ => 0
}
def globalDemand(side: ForgeDirection) = math.max(0, math.min(energyThroughput, globalBufferSize(side) - globalBuffer(side)))
}

View File

@ -4,10 +4,10 @@ import cpw.mods.fml.common.Optional
import factorization.api.Charge
import factorization.api.Coord
import factorization.api.IChargeConductor
import li.cil.oc.util.mods.Mods
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import net.minecraftforge.common.util.ForgeDirection
import li.cil.oc.util.mods.Mods
import net.minecraft.nbt.NBTTagCompound
trait Factorization extends Common {
private lazy val useFactorizationPower = isServer && Mods.Factorization.isAvailable
@ -23,33 +23,60 @@ trait Factorization extends Common {
// ----------------------------------------------------------------------- //
override def updateEntity() {
if (useFactorizationPower) {
getCharge.update()
for (side <- ForgeDirection.VALID_DIRECTIONS) {
val demand = (globalBufferSize(side) - globalBuffer(side)) / Settings.get.ratioFactorization
if (demand > 1) {
val power = getCharge.deplete(demand.toInt)
tryChangeBuffer(side, power * Settings.get.ratioFactorization)
}
}
}
if (useFactorizationPower) updateEnergy()
super.updateEntity()
}
override def invalidate() {
if (useFactorizationPower) {
getCharge.invalidate()
@Optional.Method(modid = Mods.IDs.Factorization)
private def updateEnergy() {
getCharge.update()
if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
tryAllSides((demand, _) => getCharge.deplete(demand.toInt), Settings.get.ratioFactorization)
}
}
override def invalidate() {
if (useFactorizationPower) invalidateCharge()
super.invalidate()
}
override def onChunkUnload() {
if (useFactorizationPower && !isInvalid) {
getCharge.remove()
@Optional.Method(modid = Mods.IDs.Factorization)
private def invalidateCharge() {
getCharge.invalidate()
}
override def onChunkUnload() {
if (useFactorizationPower) removeCharge()
super.onChunkUnload()
}
@Optional.Method(modid = Mods.IDs.Factorization)
private def removeCharge() {
if (!isInvalid) getCharge.remove()
}
// ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
if (useFactorizationPower) loadCharge(nbt)
}
@Optional.Method(modid = Mods.IDs.Factorization)
private def loadCharge(nbt: NBTTagCompound) {
getCharge.readFromNBT(nbt, "fzpower")
}
override def writeToNBT(nbt: NBTTagCompound) {
super.writeToNBT(nbt)
if (useFactorizationPower) saveCharge(nbt)
}
@Optional.Method(modid = Mods.IDs.Factorization)
private def saveCharge(nbt: NBTTagCompound) {
getCharge.writeToNBT(nbt, "fzpower")
}
// ----------------------------------------------------------------------- //
@Optional.Method(modid = Mods.IDs.Factorization)

View File

@ -3,21 +3,38 @@ package li.cil.oc.common.tileentity.traits.power
import cpw.mods.fml.common.Optional
import cpw.mods.fml.common.eventhandler.Event
import ic2classic.api.Direction
import li.cil.oc.common.EventHandler
import li.cil.oc.util.mods.Mods
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.common.EventHandler
import li.cil.oc.util.mods.Mods
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.tileentity.TileEntity
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.common.util.ForgeDirection
trait IndustrialCraft2Classic extends Common with IndustrialCraft2Common {
private var lastInjectedAmount = 0.0
private var conversionBuffer = 0.0
private lazy val useIndustrialCraft2ClassicPower = isServer && Mods.IndustrialCraft2Classic.isAvailable
// ----------------------------------------------------------------------- //
override def updateEntity() {
super.updateEntity()
if (useIndustrialCraft2ClassicPower && world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
updateEnergy()
}
}
@Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic)
private def updateEnergy() {
tryAllSides((demand, _) => {
val result = math.min(demand, conversionBuffer)
conversionBuffer -= result
result
}, Settings.get.ratioIndustrialCraft2)
}
override def validate() {
super.validate()
if (useIndustrialCraft2ClassicPower && !addedToIC2PowerGrid) EventHandler.scheduleIC2Add(this)
@ -42,43 +59,38 @@ trait IndustrialCraft2Classic extends Common with IndustrialCraft2Common {
// ----------------------------------------------------------------------- //
@Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic)
def isAddedToEnergyNet = addedToIC2PowerGrid
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
conversionBuffer = nbt.getDouble(Settings.namespace + "ic2cpower")
}
override def writeToNBT(nbt: NBTTagCompound) {
super.writeToNBT(nbt)
nbt.setDouble(Settings.namespace + "ic2cpower", conversionBuffer)
}
// ----------------------------------------------------------------------- //
@Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic)
def getMaxSafeInput = Integer.MAX_VALUE
def isAddedToEnergyNet: Boolean = addedToIC2PowerGrid
@Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic)
def getMaxSafeInput: Int = Int.MaxValue
@Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic)
def acceptsEnergyFrom(emitter: TileEntity, direction: Direction) = Mods.IndustrialCraft2Classic.isAvailable && canConnectPower(direction.toForgeDirection)
@Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic)
def injectEnergy(directionFrom: Direction, amount: Int) = {
lastInjectedAmount = amount
var energy = amount * Settings.get.ratioIndustrialCraft2
// Work around IC2 being uncooperative and always just passing 'unknown' along here.
if (directionFrom.toForgeDirection == ForgeDirection.UNKNOWN) {
for (side <- ForgeDirection.VALID_DIRECTIONS if energy > 0) {
energy -= tryChangeBuffer(side, energy)
}
(energy / Settings.get.ratioIndustrialCraft2).toInt == 0
}
else (amount - tryChangeBuffer(directionFrom.toForgeDirection, energy) / Settings.get.ratioIndustrialCraft2).toInt == 0
def injectEnergy(directionFrom: Direction, amount: Int): Boolean = {
conversionBuffer += amount
true
}
@Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic)
def demandsEnergy = {
def demandsEnergy: Int = {
if (!useIndustrialCraft2ClassicPower) 0
else {
var force = false
val demand = ForgeDirection.VALID_DIRECTIONS.map(side => {
val size = globalBufferSize(side)
val value = globalBuffer(side)
val space = size - value
force = force || (space > size / 2)
space
}).max / Settings.get.ratioIndustrialCraft2
if (force || lastInjectedAmount <= 0 || demand >= lastInjectedAmount) demand.toInt
else if (conversionBuffer < energyThroughput * Settings.get.tickFrequency)
math.min(ForgeDirection.VALID_DIRECTIONS.map(globalDemand).max, energyThroughput / Settings.get.ratioIndustrialCraft2).toInt
else 0
}
}
}

View File

@ -2,20 +2,37 @@ package li.cil.oc.common.tileentity.traits.power
import cpw.mods.fml.common.Optional
import cpw.mods.fml.common.eventhandler.Event
import li.cil.oc.common.EventHandler
import li.cil.oc.util.mods.Mods
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.common.EventHandler
import li.cil.oc.util.mods.Mods
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.common.util.ForgeDirection
trait IndustrialCraft2Experimental extends Common with IndustrialCraft2Common {
private var lastInjectedAmount = 0.0
private var conversionBuffer = 0.0
private lazy val useIndustrialCraft2Power = isServer && Mods.IndustrialCraft2.isAvailable
// ----------------------------------------------------------------------- //
override def updateEntity() {
super.updateEntity()
if (useIndustrialCraft2Power && world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
updateEnergy()
}
}
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
private def updateEnergy() {
tryAllSides((demand, _) => {
val result = math.min(demand, conversionBuffer)
conversionBuffer -= result
result
}, Settings.get.ratioIndustrialCraft2)
}
override def validate() {
super.validate()
if (useIndustrialCraft2Power && !addedToIC2PowerGrid) EventHandler.scheduleIC2Add(this)
@ -40,40 +57,35 @@ trait IndustrialCraft2Experimental extends Common with IndustrialCraft2Common {
// ----------------------------------------------------------------------- //
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def getSinkTier = Int.MaxValue
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
conversionBuffer = nbt.getDouble(Settings.namespace + "ic2power")
}
override def writeToNBT(nbt: NBTTagCompound) {
super.writeToNBT(nbt)
nbt.setDouble(Settings.namespace + "ic2power", conversionBuffer)
}
// ----------------------------------------------------------------------- //
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def acceptsEnergyFrom(emitter: net.minecraft.tileentity.TileEntity, direction: ForgeDirection) = Mods.IndustrialCraft2.isAvailable && canConnectPower(direction)
def getSinkTier: Int = Int.MaxValue
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def acceptsEnergyFrom(emitter: net.minecraft.tileentity.TileEntity, direction: ForgeDirection): Boolean = Mods.IndustrialCraft2.isAvailable && canConnectPower(direction)
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def injectEnergy(directionFrom: ForgeDirection, amount: Double, voltage: Double): Double = {
lastInjectedAmount = amount
var energy = amount * Settings.get.ratioIndustrialCraft2
// Work around IC2 being uncooperative and always just passing 'unknown' along here.
if (directionFrom == ForgeDirection.UNKNOWN) {
for (side <- ForgeDirection.VALID_DIRECTIONS if energy > 0) {
energy -= tryChangeBuffer(side, energy)
}
energy / Settings.get.ratioIndustrialCraft2
}
else amount - tryChangeBuffer(directionFrom, energy) / Settings.get.ratioIndustrialCraft2
conversionBuffer += amount
0.0
}
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def getDemandedEnergy = {
def getDemandedEnergy: Double = {
if (!useIndustrialCraft2Power) 0.0
else {
var force = false
val demand = ForgeDirection.VALID_DIRECTIONS.map(side => {
val size = globalBufferSize(side)
val value = globalBuffer(side)
val space = size - value
force = force || (space > size / 2)
space
}).max / Settings.get.ratioIndustrialCraft2
if (force || lastInjectedAmount <= 0 || demand >= lastInjectedAmount) demand
else 0.0
}
else if (conversionBuffer < energyThroughput * Settings.get.tickFrequency)
math.min(ForgeDirection.VALID_DIRECTIONS.map(globalDemand).max, energyThroughput / Settings.get.ratioIndustrialCraft2)
else 0
}
}

View File

@ -1,14 +1,16 @@
package li.cil.oc.common.tileentity.traits.power
import cpw.mods.fml.common.Optional
import li.cil.oc.common.EventHandler
import li.cil.oc.util.mods.Mods
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.common.EventHandler
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.mods.Mods
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.ForgeDirection
import universalelectricity.api.core.grid.electric.IEnergyNode
import universalelectricity.api.core.grid.INode
import universalelectricity.api.core.grid.INodeProvider
import universalelectricity.api.core.grid.electric.IEnergyNode
import universalelectricity.core.grid.node.NodeEnergy
trait UniversalElectricity extends Common {
@ -29,39 +31,11 @@ trait UniversalElectricity extends Common {
private def updateEnergy() {
node match {
case Some(energyNode: NodeEnergy) =>
for (side <- ForgeDirection.VALID_DIRECTIONS) {
val demand = (globalBufferSize(side) - globalBuffer(side)) / Settings.get.ratioUniversalElectricity
if (demand > 1) {
val power = energyNode.buffer.extractEnergy(demand, doExtract = true)
tryChangeBuffer(side, power * Settings.get.ratioUniversalElectricity)
}
}
tryAllSides((demand, _) => energyNode.buffer.extractEnergy(demand, doExtract = true), Settings.get.ratioUniversalElectricity)
case _ =>
}
}
// ----------------------------------------------------------------------- //
@Optional.Method(modid = Mods.IDs.UniversalElectricity)
def getNode(nodeType: Class[_ <: INode], side: ForgeDirection): INode = {
if (nodeType != null && classOf[IEnergyNode].isAssignableFrom(nodeType)) node match {
case Some(energyNode: NodeEnergy) => energyNode
case _ =>
this match {
case nodeProvider: INodeProvider =>
val energyNode = new NodeEnergy(nodeProvider, 500, 500, 500) {
override def canConnect(from: ForgeDirection) = canConnectPower(from) && super.canConnect(from)
}
node = Option(energyNode)
energyNode
case _ =>
OpenComputers.log.warn("Failed setting up UniversalElectricity power, which most likely means the class transformer did not run. You're probably running in an incorrectly configured development environment. Try adding `-Dfml.coreMods.load=li.cil.oc.common.launch.TransformerLoader` to the VM options of your run configuration.")
null
}
}
else null
}
override def validate() {
super.validate()
if (useUniversalElectricityPower) EventHandler.scheduleUEAdd(this)
@ -76,4 +50,55 @@ trait UniversalElectricity extends Common {
private def deconstructNode() {
getNode(classOf[IEnergyNode], ForgeDirection.UNKNOWN).deconstruct()
}
// ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
if (useUniversalElectricityPower) loadNode(nbt)
}
@Optional.Method(modid = Mods.IDs.UniversalElectricity)
private def loadNode(nbt: NBTTagCompound) {
node match {
case Some(energyNode: NodeEnergy) => energyNode.load(nbt.getCompoundTag("uepower"))
case _ =>
}
}
override def writeToNBT(nbt: NBTTagCompound) {
super.writeToNBT(nbt)
if (useUniversalElectricityPower) saveNode(nbt)
}
@Optional.Method(modid = Mods.IDs.UniversalElectricity)
private def saveNode(nbt: NBTTagCompound) {
node match {
case Some(energyNode: NodeEnergy) => nbt.setNewCompoundTag("uepower", energyNode.save)
case _ =>
}
}
// ----------------------------------------------------------------------- //
@Optional.Method(modid = Mods.IDs.UniversalElectricity)
def getNode(nodeType: Class[_ <: INode], side: ForgeDirection): INode = {
if (nodeType != null && classOf[IEnergyNode].isAssignableFrom(nodeType)) node match {
case Some(energyNode: NodeEnergy) => energyNode
case _ =>
this match {
case nodeProvider: INodeProvider =>
val conversionBufferSize = energyThroughput * Settings.get.tickFrequency / Settings.get.ratioUniversalElectricity
val energyNode = new NodeEnergy(nodeProvider, conversionBufferSize, conversionBufferSize, conversionBufferSize) {
override def canConnect(from: ForgeDirection) = canConnectPower(from) && super.canConnect(from)
}
node = Option(energyNode)
energyNode
case _ =>
OpenComputers.log.warn("Failed setting up UniversalElectricity power, which most likely means the class transformer did not run. You're probably running in an incorrectly configured development environment. Try adding `-Dfml.coreMods.load=li.cil.oc.common.launch.TransformerLoader` to the VM options of your run configuration.")
null
}
}
else null
}
}