Showing indicator for disk activity on disk drives, cases and server racks.
@ -2,11 +2,13 @@ package li.cil.oc.api.event;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.Cancelable;
|
||||
import cpw.mods.fml.common.eventhandler.Event;
|
||||
import li.cil.oc.api.network.Node;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* Fired on the <em>client side only</em>, signals file system access.
|
||||
* Events for handling file system access and representing it on the client.
|
||||
* <p/>
|
||||
* This is used to play file system access sounds and render disk activity
|
||||
* indicators on some containers (e.g. disk drive, computer, server).
|
||||
@ -19,52 +21,35 @@ import net.minecraft.world.World;
|
||||
*/
|
||||
@Cancelable
|
||||
public class FileSystemAccessEvent extends Event {
|
||||
/**
|
||||
* The name of the sound effect to play for the file system.
|
||||
*/
|
||||
public final String sound;
|
||||
protected String sound;
|
||||
|
||||
/**
|
||||
* The world the file system lives in.
|
||||
*/
|
||||
public final World world;
|
||||
protected World world;
|
||||
|
||||
/**
|
||||
* The x coordinate of the file system's container.
|
||||
*/
|
||||
public final double x;
|
||||
protected double x;
|
||||
|
||||
/**
|
||||
* The y coordinate of the file system's container.
|
||||
*/
|
||||
public final double y;
|
||||
protected double y;
|
||||
|
||||
/**
|
||||
* The z coordinate of the file system's container.
|
||||
*/
|
||||
public final double z;
|
||||
protected double z;
|
||||
|
||||
/**
|
||||
* The tile entity hosting the file system.
|
||||
* <p/>
|
||||
* <em>Important</em>: this can be <tt>null</tt>, which is usually the
|
||||
* case when the container is an entity or item.
|
||||
*/
|
||||
public final TileEntity tileEntity;
|
||||
protected TileEntity tileEntity;
|
||||
|
||||
protected NBTTagCompound data;
|
||||
|
||||
/**
|
||||
* Constructor for tile entity hosted file systems.
|
||||
*
|
||||
* @param sound the name of the sound effect to play.
|
||||
* @param tileEntity the tile entity hosting the file system.
|
||||
* @param data the additional data.
|
||||
*/
|
||||
public FileSystemAccessEvent(String sound, TileEntity tileEntity) {
|
||||
protected FileSystemAccessEvent(String sound, TileEntity tileEntity, NBTTagCompound data) {
|
||||
this.sound = sound;
|
||||
this.world = tileEntity.getWorldObj();
|
||||
this.x = tileEntity.xCoord + 0.5;
|
||||
this.y = tileEntity.yCoord + 0.5;
|
||||
this.z = tileEntity.zCoord + 0.5;
|
||||
this.tileEntity = tileEntity;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,13 +60,116 @@ public class FileSystemAccessEvent extends Event {
|
||||
* @param x the x coordinate of the file system's container.
|
||||
* @param y the y coordinate of the file system's container.
|
||||
* @param z the z coordinate of the file system's container.
|
||||
* @param data the additional data.
|
||||
*/
|
||||
public FileSystemAccessEvent(String sound, World world, double x, double y, double z) {
|
||||
protected FileSystemAccessEvent(String sound, World world, double x, double y, double z, NBTTagCompound data) {
|
||||
this.sound = sound;
|
||||
this.world = world;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.tileEntity = null;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the sound effect to play for the file system.
|
||||
*/
|
||||
public String getSound() {
|
||||
return sound;
|
||||
}
|
||||
|
||||
/**
|
||||
* The world the file system lives in.
|
||||
*/
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
/**
|
||||
* The x coordinate of the file system's container.
|
||||
*/
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* The y coordinate of the file system's container.
|
||||
*/
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* The z coordinate of the file system's container.
|
||||
*/
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* The tile entity hosting the file system.
|
||||
* <p/>
|
||||
* <em>Important</em>: this can be <tt>null</tt>, which is usually the
|
||||
* case when the container is an entity or item.
|
||||
*/
|
||||
public TileEntity getTileEntity() {
|
||||
return tileEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Addition custom data, this is used to transmit the number of the server
|
||||
* in a server rack the file system lives in, for example.
|
||||
*/
|
||||
public NBTTagCompound getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public static final class Server extends FileSystemAccessEvent {
|
||||
private Node node;
|
||||
|
||||
public Server(String sound, TileEntity tileEntity, Node node) {
|
||||
super(sound, tileEntity, new NBTTagCompound());
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public Server(String sound, World world, double x, double y, double z, Node node) {
|
||||
super(sound, world, x, y, z, new NBTTagCompound());
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* The node of the file system that signalled activity.
|
||||
*/
|
||||
public Node getNode() {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Client extends FileSystemAccessEvent {
|
||||
/**
|
||||
* Constructor for tile entity hosted file systems.
|
||||
*
|
||||
* @param sound the name of the sound effect to play.
|
||||
* @param tileEntity the tile entity hosting the file system.
|
||||
* @param data the additional data.
|
||||
*/
|
||||
public Client(String sound, TileEntity tileEntity, NBTTagCompound data) {
|
||||
super(sound, tileEntity, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for arbitrarily hosted file systems.
|
||||
*
|
||||
* @param sound the name of the sound effect to play.
|
||||
* @param world the world the file system lives in.
|
||||
* @param x the x coordinate of the file system's container.
|
||||
* @param y the y coordinate of the file system's container.
|
||||
* @param z the z coordinate of the file system's container.
|
||||
* @param data the additional data.
|
||||
*/
|
||||
public Client(String sound, World world, double x, double y, double z, NBTTagCompound data) {
|
||||
super(sound, world, x, y, z, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,11 +52,12 @@ local result, reason = os.execute("/bin/cp -vr /mnt/" .. boot .. "/* /mnt/" .. m
|
||||
if not result then
|
||||
error(reason, 0)
|
||||
end
|
||||
computer.setBootAddress(choice.address)
|
||||
choice.setLabel("OpenOS")
|
||||
|
||||
print("All done! Would you like to reboot now? [Y/n]")
|
||||
print("All done! Set as boot device and reboot now? [Y/n]")
|
||||
local result = io.read()
|
||||
if not result or result == "" or result:sub(1, 1):lower() == "y" then
|
||||
computer.setBootAddress(choice.address)
|
||||
print("\nRebooting now!")
|
||||
computer.shutdown(true)
|
||||
end
|
||||
|
Before Width: | Height: | Size: 624 B After Width: | Height: | Size: 623 B |
After Width: | Height: | Size: 150 B |
Before Width: | Height: | Size: 504 B After Width: | Height: | Size: 570 B |
After Width: | Height: | Size: 150 B |
Before Width: | Height: | Size: 488 B After Width: | Height: | Size: 558 B |
After Width: | Height: | Size: 149 B |
@ -17,6 +17,7 @@ import li.cil.oc.util.Audio
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.GuiScreen
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.nbt.CompressedStreamTools
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
import org.lwjgl.input.Keyboard
|
||||
@ -145,9 +146,10 @@ object PacketHandler extends CommonPacketHandler {
|
||||
|
||||
def onFileSystemActivity(p: PacketParser) = {
|
||||
val sound = p.readUTF()
|
||||
val data = CompressedStreamTools.read(p)
|
||||
if (p.readBoolean()) p.readTileEntity[net.minecraft.tileentity.TileEntity]() match {
|
||||
case Some(t) =>
|
||||
MinecraftForge.EVENT_BUS.post(new FileSystemAccessEvent(sound, t))
|
||||
MinecraftForge.EVENT_BUS.post(new FileSystemAccessEvent.Client(sound, t, data))
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
else world(p.player, p.readInt()) match {
|
||||
@ -155,7 +157,7 @@ object PacketHandler extends CommonPacketHandler {
|
||||
val x = p.readDouble()
|
||||
val y = p.readDouble()
|
||||
val z = p.readDouble()
|
||||
MinecraftForge.EVENT_BUS.post(new FileSystemAccessEvent(sound, world, x, y, z))
|
||||
MinecraftForge.EVENT_BUS.post(new FileSystemAccessEvent.Client(sound, world, x, y, z, data))
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import li.cil.oc.client.renderer.block.BlockRenderer
|
||||
import li.cil.oc.client.renderer.item.ItemRenderer
|
||||
import li.cil.oc.client.renderer.tileentity._
|
||||
import li.cil.oc.common.component.TextBuffer
|
||||
import li.cil.oc.common.event.FileAccessHandler
|
||||
import li.cil.oc.common.event.FileSystemAccessHandler
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.common.tileentity.ServerRack
|
||||
@ -61,7 +61,7 @@ private[oc] class Proxy extends CommonProxy {
|
||||
ClientRegistry.registerKeyBinding(KeyBindings.materialCosts)
|
||||
ClientRegistry.registerKeyBinding(KeyBindings.clipboardPaste)
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(FileAccessHandler)
|
||||
MinecraftForge.EVENT_BUS.register(FileSystemAccessHandler)
|
||||
MinecraftForge.EVENT_BUS.register(PetRenderer)
|
||||
MinecraftForge.EVENT_BUS.register(ServerRack)
|
||||
MinecraftForge.EVENT_BUS.register(TextBuffer)
|
||||
|
@ -30,8 +30,11 @@ object Textures {
|
||||
val guiSlot = new ResourceLocation(Settings.resourceDomain, "textures/gui/slot.png")
|
||||
|
||||
val blockCaseFrontOn = new ResourceLocation(Settings.resourceDomain, "textures/blocks/CaseFrontOn.png")
|
||||
val blockCaseFrontActivity = new ResourceLocation(Settings.resourceDomain, "textures/blocks/CaseFrontActivity.png")
|
||||
val blockDiskDriveFrontActivity = new ResourceLocation(Settings.resourceDomain, "textures/blocks/DiskDriveFrontActivity.png")
|
||||
val blockHologram = new ResourceLocation(Settings.resourceDomain, "textures/blocks/HologramEffect.png")
|
||||
val blockRackFrontOn = new ResourceLocation(Settings.resourceDomain, "textures/blocks/ServerRackFrontOn.png")
|
||||
val blockRackFrontActivity = new ResourceLocation(Settings.resourceDomain, "textures/blocks/ServerRackFrontActivity.png")
|
||||
val blockRobot = new ResourceLocation(Settings.resourceDomain, "textures/blocks/robot.png")
|
||||
val blockScreenUpIndicator = new ResourceLocation(Settings.resourceDomain, "textures/blocks/screen/up_indicator.png")
|
||||
|
||||
|
@ -14,27 +14,27 @@ object CaseRenderer extends TileEntitySpecialRenderer {
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||
|
||||
val computer = tileEntity.asInstanceOf[Case]
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS)
|
||||
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
RenderState.setBlendAlpha(1)
|
||||
|
||||
GL11.glPushMatrix()
|
||||
|
||||
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
|
||||
|
||||
computer.yaw match {
|
||||
case ForgeDirection.WEST => GL11.glRotatef(-90, 0, 1, 0)
|
||||
case ForgeDirection.NORTH => GL11.glRotatef(180, 0, 1, 0)
|
||||
case ForgeDirection.EAST => GL11.glRotatef(90, 0, 1, 0)
|
||||
case _ => // No yaw.
|
||||
}
|
||||
|
||||
GL11.glTranslatef(-0.5f, 0.5f, 0.501f)
|
||||
GL11.glScalef(1, -1, 1)
|
||||
|
||||
if (computer.isRunning) {
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS)
|
||||
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
RenderState.setBlendAlpha(1)
|
||||
|
||||
GL11.glPushMatrix()
|
||||
|
||||
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
|
||||
|
||||
computer.yaw match {
|
||||
case ForgeDirection.WEST => GL11.glRotatef(-90, 0, 1, 0)
|
||||
case ForgeDirection.NORTH => GL11.glRotatef(180, 0, 1, 0)
|
||||
case ForgeDirection.EAST => GL11.glRotatef(90, 0, 1, 0)
|
||||
case _ => // No yaw.
|
||||
}
|
||||
|
||||
GL11.glTranslatef(-0.5f, 0.5f, 0.501f)
|
||||
GL11.glScalef(1, -1, 1)
|
||||
|
||||
bindTexture(Textures.blockCaseFrontOn)
|
||||
val t = Tessellator.instance
|
||||
t.startDrawingQuads()
|
||||
@ -44,10 +44,21 @@ object CaseRenderer extends TileEntitySpecialRenderer {
|
||||
t.addVertexWithUV(0, 0, 0, 0, 0)
|
||||
t.draw()
|
||||
|
||||
GL11.glPopMatrix()
|
||||
GL11.glPopAttrib()
|
||||
if (System.currentTimeMillis() - computer.lastAccess < 400 && computer.world.rand.nextDouble() > 0.1) {
|
||||
bindTexture(Textures.blockCaseFrontActivity)
|
||||
val t = Tessellator.instance
|
||||
t.startDrawingQuads()
|
||||
t.addVertexWithUV(0, 1, 0, 0, 1)
|
||||
t.addVertexWithUV(1, 1, 0, 1, 1)
|
||||
t.addVertexWithUV(1, 0, 0, 1, 0)
|
||||
t.addVertexWithUV(0, 0, 0, 0, 0)
|
||||
t.draw()
|
||||
}
|
||||
}
|
||||
|
||||
GL11.glPopMatrix()
|
||||
GL11.glPopAttrib()
|
||||
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: leaving")
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
package li.cil.oc.client.renderer.tileentity
|
||||
|
||||
import li.cil.oc.client.Textures
|
||||
import li.cil.oc.common.tileentity.DiskDrive
|
||||
import li.cil.oc.util.RenderState
|
||||
import net.minecraft.client.renderer.OpenGlHelper
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.client.renderer.entity.RenderItem
|
||||
import net.minecraft.client.renderer.entity.RenderManager
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
|
||||
@ -16,39 +18,59 @@ object DiskDriveRenderer extends TileEntitySpecialRenderer {
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||
|
||||
val drive = tileEntity.asInstanceOf[DiskDrive]
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS)
|
||||
|
||||
GL11.glPushMatrix()
|
||||
|
||||
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
|
||||
|
||||
drive.yaw match {
|
||||
case ForgeDirection.WEST => GL11.glRotatef(-90, 0, 1, 0)
|
||||
case ForgeDirection.NORTH => GL11.glRotatef(180, 0, 1, 0)
|
||||
case ForgeDirection.EAST => GL11.glRotatef(90, 0, 1, 0)
|
||||
case _ => // No yaw.
|
||||
}
|
||||
|
||||
drive.items(0) match {
|
||||
case Some(stack) =>
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS)
|
||||
GL11.glPushMatrix()
|
||||
GL11.glTranslatef(0, 3.5f / 16, 9 / 16f)
|
||||
GL11.glRotatef(90, -1, 0, 0)
|
||||
|
||||
val brightness = drive.world.getLightBrightnessForSkyBlocks(drive.x + drive.facing.offsetX, drive.y + drive.facing.offsetY, drive.z + drive.facing.offsetZ, 0)
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, brightness % 65536, brightness / 65536)
|
||||
|
||||
GL11.glPushMatrix()
|
||||
|
||||
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
|
||||
|
||||
drive.yaw match {
|
||||
case ForgeDirection.WEST => GL11.glRotatef(-90, 0, 1, 0)
|
||||
case ForgeDirection.NORTH => GL11.glRotatef(180, 0, 1, 0)
|
||||
case ForgeDirection.EAST => GL11.glRotatef(90, 0, 1, 0)
|
||||
case _ => // No yaw.
|
||||
}
|
||||
|
||||
GL11.glTranslatef(0, 3.5f / 16, 9 / 16f)
|
||||
GL11.glRotatef(90, -1, 0, 0)
|
||||
|
||||
// This is very 'meh', but item frames do it like this, too!
|
||||
val entity = new EntityItem(drive.world, 0, 0, 0, stack)
|
||||
entity.hoverStart = 0
|
||||
RenderItem.renderInFrame = true
|
||||
RenderManager.instance.renderEntityWithPosYaw(entity, 0, 0, 0, 0, 0)
|
||||
RenderItem.renderInFrame = false
|
||||
|
||||
GL11.glPopMatrix()
|
||||
GL11.glPopAttrib()
|
||||
case _ =>
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() - drive.lastAccess < 400 && drive.world.rand.nextDouble() > 0.1) {
|
||||
GL11.glTranslatef(-0.5f, 0.5f, 0.501f)
|
||||
GL11.glScalef(1, -1, 1)
|
||||
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
RenderState.setBlendAlpha(1)
|
||||
|
||||
bindTexture(Textures.blockDiskDriveFrontActivity)
|
||||
val t = Tessellator.instance
|
||||
t.startDrawingQuads()
|
||||
t.addVertexWithUV(0, 1, 0, 0, 1)
|
||||
t.addVertexWithUV(1, 1, 0, 1, 1)
|
||||
t.addVertexWithUV(1, 0, 0, 1, 0)
|
||||
t.addVertexWithUV(0, 0, 0, 0, 0)
|
||||
t.draw()
|
||||
}
|
||||
|
||||
GL11.glPopMatrix()
|
||||
GL11.glPopAttrib()
|
||||
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: leaving")
|
||||
}
|
||||
}
|
@ -14,33 +14,44 @@ object ServerRackRenderer extends TileEntitySpecialRenderer {
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||
|
||||
val rack = tileEntity.asInstanceOf[ServerRack]
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS)
|
||||
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
|
||||
GL11.glPushMatrix()
|
||||
|
||||
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
|
||||
|
||||
rack.yaw match {
|
||||
case ForgeDirection.WEST => GL11.glRotatef(-90, 0, 1, 0)
|
||||
case ForgeDirection.NORTH => GL11.glRotatef(180, 0, 1, 0)
|
||||
case ForgeDirection.EAST => GL11.glRotatef(90, 0, 1, 0)
|
||||
case _ => // No yaw.
|
||||
}
|
||||
|
||||
GL11.glTranslatef(-0.5f, 0.5f, 0.501f)
|
||||
GL11.glScalef(1, -1, 1)
|
||||
|
||||
if (rack.anyRunning) {
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS)
|
||||
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
|
||||
GL11.glPushMatrix()
|
||||
|
||||
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
|
||||
|
||||
rack.yaw match {
|
||||
case ForgeDirection.WEST => GL11.glRotatef(-90, 0, 1, 0)
|
||||
case ForgeDirection.NORTH => GL11.glRotatef(180, 0, 1, 0)
|
||||
case ForgeDirection.EAST => GL11.glRotatef(90, 0, 1, 0)
|
||||
case _ => // No yaw.
|
||||
}
|
||||
|
||||
GL11.glTranslatef(-0.5f, 0.5f, 0.501f)
|
||||
GL11.glScalef(1, -1, 1)
|
||||
|
||||
bindTexture(Textures.blockRackFrontOn)
|
||||
|
||||
val v1 = 2 / 16f
|
||||
val fs = 3 / 16f
|
||||
for (i <- 0 until 4 if rack.isRunning(i)) {
|
||||
val l = v1 + i * fs
|
||||
val h = v1 + (i + 1) * fs
|
||||
bindTexture(Textures.blockRackFrontOn)
|
||||
val t = Tessellator.instance
|
||||
t.startDrawingQuads()
|
||||
t.addVertexWithUV(0, h, 0, 0, h)
|
||||
t.addVertexWithUV(1, h, 0, 1, h)
|
||||
t.addVertexWithUV(1, l, 0, 1, l)
|
||||
t.addVertexWithUV(0, l, 0, 0, l)
|
||||
t.draw()
|
||||
}
|
||||
for (i <- 0 until 4 if System.currentTimeMillis() - rack.lastAccess(i) < 400 && rack.world.rand.nextDouble() > 0.1) {
|
||||
val l = v1 + i * fs
|
||||
val h = v1 + (i + 1) * fs
|
||||
bindTexture(Textures.blockRackFrontActivity)
|
||||
val t = Tessellator.instance
|
||||
t.startDrawingQuads()
|
||||
t.addVertexWithUV(0, h, 0, 0, h)
|
||||
@ -49,11 +60,11 @@ object ServerRackRenderer extends TileEntitySpecialRenderer {
|
||||
t.addVertexWithUV(0, l, 0, 0, l)
|
||||
t.draw()
|
||||
}
|
||||
|
||||
GL11.glPopMatrix()
|
||||
GL11.glPopAttrib()
|
||||
}
|
||||
|
||||
GL11.glPopMatrix()
|
||||
GL11.glPopAttrib()
|
||||
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: leaving")
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package li.cil.oc.common.event
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api.event.FileSystemAccessEvent
|
||||
|
||||
object FileAccessHandler {
|
||||
@SubscribeEvent
|
||||
def onFileSystemAccess(e: FileSystemAccessEvent) {
|
||||
val volume = Settings.get.soundVolume
|
||||
e.world.playSound(e.x, e.y, e.z, e.sound, volume, 1, false)
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package li.cil.oc.common.event
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api.event.FileSystemAccessEvent
|
||||
import li.cil.oc.common.tileentity.Case
|
||||
import li.cil.oc.common.tileentity.DiskDrive
|
||||
import li.cil.oc.common.tileentity.ServerRack
|
||||
|
||||
object FileSystemAccessHandler {
|
||||
@SubscribeEvent
|
||||
def onFileSystemAccess(e: FileSystemAccessEvent.Server) {
|
||||
e.getTileEntity match {
|
||||
case t: ServerRack =>
|
||||
val serverSlot = t.servers.indexWhere {
|
||||
case Some(server) => server.componentSlot(e.getNode.address) >= 0
|
||||
case _ => false
|
||||
}
|
||||
if (serverSlot < 0) e.setCanceled(true)
|
||||
else e.getData.setInteger("server", serverSlot)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
def onFileSystemAccess(e: FileSystemAccessEvent.Client) {
|
||||
val volume = Settings.get.soundVolume
|
||||
e.getWorld.playSound(e.getX, e.getY, e.getZ, e.getSound, volume, 1, false)
|
||||
e.getTileEntity match {
|
||||
case t: DiskDrive => t.lastAccess = System.currentTimeMillis()
|
||||
case t: Case => t.lastAccess = System.currentTimeMillis()
|
||||
case t: ServerRack => t.lastAccess(e.getData.getInteger("server")) = System.currentTimeMillis()
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,9 @@ import net.minecraftforge.common.util.ForgeDirection
|
||||
class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with traits.Colored {
|
||||
def this() = this(0)
|
||||
|
||||
// Used on client side to check whether to render disk activity indicators.
|
||||
var lastAccess = 0L
|
||||
|
||||
color = Color.byTier(tier)
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
|
@ -18,6 +18,9 @@ import net.minecraft.nbt.NBTTagCompound
|
||||
class DiskDrive extends traits.Environment with traits.ComponentInventory with traits.Rotatable with Analyzable {
|
||||
val node = api.Network.newNode(this, Visibility.None).create()
|
||||
|
||||
// Used on client side to check whether to render disk activity indicators.
|
||||
var lastAccess = 0L
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) =
|
||||
|
@ -51,6 +51,9 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB
|
||||
// For client side rendering.
|
||||
var isPresent = Array.fill[Option[String]](getSizeInventory)(None)
|
||||
|
||||
// Used on client side to check whether to render disk activity indicators.
|
||||
var lastAccess = Array.fill(4)(0L)
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override protected def hasConnector(side: ForgeDirection) = side != facing
|
||||
|
||||
|
@ -2,13 +2,17 @@ package li.cil.oc.server
|
||||
|
||||
import li.cil.oc.api.component.TextBuffer.ColorDepth
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.event.FileSystemAccessEvent
|
||||
import li.cil.oc.api.network.Node
|
||||
import li.cil.oc.common._
|
||||
import li.cil.oc.common.tileentity.traits._
|
||||
import li.cil.oc.util.PackedColor
|
||||
import net.minecraft.entity.player.EntityPlayerMP
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.CompressedStreamTools
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
import scala.collection.mutable
|
||||
@ -81,28 +85,36 @@ object PacketSender {
|
||||
// Avoid spamming the network with disk activity notices.
|
||||
val fileSystemAccessTimeouts = mutable.WeakHashMap.empty[EnvironmentHost, mutable.Map[String, Long]]
|
||||
|
||||
def sendFileSystemActivity(host: EnvironmentHost, name: String) = fileSystemAccessTimeouts.synchronized {
|
||||
def sendFileSystemActivity(node: Node, host: EnvironmentHost, name: String) = fileSystemAccessTimeouts.synchronized {
|
||||
fileSystemAccessTimeouts.get(host) match {
|
||||
case Some(hostTimeouts) if hostTimeouts.getOrElse(name, 0L) > System.currentTimeMillis() => // Cooldown.
|
||||
case _ =>
|
||||
fileSystemAccessTimeouts.getOrElseUpdate(host, mutable.Map.empty) += name -> (System.currentTimeMillis() + 500)
|
||||
|
||||
val pb = new SimplePacketBuilder(PacketType.FileSystemActivity)
|
||||
|
||||
pb.writeUTF(name)
|
||||
host match {
|
||||
case t: net.minecraft.tileentity.TileEntity =>
|
||||
pb.writeBoolean(true)
|
||||
pb.writeTileEntity(t)
|
||||
case _ =>
|
||||
pb.writeBoolean(false)
|
||||
pb.writeInt(host.world.provider.dimensionId)
|
||||
pb.writeDouble(host.xPosition)
|
||||
pb.writeDouble(host.yPosition)
|
||||
pb.writeDouble(host.zPosition)
|
||||
val event = host match {
|
||||
case t: net.minecraft.tileentity.TileEntity => new FileSystemAccessEvent.Server(name, t, node)
|
||||
case _ => new FileSystemAccessEvent.Server(name, host.world, host.xPosition, host.yPosition, host.zPosition, node)
|
||||
}
|
||||
MinecraftForge.EVENT_BUS.post(event)
|
||||
if (!event.isCanceled) {
|
||||
fileSystemAccessTimeouts.getOrElseUpdate(host, mutable.Map.empty) += name -> (System.currentTimeMillis() + 500)
|
||||
|
||||
pb.sendToPlayersNearHost(host, 64)
|
||||
val pb = new SimplePacketBuilder(PacketType.FileSystemActivity)
|
||||
|
||||
pb.writeUTF(event.getSound)
|
||||
CompressedStreamTools.write(event.getData, pb)
|
||||
event.getTileEntity match {
|
||||
case t: net.minecraft.tileentity.TileEntity =>
|
||||
pb.writeBoolean(true)
|
||||
pb.writeTileEntity(t)
|
||||
case _ =>
|
||||
pb.writeBoolean(false)
|
||||
pb.writeInt(event.getWorld.provider.dimensionId)
|
||||
pb.writeDouble(event.getX)
|
||||
pb.writeDouble(event.getY)
|
||||
pb.writeDouble(event.getZ)
|
||||
}
|
||||
|
||||
pb.sendToPlayersNearHost(host, 64)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,7 +313,7 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option
|
||||
|
||||
private def diskActivity() {
|
||||
(sound, host) match {
|
||||
case (Some(s), Some(h)) => ServerPacketSender.sendFileSystemActivity(h, s)
|
||||
case (Some(s), Some(h)) => ServerPacketSender.sendFileSystemActivity(node, h, s)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|