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. # The amount a tablet can store in its internal buffer.
tablet: 10000 tablet: 10000
# The amount of energy an access point can store.
accessPoint: 600.0
} }
# Default "costs", i.e. how much energy certain operations consume. # Default "costs", i.e. how much energy certain operations consume.
@ -652,6 +655,22 @@ opencomputers {
pistonPush: 20 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. # Power values for different power systems.
value { value {
AppliedEnergistics2: 100.0 AppliedEnergistics2: 100.0
@ -659,8 +678,8 @@ opencomputers {
Factorization: 6.5 Factorization: 6.5
Galacticraft: 24.0 Galacticraft: 24.0
IndustrialCraft2: 200.0 IndustrialCraft2: 200.0
Mekanism: 555.55555 Mekanism: 700.0
RedstoneFlux: 35.0 RedstoneFlux: 18.0
UniversalElectricity: 1750.0 UniversalElectricity: 1750.0
} }
} }

View File

@ -20,7 +20,6 @@ import scala.io.Source
class Settings(config: Config) { class Settings(config: Config) {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
// client // client
val screenTextFadeStartDistance = config.getDouble("client.screenTextFadeStartDistance") val screenTextFadeStartDistance = config.getDouble("client.screenTextFadeStartDistance")
val maxScreenTextRenderDistance = config.getDouble("client.maxScreenTextRenderDistance") val maxScreenTextRenderDistance = config.getDouble("client.maxScreenTextRenderDistance")
val textLinearFiltering = config.getBoolean("client.textLinearFiltering") val textLinearFiltering = config.getBoolean("client.textLinearFiltering")
@ -50,7 +49,6 @@ class Settings(config: Config) {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
// computer // computer
val threads = config.getInt("computer.threads") max 1 val threads = config.getInt("computer.threads") max 1
val timeout = config.getDouble("computer.timeout") max 0 val timeout = config.getDouble("computer.timeout") max 0
val startupDelay = config.getDouble("computer.startupDelay") max 0.05 val startupDelay = config.getDouble("computer.startupDelay") max 0.05
@ -85,7 +83,6 @@ class Settings(config: Config) {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
// robot // robot
val allowActivateBlocks = config.getBoolean("robot.allowActivateBlocks") val allowActivateBlocks = config.getBoolean("robot.allowActivateBlocks")
val allowUseItemsWithDuration = config.getBoolean("robot.allowUseItemsWithDuration") val allowUseItemsWithDuration = config.getBoolean("robot.allowUseItemsWithDuration")
val canAttackPlayers = config.getBoolean("robot.canAttackPlayers") 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 itemDamageRate = config.getDouble("robot.itemDamageRate") max 0 min 1
val nameFormat = config.getString("robot.nameFormat") val nameFormat = config.getString("robot.nameFormat")
// ----------------------------------------------------------------------- //
// robot.xp // robot.xp
val baseXpToLevel = config.getDouble("robot.xp.baseValue") max 0 val baseXpToLevel = config.getDouble("robot.xp.baseValue") max 0
val constantXpGrowth = config.getDouble("robot.xp.constantGrowth") max 1 val constantXpGrowth = config.getDouble("robot.xp.constantGrowth") max 1
val exponentialXpGrowth = config.getDouble("robot.xp.exponentialGrowth") max 1 val exponentialXpGrowth = config.getDouble("robot.xp.exponentialGrowth") max 1
@ -124,7 +119,6 @@ class Settings(config: Config) {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
// power // power
val pureIgnorePower = config.getBoolean("power.ignorePower") val pureIgnorePower = config.getBoolean("power.ignorePower")
lazy val ignorePower = pureIgnorePower || !Mods.isPowerProvidingModPresent lazy val ignorePower = pureIgnorePower || !Mods.isPowerProvidingModPresent
val tickFrequency = config.getDouble("power.tickFrequency") max 1 val tickFrequency = config.getDouble("power.tickFrequency") max 1
@ -151,6 +145,7 @@ class Settings(config: Config) {
Array(10000.0, 15000.0, 20000.0) Array(10000.0, 15000.0, 20000.0)
} }
val bufferTablet = config.getDouble("power.buffer.tablet") max 0 val bufferTablet = config.getDouble("power.buffer.tablet") max 0
val bufferAccessPoint = config.getDouble("power.buffer.accessPoint") max 0
// power.cost // power.cost
val computerCost = config.getDouble("power.cost.computer") max 0 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 chunkloaderCost = config.getDouble("power.cost.chunkloaderCost") max 0
val pistonCost = config.getDouble("power.cost.pistonPush") 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 // power.value
private val valueAppliedEnergistics2 = config.getDouble("power.value.AppliedEnergistics2") private val valueAppliedEnergistics2 = config.getDouble("power.value.AppliedEnergistics2")
private val valueBuildCraft = config.getDouble("power.value.BuildCraft") private val valueBuildCraft = config.getDouble("power.value.BuildCraft")

View File

@ -1,9 +1,10 @@
package li.cil.oc.common.block package li.cil.oc.common.block
import li.cil.oc.Settings
import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity
import net.minecraft.world.World import net.minecraft.world.World
class AccessPoint extends Switch { class AccessPoint extends Switch with traits.PowerAcceptor {
override protected def customTextures = Array( override protected def customTextures = Array(
None, None,
Some("AccessPointTop"), 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() 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 hasTileEntity(metadata: Int) = true
override def createTileEntity(world: World, metadata: Int) = new tileentity.RobotAssembler() 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) override def createTileEntity(world: World, metadata: Int) = new tileentity.Case(tier)
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //

View File

@ -1,12 +1,12 @@
package li.cil.oc.common.block 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.client.Textures
import li.cil.oc.common.GuiType import li.cil.oc.common.GuiType
import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity
import li.cil.oc.server.PacketSender import li.cil.oc.server.PacketSender
import li.cil.oc.util.mods.BuildCraft 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.block.Block
import net.minecraft.client.renderer.texture.IIconRegister import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
@ -14,7 +14,7 @@ import net.minecraft.world.IBlockAccess
import net.minecraft.world.World import net.minecraft.world.World
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
class Charger extends RedstoneAware { class Charger extends RedstoneAware with traits.PowerAcceptor {
override protected def customTextures = Array( override protected def customTextures = Array(
None, None,
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() 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 hasTileEntity(metadata: Int) = true
override def createTileEntity(world: World, metadata: Int) = new tileentity.Disassembler() 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 hasTileEntity(metadata: Int) = true
override def createTileEntity(world: World, metadata: Int) = new tileentity.PowerConverter() 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.Side
import cpw.mods.fml.relauncher.SideOnly import cpw.mods.fml.relauncher.SideOnly
import li.cil.oc.OpenComputers import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.client.Textures import li.cil.oc.client.Textures
import li.cil.oc.common.GuiType import li.cil.oc.common.GuiType
import li.cil.oc.common.tileentity 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 hasTileEntity(metadata: Int) = true
override def createTileEntity(world: World, metadata: Int) = new tileentity.ServerRack() override def createTileEntity(world: World, metadata: Int) = new tileentity.ServerRack()

View File

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

View File

@ -1,14 +1,16 @@
package li.cil.oc.common.tileentity 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.Arguments
import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context import li.cil.oc.api.machine.Context
import li.cil.oc.api.network._ import li.cil.oc.api.network._
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.mods.Mods 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.entity.player.EntityPlayer
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.Constants.NBT import net.minecraftforge.common.util.Constants.NBT
@ -16,10 +18,24 @@ import net.minecraftforge.common.util.ForgeDirection
import scala.collection.convert.WrapAsScala._ 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 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) { override protected def relayPacket(sourceSide: ForgeDirection, packet: Packet) {
super.relayPacket(sourceSide, packet) super.relayPacket(sourceSide, packet)
if (strength > 0) { if (strength > 0) {
if (sourceSide == null || sourceSide == ForgeDirection.UNKNOWN || { val cost = Settings.get.wirelessCostPerRange
val cost = Settings.get.wirelessCostPerRange val connector = plugs(sourceSide.ordinal).node.asInstanceOf[Connector]
val connector = plugs(sourceSide.ordinal).node.asInstanceOf[Connector] if (connector.tryChangeBuffer(-strength * cost)) {
connector.tryChangeBuffer(-strength * cost) api.Network.sendWirelessPacket(this, strength, packet)
}) 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 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 override def getWorld = world
var maxComponents = 0 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 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) = { override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = {
player.addChatMessage(Localization.Analyzer.ChargerSpeed(chargeSpeed)) player.addChatMessage(Localization.Analyzer.ChargerSpeed(chargeSpeed))
null 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 connector(side: ForgeDirection) = Option(if (side != ForgeDirection.UP) node else null)
override protected def energyThroughput = Settings.get.disassemblerRate
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def canUpdate = isServer 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 connector(side: ForgeDirection) = Option(node)
override protected def energyThroughput = Settings.get.powerConverterRate
override def canUpdate = isServer 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 connector(side: ForgeDirection) = Option(if (side != ForgeDirection.UP) node else null)
override protected def energyThroughput = Settings.get.assemblerRate
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
def isAssembling = requiredEnergy > 0 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 connector(side: ForgeDirection) = Option(if (side != facing) sidedNode(side).asInstanceOf[Connector] else null)
override protected def energyThroughput = Settings.get.serverRackRate
override def getWorld = world override def getWorld = world
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //

View File

@ -34,19 +34,17 @@ trait AppliedEnergistics2 extends Common {
@Optional.Method(modid = Mods.IDs.AppliedEnergistics2) @Optional.Method(modid = Mods.IDs.AppliedEnergistics2)
private def updateEnergy() { private def updateEnergy() {
val grid = getGridNode(ForgeDirection.UNKNOWN).getGrid tryAllSides((demand, side) => {
if (grid != null) { val grid = getGridNode(side).getGrid
val cache = grid.getCache(classOf[IEnergyGrid]).asInstanceOf[IEnergyGrid] if (grid != null) {
if (cache != null) { val cache = grid.getCache(classOf[IEnergyGrid]).asInstanceOf[IEnergyGrid]
for (side <- ForgeDirection.VALID_DIRECTIONS) { if (cache != null) {
val demand = (globalBufferSize(side) - globalBuffer(side)) / Settings.get.ratioAppliedEnergistics2 cache.extractAEPower(demand, Actionable.MODULATE, PowerMultiplier.CONFIG)
if (demand > 1) {
val power = cache.extractAEPower(demand, Actionable.MODULATE, PowerMultiplier.CONFIG)
tryChangeBuffer(side, power * Settings.get.ratioAppliedEnergistics2)
}
} }
else 0.0
} }
} else 0.0
}, Settings.get.ratioAppliedEnergistics2)
} }
override def validate() { 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.IPowerReceptor
import buildcraft.api.power.PowerHandler import buildcraft.api.power.PowerHandler
import cpw.mods.fml.common.Optional 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.OpenComputers
import li.cil.oc.Settings 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.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
@ -26,13 +26,7 @@ trait BuildCraft extends Common {
@Optional.Method(modid = Mods.IDs.BuildCraftPower) @Optional.Method(modid = Mods.IDs.BuildCraftPower)
private def updateEnergy() { private def updateEnergy() {
for (side <- ForgeDirection.VALID_DIRECTIONS) { tryAllSides((demand, _) => getPowerProvider.useEnergy(1, demand.toFloat, true), Settings.get.ratioBuildCraft)
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)
}
}
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@ -43,7 +37,7 @@ trait BuildCraft extends Common {
} }
@Optional.Method(modid = Mods.IDs.BuildCraftPower) @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"))) Option(getPowerProvider).foreach(_.readFromNBT(nbt.getCompoundTag(Settings.namespace + "bcpower")))
} }
@ -53,7 +47,7 @@ trait BuildCraft extends Common {
} }
@Optional.Method(modid = Mods.IDs.BuildCraftPower) @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)) Option(getPowerProvider).foreach(h => nbt.setNewCompoundTag(Settings.namespace + "bcpower", h.writeToNBT))
} }
@ -66,7 +60,8 @@ trait BuildCraft extends Common {
case receptor: IPowerReceptor => case receptor: IPowerReceptor =>
val handler = new PowerHandler(receptor, PowerHandler.Type.MACHINE) val handler = new PowerHandler(receptor, PowerHandler.Type.MACHINE)
if (handler != null) { 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) handler.configurePowerPerdition(0, 0)
powerHandler = Some(handler) 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) = def canConnectPower(side: ForgeDirection) =
!Settings.get.ignorePower && side != null && side != ForgeDirection.UNKNOWN && !Settings.get.ignorePower && side != null && side != ForgeDirection.UNKNOWN &&
(if (isClient) hasConnector(side) else connector(side).isDefined) (if (isClient) hasConnector(side) else connector(side).isDefined)
@ -23,8 +40,9 @@ trait Common extends TileEntity {
if (isClient || Settings.get.ignorePower) 0 if (isClient || Settings.get.ignorePower) 0
else connector(side) match { else connector(side) match {
case Some(node) => case Some(node) =>
if (doReceive) amount - node.changeBuffer(amount) val cappedAmount = math.max(-energyThroughput, math.min(energyThroughput, amount))
else math.min(amount, node.globalBufferSize - node.globalBuffer) if (doReceive) amount - node.changeBuffer(cappedAmount)
else math.min(cappedAmount, globalDemand(side))
case _ => 0 case _ => 0
} }
@ -41,4 +59,6 @@ trait Common extends TileEntity {
case Some(node) => node.globalBufferSize case Some(node) => node.globalBufferSize
case _ => 0 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.Charge
import factorization.api.Coord import factorization.api.Coord
import factorization.api.IChargeConductor import factorization.api.IChargeConductor
import li.cil.oc.util.mods.Mods
import li.cil.oc.OpenComputers import li.cil.oc.OpenComputers
import li.cil.oc.Settings 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 { trait Factorization extends Common {
private lazy val useFactorizationPower = isServer && Mods.Factorization.isAvailable private lazy val useFactorizationPower = isServer && Mods.Factorization.isAvailable
@ -23,33 +23,60 @@ trait Factorization extends Common {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def updateEntity() { override def updateEntity() {
if (useFactorizationPower) { if (useFactorizationPower) updateEnergy()
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)
}
}
}
super.updateEntity() super.updateEntity()
} }
override def invalidate() { @Optional.Method(modid = Mods.IDs.Factorization)
if (useFactorizationPower) { private def updateEnergy() {
getCharge.invalidate() 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() super.invalidate()
} }
@Optional.Method(modid = Mods.IDs.Factorization)
private def invalidateCharge() {
getCharge.invalidate()
}
override def onChunkUnload() { override def onChunkUnload() {
if (useFactorizationPower && !isInvalid) { if (useFactorizationPower) removeCharge()
getCharge.remove()
}
super.onChunkUnload() 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) @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.Optional
import cpw.mods.fml.common.eventhandler.Event import cpw.mods.fml.common.eventhandler.Event
import ic2classic.api.Direction 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.OpenComputers
import li.cil.oc.Settings 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.minecraft.tileentity.TileEntity
import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
trait IndustrialCraft2Classic extends Common with IndustrialCraft2Common { trait IndustrialCraft2Classic extends Common with IndustrialCraft2Common {
private var lastInjectedAmount = 0.0 private var conversionBuffer = 0.0
private lazy val useIndustrialCraft2ClassicPower = isServer && Mods.IndustrialCraft2Classic.isAvailable 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() { override def validate() {
super.validate() super.validate()
if (useIndustrialCraft2ClassicPower && !addedToIC2PowerGrid) EventHandler.scheduleIC2Add(this) if (useIndustrialCraft2ClassicPower && !addedToIC2PowerGrid) EventHandler.scheduleIC2Add(this)
@ -42,43 +59,38 @@ trait IndustrialCraft2Classic extends Common with IndustrialCraft2Common {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic) override def readFromNBT(nbt: NBTTagCompound) {
def isAddedToEnergyNet = addedToIC2PowerGrid 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) @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) @Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic)
def acceptsEnergyFrom(emitter: TileEntity, direction: Direction) = Mods.IndustrialCraft2Classic.isAvailable && canConnectPower(direction.toForgeDirection) def acceptsEnergyFrom(emitter: TileEntity, direction: Direction) = Mods.IndustrialCraft2Classic.isAvailable && canConnectPower(direction.toForgeDirection)
@Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic) @Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic)
def injectEnergy(directionFrom: Direction, amount: Int) = { def injectEnergy(directionFrom: Direction, amount: Int): Boolean = {
lastInjectedAmount = amount conversionBuffer += amount
var energy = amount * Settings.get.ratioIndustrialCraft2 true
// 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
} }
@Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic) @Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic)
def demandsEnergy = { def demandsEnergy: Int = {
if (!useIndustrialCraft2ClassicPower) 0 if (!useIndustrialCraft2ClassicPower) 0
else { else if (conversionBuffer < energyThroughput * Settings.get.tickFrequency)
var force = false math.min(ForgeDirection.VALID_DIRECTIONS.map(globalDemand).max, energyThroughput / Settings.get.ratioIndustrialCraft2).toInt
val demand = ForgeDirection.VALID_DIRECTIONS.map(side => { else 0
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 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.Optional
import cpw.mods.fml.common.eventhandler.Event 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.OpenComputers
import li.cil.oc.Settings 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.MinecraftForge
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
trait IndustrialCraft2Experimental extends Common with IndustrialCraft2Common { trait IndustrialCraft2Experimental extends Common with IndustrialCraft2Common {
private var lastInjectedAmount = 0.0 private var conversionBuffer = 0.0
private lazy val useIndustrialCraft2Power = isServer && Mods.IndustrialCraft2.isAvailable 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() { override def validate() {
super.validate() super.validate()
if (useIndustrialCraft2Power && !addedToIC2PowerGrid) EventHandler.scheduleIC2Add(this) if (useIndustrialCraft2Power && !addedToIC2PowerGrid) EventHandler.scheduleIC2Add(this)
@ -40,40 +57,35 @@ trait IndustrialCraft2Experimental extends Common with IndustrialCraft2Common {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@Optional.Method(modid = Mods.IDs.IndustrialCraft2) override def readFromNBT(nbt: NBTTagCompound) {
def getSinkTier = Int.MaxValue 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) @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) @Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def injectEnergy(directionFrom: ForgeDirection, amount: Double, voltage: Double): Double = { def injectEnergy(directionFrom: ForgeDirection, amount: Double, voltage: Double): Double = {
lastInjectedAmount = amount conversionBuffer += amount
var energy = amount * Settings.get.ratioIndustrialCraft2 0.0
// 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
} }
@Optional.Method(modid = Mods.IDs.IndustrialCraft2) @Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def getDemandedEnergy = { def getDemandedEnergy: Double = {
if (!useIndustrialCraft2Power) 0.0 if (!useIndustrialCraft2Power) 0.0
else { else if (conversionBuffer < energyThroughput * Settings.get.tickFrequency)
var force = false math.min(ForgeDirection.VALID_DIRECTIONS.map(globalDemand).max, energyThroughput / Settings.get.ratioIndustrialCraft2)
val demand = ForgeDirection.VALID_DIRECTIONS.map(side => { else 0
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
}
} }
} }

View File

@ -1,14 +1,16 @@
package li.cil.oc.common.tileentity.traits.power package li.cil.oc.common.tileentity.traits.power
import cpw.mods.fml.common.Optional 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.OpenComputers
import li.cil.oc.Settings 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 net.minecraftforge.common.util.ForgeDirection
import universalelectricity.api.core.grid.electric.IEnergyNode
import universalelectricity.api.core.grid.INode import universalelectricity.api.core.grid.INode
import universalelectricity.api.core.grid.INodeProvider import universalelectricity.api.core.grid.INodeProvider
import universalelectricity.api.core.grid.electric.IEnergyNode
import universalelectricity.core.grid.node.NodeEnergy import universalelectricity.core.grid.node.NodeEnergy
trait UniversalElectricity extends Common { trait UniversalElectricity extends Common {
@ -29,39 +31,11 @@ trait UniversalElectricity extends Common {
private def updateEnergy() { private def updateEnergy() {
node match { node match {
case Some(energyNode: NodeEnergy) => case Some(energyNode: NodeEnergy) =>
for (side <- ForgeDirection.VALID_DIRECTIONS) { tryAllSides((demand, _) => energyNode.buffer.extractEnergy(demand, doExtract = true), Settings.get.ratioUniversalElectricity)
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)
}
}
case _ => 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() { override def validate() {
super.validate() super.validate()
if (useUniversalElectricityPower) EventHandler.scheduleUEAdd(this) if (useUniversalElectricityPower) EventHandler.scheduleUEAdd(this)
@ -76,4 +50,55 @@ trait UniversalElectricity extends Common {
private def deconstructNode() { private def deconstructNode() {
getNode(classOf[IEnergyNode], ForgeDirection.UNKNOWN).deconstruct() 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
}
} }