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.Cancelable;
|
||||||
import cpw.mods.fml.common.eventhandler.Event;
|
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.tileentity.TileEntity;
|
||||||
import net.minecraft.world.World;
|
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/>
|
* <p/>
|
||||||
* This is used to play file system access sounds and render disk activity
|
* This is used to play file system access sounds and render disk activity
|
||||||
* indicators on some containers (e.g. disk drive, computer, server).
|
* indicators on some containers (e.g. disk drive, computer, server).
|
||||||
@ -19,52 +21,35 @@ import net.minecraft.world.World;
|
|||||||
*/
|
*/
|
||||||
@Cancelable
|
@Cancelable
|
||||||
public class FileSystemAccessEvent extends Event {
|
public class FileSystemAccessEvent extends Event {
|
||||||
/**
|
protected String sound;
|
||||||
* The name of the sound effect to play for the file system.
|
|
||||||
*/
|
|
||||||
public final String sound;
|
|
||||||
|
|
||||||
/**
|
protected World world;
|
||||||
* The world the file system lives in.
|
|
||||||
*/
|
|
||||||
public final World world;
|
|
||||||
|
|
||||||
/**
|
protected double x;
|
||||||
* The x coordinate of the file system's container.
|
|
||||||
*/
|
|
||||||
public final double x;
|
|
||||||
|
|
||||||
/**
|
protected double y;
|
||||||
* The y coordinate of the file system's container.
|
|
||||||
*/
|
|
||||||
public final double y;
|
|
||||||
|
|
||||||
/**
|
protected double z;
|
||||||
* The z coordinate of the file system's container.
|
|
||||||
*/
|
|
||||||
public final double z;
|
|
||||||
|
|
||||||
/**
|
protected TileEntity tileEntity;
|
||||||
* The tile entity hosting the file system.
|
|
||||||
* <p/>
|
protected NBTTagCompound data;
|
||||||
* <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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for tile entity hosted file systems.
|
* Constructor for tile entity hosted file systems.
|
||||||
*
|
*
|
||||||
* @param sound the name of the sound effect to play.
|
* @param sound the name of the sound effect to play.
|
||||||
* @param tileEntity the tile entity hosting the file system.
|
* @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.sound = sound;
|
||||||
this.world = tileEntity.getWorldObj();
|
this.world = tileEntity.getWorldObj();
|
||||||
this.x = tileEntity.xCoord + 0.5;
|
this.x = tileEntity.xCoord + 0.5;
|
||||||
this.y = tileEntity.yCoord + 0.5;
|
this.y = tileEntity.yCoord + 0.5;
|
||||||
this.z = tileEntity.zCoord + 0.5;
|
this.z = tileEntity.zCoord + 0.5;
|
||||||
this.tileEntity = tileEntity;
|
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 x the x coordinate of the file system's container.
|
||||||
* @param y the y 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 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.sound = sound;
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
this.tileEntity = null;
|
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
|
if not result then
|
||||||
error(reason, 0)
|
error(reason, 0)
|
||||||
end
|
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()
|
local result = io.read()
|
||||||
if not result or result == "" or result:sub(1, 1):lower() == "y" then
|
if not result or result == "" or result:sub(1, 1):lower() == "y" then
|
||||||
|
computer.setBootAddress(choice.address)
|
||||||
print("\nRebooting now!")
|
print("\nRebooting now!")
|
||||||
computer.shutdown(true)
|
computer.shutdown(true)
|
||||||
end
|
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.Minecraft
|
||||||
import net.minecraft.client.gui.GuiScreen
|
import net.minecraft.client.gui.GuiScreen
|
||||||
import net.minecraft.entity.player.EntityPlayer
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraft.nbt.CompressedStreamTools
|
||||||
import net.minecraftforge.common.MinecraftForge
|
import net.minecraftforge.common.MinecraftForge
|
||||||
import net.minecraftforge.common.util.ForgeDirection
|
import net.minecraftforge.common.util.ForgeDirection
|
||||||
import org.lwjgl.input.Keyboard
|
import org.lwjgl.input.Keyboard
|
||||||
@ -145,9 +146,10 @@ object PacketHandler extends CommonPacketHandler {
|
|||||||
|
|
||||||
def onFileSystemActivity(p: PacketParser) = {
|
def onFileSystemActivity(p: PacketParser) = {
|
||||||
val sound = p.readUTF()
|
val sound = p.readUTF()
|
||||||
|
val data = CompressedStreamTools.read(p)
|
||||||
if (p.readBoolean()) p.readTileEntity[net.minecraft.tileentity.TileEntity]() match {
|
if (p.readBoolean()) p.readTileEntity[net.minecraft.tileentity.TileEntity]() match {
|
||||||
case Some(t) =>
|
case Some(t) =>
|
||||||
MinecraftForge.EVENT_BUS.post(new FileSystemAccessEvent(sound, t))
|
MinecraftForge.EVENT_BUS.post(new FileSystemAccessEvent.Client(sound, t, data))
|
||||||
case _ => // Invalid packet.
|
case _ => // Invalid packet.
|
||||||
}
|
}
|
||||||
else world(p.player, p.readInt()) match {
|
else world(p.player, p.readInt()) match {
|
||||||
@ -155,7 +157,7 @@ object PacketHandler extends CommonPacketHandler {
|
|||||||
val x = p.readDouble()
|
val x = p.readDouble()
|
||||||
val y = p.readDouble()
|
val y = p.readDouble()
|
||||||
val z = 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.
|
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.item.ItemRenderer
|
||||||
import li.cil.oc.client.renderer.tileentity._
|
import li.cil.oc.client.renderer.tileentity._
|
||||||
import li.cil.oc.common.component.TextBuffer
|
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.init.Items
|
||||||
import li.cil.oc.common.tileentity
|
import li.cil.oc.common.tileentity
|
||||||
import li.cil.oc.common.tileentity.ServerRack
|
import li.cil.oc.common.tileentity.ServerRack
|
||||||
@ -61,7 +61,7 @@ private[oc] class Proxy extends CommonProxy {
|
|||||||
ClientRegistry.registerKeyBinding(KeyBindings.materialCosts)
|
ClientRegistry.registerKeyBinding(KeyBindings.materialCosts)
|
||||||
ClientRegistry.registerKeyBinding(KeyBindings.clipboardPaste)
|
ClientRegistry.registerKeyBinding(KeyBindings.clipboardPaste)
|
||||||
|
|
||||||
MinecraftForge.EVENT_BUS.register(FileAccessHandler)
|
MinecraftForge.EVENT_BUS.register(FileSystemAccessHandler)
|
||||||
MinecraftForge.EVENT_BUS.register(PetRenderer)
|
MinecraftForge.EVENT_BUS.register(PetRenderer)
|
||||||
MinecraftForge.EVENT_BUS.register(ServerRack)
|
MinecraftForge.EVENT_BUS.register(ServerRack)
|
||||||
MinecraftForge.EVENT_BUS.register(TextBuffer)
|
MinecraftForge.EVENT_BUS.register(TextBuffer)
|
||||||
|
@ -30,8 +30,11 @@ object Textures {
|
|||||||
val guiSlot = new ResourceLocation(Settings.resourceDomain, "textures/gui/slot.png")
|
val guiSlot = new ResourceLocation(Settings.resourceDomain, "textures/gui/slot.png")
|
||||||
|
|
||||||
val blockCaseFrontOn = new ResourceLocation(Settings.resourceDomain, "textures/blocks/CaseFrontOn.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 blockHologram = new ResourceLocation(Settings.resourceDomain, "textures/blocks/HologramEffect.png")
|
||||||
val blockRackFrontOn = new ResourceLocation(Settings.resourceDomain, "textures/blocks/ServerRackFrontOn.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 blockRobot = new ResourceLocation(Settings.resourceDomain, "textures/blocks/robot.png")
|
||||||
val blockScreenUpIndicator = new ResourceLocation(Settings.resourceDomain, "textures/blocks/screen/up_indicator.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)")
|
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||||
|
|
||||||
val computer = tileEntity.asInstanceOf[Case]
|
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) {
|
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)
|
bindTexture(Textures.blockCaseFrontOn)
|
||||||
val t = Tessellator.instance
|
val t = Tessellator.instance
|
||||||
t.startDrawingQuads()
|
t.startDrawingQuads()
|
||||||
@ -44,10 +44,21 @@ object CaseRenderer extends TileEntitySpecialRenderer {
|
|||||||
t.addVertexWithUV(0, 0, 0, 0, 0)
|
t.addVertexWithUV(0, 0, 0, 0, 0)
|
||||||
t.draw()
|
t.draw()
|
||||||
|
|
||||||
GL11.glPopMatrix()
|
if (System.currentTimeMillis() - computer.lastAccess < 400 && computer.world.rand.nextDouble() > 0.1) {
|
||||||
GL11.glPopAttrib()
|
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")
|
RenderState.checkError(getClass.getName + ".renderTileEntityAt: leaving")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,8 +1,10 @@
|
|||||||
package li.cil.oc.client.renderer.tileentity
|
package li.cil.oc.client.renderer.tileentity
|
||||||
|
|
||||||
|
import li.cil.oc.client.Textures
|
||||||
import li.cil.oc.common.tileentity.DiskDrive
|
import li.cil.oc.common.tileentity.DiskDrive
|
||||||
import li.cil.oc.util.RenderState
|
import li.cil.oc.util.RenderState
|
||||||
import net.minecraft.client.renderer.OpenGlHelper
|
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.RenderItem
|
||||||
import net.minecraft.client.renderer.entity.RenderManager
|
import net.minecraft.client.renderer.entity.RenderManager
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
|
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
|
||||||
@ -16,39 +18,59 @@ object DiskDriveRenderer extends TileEntitySpecialRenderer {
|
|||||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||||
|
|
||||||
val drive = tileEntity.asInstanceOf[DiskDrive]
|
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 {
|
drive.items(0) match {
|
||||||
case Some(stack) =>
|
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)
|
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)
|
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!
|
// This is very 'meh', but item frames do it like this, too!
|
||||||
val entity = new EntityItem(drive.world, 0, 0, 0, stack)
|
val entity = new EntityItem(drive.world, 0, 0, 0, stack)
|
||||||
entity.hoverStart = 0
|
entity.hoverStart = 0
|
||||||
RenderItem.renderInFrame = true
|
RenderItem.renderInFrame = true
|
||||||
RenderManager.instance.renderEntityWithPosYaw(entity, 0, 0, 0, 0, 0)
|
RenderManager.instance.renderEntityWithPosYaw(entity, 0, 0, 0, 0, 0)
|
||||||
RenderItem.renderInFrame = false
|
RenderItem.renderInFrame = false
|
||||||
|
|
||||||
GL11.glPopMatrix()
|
GL11.glPopMatrix()
|
||||||
GL11.glPopAttrib()
|
|
||||||
case _ =>
|
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")
|
RenderState.checkError(getClass.getName + ".renderTileEntityAt: leaving")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,33 +14,44 @@ object ServerRackRenderer extends TileEntitySpecialRenderer {
|
|||||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||||
|
|
||||||
val rack = tileEntity.asInstanceOf[ServerRack]
|
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) {
|
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 v1 = 2 / 16f
|
||||||
val fs = 3 / 16f
|
val fs = 3 / 16f
|
||||||
for (i <- 0 until 4 if rack.isRunning(i)) {
|
for (i <- 0 until 4 if rack.isRunning(i)) {
|
||||||
val l = v1 + i * fs
|
val l = v1 + i * fs
|
||||||
val h = v1 + (i + 1) * 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
|
val t = Tessellator.instance
|
||||||
t.startDrawingQuads()
|
t.startDrawingQuads()
|
||||||
t.addVertexWithUV(0, h, 0, 0, h)
|
t.addVertexWithUV(0, h, 0, 0, h)
|
||||||
@ -49,11 +60,11 @@ object ServerRackRenderer extends TileEntitySpecialRenderer {
|
|||||||
t.addVertexWithUV(0, l, 0, 0, l)
|
t.addVertexWithUV(0, l, 0, 0, l)
|
||||||
t.draw()
|
t.draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
GL11.glPopMatrix()
|
|
||||||
GL11.glPopAttrib()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GL11.glPopMatrix()
|
||||||
|
GL11.glPopAttrib()
|
||||||
|
|
||||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: leaving")
|
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 {
|
class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with traits.Colored {
|
||||||
def this() = this(0)
|
def this() = this(0)
|
||||||
|
|
||||||
|
// Used on client side to check whether to render disk activity indicators.
|
||||||
|
var lastAccess = 0L
|
||||||
|
|
||||||
color = Color.byTier(tier)
|
color = Color.byTier(tier)
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@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 {
|
class DiskDrive extends traits.Environment with traits.ComponentInventory with traits.Rotatable with Analyzable {
|
||||||
val node = api.Network.newNode(this, Visibility.None).create()
|
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) =
|
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.
|
// For client side rendering.
|
||||||
var isPresent = Array.fill[Option[String]](getSizeInventory)(None)
|
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)
|
@SideOnly(Side.CLIENT)
|
||||||
override protected def hasConnector(side: ForgeDirection) = side != facing
|
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.component.TextBuffer.ColorDepth
|
||||||
import li.cil.oc.api.driver.EnvironmentHost
|
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._
|
||||||
import li.cil.oc.common.tileentity.traits._
|
import li.cil.oc.common.tileentity.traits._
|
||||||
import li.cil.oc.util.PackedColor
|
import li.cil.oc.util.PackedColor
|
||||||
import net.minecraft.entity.player.EntityPlayerMP
|
import net.minecraft.entity.player.EntityPlayerMP
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.nbt.CompressedStreamTools
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
import net.minecraftforge.common.MinecraftForge
|
||||||
import net.minecraftforge.common.util.ForgeDirection
|
import net.minecraftforge.common.util.ForgeDirection
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
@ -81,28 +85,36 @@ object PacketSender {
|
|||||||
// Avoid spamming the network with disk activity notices.
|
// Avoid spamming the network with disk activity notices.
|
||||||
val fileSystemAccessTimeouts = mutable.WeakHashMap.empty[EnvironmentHost, mutable.Map[String, Long]]
|
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 {
|
fileSystemAccessTimeouts.get(host) match {
|
||||||
case Some(hostTimeouts) if hostTimeouts.getOrElse(name, 0L) > System.currentTimeMillis() => // Cooldown.
|
case Some(hostTimeouts) if hostTimeouts.getOrElse(name, 0L) > System.currentTimeMillis() => // Cooldown.
|
||||||
case _ =>
|
case _ =>
|
||||||
fileSystemAccessTimeouts.getOrElseUpdate(host, mutable.Map.empty) += name -> (System.currentTimeMillis() + 500)
|
val event = host match {
|
||||||
|
case t: net.minecraft.tileentity.TileEntity => new FileSystemAccessEvent.Server(name, t, node)
|
||||||
val pb = new SimplePacketBuilder(PacketType.FileSystemActivity)
|
case _ => new FileSystemAccessEvent.Server(name, host.world, host.xPosition, host.yPosition, host.zPosition, node)
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
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() {
|
private def diskActivity() {
|
||||||
(sound, host) match {
|
(sound, host) match {
|
||||||
case (Some(s), Some(h)) => ServerPacketSender.sendFileSystemActivity(h, s)
|
case (Some(s), Some(h)) => ServerPacketSender.sendFileSystemActivity(node, h, s)
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|