working on performance, removing implicit conversions to rich number types in frequently called places (i.e. anything somehow called per tick); optimized power distribution a bit; added a tick delay for continuous power consumption stuff (screens, computer); converted some methods to lazy vals and caching multi-screen bounds

This commit is contained in:
Florian Nücke 2013-12-09 01:32:31 +01:00
parent 8c948098d8
commit 407d25131f
44 changed files with 266 additions and 240 deletions

View File

@ -87,6 +87,7 @@ class Settings(config: Config) {
val ratioUniversalElectricity = config.getDouble("power.ratioUniversalElectricity").toFloat
val chargeRate = config.getDouble("power.chargerChargeRate")
val generatorEfficiency = config.getDouble("power.generatorEfficiency")
val tickFrequency = 20
// power.buffer
val bufferCapacitor = config.getDouble("power.buffer.capacitor") max 0

View File

@ -41,7 +41,7 @@ object PacketSender {
val pb = new PacketBuilder(PacketType.Clipboard)
pb.writeTileEntity(t)
pb.writeUTF(value.substring(0, value.length min 1024))
pb.writeUTF(value.substring(0, math.min(value.length, 1024)))
pb.sendToServer()
}

View File

@ -116,9 +116,9 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten
protected def changeSize(w: Double, h: Double) = {
val bw = w * MonospaceFontRenderer.fontWidth
val bh = h * MonospaceFontRenderer.fontHeight
val scaleX = (bufferWidth / (bw + bufferMargin * 2.0)) min 1
val scaleY = (bufferHeight / (bh + bufferMargin * 2.0)) min 1
scaleX min scaleY
val scaleX = math.min(bufferWidth / (bw + bufferMargin * 2.0), 1)
val scaleY = math.min(bufferHeight / (bh + bufferMargin * 2.0), 1)
math.min(scaleX, scaleY)
}
private def drawSelection() {

View File

@ -61,9 +61,9 @@ class Screen(val screen: tileentity.Screen) extends Buffer {
protected def changeSize(w: Double, h: Double) = {
val bw = w * MonospaceFontRenderer.fontWidth
val bh = h * MonospaceFontRenderer.fontHeight
val scaleX = (width / (bw + bufferMargin * 2.0)) min 1
val scaleY = (height / (bh + bufferMargin * 2.0)) min 1
val scale = scaleX min scaleY
val scaleX = math.min(width / (bw + bufferMargin * 2.0), 1)
val scaleY = math.min(height / (bh + bufferMargin * 2.0), 1)
val scale = math.min(scaleX, scaleY)
val innerWidth = (bw * scale).toInt
val innerHeight = (bh * scale).toInt
x = (width - (innerWidth + bufferMargin * 2)) / 2

View File

@ -19,7 +19,8 @@ object MonospaceFontRenderer {
def init(textureManager: TextureManager) = this.synchronized(
instance = instance.orElse(Some(new Renderer(textureManager))))
val (fontWidth, fontHeight) = (5, 9)
val fontWidth = 5
val fontHeight = 9
def drawString(x: Int, y: Int, value: Array[Char], color: Array[Short], depth: PackedColor.Depth.Value) = instance match {
case None => OpenComputers.log.warning("Trying to render string with uninitialized MonospaceFontRenderer.")

View File

@ -96,7 +96,10 @@ object BufferRenderer {
}
private def drawBorder(x: Double, y: Double, w: Double, h: Double, u1: Int, v1: Int, u2: Int, v2: Int) = {
val (u1d, u2d, v1d, v2d) = (u1 / 16.0, u2 / 16.0, v1 / 16.0, v2 / 16.0)
val u1d = u1 / 16.0
val u2d = u2 / 16.0
val v1d = v1 / 16.0
val v2d = v2 / 16.0
val t = Tessellator.instance
t.startDrawingQuads()
t.addVertexWithUV(x, y + h, 0, u1d, v2d)

View File

@ -64,7 +64,7 @@ object ScreenRenderer extends TileEntitySpecialRenderer with Callable[Int] with
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
if (distance > fadeDistanceSq) {
RenderState.setBlendAlpha(0f max (1 - (distance - fadeDistanceSq) * fadeRatio).toFloat)
RenderState.setBlendAlpha(math.max(0, 1 - ((distance - fadeDistanceSq) * fadeRatio).toFloat))
}
MonospaceFontRenderer.init(tileEntityRenderer.renderEngine)
@ -77,8 +77,10 @@ object ScreenRenderer extends TileEntitySpecialRenderer with Callable[Int] with
private def compileOrDraw(list: Int) = if (screen.bufferIsDirty && !RenderState.compilingDisplayList) {
screen.bufferIsDirty = false
val (sx, sy) = (screen.width, screen.height)
val (tw, th) = (sx * 16f, sy * 16f)
val sx = screen.width
val sy = screen.height
val tw = sx * 16f
val th = sy * 16f
GL11.glNewList(list, GL11.GL_COMPILE_AND_EXECUTE)

View File

@ -46,7 +46,7 @@ class PacketBuilder(packetType: PacketType.Value, private val stream: ByteArrayO
val manager = server.getConfigurationManager
for (player <- manager.playerEntityList.map(_.asInstanceOf[EntityPlayerMP]) if player.dimension == dimension) {
val playerRenderDistance = Int.MaxValue // ObfuscationReflectionHelper.getPrivateValue(classOf[EntityPlayerMP], player, "renderDistance").asInstanceOf[Integer]
val playerSpecificRange = range min ((manager.getViewDistance min playerRenderDistance) * 16)
val playerSpecificRange = math.min(range, (manager.getViewDistance min playerRenderDistance) * 16)
if (player.getDistanceSq(x, y, z) < playerSpecificRange * playerSpecificRange) {
sendToPlayer(player.asInstanceOf[Player])
}

View File

@ -18,7 +18,7 @@ abstract class Computer extends Delegate {
override def isProvidingWeakPower(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) =
world.getBlockTileEntity(x, y, z) match {
case computer: tileentity.Computer => computer.output(side) max 0 min 15
case computer: tileentity.Computer => math.min(math.max(computer.output(side), 0), 15)
case _ => super.isProvidingWeakPower(world, x, y, z, side)
}

View File

@ -79,8 +79,8 @@ class Keyboard(val parent: SpecialDelegator) extends SpecialDelegate {
val z0 = -up.offsetZ * sizes(1) - side.offsetZ * sizes(2) - forward.offsetZ * sizes(0)
val z1 = up.offsetZ * sizes(1) + side.offsetZ * sizes(2) - forward.offsetZ * 0.5f
AxisAlignedBB.getBoundingBox(
(x0 min x1) + 0.5f, (y0 min y1) + 0.5f, (z0 min z1) + 0.5f,
(x0 max x1) + 0.5f, (y0 max y1) + 0.5f, (z0 max z1) + 0.5f)
math.min(x0, x1) + 0.5f, math.min(y0, y1) + 0.5f, math.min(z0, z1) + 0.5f,
math.max(x0, x1) + 0.5f, math.max(y0, y1) + 0.5f, math.max(z0, z1) + 0.5f)
}
override def neighborBlockChanged(world: World, x: Int, y: Int, z: Int, blockId: Int) =

View File

@ -97,8 +97,7 @@ class RobotAfterimage(val parent: SpecialDelegator) extends SpecialDelegate {
def findMovingRobot(world: IBlockAccess, x: Int, y: Int, z: Int): Option[tileentity.Robot] = {
for (side <- ForgeDirection.VALID_DIRECTIONS) {
val (rx, ry, rz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
world.getBlockTileEntity(rx, ry, rz) match {
world.getBlockTileEntity(x + side.offsetX, y + side.offsetY, z + side.offsetZ) match {
case proxy: tileentity.RobotProxy if proxy.robot.moveFromX == x && proxy.robot.moveFromY == y && proxy.robot.moveFromZ == z => return Some(proxy.robot)
case _ =>
}

View File

@ -32,7 +32,7 @@ class RobotProxy(val parent: SpecialDelegator) extends Computer with SpecialDele
if (stack.hasTagCompound) {
if (stack.getTagCompound.hasKey(Settings.namespace + "xp")) {
val xp = stack.getTagCompound.getDouble(Settings.namespace + "xp")
val level = (Math.pow(xp - Settings.get.baseXpToLevel, 1 / Settings.get.exponentialXpGrowth) / Settings.get.constantXpGrowth).toInt min 30
val level = math.min((Math.pow(xp - Settings.get.baseXpToLevel, 1 / Settings.get.exponentialXpGrowth) / Settings.get.constantXpGrowth).toInt, 30)
if (level > 0) {
tooltip.addAll(Tooltip.get(unlocalizedName + "_Level", level))
}

View File

@ -77,7 +77,8 @@ abstract class Screen(val parent: SimpleDelegator) extends SimpleDelegate {
override def icon(world: IBlockAccess, x: Int, y: Int, z: Int, worldSide: ForgeDirection, localSide: ForgeDirection) =
world.getBlockTileEntity(x, y, z) match {
case screen: tileentity.Screen if screen.width > 1 || screen.height > 1 =>
val (right, bottom) = (screen.width - 1, screen.height - 1)
val right = screen.width - 1
val bottom = screen.height - 1
val (px, py) = screen.localPosition
val (lx, ly) = screen.pitch match {
case ForgeDirection.NORTH => (px, py)

View File

@ -90,7 +90,7 @@ class Buffer(val owner: tileentity.Buffer) extends api.network.Environment with
// avoid sending too much data to our clients.
val (x, truncated) =
if (col < 0) (0, s.substring(-col))
else (col, s.substring(0, s.length min (buffer.width - col)))
else (col, s.substring(0, math.min(s.length, buffer.width - col)))
if (buffer.set(x, row, truncated))
owner.onScreenSet(x, row, truncated)
}

View File

@ -69,10 +69,10 @@ abstract class Player(protected val playerInventory: InventoryPlayer, val otherI
if (intoSlot.getHasStack) {
val intoStack = intoSlot.getStack
val itemsAreEqual = fromStack.isItemEqual(intoStack) && ItemStack.areItemStackTagsEqual(fromStack, intoStack)
val maxStackSize = fromStack.getMaxStackSize min intoSlot.getSlotStackLimit
val maxStackSize = math.min(fromStack.getMaxStackSize, intoSlot.getSlotStackLimit)
val slotHasCapacity = intoStack.stackSize < maxStackSize
if (itemsAreEqual && slotHasCapacity) {
val itemsMoved = (maxStackSize - intoStack.stackSize) min fromStack.stackSize
val itemsMoved = math.min(maxStackSize - intoStack.stackSize, fromStack.stackSize)
if (itemsMoved > 0) {
intoStack.stackSize += from.decrStackSize(itemsMoved).stackSize
intoSlot.onSlotChanged()
@ -85,8 +85,8 @@ abstract class Player(protected val playerInventory: InventoryPlayer, val otherI
for (i <- begin until end by step if from.getHasStack && from.getStack.stackSize > 0) {
val intoSlot = inventorySlots.get(i).asInstanceOf[Slot]
if (!intoSlot.getHasStack && intoSlot.isItemValid(fromStack)) {
val maxStackSize = fromStack.getMaxStackSize min intoSlot.getSlotStackLimit
val itemsMoved = maxStackSize min fromStack.stackSize
val maxStackSize = math.min(fromStack.getMaxStackSize, intoSlot.getSlotStackLimit)
val itemsMoved = math.min(maxStackSize, fromStack.stackSize)
intoSlot.putStack(from.decrStackSize(itemsMoved))
somethingChanged = true
}

View File

@ -25,7 +25,7 @@ class Robot(playerInventory: InventoryPlayer, robot: tileentity.Robot) extends P
override def detectAndSendChanges() {
super.detectAndSendChanges()
if ((robot.globalBuffer - lastSentBuffer).abs > 1) {
if (math.abs(robot.globalBuffer - lastSentBuffer) > 1) {
lastSentBuffer = robot.globalBuffer
ServerPacketSender.sendPowerState(robot)
}

View File

@ -39,7 +39,7 @@ trait BundledRedstone extends Redstone with IBundledEmitter with IBundledUpdatab
}
def bundledInput(side: ForgeDirection, color: Int) =
_bundledInput(side.ordinal())(color) max _rednetInput(side.ordinal())(color)
math.max(_bundledInput(side.ordinal())(color), _rednetInput(side.ordinal())(color))
def rednetInput(side: ForgeDirection, color: Int, value: Int) =
if (_rednetInput(side.ordinal())(color) != value) {
@ -134,7 +134,9 @@ trait BundledRedstone extends Redstone with IBundledEmitter with IBundledUpdatab
if (side == ForgeDirection.UNKNOWN) {
if (Loader.isModLoaded("MineFactoryReloaded")) {
for (side <- ForgeDirection.VALID_DIRECTIONS) {
val (nx, ny, nz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
val nx = x + side.offsetX
val ny = y + side.offsetY
val nz = z + side.offsetZ
Block.blocksList(world.getBlockId(nx, ny, nz)) match {
case block: IRedNetNetworkContainer => block.updateNetwork(world, x, y, z)
case _ =>
@ -143,7 +145,9 @@ trait BundledRedstone extends Redstone with IBundledEmitter with IBundledUpdatab
}
}
else {
val (nx, ny, nz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
val nx = x + side.offsetX
val ny = y + side.offsetY
val nz = z + side.offsetZ
if (Loader.isModLoaded("MineFactoryReloaded")) {
Block.blocksList(world.getBlockId(nx, ny, nz)) match {
case block: IRedNetNetworkContainer => block.updateNetwork(world, x, y, z)
@ -157,7 +161,7 @@ trait BundledRedstone extends Redstone with IBundledEmitter with IBundledUpdatab
// ----------------------------------------------------------------------- //
@Optional.Method(modid = "RedLogic")
def getBundledCableStrength(blockFace: Int, toDirection: Int): Array[Byte] = _bundledOutput(toLocal(ForgeDirection.getOrientation(toDirection)).ordinal()).map(value => (value max 0 min 255).toByte)
def getBundledCableStrength(blockFace: Int, toDirection: Int): Array[Byte] = _bundledOutput(toLocal(ForgeDirection.getOrientation(toDirection)).ordinal()).map(value => math.min(math.max(value, 0), 255).toByte)
@Optional.Method(modid = "RedLogic")
def onBundledInputChanged() = checkRedstoneInputChanged()

View File

@ -76,7 +76,7 @@ class Charger extends Environment with Redstone with Analyzable {
override protected def onRedstoneInputChanged(side: ForgeDirection) {
super.onRedstoneInputChanged(side)
chargeSpeed = 0.0 max (ForgeDirection.VALID_DIRECTIONS.map(input).max min 15) / 15.0
chargeSpeed = math.max(0, math.min(ForgeDirection.VALID_DIRECTIONS.map(input).max, 15) / 15.0)
if (isServer) {
ServerPacketSender.sendChargerState(this)
}

View File

@ -18,7 +18,7 @@ abstract class Computer(isRemote: Boolean) extends Environment with ComponentInv
def node = if (isClient) null else computer.node
override def isClient = computer == null
override lazy val isClient = computer == null
private var _isRunning = false

View File

@ -20,11 +20,14 @@ abstract class Environment extends net.minecraft.tileentity.TileEntity with Tile
def block = getBlockType
private var addedToNetwork = false
// ----------------------------------------------------------------------- //
override def updateEntity() {
super.updateEntity()
if (node != null && node.network == null) {
if (!addedToNetwork) {
addedToNetwork = true
Network.joinOrCreateNetwork(this)
}
}

View File

@ -15,7 +15,7 @@ class Keyboard(isRemote: Boolean) extends Environment with SidedEnvironment with
def node = if (isClient) null else keyboard.node
override def isClient = keyboard == null
override lazy val isClient = keyboard == null
def onAnalyze(stats: NBTTagCompound, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = node

View File

@ -21,6 +21,10 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I
withConnector().
create()
private lazy val isIndustrialCraftAvailable = Loader.isModLoaded("IC2")
private lazy val isBuildCraftAvailable = Loader.isModLoaded("BuildCraft|Energy")
private def demand = if (Settings.get.ignorePower) 0.0 else node.globalBufferSize - node.globalBuffer
def onAnalyze(stats: NBTTagCompound, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = null
@ -30,16 +34,19 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I
override def updateEntity() {
super.updateEntity()
if (isServer) {
if (Loader.isModLoaded("IC2")) {
if (isIndustrialCraftAvailable) {
loadIC2()
}
if (demand > 0 && Loader.isModLoaded("BuildCraft|Energy")) {
if (isBuildCraftAvailable && demand > 1 && world.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0) {
val wantInMJ = demand.toFloat / Settings.get.ratioBuildCraft
val gotInMJ = getPowerProvider.useEnergy(1, wantInMJ, true)
val powerProvider = getPowerProvider
if (wantInMJ < powerProvider.getEnergyStored) {
val gotInMJ = powerProvider.useEnergy(1, wantInMJ, true)
node.changeBuffer(gotInMJ * Settings.get.ratioBuildCraft)
}
}
}
}
override def onChunkUnload() {
super.onChunkUnload()
@ -74,7 +81,7 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I
// ----------------------------------------------------------------------- //
// IndustrialCraft
private var isIC2Loaded = false
private var addedToPowerGrid = false
private var lastPacketSize = 0.0
@ -82,17 +89,17 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I
@Optional.Method(modid = "IC2")
def loadIC2() {
if (!isIC2Loaded) {
if (!addedToPowerGrid) {
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this))
isIC2Loaded = true
addedToPowerGrid = true
}
}
@Optional.Method(modid = "IC2")
def unloadIC2() {
if (isIC2Loaded) {
if (addedToPowerGrid) {
MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this))
isIC2Loaded = false
addedToPowerGrid = false
}
}

View File

@ -114,14 +114,14 @@ trait Redstone extends RotationAware with network.Environment with Persistable w
case emitter: IRedstoneEmitter =>
var strength = 0
for (i <- -1 to 5) {
strength = strength max emitter.getEmittedSignalStrength(i, side.getOpposite.ordinal())
strength = math.max(strength, emitter.getEmittedSignalStrength(i, side.getOpposite.ordinal()))
}
strength
case _ => 0
}
}
else 0
vanilla max redLogic
math.max(vanilla, redLogic)
}
protected def onRedstoneInputChanged(side: ForgeDirection) {}
@ -131,7 +131,9 @@ trait Redstone extends RotationAware with network.Environment with Persistable w
world.notifyBlocksOfNeighborChange(x, y, z, block.blockID)
}
else {
val (nx, ny, nz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
val nx = x + side.offsetX
val ny = y + side.offsetY
val nz = z + side.offsetZ
world.notifyBlockOfNeighborChange(nx, ny, nz, block.blockID)
world.notifyBlocksOfNeighborChange(nx, ny, nz, world.getBlockId(nx, ny, nz))
}

View File

@ -97,7 +97,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
def updateXpInfo() {
// xp(level) = base + (level * const) ^ exp
// pow(xp(level) - base, 1/exp) / const = level
level = (Math.pow(xp - Settings.get.baseXpToLevel, 1 / Settings.get.exponentialXpGrowth) / Settings.get.constantXpGrowth).toInt min 30
level = math.min((Math.pow(xp - Settings.get.baseXpToLevel, 1 / Settings.get.exponentialXpGrowth) / Settings.get.constantXpGrowth).toInt, 30)
if (battery != null) {
battery.setLocalBufferSize(Settings.get.bufferRobot + Settings.get.bufferPerLevel * level)
}
@ -140,7 +140,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
Blocks.robotAfterimage.setBlock(world, ox, oy, oz, 1)
assert(Delegator.subBlock(world, ox, oy, oz).exists(_ == Blocks.robotAfterimage))
// Here instead of Lua callback so that it gets called on client, too.
val moveTicks = (Settings.get.moveDelay * 20).toInt max 1
val moveTicks = math.max((Settings.get.moveDelay * 20).toInt, 1)
setAnimateMove(ox, oy, oz, moveTicks)
if (isServer) {
world.scheduleBlockUpdate(ox, oy, oz, Blocks.robotAfterimage.parent.blockID, moveTicks - 1)

View File

@ -100,9 +100,9 @@ class RobotProxy(val robot: Robot) extends Computer(robot.isClient) with ISidedI
override def onInventoryChanged() = robot.onInventoryChanged()
override def isClient = robot.isClient
override lazy val isClient = robot.isClient
override def isServer = robot.isServer
override lazy val isServer = robot.isServer
// ----------------------------------------------------------------------- //

View File

@ -38,6 +38,8 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable
var hasPower = true
var cachedBounds: Option[AxisAlignedBB] = None
def canConnect(side: ForgeDirection) = toLocal(side) != ForgeDirection.SOUTH
def sidedNode(side: ForgeDirection) = if (canConnect(side)) node else null
@ -49,8 +51,7 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable
def localPosition = {
val (lx, ly, _) = project(this)
val (ox, oy, _) = project(origin)
val (px, py) = (lx - ox, ly - oy)
(px, py)
(lx - ox, ly - oy)
}
override def hasKeyboard = screens.exists(screen => ForgeDirection.VALID_DIRECTIONS.
@ -66,6 +67,7 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable
origin = this
screens.clear()
screens += this
cachedBounds = None
}
def click(player: EntityPlayer, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
@ -119,12 +121,15 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable
override def updateEntity() {
super.updateEntity()
if (isServer) {
if (isServer && world.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0) {
if (litPixels < 0) {
litPixels = buffer.lines.foldLeft(0)((acc, line) => acc + line.count(_ != ' '))
litPixels = 0
for (line <- buffer.lines) for (c <- line) {
if (c != ' ') litPixels += 1
}
}
val hadPower = hasPower
val neededPower = Settings.get.screenCost + pixelCost * litPixels
val neededPower = (Settings.get.screenCost + pixelCost * litPixels) * Settings.get.tickFrequency
hasPower = buffer.node.tryChangeBuffer(-neededPower)
if (hasPower != hadPower) {
ServerPacketSender.sendScreenPowerChange(this, hasPower)
@ -213,14 +218,17 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable
@SideOnly(Side.CLIENT)
override def getRenderBoundingBox =
if ((width == 1 && height == 1) || !isOrigin) super.getRenderBoundingBox
else {
else cachedBounds match {
case Some(bounds) => bounds
case _ =>
val (sx, sy, sz) = unproject(width, height, 1)
val ox = x + (if (sx < 0) 1 else 0)
val oy = y + (if (sy < 0) 1 else 0)
val oz = z + (if (sz < 0) 1 else 0)
val b = AxisAlignedBB.getAABBPool.getAABB(ox, oy, oz, ox + sx, oy + sy, oz + sz)
b.setBounds(b.minX min b.maxX, b.minY min b.maxY, b.minZ min b.maxZ,
b.minX max b.maxX, b.minY max b.maxY, b.minZ max b.maxZ)
val b = AxisAlignedBB.getBoundingBox(ox, oy, oz, ox + sx, oy + sy, oz + sz)
b.setBounds(math.min(b.minX, b.maxX), math.min(b.minY, b.maxY), math.min(b.minZ, b.maxZ),
math.max(b.minX, b.maxX), math.max(b.minY, b.maxY), math.max(b.minZ, b.maxZ))
cachedBounds = Some(b)
b
}
@ -297,6 +305,7 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable
screen.height = newHeight
screen.origin = newOrigin
screen.screens ++= newScreens // It's a set, so there won't be duplicates.
screen.cachedBounds = None
}
true
}

View File

@ -16,9 +16,9 @@ trait TileEntity {
def block: Block
def isClient = world.isRemote
lazy val isClient = world.isRemote
def isServer = !isClient
lazy val isServer = !isClient
@SideOnly(Side.CLIENT)
def readFromNBTForClient(nbt: NBTTagCompound) {}

View File

@ -120,7 +120,7 @@ class Computer(val owner: tileentity.Computer) extends ManagedComponent with Con
})
def pause(seconds: Double): Boolean = {
val ticksToPause = (seconds * 20).toInt max 0
val ticksToPause = math.max((seconds * 20).toInt, 0)
def shouldPause(state: Computer.State.Value) = state match {
case Computer.State.Stopping | Computer.State.Stopped => false
case Computer.State.Paused if ticksToPause <= remainingPause => false
@ -215,13 +215,14 @@ class Computer(val owner: tileentity.Computer) extends ManagedComponent with Con
worldTime = owner.world.getWorldTime
// We can have rollbacks from '/time set'. Avoid getting negative uptimes.
timeStarted = timeStarted min worldTime
timeStarted = math.min(timeStarted, worldTime)
// Reset direct call limits.
callCounts.synchronized(callCounts.clear())
callCounts.synchronized(if (callCounts.size > 0) callCounts.clear())
// Make sure we have enough power.
val cost = if (isRobot) Settings.get.robotCost else Settings.get.computerCost
if (owner.world.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0) {
val cost = (if (isRobot) Settings.get.robotCost else Settings.get.computerCost) * Settings.get.tickFrequency
state.synchronized(state.top match {
case Computer.State.Paused |
Computer.State.Restarting |
@ -236,6 +237,7 @@ class Computer(val owner: tileentity.Computer) extends ManagedComponent with Con
crash("not enough energy")
}
})
}
// Avoid spamming user list across the network.
if (worldTime % 20 == 0 && usersChanged) {
@ -396,6 +398,7 @@ class Computer(val owner: tileentity.Computer) extends ManagedComponent with Con
}
private def processAddedComponents() {
if (addedComponents.size > 0) {
for (component <- addedComponents) {
if (component.canBeSeenFrom(node)) {
components.synchronized(components += component.address -> component.name)
@ -408,6 +411,7 @@ class Computer(val owner: tileentity.Computer) extends ManagedComponent with Con
}
addedComponents.clear()
}
}
private def verifyComponents() {
val invalid = mutable.Set.empty[String]
@ -1214,7 +1218,7 @@ class Computer(val owner: tileentity.Computer) extends ManagedComponent with Con
// memory, regardless of the memory need of the underlying system
// (which may change across releases).
lua.gc(LuaState.GcAction.COLLECT, 0)
kernelMemory = lua.getTotalMemory - lua.getFreeMemory max 1
kernelMemory = math.max(lua.getTotalMemory - lua.getFreeMemory, 1)
recomputeMemory()
// Fake zero sleep to avoid stopping if there are no signals.

View File

@ -33,8 +33,8 @@ class Crafting(val owner: MCTileEntity) extends ManagedComponent {
val manager = CraftingManager.getInstance
val result = manager.findMatchingRecipe(CraftingInventory, owner.getWorldObj)
if (result == null) return false
val targetStackSize = if (result.isStackable) wantedCount min result.getMaxStackSize else result.stackSize
val timesCrafted = (targetStackSize / result.stackSize) min amountPossible
val targetStackSize = if (result.isStackable) math.min(wantedCount, result.getMaxStackSize) else result.stackSize
val timesCrafted = math.min(targetStackSize / result.stackSize, amountPossible)
if (timesCrafted <= 0) return true
GameRegistry.onItemCrafted(context.player, result, this)
val surplus = mutable.ArrayBuffer.empty[ItemStack]
@ -75,7 +75,7 @@ class Crafting(val owner: MCTileEntity) extends ManagedComponent {
val stack = inventory.getStackInSlot(toParentSlot(slot))
setInventorySlotContents(slot, stack)
if (stack != null) {
amountPossible = amountPossible min stack.stackSize
amountPossible = math.min(amountPossible, stack.stackSize)
}
}
}

View File

@ -133,7 +133,7 @@ class FileSystem(val fileSystem: api.fs.FileSystem, var label: Label) extends Ma
Option(fileSystem.getHandle(handle)) match {
case Some(file) =>
// Limit size of read buffer to avoid crazy allocations.
val buffer = new Array[Byte](n min Settings.get.maxReadBuffer)
val buffer = new Array[Byte](math.min(n, Settings.get.maxReadBuffer))
val read = file.read(buffer)
if (read >= 0) {
val bytes =

View File

@ -38,11 +38,11 @@ class Generator(val owner: MCTileEntity) extends ManagedComponent {
if (space <= 0) {
return result(false, "queue is full")
}
val moveCount = stack.stackSize min space min count
val moveCount = math.min(stack.stackSize, math.min(space, count))
existingStack.stackSize += moveCount
stack.stackSize -= moveCount
case _ =>
inventory = Some(stack.splitStack(stack.stackSize min count))
inventory = Some(stack.splitStack(math.min(stack.stackSize, count)))
}
player.inventory.setInventorySlotContents(context.selectedSlot, stack)
result(true)
@ -61,7 +61,7 @@ class Generator(val owner: MCTileEntity) extends ManagedComponent {
val count = if (args.count > 0) args.checkInteger(0) else Int.MaxValue
inventory match {
case Some(stack) =>
val removedStack = stack.splitStack(count min stack.stackSize)
val removedStack = stack.splitStack(math.min(count, stack.stackSize))
val success = context.player.inventory.addItemStackToInventory(removedStack)
stack.stackSize += removedStack.stackSize
if (success && stack.stackSize <= 0) {

View File

@ -56,8 +56,8 @@ abstract class GraphicsCard extends ManagedComponent {
screen(s => {
val (gmw, gmh) = maxResolution
val (smw, smh) = s.maxResolution
s.resolution = (gmw min smw, gmh min smh)
s.depth = PackedColor.Depth(maxDepth.id min s.maxDepth.id)
s.resolution = (math.min(gmw, smw), math.min(gmh, smh))
s.depth = PackedColor.Depth(math.min(maxDepth.id, s.maxDepth.id))
s.foreground = 0xFFFFFF
s.background = 0x000000
result(true)
@ -101,7 +101,7 @@ abstract class GraphicsCard extends ManagedComponent {
@LuaCallback(value = "maxDepth", direct = true)
def maxDepth(context: Context, args: Arguments): Array[AnyRef] =
screen(s => result(PackedColor.Depth(maxDepth.id min s.maxDepth.id) match {
screen(s => result(PackedColor.Depth(math.min(maxDepth.id, s.maxDepth.id)) match {
case PackedColor.Depth.OneBit => 1
case PackedColor.Depth.FourBit => 4
case PackedColor.Depth.EightBit => 8
@ -128,7 +128,7 @@ abstract class GraphicsCard extends ManagedComponent {
screen(s => {
val (gmw, gmh) = maxResolution
val (smw, smh) = s.maxResolution
result(gmw min smw, gmh min smh)
result(math.min(gmw, smw), math.min(gmh, smh))
})
@LuaCallback(value = "get", direct = true)

View File

@ -18,13 +18,13 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent {
var globalBufferSize = 0.0
var dirty = true
private var lastSentRatio = 0.0
private val buffers = mutable.Set.empty[Connector]
private val buffers = mutable.ArrayBuffer.empty[Connector]
private val distributors = mutable.Set.empty[PowerDistributor]
private var dirty = true
private val distributors = mutable.ArrayBuffer.empty[PowerDistributor]
// ----------------------------------------------------------------------- //
@ -37,36 +37,29 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent {
// ----------------------------------------------------------------------- //
def changeBuffer(delta: Double): Double = {
if (delta == 0) {
return 0
if (delta == 0) 0
else if (Settings.get.ignorePower) {
if (delta < 0) 0
else /* if (delta > 0) */ delta
}
if (Settings.get.ignorePower) {
if (delta < 0) {
return 0
}
else /* if (delta > 0) */ {
return delta
}
}
this.synchronized {
else this.synchronized {
val oldBuffer = globalBuffer
globalBuffer = (globalBuffer + delta) max 0 min globalBufferSize
globalBuffer = math.min(math.max(globalBuffer + delta, 0), globalBufferSize)
if (globalBuffer == oldBuffer) {
return delta
}
dirty = true
if (delta < 0) {
var remaining = -delta
for (connector <- buffers) {
for (connector <- buffers if remaining > 0 && connector.localBufferSize > 0) {
if (connector.localBuffer > 0) {
connector.dirty = true
if (connector.localBuffer < remaining) {
remaining -= connector.localBuffer
connector.localBuffer = 0
}
else {
connector.localBuffer -= remaining
return 0
remaining = 0
}
}
}
@ -74,9 +67,8 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent {
}
else /* if (delta > 0) */ {
var remaining = delta
for (connector <- buffers) {
for (connector <- buffers if remaining > 0 && connector.localBufferSize > 0) {
if (connector.localBuffer < connector.localBufferSize) {
connector.dirty = true
val space = connector.localBufferSize - connector.localBuffer
if (space < remaining) {
remaining -= space
@ -84,7 +76,7 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent {
}
else {
connector.localBuffer += remaining
return 0
remaining = 0
}
}
}
@ -96,7 +88,7 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent {
// ----------------------------------------------------------------------- //
override def update() {
if (node != null && (dirty || buffers.exists(_.dirty))) {
if (dirty && owner.world.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0 && node != null) {
updateCachedValues()
}
}
@ -108,21 +100,25 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent {
if (node == this.node) {
for (node <- node.reachableNodes) node match {
case connector: Connector if connector.localBufferSize > 0 => this.synchronized {
assert(!buffers.contains(connector))
buffers += connector
globalBuffer += connector.localBuffer
globalBufferSize += connector.localBufferSize
}
case _ => node.host match {
case distributor: PowerDistributor if distributor.node.canBeSeenFrom(this.node) =>
assert(!distributors.contains(distributor))
distributors += distributor
case _ =>
}
}
assert(!distributors.contains(this))
distributors += this
dirty = true
}
else node match {
case connector: Connector if connector.localBufferSize > 0 => this.synchronized {
assert(!buffers.contains(connector))
buffers += connector
globalBuffer += connector.localBuffer
globalBufferSize += connector.localBufferSize
@ -130,6 +126,7 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent {
}
case _ => node.host match {
case distributor: PowerDistributor if distributor.node.canBeSeenFrom(this.node) =>
assert(!distributors.contains(distributor))
distributors += distributor
case _ =>
}
@ -162,16 +159,16 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent {
def updateCachedValues() {
// Computer average fill ratio of all buffers.
val (sumBuffer, sumBufferSize) =
buffers.foldRight((0.0, 0.0))((c, acc) => {
c.dirty = false // clear dirty flag for all connectors
(acc._1 + c.localBuffer, acc._2 + c.localBufferSize)
})
var sumBuffer, sumBufferSize = 0.0
for (buffer <- buffers) {
sumBuffer += buffer.localBuffer
sumBufferSize += buffer.localBufferSize
}
// Only send updates if the state changed by more than 5%, more won't be
// noticeable "from the outside" anyway. We send more frequent updates in
// the gui/container of a block that needs it (like robots).
val fillRatio = sumBuffer / sumBufferSize
val shouldSend = (lastSentRatio - fillRatio).abs > (5.0 / 100.0)
val shouldSend = math.abs(lastSentRatio - fillRatio) > (5.0 / 100.0)
for (distributor <- distributors) distributor.synchronized {
distributor.dirty = false
distributor.globalBuffer = sumBuffer

View File

@ -73,7 +73,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte
if (args.count > 0 && args.checkAny(0) != null) checkSlot(args, 0)
else selectedSlot
result(stackInSlot(slot) match {
case Some(stack) => (robot.getInventoryStackLimit min stack.getMaxStackSize) - stack.stackSize
case Some(stack) => math.min(robot.getInventoryStackLimit, stack.getMaxStackSize) - stack.stackSize
case _ => robot.getInventoryStackLimit
})
}
@ -98,8 +98,8 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte
else result((stackInSlot(selectedSlot), stackInSlot(slot)) match {
case (Some(from), Some(to)) =>
if (haveSameItemType(from, to)) {
val space = (robot.getInventoryStackLimit min to.getMaxStackSize) - to.stackSize
val amount = count min space min from.stackSize
val space = math.min(robot.getInventoryStackLimit, to.getMaxStackSize) - to.stackSize
val amount = math.min(count, math.min(space, from.stackSize))
if (amount > 0) {
from.stackSize -= amount
to.stackSize += amount
@ -148,7 +148,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte
if (dropped != null && dropped.stackSize > 0) {
def tryDropIntoInventory(inventory: IInventory, filter: (Int) => Boolean) = {
var success = false
val maxStackSize = inventory.getInventoryStackLimit min dropped.getMaxStackSize
val maxStackSize = math.min(inventory.getInventoryStackLimit, dropped.getMaxStackSize)
val shouldTryMerge = !dropped.isItemStackDamageable && dropped.getMaxStackSize > 1 && inventory.getInventoryStackLimit > 1
if (shouldTryMerge) {
for (slot <- 0 until inventory.getSizeInventory if dropped.stackSize > 0 && filter(slot)) {
@ -157,7 +157,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte
existing.isItemEqual(dropped) && ItemStack.areItemStackTagsEqual(existing, dropped)
if (shouldMerge) {
val space = maxStackSize - existing.stackSize
val amount = space min dropped.stackSize
val amount = math.min(space, dropped.stackSize)
assert(amount > 0)
success = true
existing.stackSize += amount
@ -168,7 +168,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte
def canDropIntoSlot(slot: Int) = filter(slot) && inventory.isItemValidForSlot(slot, dropped) && inventory.getStackInSlot(slot) == null
for (slot <- 0 until inventory.getSizeInventory if dropped.stackSize > 0 && canDropIntoSlot(slot)) {
val amount = maxStackSize min dropped.stackSize
val amount = math.min(maxStackSize, dropped.stackSize)
inventory.setInventorySlotContents(slot, dropped.splitStack(amount))
success = true
}
@ -256,8 +256,8 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte
for (slot <- 0 until inventory.getSizeInventory if !success && filter(slot)) {
val stack = inventory.getStackInSlot(slot)
if (stack != null) {
val maxStackSize = robot.getInventoryStackLimit min stack.getMaxStackSize
val amount = maxStackSize min stack.stackSize min count
val maxStackSize = math.min(robot.getInventoryStackLimit, stack.getMaxStackSize)
val amount = math.min(maxStackSize, math.min(stack.stackSize, count))
val sucked = stack.splitStack(amount)
success = player.inventory.addItemStackToInventory(sucked)
stack.stackSize += sucked.stackSize
@ -600,7 +600,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte
private def checkOptionalItemCount(args: Arguments, n: Int) =
if (args.count > n && args.checkAny(n) != null) {
args.checkInteger(n) max 0 min robot.getInventoryStackLimit
math.max(args.checkInteger(n), math.min(0, robot.getInventoryStackLimit))
}
else robot.getInventoryStackLimit

View File

@ -30,7 +30,7 @@ class WirelessNetworkCard(val owner: TileEntity) extends NetworkCard {
@LuaCallback("setStrength")
def setStrength(context: Context, args: Arguments): Array[AnyRef] = {
strength = args.checkDouble(0) max 0 min Settings.get.maxWirelessRange
strength = math.max(args.checkDouble(0), math.min(0, Settings.get.maxWirelessRange))
result(strength)
}

View File

@ -80,17 +80,17 @@ class Inventory(player: Player) extends InventoryPlayer(player) {
val existing = getStackInSlot(slot)
existing != null && existing.isItemEqual(stack) &&
(!existing.getHasSubtypes || existing.getItemDamage == stack.getItemDamage) &&
(existing.stackSize < (existing.getMaxStackSize min getInventoryStackLimit))
(existing.stackSize < math.min(existing.getMaxStackSize, getInventoryStackLimit))
}).getOrElse(getFirstEmptyStackAccepting(stack))
if (slot >= firstInventorySlot) {
if (getStackInSlot(slot) == null) {
val amount = stack.stackSize min (getInventoryStackLimit min stack.getMaxStackSize)
val amount = math.min(stack.stackSize, math.min(getInventoryStackLimit, stack.getMaxStackSize))
setInventorySlotContents(slot, stack.splitStack(amount))
}
else {
val existing = getStackInSlot(slot)
val space = (getInventoryStackLimit min existing.getMaxStackSize) - existing.stackSize
val amount = stack.stackSize min space
val space = math.min(getInventoryStackLimit, existing.getMaxStackSize) - existing.stackSize
val amount = math.min(stack.stackSize, space)
existing.stackSize += amount
stack.stackSize -= amount
}

View File

@ -153,7 +153,7 @@ class Player(val robot: Robot) extends EntityPlayer(robot.world, Settings.get.na
(!PortalGun.isPortalGun(stack) || PortalGun.isStandardPortalGun(stack)) && {
val oldSize = stack.stackSize
val oldDamage = if (stack != null) stack.getItemDamage else 0
val heldTicks = 0 max stack.getMaxItemUseDuration min (duration * 20).toInt
val heldTicks = math.max(0, math.min(stack.getMaxItemUseDuration, (duration * 20).toInt))
val newStack = stack.useItemRightClick(world, this)
if (isUsingItem) {
getItemInUse.onPlayerStoppedUsing(world, this, getItemInUse.getMaxItemUseDuration - heldTicks)
@ -270,7 +270,7 @@ class Player(val robot: Robot) extends EntityPlayer(robot.world, Settings.get.na
if (stack != null) {
robot.addXp(Settings.get.robotActionXp)
}
return (breakTime * Settings.get.harvestRatio * ((1 - robot.level * Settings.get.harvestSpeedBoostPerLevel) max 0)) max 0.05
return math.max(breakTime * Settings.get.harvestRatio * math.max(1 - robot.level * Settings.get.harvestSpeedBoostPerLevel, 0), 0.05)
}
0
}
@ -280,13 +280,13 @@ class Player(val robot: Robot) extends EntityPlayer(robot.world, Settings.get.na
private def tryRepair(stack: ItemStack, oldDamage: Int) {
val needsRepairing = stack.isItemStackDamageable && stack.getItemDamage > oldDamage
val damageRate = Settings.get.itemDamageRate * ((1 - robot.level * Settings.get.toolEfficiencyPerLevel) max 0)
val damageRate = Settings.get.itemDamageRate * math.max(1 - robot.level * Settings.get.toolEfficiencyPerLevel, 0)
val shouldRepair = needsRepairing && getRNG.nextDouble() >= damageRate
if (shouldRepair) {
// If an item takes a lot of damage at once we don't necessarily want to
// make *all* of that damage go away. Instead we scale it according to
// our damage probability. This makes sure we don't discard massive
// damage spikes (e.g. on axes when using the treecapitator mod or such).
// damage spikes (e.g. on axes when using the TreeCapitator mod or such).
val addedDamage = ((stack.getItemDamage - oldDamage) * damageRate).toInt
stack.setItemDamage(oldDamage + addedDamage)
}

View File

@ -277,7 +277,7 @@ trait VirtualFileSystem extends OutputStreamFileSystem {
override def available() =
if (isClosed) 0
else (file.data.length - position) max 0
else math.max(file.data.length - position, 0)
override def close() = isClosed = true
@ -293,9 +293,10 @@ trait VirtualFileSystem extends OutputStreamFileSystem {
override def read(b: Array[Byte], off: Int, len: Int) =
if (!isClosed) {
if (available == 0) -1
val count = available()
if (count == 0) -1
else {
val n = len min available
val n = math.min(len, count)
file.data.view(position, file.data.length).copyToArray(b, off, n)
position += n
n
@ -311,7 +312,7 @@ trait VirtualFileSystem extends OutputStreamFileSystem {
override def skip(n: Long) =
if (!isClosed) {
position = ((position + n) min Int.MaxValue).toInt
position = math.min((position + n).toInt, Int.MaxValue)
position
}
else throw new io.IOException("file is closed")

View File

@ -85,7 +85,7 @@ object ZipFileInputStreamFileSystem {
var root: ArchiveDirectory = null
for (entry <- directories ++ files) {
if (entry.path.length > 0) {
val parent = entry.path.substring(0, entry.path.lastIndexOf('/') max 0)
val parent = entry.path.substring(0, math.max(entry.path.lastIndexOf('/'), 0))
directories.find(d => d.path == parent) match {
case Some(directory) => directory.children += entry
case _ =>

View File

@ -13,8 +13,6 @@ trait Connector extends Node with network.Connector with Persistable {
var localBuffer = 0.0
var dirty = true
private var distributor: Option[PowerDistributor] = None
// ----------------------------------------------------------------------- //
@ -26,18 +24,21 @@ trait Connector extends Node with network.Connector with Persistable {
// ----------------------------------------------------------------------- //
def changeBuffer(delta: Double): Double = {
if (delta == 0) {
return 0
if (delta == 0) 0
else if (Settings.get.ignorePower) {
if (delta < 0) 0
else /* if (delta > 0) */ delta
}
if (Settings.get.ignorePower) {
if (delta < 0) {
return 0
}
else /* if (delta > 0) */ {
return delta
else {
this.synchronized(distributor match {
case Some(d) => d.synchronized(d.changeBuffer(change(delta)))
case _ => change(delta)
})
}
}
def change() = {
private def change(delta: Double): Double = {
if (localBufferSize <= 0) return delta
val oldBuffer = localBuffer
localBuffer += delta
val remaining = if (localBuffer < 0) {
@ -51,27 +52,19 @@ trait Connector extends Node with network.Connector with Persistable {
remaining
}
else 0
dirty ||= (localBuffer != oldBuffer)
remaining
}
if (localBuffer != oldBuffer) {
this.synchronized(distributor match {
case Some(d) => d.synchronized(d.changeBuffer(change()))
case _ => change()
case Some(d) => d.dirty = true
case _ =>
})
}
remaining
}
def tryChangeBuffer(delta: Double): Boolean = {
if (delta == 0) {
return true
}
if (Settings.get.ignorePower) {
if (delta < 0) {
return true
}
else /* if (delta > 0) */ {
return false
}
}
if (delta == 0) true
else if (Settings.get.ignorePower) delta < 0
else {
this.synchronized(distributor match {
case Some(d) => d.synchronized {
val newGlobalBuffer = globalBuffer + delta
@ -88,18 +81,19 @@ trait Connector extends Node with network.Connector with Persistable {
}
})
}
}
def setLocalBufferSize(size: Double) {
this.synchronized(distributor match {
case Some(d) => d.synchronized {
localBufferSize = size max 0
val surplus = (localBuffer - localBufferSize) max 0
localBuffer = localBuffer min localBufferSize
localBufferSize = math.max(size, 0)
val surplus = math.max(localBuffer - localBufferSize, 0)
localBuffer = math.min(localBuffer, localBufferSize)
d.changeBuffer(surplus)
}
case _ =>
localBufferSize = size max 0
localBuffer = localBuffer min localBufferSize
localBufferSize = math.max(size, 0)
localBuffer = math.min(localBuffer, localBufferSize)
})
}
@ -137,8 +131,7 @@ trait Connector extends Node with network.Connector with Persistable {
override def load(nbt: NBTTagCompound) {
super.load(nbt)
localBuffer = nbt.getDouble("buffer") max 0 min localBufferSize
dirty = true
localBuffer = math.max(nbt.getDouble("buffer"), math.min(0, localBufferSize))
}
override def save(nbt: NBTTagCompound) {

View File

@ -220,15 +220,15 @@ object LuaStateFactory {
state.pushScalaFunction(lua => {
val string = lua.checkString(1)
val start = (lua.checkInteger(2) match {
val start = math.max(0, lua.checkInteger(2) match {
case i if i < 0 => string.length + i
case i => i - 1
}) max 0
})
val end =
if (lua.getTop > 2) (lua.checkInteger(3) match {
if (lua.getTop > 2) math.min(string.length, lua.checkInteger(3) match {
case i if i < 0 => string.length + i + 1
case i => i
}) min string.length
})
else string.length
if (end <= start) lua.pushString("")
else lua.pushString(string.substring(start, end))

View File

@ -8,7 +8,7 @@ class RTree[Data](private val M: Int)(implicit val coordinate: Data => (Double,
// Used for quick checks whether values are in the tree, e.g. for updates.
private val entries = mutable.Map.empty[Data, Leaf]
private val m = (M / 2) max 1
private val m = math.max(M / 2, 1)
private var root = new NonLeaf()
@ -215,7 +215,7 @@ class RTree[Data](private val M: Int)(implicit val coordinate: Data => (Double,
val newVol2 = r2.volumeIncluding(value)
val growth1 = newVol1 - r1.volume
val growth2 = newVol2 - r2.volume
val d = (growth2 - growth1).abs
val d = math.abs(growth2 - growth1)
if (d > best) {
bestValue = Some(value)
r = if (growth1 < growth2 || (growth1 == growth2 && newVol1 < newVol2)) r1 else r2
@ -263,9 +263,9 @@ class RTree[Data](private val M: Int)(implicit val coordinate: Data => (Double,
private class Point(val x: Double, val y: Double, val z: Double) {
def this(p: (Double, Double, Double)) = this(p._1, p._2, p._3)
def min(other: Point) = new Point(x min other.x, y min other.y, z min other.z)
def min(other: Point) = new Point(math.min(x, other.x), math.min(y, other.y), math.min(z, other.z))
def max(other: Point) = new Point(x max other.x, y max other.y, z max other.z)
def max(other: Point) = new Point(math.max(x, other.x), math.max(y, other.y), math.max(z, other.z))
def asTuple = (x, y, z)
}

View File

@ -71,13 +71,13 @@ class TextBuffer(var width: Int, var height: Int, initialDepth: PackedColor.Dept
*/
def size_=(value: (Int, Int)): Boolean = {
val (iw, ih) = value
val (w, h) = (iw max 1, ih max 1)
val (w, h) = (math.max(iw, 1), math.max(ih, 1))
if (width != w || height != h) {
val newBuffer = Array.fill(h, w)(' ')
val newColor = Array.fill(h, w)(packed)
(0 until (h min height)).foreach(y => {
Array.copy(buffer(y), 0, newBuffer(y), 0, w min width)
Array.copy(color(y), 0, newColor(y), 0, w min width)
(0 until math.min(h, height)).foreach(y => {
Array.copy(buffer(y), 0, newBuffer(y), 0, math.min(w, width))
Array.copy(color(y), 0, newColor(y), 0, math.min(w, width))
})
buffer = newBuffer
color = newColor
@ -98,7 +98,7 @@ class TextBuffer(var width: Int, var height: Int, initialDepth: PackedColor.Dept
var changed = false
val line = buffer(row)
val lineColor = color(row)
for (x <- col until ((col + s.length) min width)) if (x >= 0) {
for (x <- col until math.min(col + s.length, width)) if (x >= 0) {
val c = s(x - col)
changed = changed || (line(x) != c) || (lineColor(x) != packed)
line(x) = c
@ -113,10 +113,10 @@ class TextBuffer(var width: Int, var height: Int, initialDepth: PackedColor.Dept
if (w <= 0 || h <= 0) return false
if (col + w < 0 || row + h < 0 || col >= width || row >= height) return false
var changed = false
for (y <- (row max 0) until ((row + h) min height)) {
for (y <- math.max(row, 0) until math.min(row + h, height)) {
val line = buffer(y)
val lineColor = color(y)
for (x <- (col max 0) until ((col + w) min width)) {
for (x <- math.max(col, 0) until math.min(col + w, width)) {
changed = changed || (line(x) != c) || (lineColor(x) != packed)
line(x) = c
lineColor(x) = packed
@ -133,11 +133,11 @@ class TextBuffer(var width: Int, var height: Int, initialDepth: PackedColor.Dept
// Loop over the target rectangle, starting from the directions away from
// the source rectangle and copy the data. This way we ensure we don't
// overwrite anything we still need to copy.
val (dx0, dx1) = ((col + tx + w - 1) max 0 min (width - 1), (col + tx) max 0 min width) match {
val (dx0, dx1) = (math.max(col + tx + w - 1, math.min(0, width - 1)), math.max(col + tx, math.min(0, width))) match {
case dx if tx > 0 => dx
case dx => dx.swap
}
val (dy0, dy1) = ((row + ty + h - 1) max 0 min (height - 1), (row + ty) max 0 min height) match {
val (dy0, dy1) = (math.max(row + ty + h - 1, math.min(0, height - 1)), math.max(row + ty, math.min(0, height))) match {
case dy if ty > 0 => dy
case dy => dy.swap
}
@ -170,7 +170,7 @@ class TextBuffer(var width: Int, var height: Int, initialDepth: PackedColor.Dept
size = (w, h)
val b = nbt.getTagList("buffer")
for (i <- 0 until (h min b.tagCount)) {
for (i <- 0 until math.min(h, b.tagCount)) {
val line = b.tagAt(i).asInstanceOf[NBTTagString].data
set(0, i, line)
}

View File

@ -33,10 +33,9 @@ object WirelessNetwork {
case Some(tree) =>
tree(card) match {
case Some((x, y, z)) =>
val (dx, dy, dz) = (
(card.owner.xCoord + 0.5 - x).abs,
(card.owner.yCoord + 0.5 - y).abs,
(card.owner.zCoord + 0.5 - z).abs)
val dx = math.abs(card.owner.xCoord + 0.5 - x)
val dy = math.abs(card.owner.yCoord + 0.5 - y)
val dz = math.abs(card.owner.zCoord + 0.5 - z)
if (dx > 0.5 || dy > 0.5 || dz > 0.5) {
tree.remove(card)
tree.add(card)