mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-28 15:30:08 -04:00
Merge branch 'master' of github.com:MightyPirates/OpenComputers into MC1.7
Conflicts: src/main/scala/li/cil/oc/common/tileentity/traits/PowerAcceptor.scala src/main/scala/li/cil/oc/server/TickHandler.scala
This commit is contained in:
commit
552bf5e3c2
@ -46,6 +46,10 @@ opencomputers {
|
|||||||
# The volume multiplier applied to sounds from this mod like the computer
|
# The volume multiplier applied to sounds from this mod like the computer
|
||||||
# running noise. Disable sounds by setting this to zero.
|
# running noise. Disable sounds by setting this to zero.
|
||||||
soundVolume: 1.0
|
soundVolume: 1.0
|
||||||
|
|
||||||
|
# This is the scaling of the individual chars rendered on screens. This
|
||||||
|
# is set to slightly overscale per default, to avoid
|
||||||
|
fontCharScale: 1.01
|
||||||
}
|
}
|
||||||
|
|
||||||
# Computer related settings, concerns server performance and security.
|
# Computer related settings, concerns server performance and security.
|
||||||
|
@ -20,6 +20,7 @@ class Settings(config: Config) {
|
|||||||
val pasteShortcut = config.getStringList("client.pasteShortcut").toSet
|
val pasteShortcut = config.getStringList("client.pasteShortcut").toSet
|
||||||
val robotLabels = config.getBoolean("client.robotLabels")
|
val robotLabels = config.getBoolean("client.robotLabels")
|
||||||
val soundVolume = config.getDouble("client.soundVolume").toFloat max 0 min 2
|
val soundVolume = config.getDouble("client.soundVolume").toFloat max 0 min 2
|
||||||
|
val fontCharScale = config.getDouble("client.fontCharScale") max 0.5 min 2
|
||||||
val rTreeDebugRenderer = false // *Not* to be configurable via config file.
|
val rTreeDebugRenderer = false // *Not* to be configurable via config file.
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
@ -43,6 +43,9 @@ object MonospaceFontRenderer {
|
|||||||
|
|
||||||
// Set up the display lists.
|
// Set up the display lists.
|
||||||
{
|
{
|
||||||
|
val s = Settings.get.fontCharScale
|
||||||
|
val dw = charWidth * s - charWidth
|
||||||
|
val dh = charHeight * s - charHeight
|
||||||
val t = Tessellator.instance
|
val t = Tessellator.instance
|
||||||
// Now create lists for all printable chars.
|
// Now create lists for all printable chars.
|
||||||
for (index <- 1 until 0xFF) {
|
for (index <- 1 until 0xFF) {
|
||||||
@ -52,10 +55,10 @@ object MonospaceFontRenderer {
|
|||||||
val v = y * vStep
|
val v = y * vStep
|
||||||
GL11.glNewList(charLists + index, GL11.GL_COMPILE)
|
GL11.glNewList(charLists + index, GL11.GL_COMPILE)
|
||||||
t.startDrawingQuads()
|
t.startDrawingQuads()
|
||||||
t.addVertexWithUV(0, charHeight, 0, u, v + vSize)
|
t.addVertexWithUV(-dw, charHeight * s, 0, u, v + vSize)
|
||||||
t.addVertexWithUV(charWidth, charHeight, 0, u + uSize, v + vSize)
|
t.addVertexWithUV(charWidth * s, charHeight * s, 0, u + uSize, v + vSize)
|
||||||
t.addVertexWithUV(charWidth, 0, 0, u + uSize, v)
|
t.addVertexWithUV(charWidth * s, -dh, 0, u + uSize, v)
|
||||||
t.addVertexWithUV(0, 0, 0, u, v)
|
t.addVertexWithUV(-dw, -dh, 0, u, v)
|
||||||
t.draw()
|
t.draw()
|
||||||
GL11.glTranslatef(charWidth, 0, 0)
|
GL11.glTranslatef(charWidth, 0, 0)
|
||||||
GL11.glEndList()
|
GL11.glEndList()
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package li.cil.oc.common
|
package li.cil.oc.common
|
||||||
|
|
||||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
||||||
import cpw.mods.fml.common.FMLCommonHandler
|
|
||||||
import cpw.mods.fml.common.gameevent.PlayerEvent._
|
import cpw.mods.fml.common.gameevent.PlayerEvent._
|
||||||
import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent
|
import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent
|
||||||
|
import cpw.mods.fml.common.{Optional, FMLCommonHandler}
|
||||||
|
import ic2.api.energy.event.{EnergyTileLoadEvent, EnergyTileUnloadEvent}
|
||||||
import li.cil.oc.api.Network
|
import li.cil.oc.api.Network
|
||||||
|
import li.cil.oc.common.tileentity.traits.IC2PowerGridAware
|
||||||
import li.cil.oc.server.driver.Registry
|
import li.cil.oc.server.driver.Registry
|
||||||
import li.cil.oc.util.ExtendedNBT._
|
import li.cil.oc.util.ExtendedNBT._
|
||||||
import li.cil.oc.util.LuaStateFactory
|
import li.cil.oc.util.LuaStateFactory
|
||||||
@ -15,14 +17,15 @@ import net.minecraft.item.{ItemMap, ItemStack}
|
|||||||
import net.minecraft.server.MinecraftServer
|
import net.minecraft.server.MinecraftServer
|
||||||
import net.minecraft.tileentity.TileEntity
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraft.util.{ChatComponentTranslation, ChatComponentText}
|
import net.minecraft.util.{ChatComponentTranslation, ChatComponentText}
|
||||||
|
import net.minecraftforge.common.MinecraftForge
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
|
||||||
object EventHandler {
|
object EventHandler {
|
||||||
val pendingAdds = mutable.Buffer.empty[() => Unit]
|
val pending = mutable.Buffer.empty[() => Unit]
|
||||||
|
|
||||||
def schedule(tileEntity: TileEntity) =
|
def schedule(tileEntity: TileEntity) =
|
||||||
if (FMLCommonHandler.instance.getEffectiveSide.isServer) pendingAdds.synchronized {
|
if (FMLCommonHandler.instance.getEffectiveSide.isServer) pending.synchronized {
|
||||||
pendingAdds += (() => Network.joinOrCreateNetwork(tileEntity))
|
pending += (() => Network.joinOrCreateNetwork(tileEntity))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO FMP
|
/* TODO FMP
|
||||||
@ -33,12 +36,28 @@ object EventHandler {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@Optional.Method(modid = "IC2")
|
||||||
|
def scheduleIC2Add(tileEntity: TileEntity with IC2PowerGridAware) = pending.synchronized {
|
||||||
|
pending += (() => if (!tileEntity.addedToPowerGrid && !tileEntity.isInvalid) {
|
||||||
|
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(tileEntity))
|
||||||
|
tileEntity.addedToPowerGrid = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@Optional.Method(modid = "IC2")
|
||||||
|
def scheduleIC2Remove(tileEntity: TileEntity with IC2PowerGridAware) = pending.synchronized {
|
||||||
|
pending += (() => if (tileEntity.addedToPowerGrid) {
|
||||||
|
MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(tileEntity))
|
||||||
|
tileEntity.addedToPowerGrid = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
def onTick(e: ServerTickEvent) = pendingAdds.synchronized {
|
def onTick(e: ServerTickEvent) = pending.synchronized {
|
||||||
for (callback <- pendingAdds) {
|
for (callback <- pending) {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
pendingAdds.clear()
|
pending.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -19,7 +19,13 @@ object SaveHandler {
|
|||||||
|
|
||||||
def scheduleSave(dimension: Int, chunk: ChunkCoordIntPair, name: String, data: Array[Byte]) = saveData.synchronized {
|
def scheduleSave(dimension: Int, chunk: ChunkCoordIntPair, name: String, data: Array[Byte]) = saveData.synchronized {
|
||||||
if (chunk == null) throw new IllegalArgumentException("chunk is null")
|
if (chunk == null) throw new IllegalArgumentException("chunk is null")
|
||||||
else saveData.getOrElseUpdate(dimension, mutable.Map.empty).getOrElseUpdate(chunk, mutable.Map.empty) += name -> data
|
else {
|
||||||
|
val chunks = saveData.getOrElseUpdate(dimension, mutable.Map.empty)
|
||||||
|
// Make sure we get rid of old versions (e.g. left over by other mods
|
||||||
|
// triggering a save - this is mostly used for RiM compatibility).
|
||||||
|
chunks.values.foreach(_ -= name)
|
||||||
|
chunks.getOrElseUpdate(chunk, mutable.Map.empty) += name -> data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def load(dimension: Int, chunk: ChunkCoordIntPair, name: String): Array[Byte] = {
|
def load(dimension: Int, chunk: ChunkCoordIntPair, name: String): Array[Byte] = {
|
||||||
|
@ -69,8 +69,8 @@ class Analyzer(val parent: Delegator) extends Delegate {
|
|||||||
player.addChatMessage(new ChatComponentTranslation(
|
player.addChatMessage(new ChatComponentTranslation(
|
||||||
Settings.namespace + "gui.Analyzer.Address",
|
Settings.namespace + "gui.Analyzer.Address",
|
||||||
address))
|
address))
|
||||||
|
PacketSender.sendAnalyze(address, player)
|
||||||
}
|
}
|
||||||
PacketSender.sendAnalyze(address, player)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override def registerIcons(iconRegister: IIconRegister) {
|
override def registerIcons(iconRegister: IIconRegister) {
|
||||||
|
@ -28,7 +28,7 @@ class Adapter extends traits.Environment with Analyzable {
|
|||||||
|
|
||||||
override def updateEntity() {
|
override def updateEntity() {
|
||||||
super.updateEntity()
|
super.updateEntity()
|
||||||
if (blocks.nonEmpty) {
|
if (updatingBlocks.nonEmpty) {
|
||||||
for (block <- updatingBlocks) {
|
for (block <- updatingBlocks) {
|
||||||
block.update()
|
block.update()
|
||||||
}
|
}
|
||||||
@ -101,6 +101,13 @@ class Adapter extends traits.Environment with Analyzable {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
override def onDisconnect(node: Node) {
|
||||||
|
super.onDisconnect(node)
|
||||||
|
if (node == this.node) {
|
||||||
|
updatingBlocks.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override def readFromNBT(nbt: NBTTagCompound) {
|
override def readFromNBT(nbt: NBTTagCompound) {
|
||||||
super.readFromNBT(nbt)
|
super.readFromNBT(nbt)
|
||||||
|
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package li.cil.oc.common.tileentity.traits
|
||||||
|
|
||||||
|
import ic2.api.energy.tile.IEnergySink
|
||||||
|
import cpw.mods.fml.common.Optional
|
||||||
|
|
||||||
|
@Optional.Interface(iface = "ic2.api.energy.tile.IEnergySink", modid = "IC2")
|
||||||
|
trait IC2PowerGridAware extends IEnergySink {
|
||||||
|
var addedToPowerGrid = false
|
||||||
|
}
|
@ -1,25 +1,23 @@
|
|||||||
package li.cil.oc.common.tileentity.traits
|
package li.cil.oc.common.tileentity.traits
|
||||||
|
|
||||||
import buildcraft.api.power.{PowerHandler, IPowerReceptor}
|
import buildcraft.api.power.{PowerHandler, IPowerReceptor}
|
||||||
|
import li.cil.oc.common.EventHandler
|
||||||
//import cofh.api.energy.IEnergyHandler
|
//import cofh.api.energy.IEnergyHandler
|
||||||
import cpw.mods.fml.common.{ModAPIManager, Loader, Optional}
|
import cpw.mods.fml.common.{ModAPIManager, Loader, Optional}
|
||||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||||
import ic2.api.energy.event.{EnergyTileUnloadEvent, EnergyTileLoadEvent}
|
|
||||||
import ic2.api.energy.tile.IEnergySink
|
|
||||||
import li.cil.oc.api.network.Connector
|
import li.cil.oc.api.network.Connector
|
||||||
import li.cil.oc.Settings
|
import li.cil.oc.Settings
|
||||||
import net.minecraftforge.common.MinecraftForge
|
|
||||||
import net.minecraftforge.common.util.ForgeDirection
|
import net.minecraftforge.common.util.ForgeDirection
|
||||||
//import universalelectricity.api.energy.{IEnergyContainer, IEnergyInterface}
|
//import universalelectricity.api.energy.{IEnergyContainer, IEnergyInterface}
|
||||||
|
|
||||||
@Optional.InterfaceList(Array(
|
@Optional.InterfaceList(Array(
|
||||||
new Optional.Interface(iface = "buildcraft.api.power.IPowerReceptor", modid = "BuildCraftAPI|power"),
|
new Optional.Interface(iface = "buildcraft.api.power.IPowerReceptor", modid = "BuildCraftAPI|power"),
|
||||||
new Optional.Interface(iface = "ic2.api.energy.tile.IEnergySink", modid = "IC2")
|
new Optional.Interface(iface = "universalelectricity.api.energy.IEnergyContainer", modid = "UniversalElectricity")
|
||||||
// new Optional.Interface(iface = "cofh.api.energy.IEnergyHandler", modid = "ThermalExpansion"),
|
// new Optional.Interface(iface = "cofh.api.energy.IEnergyHandler", modid = "ThermalExpansion"),
|
||||||
// new Optional.Interface(iface = "universalelectricity.api.energy.IEnergyInterface", modid = "UniversalElectricity"),
|
// new Optional.Interface(iface = "universalelectricity.api.energy.IEnergyInterface", modid = "UniversalElectricity"),
|
||||||
// new Optional.Interface(iface = "universalelectricity.api.energy.IEnergyContainer", modid = "UniversalElectricity")
|
// new Optional.Interface(iface = "universalelectricity.api.energy.IEnergyContainer", modid = "UniversalElectricity")
|
||||||
))
|
))
|
||||||
trait PowerAcceptor extends TileEntity with IPowerReceptor with IEnergySink /* with IEnergyHandler with IEnergyInterface with IEnergyContainer */ {
|
trait PowerAcceptor extends TileEntity with IPowerReceptor with IC2PowerGridAware /* with IEnergyHandler with IEnergyInterface with IEnergyContainer */ {
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
protected def hasConnector(side: ForgeDirection) = false
|
protected def hasConnector(side: ForgeDirection) = false
|
||||||
|
|
||||||
@ -100,22 +98,14 @@ trait PowerAcceptor extends TileEntity with IPowerReceptor with IEnergySink /* w
|
|||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
// IndustrialCraft2
|
// IndustrialCraft2
|
||||||
|
|
||||||
private var addedToPowerGrid = false
|
|
||||||
|
|
||||||
@Optional.Method(modid = "IC2")
|
@Optional.Method(modid = "IC2")
|
||||||
def loadIC2() {
|
def loadIC2() {
|
||||||
if (!addedToPowerGrid) {
|
if (!addedToPowerGrid) EventHandler.scheduleIC2Add(this)
|
||||||
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this))
|
|
||||||
addedToPowerGrid = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Optional.Method(modid = "IC2")
|
@Optional.Method(modid = "IC2")
|
||||||
def unloadIC2() {
|
def unloadIC2() {
|
||||||
if (addedToPowerGrid) {
|
if (addedToPowerGrid) EventHandler.scheduleIC2Remove(this)
|
||||||
MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this))
|
|
||||||
addedToPowerGrid = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Optional.Method(modid = "IC2")
|
@Optional.Method(modid = "IC2")
|
||||||
|
@ -507,10 +507,10 @@ class Machine(val owner: Owner, val rom: Option[ManagedEnvironment], constructor
|
|||||||
for ((address, name) <- _components) {
|
for ((address, name) <- _components) {
|
||||||
if (node.network.node(address) == null) {
|
if (node.network.node(address) == null) {
|
||||||
if (name == "filesystem") {
|
if (name == "filesystem") {
|
||||||
OpenComputers.log.fine("A component of type '%s' disappeared! This usually means that it didn't save its node.".format(name))
|
OpenComputers.log.fine(s"A component of type '$name' disappeared ($address)! This usually means that it didn't save its node.")
|
||||||
OpenComputers.log.fine("If this was a file system provided by a ComputerCraft peripheral, this is normal.")
|
OpenComputers.log.fine("If this was a file system provided by a ComputerCraft peripheral, this is normal.")
|
||||||
}
|
}
|
||||||
else OpenComputers.log.warning("A component of type '%s' disappeared! This usually means that it didn't save its node.".format(name))
|
else OpenComputers.log.warning(s"A component of type '$name' disappeared ($address)! This usually means that it didn't save its node.")
|
||||||
signal("component_removed", address, name)
|
signal("component_removed", address, name)
|
||||||
invalid += address
|
invalid += address
|
||||||
}
|
}
|
||||||
|
@ -596,10 +596,18 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu
|
|||||||
// on. First, clear the stack, meaning the current kernel.
|
// on. First, clear the stack, meaning the current kernel.
|
||||||
lua.setTop(0)
|
lua.setTop(0)
|
||||||
|
|
||||||
|
// Since we have no world yet, we rely on the dimension we were saved in.
|
||||||
|
// Same goes for the chunk. This also works around issues with computers
|
||||||
|
// being moved (e.g. Redstone in Motion).
|
||||||
val dimension = nbt.getInteger("dimension")
|
val dimension = nbt.getInteger("dimension")
|
||||||
|
val chunk =
|
||||||
|
if (nbt.hasKey("chunkX") && nbt.hasKey("chunkZ"))
|
||||||
|
new ChunkCoordIntPair(nbt.getInteger("chunkX"), nbt.getInteger("chunkZ"))
|
||||||
|
else
|
||||||
|
new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4)
|
||||||
val kernel =
|
val kernel =
|
||||||
if (nbt.hasKey("kernel")) nbt.getByteArray("kernel")
|
if (nbt.hasKey("kernel")) nbt.getByteArray("kernel")
|
||||||
else SaveHandler.load(dimension, new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_kernel")
|
else SaveHandler.load(dimension, chunk, node.address + "_kernel")
|
||||||
unpersist(kernel)
|
unpersist(kernel)
|
||||||
if (!lua.isThread(1)) {
|
if (!lua.isThread(1)) {
|
||||||
// This shouldn't really happen, but there's a chance it does if
|
// This shouldn't really happen, but there's a chance it does if
|
||||||
@ -609,7 +617,7 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu
|
|||||||
if (state.contains(Machine.State.SynchronizedCall) || state.contains(Machine.State.SynchronizedReturn)) {
|
if (state.contains(Machine.State.SynchronizedCall) || state.contains(Machine.State.SynchronizedReturn)) {
|
||||||
val stack =
|
val stack =
|
||||||
if (nbt.hasKey("stack")) nbt.getByteArray("stack")
|
if (nbt.hasKey("stack")) nbt.getByteArray("stack")
|
||||||
else SaveHandler.load(dimension, new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_stack")
|
else SaveHandler.load(dimension, chunk, node.address + "_stack")
|
||||||
unpersist(stack)
|
unpersist(stack)
|
||||||
if (!(if (state.contains(Machine.State.SynchronizedCall)) lua.isFunction(2) else lua.isTable(2))) {
|
if (!(if (state.contains(Machine.State.SynchronizedCall)) lua.isFunction(2) else lua.isTable(2))) {
|
||||||
// Same as with the above, should not really happen normally, but
|
// Same as with the above, should not really happen normally, but
|
||||||
@ -637,14 +645,20 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu
|
|||||||
// Try persisting Lua, because that's what all of the rest depends on.
|
// Try persisting Lua, because that's what all of the rest depends on.
|
||||||
// Save the kernel state (which is always at stack index one).
|
// Save the kernel state (which is always at stack index one).
|
||||||
assert(lua.isThread(1))
|
assert(lua.isThread(1))
|
||||||
|
|
||||||
|
// We have to save the dimension and chunk coordinates, because they are
|
||||||
|
// not available on load / may have changed if the computer was moved.
|
||||||
val dimension = machine.owner.world.provider.dimensionId
|
val dimension = machine.owner.world.provider.dimensionId
|
||||||
|
val chunk = new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4)
|
||||||
nbt.setInteger("dimension", dimension)
|
nbt.setInteger("dimension", dimension)
|
||||||
SaveHandler.scheduleSave(dimension, new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_kernel", persist(1))
|
nbt.setInteger("chunkX", chunk.chunkXPos)
|
||||||
|
nbt.setInteger("chunkZ", chunk.chunkZPos)
|
||||||
|
SaveHandler.scheduleSave(dimension, chunk, node.address + "_kernel", persist(1))
|
||||||
// While in a driver call we have one object on the global stack: either
|
// While in a driver call we have one object on the global stack: either
|
||||||
// the function to call the driver with, or the result of the call.
|
// the function to call the driver with, or the result of the call.
|
||||||
if (state.contains(Machine.State.SynchronizedCall) || state.contains(Machine.State.SynchronizedReturn)) {
|
if (state.contains(Machine.State.SynchronizedCall) || state.contains(Machine.State.SynchronizedReturn)) {
|
||||||
assert(if (state.contains(Machine.State.SynchronizedCall)) lua.isFunction(2) else lua.isTable(2))
|
assert(if (state.contains(Machine.State.SynchronizedCall)) lua.isFunction(2) else lua.isTable(2))
|
||||||
SaveHandler.scheduleSave(dimension, new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_stack", persist(2))
|
SaveHandler.scheduleSave(dimension, chunk, node.address + "_stack", persist(2))
|
||||||
}
|
}
|
||||||
|
|
||||||
nbt.setInteger("kernelMemory", math.ceil(kernelMemory / ramScale).toInt)
|
nbt.setInteger("kernelMemory", math.ceil(kernelMemory / ramScale).toInt)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user