added power consumption for hologram projector; added scale setting, so hologram can be from 1x1x1 up to 9x6x9, higher scale consumes more energy

This commit is contained in:
Florian Nücke 2014-02-27 03:25:27 +01:00
parent e04a8767d6
commit c3e9ed1e97
9 changed files with 79 additions and 23 deletions

View File

@ -120,6 +120,7 @@ class Settings(config: Config) {
val robotCost = config.getDouble("power.cost.robot") max 0
val sleepCostFactor = config.getDouble("power.cost.sleepFactor") max 0
val screenCost = config.getDouble("power.cost.screen") max 0
val hologramCost = config.getDouble("power.cost.hologram") max 0
val hddReadCost = (config.getDouble("power.cost.hddRead") max 0) / 1024
val hddWriteCost = (config.getDouble("power.cost.hddWrite") max 0) / 1024
val gpuSetCost = (config.getDouble("power.cost.gpuSet") max 0) / Settings.basicScreenPixels

View File

@ -26,6 +26,7 @@ class PacketHandler extends CommonPacketHandler {
case PacketType.ChargerState => onChargerState(p)
case PacketType.ComputerState => onComputerState(p)
case PacketType.ComputerUserList => onComputerUserList(p)
case PacketType.HologramScale => onHologramScale(p)
case PacketType.HologramSet => onHologramSet(p)
case PacketType.PowerState => onPowerState(p)
case PacketType.RedstoneState => onRedstoneState(p)
@ -101,6 +102,14 @@ class PacketHandler extends CommonPacketHandler {
case _ => // Invalid packet.
}
def onHologramScale(p: PacketParser) =
p.readTileEntity[Hologram]() match {
case Some(t) =>
t.scale = p.readDouble()
t.dirty = true
case _ => // Invalid packet.
}
def onHologramSet(p: PacketParser) =
p.readTileEntity[Hologram]() match {
case Some(t) =>

View File

@ -40,6 +40,7 @@ object CableRenderer extends TileEntitySpecialRenderer {
for (mask <- 0 to 0xFF >> 2) {
GL11.glNewList(displayLists + mask, GL11.GL_COMPILE)
t.startDrawingQuads()
for (side <- ForgeDirection.VALID_DIRECTIONS) {
val connects = (side.flag & mask) != 0
val z = if (connects) 0 else lb
@ -48,7 +49,6 @@ object CableRenderer extends TileEntitySpecialRenderer {
exists(s => (s.flag & mask) != 0)) uo
else 0
t.startDrawingQuads()
t.setNormal(side.offsetX, side.offsetY, -side.offsetZ)
val (tx, ty, tz, u, v) = side match {
case ForgeDirection.WEST => (Array.fill(4)(z), t2, t1, uv1.reverse, uv2)
@ -63,7 +63,6 @@ object CableRenderer extends TileEntitySpecialRenderer {
t.addVertexWithUV(tx(1), ty(1), tz(1), u(1) + uc, v(1))
t.addVertexWithUV(tx(2), ty(2), tz(2), u(2) + uc, v(2))
t.addVertexWithUV(tx(3), ty(3), tz(3), u(3) + uc, v(3))
t.draw()
if (connects) {
val (axis, sign, uv1, uv2, uv3, uv4) = side match {
@ -79,39 +78,32 @@ object CableRenderer extends TileEntitySpecialRenderer {
val o1 = offsets((axis + sign + 3) % 3)
val o2 = offsets((axis - sign + 3) % 3)
t.startDrawingQuads()
normal(side, 0)
t.addVertexWithUV(tx(0) - sign * tl(0), ty(0) - sign * tl(1), tz(0) - sign * tl(2), u(uv(0 + uv1)) + uo, v(uv(0 + uv1)) * vs)
t.addVertexWithUV(tx(1) - sign * tl(0), ty(1) - sign * tl(1), tz(1) - sign * tl(2), u(uv(1 + uv1)) + uo, v(uv(1 + uv1)) * vs)
t.addVertexWithUV(tx(2) + o1(0), ty(2) + o1(1), tz(2) + o1(2), u(uv(2 + uv1)) + uo, v(uv(2 + uv1)) * vs)
t.addVertexWithUV(tx(3) + o1(0), ty(3) + o1(1), tz(3) + o1(2), u(uv(3 + uv1)) + uo, v(uv(3 + uv1)) * vs)
t.draw()
t.startDrawingQuads()
normal(side, 1)
t.addVertexWithUV(tx(0) - o1(0), ty(0) - o1(1), tz(0) - o1(2), u(uv(0 + uv2)) + uo, v(uv(0 + uv2)) * vs)
t.addVertexWithUV(tx(1) - o1(0), ty(1) - o1(1), tz(1) - o1(2), u(uv(1 + uv2)) + uo, v(uv(1 + uv2)) * vs)
t.addVertexWithUV(tx(2) - sign * tl(0), ty(2) - sign * tl(1), tz(2) - sign * tl(2), u(uv(2 + uv2)) + uo, v(uv(2 + uv2)) * vs)
t.addVertexWithUV(tx(3) - sign * tl(0), ty(3) - sign * tl(1), tz(3) - sign * tl(2), u(uv(3 + uv2)) + uo, v(uv(3 + uv2)) * vs)
t.draw()
t.startDrawingQuads()
normal(side, 2)
t.addVertexWithUV(tx(0) - sign * tl(0), ty(0) - sign * tl(1), tz(0) - sign * tl(2), u(uv(0 + uv3)) + uo, v(uv(0 + uv3)) * vs)
t.addVertexWithUV(tx(1) - o2(0), ty(1) - o2(1), tz(1) - o2(2), u(uv(1 + uv3)) + uo, v(uv(1 + uv3)) * vs)
t.addVertexWithUV(tx(2) - o2(0), ty(2) - o2(1), tz(2) - o2(2), u(uv(2 + uv3)) + uo, v(uv(2 + uv3)) * vs)
t.addVertexWithUV(tx(3) - sign * tl(0), ty(3) - sign * tl(1), tz(3) - sign * tl(2), u(uv(3 + uv3)) + uo, v(uv(3 + uv3)) * vs)
t.draw()
t.startDrawingQuads()
normal(side, 3)
t.addVertexWithUV(tx(0) + o2(0), ty(0) + o2(1), tz(0) + o2(2), u(uv(0 + uv4)) + uo, v(uv(0 + uv4)) * vs)
t.addVertexWithUV(tx(1) - sign * tl(0), ty(1) - sign * tl(1), tz(1) - sign * tl(2), u(uv(1 + uv4)) + uo, v(uv(1 + uv4)) * vs)
t.addVertexWithUV(tx(2) - sign * tl(0), ty(2) - sign * tl(1), tz(2) - sign * tl(2), u(uv(2 + uv4)) + uo, v(uv(2 + uv4)) * vs)
t.addVertexWithUV(tx(3) + o2(0), ty(3) + o2(1), tz(3) + o2(2), u(uv(3 + uv4)) + uo, v(uv(3 + uv4)) * vs)
t.draw()
}
}
t.draw()
GL11.glEndList()
}

View File

@ -28,15 +28,16 @@ object HologramRenderer extends TileEntitySpecialRenderer with Callable[Int] wit
override def renderTileEntityAt(te: TileEntity, x: Double, y: Double, z: Double, f: Float) {
hologram = te.asInstanceOf[Hologram]
if (!hologram.hasPower) return
GL11.glPushAttrib(0xFFFFFFFF)
RenderState.makeItBlend()
GL11.glPushMatrix()
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
GL11.glScaled(1.001, 1.001, 1.001) // Avoid z-fighting with other blocks.
GL11.glTranslated(-1.5 * hologram.scale, 0, -1.5 * hologram.scale)
GL11.glScaled(1.01, 1.01, 1.01) // Avoid z-fighting with other blocks.
GL11.glTranslated(x - 1, y + 0.5, z - 1)
// Do a bit of flickering, because that's what holograms do!
if (random.nextDouble() < 0.025) {
GL11.glScaled(1 + random.nextGaussian() * 0.01, 1 + random.nextGaussian() * 0.001, 1 + random.nextGaussian() * 0.01)
GL11.glTranslated(random.nextGaussian() * 0.01, random.nextGaussian() * 0.01, random.nextGaussian() * 0.01)
@ -68,9 +69,9 @@ object HologramRenderer extends TileEntitySpecialRenderer with Callable[Int] wit
bindTexture(TexturePreloader.blockHologram)
val t = Tessellator.instance
t.startDrawingQuads()
t.setColorRGBA_F(1, 1, 1, 0.7f)
t.setColorRGBA_F(1, 1, 1, 0.5f)
val s = 1f / 16f
val s = 1f / 16f * hologram.scale
for (hx <- 0 until hologram.width) {
val wx = hx * s
for (hz <- 0 until hologram.width) {

View File

@ -8,6 +8,7 @@ object PacketType extends Enumeration {
ChargerState,
ComputerState,
ComputerUserList,
HologramScale,
HologramSet,
PowerState,
RedstoneState,

View File

@ -20,12 +20,20 @@ class Hologram extends Environment with SidedEnvironment {
val volume = new Array[Int](width * width)
// Render scale.
var scale = 1.0
// Relative number of lit columns (for energy cost).
var litRatio = -1.0
// Whether we need to send an update packet/recompile our display list.
var dirty = false
// Time to wait before sending another update packet.
var cooldown = 0
var hasPower = true
// ----------------------------------------------------------------------- //
override def canConnect(side: ForgeDirection) = side != ForgeDirection.UP
@ -38,6 +46,7 @@ class Hologram extends Environment with SidedEnvironment {
def clear(computer: Context, args: Arguments): Array[AnyRef] = this.synchronized {
for (i <- 0 until volume.length) volume(i) = 0
dirty = true
litRatio = 0
null
}
@ -55,6 +64,7 @@ class Hologram extends Environment with SidedEnvironment {
val value = args.checkInteger(2)
volume(x + z * width) = value
dirty = true
litRatio = -1
null
}
@ -67,6 +77,19 @@ class Hologram extends Environment with SidedEnvironment {
// manually check the height, to avoid the shift being a no-op.
volume(x + z * width) = if (height > 0) 0xFFFFFFFF >>> (32 - height) else 0
dirty = true
litRatio = -1
null
}
@Callback(doc = """function():number -- Returns the render scale of the hologram.""")
def getScale(computer: Context, args: Arguments): Array[AnyRef] = {
result(scale)
}
@Callback(doc = """function(value:number) -- Set the render scale. A larger scale consumes more energy.""")
def setScale(computer: Context, args: Arguments): Array[AnyRef] = {
scale = math.max(0.333333, math.min(3, args.checkDouble(0)))
ServerPacketSender.sendHologramScale(this)
null
}
@ -74,13 +97,24 @@ class Hologram extends Environment with SidedEnvironment {
override def updateEntity() {
super.updateEntity()
if (isServer && dirty) {
cooldown -= 1
if (cooldown <= 0) {
dirty = false
cooldown = 10
ServerPacketSender.sendHologramSet(this)
if (isServer) {
if (dirty) {
cooldown -= 1
if (cooldown <= 0) {
dirty = false
cooldown = 10
ServerPacketSender.sendHologramSet(this)
}
}
if (litRatio < 0) {
litRatio = 0
for (i <- 0 until volume.length) {
if (volume(i) != 0) litRatio += 1
}
litRatio /= volume.length
}
hasPower = node.changeBuffer(-Settings.get.hologramCost * litRatio * scale) == 0
}
}
@ -88,29 +122,33 @@ class Hologram extends Environment with SidedEnvironment {
override def shouldRenderInPass(pass: Int) = pass == 1
override def getRenderBoundingBox = AxisAlignedBB.getAABBPool.getAABB(xCoord - 1, yCoord, zCoord - 1, xCoord + 2, yCoord + 2.25, zCoord + 2)
override def getRenderBoundingBox = AxisAlignedBB.getAABBPool.getAABB(xCoord + 0.5 - 1.5 * scale, yCoord, zCoord - scale, xCoord + 0.5 + 1.5 * scale, yCoord + 0.25 + 2 * scale, zCoord + 0.5 + 1.5 * scale)
// ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
nbt.getIntArray(Settings.namespace + "volume").copyToArray(volume)
scale = nbt.getDouble(Settings.namespace + "scale")
}
override def writeToNBT(nbt: NBTTagCompound) = this.synchronized {
super.writeToNBT(nbt)
nbt.setIntArray(Settings.namespace + "volume", volume)
nbt.setDouble(Settings.namespace + "scale", scale)
}
@SideOnly(Side.CLIENT)
override def readFromNBTForClient(nbt: NBTTagCompound) {
super.readFromNBTForClient(nbt)
nbt.getIntArray("volume").copyToArray(volume)
scale = nbt.getDouble("scale")
dirty = true
}
override def writeToNBTForClient(nbt: NBTTagCompound) {
super.writeToNBTForClient(nbt)
nbt.setIntArray("volume", volume)
nbt.setDouble("scale", scale)
}
}

View File

@ -55,6 +55,15 @@ object PacketSender {
pb.sendToNearbyPlayers(t)
}
def sendHologramScale(t: Hologram) {
val pb = new PacketBuilder(PacketType.HologramScale)
pb.writeTileEntity(t)
pb.writeDouble(t.scale)
pb.sendToNearbyPlayers(t)
}
def sendHologramSet(t: Hologram) {
val pb = new PacketBuilder(PacketType.HologramSet)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 B

After

Width:  |  Height:  |  Size: 157 B

View File

@ -471,6 +471,11 @@ opencomputers {
# tick.
screen: 0.05
# The amount of energy a hologram projetor consumes per tick. This
# is the cost if every column is lit. If not a single voxel is
# displayed the hologram projector will not drain energy.
hologram: 0.2
# Energy it takes read one kilobyte from a file system. Note that non
# I/O operations on file systems such as `list` or `getFreeSpace` do
# *not* consume power. Note that this very much determines how much