diff --git a/src/main/java/li/cil/oc/api/FileSystem.java b/src/main/java/li/cil/oc/api/FileSystem.java index 7d198dd7c..d177a38f5 100644 --- a/src/main/java/li/cil/oc/api/FileSystem.java +++ b/src/main/java/li/cil/oc/api/FileSystem.java @@ -147,7 +147,9 @@ public final class FileSystem { * @param label the label of the file system. * @param host the tile entity containing the file system. * @param accessSound the name of the sound effect to play when the file - * system is accessed. + * system is accessed. This has to be the fully + * qualified resource name, e.g. + * opencomputers:floppy_access. * @return the network node wrapping the file system. */ public static ManagedEnvironment asManagedEnvironment(final li.cil.oc.api.fs.FileSystem fileSystem, final Label label, final EnvironmentHost host, final String accessSound) { @@ -164,7 +166,9 @@ public final class FileSystem { * @param label the read-only label of the file system. * @param host the tile entity containing the file system. * @param accessSound the name of the sound effect to play when the file - * system is accessed. + * system is accessed. This has to be the fully + * qualified resource name, e.g. + * opencomputers:floppy_access. * @return the network node wrapping the file system. */ public static ManagedEnvironment asManagedEnvironment(final li.cil.oc.api.fs.FileSystem fileSystem, final String label, final EnvironmentHost host, final String accessSound) { diff --git a/src/main/java/li/cil/oc/api/driver/item/Container.java b/src/main/java/li/cil/oc/api/driver/item/Container.java index 8abf54c76..e3e42a2fb 100644 --- a/src/main/java/li/cil/oc/api/driver/item/Container.java +++ b/src/main/java/li/cil/oc/api/driver/item/Container.java @@ -17,7 +17,7 @@ public interface Container extends Item { * The type of slot provided as the dynamic slot. This will usually be * for other upgrades, but may be for any type of item component. *
- * While the driver's own type implicitly has to be 'Upgrade' and could + * While the driver's own type implicitly has to be 'Container' and could * therefore be used instead, this makes the intention more clear. * * @param stack the item stack to get the provided slot type for. diff --git a/src/main/java/li/cil/oc/api/event/FileSystemAccessEvent.java b/src/main/java/li/cil/oc/api/event/FileSystemAccessEvent.java new file mode 100644 index 000000000..70e96fd88 --- /dev/null +++ b/src/main/java/li/cil/oc/api/event/FileSystemAccessEvent.java @@ -0,0 +1,87 @@ +package li.cil.oc.api.event; + +import cpw.mods.fml.common.eventhandler.Cancelable; +import cpw.mods.fml.common.eventhandler.Event; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +/** + * Fired on the client side only, signals file system access. + * + * This is used to play file system access sounds and render disk activity + * indicators on some containers (e.g. disk drive, computer, server). + * + * Use this to implement rendering of disk access indicators on you own + * containers / computers / drive bays. + * + * Canceling this event is provided to allow registering higher priority + * event handlers that override default behavior. + */ +@Cancelable +public class FileSystemAccessEvent extends Event { + /** + * The name of the sound effect to play for the file system. + */ + public final String sound; + + /** + * The world the file system lives in. + */ + public final World world; + + /** + * The x coordinate of the file system's container. + */ + public final double x; + + /** + * The y coordinate of the file system's container. + */ + public final double y; + + /** + * The z coordinate of the file system's container. + */ + public final double z; + + /** + * The tile entity hosting the file system. + * + * Important: this can be null, which is usually the + * case when the container is an entity or item. + */ + public final TileEntity tileEntity; + + /** + * 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. + */ + public FileSystemAccessEvent(String sound, TileEntity tileEntity) { + 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; + } + + /** + * 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. + */ + public FileSystemAccessEvent(String sound, World world, double x, double y, double z) { + this.sound = sound; + this.world = world; + this.x = x; + this.y = y; + this.z = z; + this.tileEntity = null; + } +} diff --git a/src/main/java/li/cil/oc/api/event/RobotUsedTool.java b/src/main/java/li/cil/oc/api/event/RobotUsedToolEvent.java similarity index 88% rename from src/main/java/li/cil/oc/api/event/RobotUsedTool.java rename to src/main/java/li/cil/oc/api/event/RobotUsedToolEvent.java index fa62adfde..b0800a0f0 100644 --- a/src/main/java/li/cil/oc/api/event/RobotUsedTool.java +++ b/src/main/java/li/cil/oc/api/event/RobotUsedToolEvent.java @@ -3,7 +3,7 @@ package li.cil.oc.api.event; import li.cil.oc.api.tileentity.Robot; import net.minecraft.item.ItemStack; -public class RobotUsedTool extends RobotEvent { +public class RobotUsedToolEvent extends RobotEvent { /** * The tool that was used, before and after use. */ @@ -11,7 +11,7 @@ public class RobotUsedTool extends RobotEvent { protected double damageRate; - protected RobotUsedTool(Robot robot, ItemStack toolBeforeUse, ItemStack toolAfterUse, double damageRate) { + protected RobotUsedToolEvent(Robot robot, ItemStack toolBeforeUse, ItemStack toolAfterUse, double damageRate) { super(robot); this.toolBeforeUse = toolBeforeUse; this.toolAfterUse = toolAfterUse; @@ -35,7 +35,7 @@ public class RobotUsedTool extends RobotEvent { * rate at which the tool should lose durability, which is used by the * experience upgrade, for example. */ - public static class ComputeDamageRate extends RobotUsedTool { + public static class ComputeDamageRate extends RobotUsedToolEvent { public ComputeDamageRate(Robot robot, ItemStack toolBeforeUse, ItemStack toolAfterUse, double damageRate) { super(robot, toolBeforeUse, toolAfterUse, damageRate); } @@ -62,7 +62,7 @@ public class RobotUsedTool extends RobotEvent { * durability that was lost. This may be required for tools where the * durability is stored in the item's NBT tag. */ - public static class ApplyDamageRate extends RobotUsedTool { + public static class ApplyDamageRate extends RobotUsedToolEvent { public ApplyDamageRate(Robot robot, ItemStack toolBeforeUse, ItemStack toolAfterUse, double damageRate) { super(robot, toolBeforeUse, toolAfterUse, damageRate); } diff --git a/src/main/scala/li/cil/oc/client/PacketHandler.scala b/src/main/scala/li/cil/oc/client/PacketHandler.scala index b6c939502..4d5807618 100644 --- a/src/main/scala/li/cil/oc/client/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/client/PacketHandler.scala @@ -6,16 +6,18 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent import cpw.mods.fml.common.network.FMLNetworkEvent.ClientCustomPacketEvent import li.cil.oc.Localization import li.cil.oc.api.component +import li.cil.oc.api.event.FileSystemAccessEvent import li.cil.oc.api.network.ManagedEnvironment import li.cil.oc.client.renderer.PetRenderer +import li.cil.oc.common.PacketType import li.cil.oc.common.tileentity._ import li.cil.oc.common.tileentity.traits._ -import li.cil.oc.common.PacketType import li.cil.oc.common.{PacketHandler => CommonPacketHandler} 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.minecraftforge.common.MinecraftForge import net.minecraftforge.common.util.ForgeDirection import org.lwjgl.input.Keyboard @@ -39,6 +41,7 @@ object PacketHandler extends CommonPacketHandler { case PacketType.ComputerState => onComputerState(p) case PacketType.ComputerUserList => onComputerUserList(p) case PacketType.DisassemblerActiveChange => onDisassemblerActiveChange(p) + case PacketType.FileSystemActivity => onFileSystemActivity(p) case PacketType.FloppyChange => onFloppyChange(p) case PacketType.HologramClear => onHologramClear(p) case PacketType.HologramColor => onHologramColor(p) @@ -140,6 +143,23 @@ object PacketHandler extends CommonPacketHandler { case _ => // Invalid packet. } + def onFileSystemActivity(p: PacketParser) = { + val sound = p.readUTF() + if (p.readBoolean()) p.readTileEntity[net.minecraft.tileentity.TileEntity]() match { + case Some(t) => + MinecraftForge.EVENT_BUS.post(new FileSystemAccessEvent(sound, t)) + case _ => // Invalid packet. + } + else world(p.player, p.readInt()) match { + case Some(world) => + val x = p.readDouble() + val y = p.readDouble() + val z = p.readDouble() + MinecraftForge.EVENT_BUS.post(new FileSystemAccessEvent(sound, world, x, y, z)) + case _ => // Invalid packet. + } + } + def onFloppyChange(p: PacketParser) = p.readTileEntity[DiskDrive]() match { case Some(t) => t.setInventorySlotContents(0, p.readItemStack()) diff --git a/src/main/scala/li/cil/oc/client/Proxy.scala b/src/main/scala/li/cil/oc/client/Proxy.scala index 15359872f..a61dec025 100644 --- a/src/main/scala/li/cil/oc/client/Proxy.scala +++ b/src/main/scala/li/cil/oc/client/Proxy.scala @@ -16,6 +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.init.Items import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity.ServerRack @@ -60,6 +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(PetRenderer) MinecraftForge.EVENT_BUS.register(ServerRack) MinecraftForge.EVENT_BUS.register(TextBuffer) diff --git a/src/main/scala/li/cil/oc/common/PacketBuilder.scala b/src/main/scala/li/cil/oc/common/PacketBuilder.scala index a595b7ee3..6e59be041 100644 --- a/src/main/scala/li/cil/oc/common/PacketBuilder.scala +++ b/src/main/scala/li/cil/oc/common/PacketBuilder.scala @@ -44,9 +44,9 @@ abstract class PacketBuilder(stream: OutputStream) extends DataOutputStream(stre def sendToAllPlayers() = OpenComputers.channel.sendToAll(packet) - def sendToNearbyPlayers(t: TileEntity, range: Double = 1024): Unit = sendToNearbyPlayers(t.getWorldObj, t.xCoord + 0.5, t.yCoord + 0.5, t.zCoord + 0.5, range) + def sendToPlayersNearTileEntity(t: TileEntity, range: Double = 1024): Unit = sendToNearbyPlayers(t.getWorldObj, t.xCoord + 0.5, t.yCoord + 0.5, t.zCoord + 0.5, range) - def sendToNearbyPlayers(host: EnvironmentHost): Unit = sendToNearbyPlayers(host.world, host.xPosition, host.yPosition, host.zPosition, 1024) + def sendToPlayersNearHost(host: EnvironmentHost, range: Double = 1024): Unit = sendToNearbyPlayers(host.world, host.xPosition, host.yPosition, host.zPosition, range) def sendToNearbyPlayers(world: World, x: Double, y: Double, z: Double, range: Double) { val dimension = world.provider.dimensionId diff --git a/src/main/scala/li/cil/oc/common/PacketType.scala b/src/main/scala/li/cil/oc/common/PacketType.scala index 54e84575e..005af9050 100644 --- a/src/main/scala/li/cil/oc/common/PacketType.scala +++ b/src/main/scala/li/cil/oc/common/PacketType.scala @@ -10,6 +10,7 @@ object PacketType extends Enumeration { ComputerState, ComputerUserList, DisassemblerActiveChange, + FileSystemActivity, FloppyChange, HologramClear, HologramColor, diff --git a/src/main/scala/li/cil/oc/common/component/TextBuffer.scala b/src/main/scala/li/cil/oc/common/component/TextBuffer.scala index d8b1387cf..ef1b7482b 100644 --- a/src/main/scala/li/cil/oc/common/component/TextBuffer.scala +++ b/src/main/scala/li/cil/oc/common/component/TextBuffer.scala @@ -118,7 +118,7 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi } this.synchronized { - _pendingCommands.foreach(_.sendToNearbyPlayers(host)) + _pendingCommands.foreach(_.sendToPlayersNearHost(host)) _pendingCommands = None } } diff --git a/src/main/scala/li/cil/oc/common/event/ExperienceUpgradeHandler.scala b/src/main/scala/li/cil/oc/common/event/ExperienceUpgradeHandler.scala index a08d505cc..7b3a6564f 100644 --- a/src/main/scala/li/cil/oc/common/event/ExperienceUpgradeHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/ExperienceUpgradeHandler.scala @@ -1,11 +1,11 @@ package li.cil.oc.common.event import cpw.mods.fml.common.eventhandler.SubscribeEvent +import li.cil.oc.Localization +import li.cil.oc.Settings import li.cil.oc.api.event._ import li.cil.oc.api.tileentity.Robot import li.cil.oc.server.component -import li.cil.oc.Localization -import li.cil.oc.Settings import org.lwjgl.opengl.GL11 object ExperienceUpgradeHandler { @@ -19,7 +19,7 @@ object ExperienceUpgradeHandler { } @SubscribeEvent - def onRobotComputeDamageRate(e: RobotUsedTool.ComputeDamageRate) { + def onRobotComputeDamageRate(e: RobotUsedToolEvent.ComputeDamageRate) { e.setDamageRate(e.getDamageRate * math.max(0, 1 - getLevel(e.robot) * Settings.get.toolEfficiencyPerLevel)) } diff --git a/src/main/scala/li/cil/oc/common/event/FileAccessHandler.scala b/src/main/scala/li/cil/oc/common/event/FileAccessHandler.scala new file mode 100644 index 000000000..ba21e128c --- /dev/null +++ b/src/main/scala/li/cil/oc/common/event/FileAccessHandler.scala @@ -0,0 +1,13 @@ +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) + } +} diff --git a/src/main/scala/li/cil/oc/common/event/RedstoneFluxToolHandler.scala b/src/main/scala/li/cil/oc/common/event/RedstoneFluxToolHandler.scala index 0f739deb6..5009ca020 100644 --- a/src/main/scala/li/cil/oc/common/event/RedstoneFluxToolHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/RedstoneFluxToolHandler.scala @@ -2,11 +2,11 @@ package li.cil.oc.common.event import cofh.api.energy.IEnergyContainerItem import cpw.mods.fml.common.eventhandler.SubscribeEvent -import li.cil.oc.api.event.RobotUsedTool +import li.cil.oc.api.event.RobotUsedToolEvent object RedstoneFluxToolHandler { @SubscribeEvent - def onRobotApplyDamageRate(e: RobotUsedTool.ApplyDamageRate) { + def onRobotApplyDamageRate(e: RobotUsedToolEvent.ApplyDamageRate) { (e.toolBeforeUse.getItem, e.toolAfterUse.getItem) match { case (energyBefore: IEnergyContainerItem, energyAfter: IEnergyContainerItem) => val damage = energyBefore.getEnergyStored(e.toolBeforeUse) - energyAfter.getEnergyStored(e.toolAfterUse) diff --git a/src/main/scala/li/cil/oc/common/event/RobotCommonHandler.scala b/src/main/scala/li/cil/oc/common/event/RobotCommonHandler.scala index 0ff2fc283..c347c0140 100644 --- a/src/main/scala/li/cil/oc/common/event/RobotCommonHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/RobotCommonHandler.scala @@ -1,11 +1,11 @@ package li.cil.oc.common.event import cpw.mods.fml.common.eventhandler.SubscribeEvent -import li.cil.oc.api.event.RobotUsedTool +import li.cil.oc.api.event.RobotUsedToolEvent object RobotCommonHandler { @SubscribeEvent - def onRobotApplyDamageRate(e: RobotUsedTool.ApplyDamageRate) { + def onRobotApplyDamageRate(e: RobotUsedToolEvent.ApplyDamageRate) { if (e.toolAfterUse.isItemStackDamageable) { val damage = e.toolAfterUse.getItemDamage - e.toolBeforeUse.getItemDamage if (damage > 0) { diff --git a/src/main/scala/li/cil/oc/common/event/TinkersConstructToolHandler.scala b/src/main/scala/li/cil/oc/common/event/TinkersConstructToolHandler.scala index cd6b059b1..1b6ceedbb 100644 --- a/src/main/scala/li/cil/oc/common/event/TinkersConstructToolHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/TinkersConstructToolHandler.scala @@ -1,14 +1,14 @@ package li.cil.oc.common.event import cpw.mods.fml.common.eventhandler.SubscribeEvent -import li.cil.oc.api.event.RobotUsedTool +import li.cil.oc.api.event.RobotUsedToolEvent import net.minecraft.item.ItemStack object TinkersConstructToolHandler { def isTinkerTool(stack: ItemStack) = stack.hasTagCompound && stack.getTagCompound.hasKey("InfiTool") @SubscribeEvent - def onRobotApplyDamageRate(e: RobotUsedTool.ApplyDamageRate) { + def onRobotApplyDamageRate(e: RobotUsedToolEvent.ApplyDamageRate) { if (isTinkerTool(e.toolBeforeUse)) { val nbtBefore = e.toolBeforeUse.getTagCompound.getCompoundTag("InfiTool") val nbtAfter = e.toolAfterUse.getTagCompound.getCompoundTag("InfiTool") diff --git a/src/main/scala/li/cil/oc/common/event/UniversalElectricityToolHandler.scala b/src/main/scala/li/cil/oc/common/event/UniversalElectricityToolHandler.scala index 6b51eb542..fea727314 100644 --- a/src/main/scala/li/cil/oc/common/event/UniversalElectricityToolHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/UniversalElectricityToolHandler.scala @@ -1,12 +1,12 @@ package li.cil.oc.common.event import cpw.mods.fml.common.eventhandler.SubscribeEvent -import li.cil.oc.api.event.RobotUsedTool +import li.cil.oc.api.event.RobotUsedToolEvent import li.cil.oc.util.mods.UniversalElectricity object UniversalElectricityToolHandler { @SubscribeEvent - def onRobotApplyDamageRate(e: RobotUsedTool.ApplyDamageRate) { + def onRobotApplyDamageRate(e: RobotUsedToolEvent.ApplyDamageRate) { if (UniversalElectricity.isEnergyItem(e.toolAfterUse)) { val damage = UniversalElectricity.getEnergyInItem(e.toolBeforeUse) - UniversalElectricity.getEnergyInItem(e.toolAfterUse) if (damage > 0) { diff --git a/src/main/scala/li/cil/oc/common/tileentity/Robot.scala b/src/main/scala/li/cil/oc/common/tileentity/Robot.scala index 0992ff8fd..cd7d10788 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Robot.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Robot.scala @@ -194,7 +194,7 @@ class Robot extends traits.Computer with traits.PowerInformation with tileentity } else { world.playSound(nx + 0.5, ny + 0.5, nz + 0.5, "liquid.water", - world.rand.nextFloat * 0.25F + 0.75F, world.rand.nextFloat * 1.0F + 0.5F, false) + world.rand.nextFloat * 0.25f + 0.75f, world.rand.nextFloat * 1.0f + 0.5f, false) } } } diff --git a/src/main/scala/li/cil/oc/server/PacketSender.scala b/src/main/scala/li/cil/oc/server/PacketSender.scala index fab863ab6..4a92ebb81 100644 --- a/src/main/scala/li/cil/oc/server/PacketSender.scala +++ b/src/main/scala/li/cil/oc/server/PacketSender.scala @@ -11,6 +11,8 @@ import net.minecraft.nbt.NBTTagCompound import net.minecraft.world.World import net.minecraftforge.common.util.ForgeDirection +import scala.collection.mutable + object PacketSender { def sendAbstractBusState(t: AbstractBusAware) { val pb = new SimplePacketBuilder(PacketType.AbstractBusState) @@ -18,7 +20,7 @@ object PacketSender { pb.writeTileEntity(t) pb.writeBoolean(t.isAbstractBusAvailable) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendAnalyze(address: String, player: EntityPlayerMP) { @@ -36,7 +38,7 @@ object PacketSender { pb.writeDouble(t.chargeSpeed) pb.writeBoolean(t.hasPower) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendColorChange(t: Colored) { @@ -45,7 +47,7 @@ object PacketSender { pb.writeTileEntity(t) pb.writeInt(t.color) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendComputerState(t: Computer) { @@ -54,7 +56,7 @@ object PacketSender { pb.writeTileEntity(t) pb.writeBoolean(t.isRunning) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendComputerUserList(t: Computer, list: Array[String]) { @@ -64,7 +66,7 @@ object PacketSender { pb.writeInt(list.length) list.foreach(pb.writeUTF) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendDisassemblerActive(t: tileentity.Disassembler, active: Boolean) { @@ -73,7 +75,35 @@ object PacketSender { pb.writeTileEntity(t) pb.writeBoolean(active) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) + } + + // 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 { + 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) + } + + pb.sendToPlayersNearHost(host, 64) + } } def sendFloppyChange(t: tileentity.DiskDrive, stack: ItemStack = null) { @@ -82,7 +112,7 @@ object PacketSender { pb.writeTileEntity(t) pb.writeItemStack(stack) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendHologramClear(t: tileentity.Hologram) { @@ -90,7 +120,7 @@ object PacketSender { pb.writeTileEntity(t) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendHologramColor(t: tileentity.Hologram, index: Int, value: Int) { @@ -100,7 +130,7 @@ object PacketSender { pb.writeInt(index) pb.writeInt(value) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendHologramPowerChange(t: tileentity.Hologram) { @@ -109,7 +139,7 @@ object PacketSender { pb.writeTileEntity(t) pb.writeBoolean(t.hasPower) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendHologramScale(t: tileentity.Hologram) { @@ -118,7 +148,7 @@ object PacketSender { pb.writeTileEntity(t) pb.writeDouble(t.scale) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendHologramSet(t: tileentity.Hologram) { @@ -136,7 +166,7 @@ object PacketSender { } } - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendHologramOffset(t: tileentity.Hologram) { @@ -147,7 +177,7 @@ object PacketSender { pb.writeDouble(t.translation.yCoord) pb.writeDouble(t.translation.zCoord) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } @@ -180,7 +210,7 @@ object PacketSender { pb.writeDouble(t.globalBuffer) pb.writeDouble(t.globalBufferSize) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendRedstoneState(t: RedstoneAware) { @@ -192,7 +222,7 @@ object PacketSender { pb.writeByte(t.output(d)) } - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendRobotAssembling(t: tileentity.RobotAssembler, assembling: Boolean) { @@ -201,7 +231,7 @@ object PacketSender { pb.writeTileEntity(t) pb.writeBoolean(assembling) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearHost(t) } def sendRobotMove(t: tileentity.Robot, ox: Int, oy: Int, oz: Int, direction: ForgeDirection) { @@ -214,7 +244,7 @@ object PacketSender { pb.writeInt(oz) pb.writeDirection(direction) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendRobotAnimateSwing(t: tileentity.Robot) { @@ -223,7 +253,7 @@ object PacketSender { pb.writeTileEntity(t.proxy) pb.writeInt(t.animationTicksTotal) - pb.sendToNearbyPlayers(t, 64) + pb.sendToPlayersNearTileEntity(t, 64) } def sendRobotAnimateTurn(t: tileentity.Robot) { @@ -233,7 +263,7 @@ object PacketSender { pb.writeByte(t.turnAxis) pb.writeInt(t.animationTicksTotal) - pb.sendToNearbyPlayers(t, 64) + pb.sendToPlayersNearTileEntity(t, 64) } def sendRobotInventory(t: tileentity.Robot, slot: Int, stack: ItemStack) { @@ -243,7 +273,7 @@ object PacketSender { pb.writeInt(slot) pb.writeItemStack(stack) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendRobotSelectedSlotChange(t: tileentity.Robot) { @@ -252,7 +282,7 @@ object PacketSender { pb.writeTileEntity(t.proxy) pb.writeInt(t.selectedSlot) - pb.sendToNearbyPlayers(t, 16) + pb.sendToPlayersNearTileEntity(t, 16) } def sendRotatableState(t: Rotatable) { @@ -262,7 +292,7 @@ object PacketSender { pb.writeDirection(t.pitch) pb.writeDirection(t.yaw) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendSwitchActivity(t: tileentity.Switch) { @@ -270,7 +300,7 @@ object PacketSender { pb.writeTileEntity(t) - pb.sendToNearbyPlayers(t, 64) + pb.sendToPlayersNearTileEntity(t, 64) } def appendTextBufferColorChange(pb: PacketBuilder, foreground: PackedColor.Color, background: PackedColor.Color) { @@ -347,7 +377,7 @@ object PacketSender { pb.writeUTF(address) pb.writeBoolean(hasPower) - pb.sendToNearbyPlayers(host) + pb.sendToPlayersNearHost(host) } def sendScreenTouchMode(t: tileentity.Screen, value: Boolean) { @@ -356,7 +386,7 @@ object PacketSender { pb.writeTileEntity(t) pb.writeBoolean(value) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendServerPresence(t: tileentity.ServerRack) { @@ -371,7 +401,7 @@ object PacketSender { pb.writeBoolean(false) } - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendServerState(t: tileentity.ServerRack) { @@ -381,7 +411,7 @@ object PacketSender { pb.writeInt(-1) pb.writeInt(t.range) - pb.sendToNearbyPlayers(t) + pb.sendToPlayersNearTileEntity(t) } def sendServerState(t: tileentity.ServerRack, number: Int, player: Option[EntityPlayerMP] = None) { @@ -399,7 +429,7 @@ object PacketSender { player match { case Some(p) => pb.sendToPlayer(p) - case _ => pb.sendToNearbyPlayers(t) + case _ => pb.sendToPlayersNearTileEntity(t) } } diff --git a/src/main/scala/li/cil/oc/server/component/FileSystem.scala b/src/main/scala/li/cil/oc/server/component/FileSystem.scala index 3ce445c56..f17d9ba6b 100644 --- a/src/main/scala/li/cil/oc/server/component/FileSystem.scala +++ b/src/main/scala/li/cil/oc/server/component/FileSystem.scala @@ -14,7 +14,7 @@ import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context import li.cil.oc.api.network._ import li.cil.oc.api.prefab -import li.cil.oc.common.Sound +import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.ExtendedNBT._ import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagIntArray @@ -65,21 +65,25 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option @Callback(direct = true, doc = """function(path:string):boolean -- Returns whether an object exists at the specified absolute path in the file system.""") def exists(context: Context, args: Arguments): Array[AnyRef] = fileSystem.synchronized { + diskActivity() result(fileSystem.exists(clean(args.checkString(0)))) } @Callback(direct = true, doc = """function(path:string):number -- Returns the size of the object at the specified absolute path in the file system.""") def size(context: Context, args: Arguments): Array[AnyRef] = fileSystem.synchronized { + diskActivity() result(fileSystem.size(clean(args.checkString(0)))) } @Callback(direct = true, doc = """function(path:string):boolean -- Returns whether the object at the specified absolute path in the file system is a directory.""") def isDirectory(context: Context, args: Arguments): Array[AnyRef] = fileSystem.synchronized { + diskActivity() result(fileSystem.isDirectory(clean(args.checkString(0)))) } @Callback(direct = true, doc = """function(path:string):number -- Returns the (real world) timestamp of when the object at the specified absolute path in the file system was modified.""") def lastModified(context: Context, args: Arguments): Array[AnyRef] = fileSystem.synchronized { + diskActivity() result(fileSystem.lastModified(clean(args.checkString(0)))) } @@ -87,7 +91,7 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option def list(context: Context, args: Arguments): Array[AnyRef] = fileSystem.synchronized { Option(fileSystem.list(clean(args.checkString(0)))) match { case Some(list) => - makeSomeNoise() + diskActivity() Array(list) case _ => null } @@ -98,7 +102,7 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option def recurse(path: String): Boolean = !fileSystem.exists(path) && (fileSystem.makeDirectory(path) || (recurse(path.split("/").dropRight(1).mkString("/")) && fileSystem.makeDirectory(path))) val success = recurse(clean(args.checkString(0))) - if (success) makeSomeNoise() + diskActivity() result(success) } @@ -107,14 +111,14 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option def recurse(parent: String): Boolean = (!fileSystem.isDirectory(parent) || fileSystem.list(parent).forall(child => recurse(parent + "/" + child))) && fileSystem.delete(parent) val success = recurse(clean(args.checkString(0))) - if (success) makeSomeNoise() + diskActivity() result(success) } @Callback(doc = """function(from:string, to:string):boolean -- Renames/moves an object from the first specified absolute path in the file system to the second.""") def rename(context: Context, args: Arguments): Array[AnyRef] = fileSystem.synchronized { val success = fileSystem.rename(clean(args.checkString(0)), clean(args.checkString(1))) - if (success) makeSomeNoise() + diskActivity() result(success) } @@ -143,6 +147,7 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option if (handle > 0) { owners.getOrElseUpdate(context.node.address, mutable.Set.empty[Int]) += handle } + diskActivity() result(handle) } @@ -168,7 +173,7 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option if (!node.tryChangeBuffer(-Settings.get.hddReadCost * bytes.length)) { throw new IOException("not enough energy") } - makeSomeNoise() + diskActivity() result(bytes) } else { @@ -208,7 +213,7 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option Option(fileSystem.getHandle(handle)) match { case Some(file) => file.write(value) - makeSomeNoise() + diskActivity() result(true) case _ => throw new IOException("bad file descriptor") } @@ -306,9 +311,9 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option if (!owners.contains(owner) || !owners(owner).contains(handle)) throw new IOException("bad file descriptor") - private def makeSomeNoise() { + private def diskActivity() { (sound, host) match { - case (Some(s), Some(h)) => Sound.play(h, s) + case (Some(s), Some(h)) => ServerPacketSender.sendFileSystemActivity(h, s) case _ => } } diff --git a/src/main/scala/li/cil/oc/server/component/robot/Player.scala b/src/main/scala/li/cil/oc/server/component/robot/Player.scala index 0701b1004..829a499a7 100644 --- a/src/main/scala/li/cil/oc/server/component/robot/Player.scala +++ b/src/main/scala/li/cil/oc/server/component/robot/Player.scala @@ -5,21 +5,21 @@ import java.util.UUID import com.mojang.authlib.GameProfile import cpw.mods.fml.common.ObfuscationReflectionHelper import cpw.mods.fml.common.eventhandler.Event +import li.cil.oc.OpenComputers +import li.cil.oc.Settings import li.cil.oc.api.event._ import li.cil.oc.common.tileentity import li.cil.oc.util.mods.Mods import li.cil.oc.util.mods.PortalGun import li.cil.oc.util.mods.TinkersConstruct -import li.cil.oc.OpenComputers -import li.cil.oc.Settings import net.minecraft.block.Block import net.minecraft.block.BlockPistonBase -import net.minecraft.entity.item.EntityItem -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayer.EnumStatus import net.minecraft.entity.Entity import net.minecraft.entity.EntityLivingBase import net.minecraft.entity.IMerchant +import net.minecraft.entity.item.EntityItem +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.EntityPlayer.EnumStatus import net.minecraft.init.Blocks import net.minecraft.init.Items import net.minecraft.item.ItemBlock @@ -29,14 +29,14 @@ import net.minecraft.potion.PotionEffect import net.minecraft.server.MinecraftServer import net.minecraft.util._ import net.minecraft.world.WorldServer -import net.minecraftforge.common.util.FakePlayer -import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.ForgeHooks import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.common.util.FakePlayer +import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.event.ForgeEventFactory -import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action import net.minecraftforge.event.entity.player.EntityInteractEvent import net.minecraftforge.event.entity.player.PlayerInteractEvent +import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action import net.minecraftforge.event.world.BlockEvent import net.minecraftforge.fluids.FluidRegistry @@ -397,10 +397,10 @@ class Player(val robot: tileentity.Robot) extends FakePlayer(robot.world.asInsta private def tryRepair(stack: ItemStack, oldStack: ItemStack) { // Only if the underlying type didn't change. if (stack.getItem == oldStack.getItem) { - val damageRate = new RobotUsedTool.ComputeDamageRate(robot, oldStack, stack, Settings.get.itemDamageRate) + val damageRate = new RobotUsedToolEvent.ComputeDamageRate(robot, oldStack, stack, Settings.get.itemDamageRate) MinecraftForge.EVENT_BUS.post(damageRate) if (damageRate.getDamageRate < 1) { - MinecraftForge.EVENT_BUS.post(new RobotUsedTool.ApplyDamageRate(robot, oldStack, stack, damageRate.getDamageRate)) + MinecraftForge.EVENT_BUS.post(new RobotUsedToolEvent.ApplyDamageRate(robot, oldStack, stack, damageRate.getDamageRate)) } } } diff --git a/src/main/scala/li/cil/oc/server/driver/item/ComputerCraftMedia.scala b/src/main/scala/li/cil/oc/server/driver/item/ComputerCraftMedia.scala index 334a142ad..3df6d4fd8 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/ComputerCraftMedia.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/ComputerCraftMedia.scala @@ -2,6 +2,7 @@ package li.cil.oc.server.driver.item import dan200.computercraft.api.media.IMedia import li.cil.oc +import li.cil.oc.Settings import li.cil.oc.api.driver.EnvironmentHost import li.cil.oc.api.fs.Label import li.cil.oc.common.Slot @@ -18,7 +19,7 @@ object ComputerCraftMedia extends Item { if (Mods.ComputerCraft.isAvailable && ComputerCraft.isDisk(stack) && host != null) { val address = addressFromTag(dataTag(stack)) val mount = ComputerCraft.createDiskMount(stack, host.world) - Option(oc.api.FileSystem.asManagedEnvironment(mount, new ComputerCraftLabel(stack), host, "floppy_access")) match { + Option(oc.api.FileSystem.asManagedEnvironment(mount, new ComputerCraftLabel(stack), host, Settings.resourceDomain + ":floppy_access")) match { case Some(environment) => environment.node.asInstanceOf[oc.server.network.Node].address = address environment diff --git a/src/main/scala/li/cil/oc/server/driver/item/FileSystem.scala b/src/main/scala/li/cil/oc/server/driver/item/FileSystem.scala index 3bcefdaef..078216560 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/FileSystem.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/FileSystem.scala @@ -43,7 +43,7 @@ object FileSystem extends Item { val address = addressFromTag(dataTag(stack)) val isFloppy = api.Items.get(stack) == api.Items.get("floppy") val fs = oc.api.FileSystem.fromSaveDirectory(address, capacity, Settings.get.bufferChanges) - val environment = oc.api.FileSystem.asManagedEnvironment(fs, new ReadWriteItemLabel(stack), host, if (isFloppy) "floppy_access" else "hdd_access") + val environment = oc.api.FileSystem.asManagedEnvironment(fs, new ReadWriteItemLabel(stack), host, Settings.resourceDomain + ":" + (if (isFloppy) "floppy_access" else "hdd_access")) if (environment != null && environment.node != null) { environment.node.asInstanceOf[oc.server.network.Node].address = address } diff --git a/src/main/scala/li/cil/oc/server/driver/item/Loot.scala b/src/main/scala/li/cil/oc/server/driver/item/Loot.scala index 8cd8829d3..71e244243 100644 --- a/src/main/scala/li/cil/oc/server/driver/item/Loot.scala +++ b/src/main/scala/li/cil/oc/server/driver/item/Loot.scala @@ -30,7 +30,7 @@ object Loot extends Item { dataTag(stack).getString(Settings.namespace + "fs.label") } else null - api.FileSystem.asManagedEnvironment(fs, label, host, "floppy_access") + api.FileSystem.asManagedEnvironment(fs, label, host, Settings.resourceDomain + ":floppy_access") } else null