diff --git a/li/cil/oc/common/Proxy.scala b/li/cil/oc/common/Proxy.scala index 919921b4b..03f620e97 100644 --- a/li/cil/oc/common/Proxy.scala +++ b/li/cil/oc/common/Proxy.scala @@ -1,11 +1,14 @@ package li.cil.oc.common +import cpw.mods.fml.common.IPlayerTracker import cpw.mods.fml.common.event._ +import cpw.mods.fml.common.registry.GameRegistry import li.cil.oc._ import li.cil.oc.server.component.Computer import li.cil.oc.server.driver import li.cil.oc.server.fs import li.cil.oc.server.network +import net.minecraft.entity.player.EntityPlayer import net.minecraftforge.common.MinecraftForge class Proxy { @@ -33,6 +36,22 @@ class Proxy { MinecraftForge.EVENT_BUS.register(Computer) MinecraftForge.EVENT_BUS.register(network.Network) + + GameRegistry.registerPlayerTracker(new IPlayerTracker { + def onPlayerRespawn(player: EntityPlayer) { + MinecraftForge.EVENT_BUS.post(new ReleasePressedKeys(player)) + } + + def onPlayerChangedDimension(player: EntityPlayer) { + MinecraftForge.EVENT_BUS.post(new ReleasePressedKeys(player)) + } + + def onPlayerLogout(player: EntityPlayer) { + MinecraftForge.EVENT_BUS.post(new ReleasePressedKeys(player)) + } + + def onPlayerLogin(player: EntityPlayer) {} + }) } def postInit(e: FMLPostInitializationEvent): Unit = { diff --git a/li/cil/oc/common/ReleasePressedKeys.scala b/li/cil/oc/common/ReleasePressedKeys.scala new file mode 100644 index 000000000..de1d56978 --- /dev/null +++ b/li/cil/oc/common/ReleasePressedKeys.scala @@ -0,0 +1,6 @@ +package li.cil.oc.common + +import net.minecraft.entity.player.EntityPlayer +import net.minecraftforge.event.Event + +class ReleasePressedKeys(val player: EntityPlayer) extends Event diff --git a/li/cil/oc/common/tileentity/Keyboard.scala b/li/cil/oc/common/tileentity/Keyboard.scala index 0c95f1f8f..a6c5b0d46 100644 --- a/li/cil/oc/common/tileentity/Keyboard.scala +++ b/li/cil/oc/common/tileentity/Keyboard.scala @@ -1,17 +1,22 @@ package li.cil.oc.common.tileentity -import cpw.mods.fml.common.network.Player import li.cil.oc.api import li.cil.oc.api.Network import li.cil.oc.api.network.{Visibility, Message} +import li.cil.oc.common.ReleasePressedKeys import net.minecraft.entity.player.EntityPlayer import net.minecraft.nbt.NBTTagCompound +import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.event.ForgeSubscribe +import scala.collection.mutable class Keyboard extends Rotatable with Environment { val node = api.Network.newNode(this, Visibility.Network). withComponent("keyboard"). create() + val pressedKeys = mutable.Map.empty[EntityPlayer, mutable.Map[Integer, Character]] + // ----------------------------------------------------------------------- // override def updateEntity() { @@ -22,6 +27,33 @@ class Keyboard extends Rotatable with Environment { // ----------------------------------------------------------------------- // + override def invalidate() { + super.invalidate() + MinecraftForge.EVENT_BUS.unregister(this) + } + + override def validate() { + super.validate() + MinecraftForge.EVENT_BUS.register(this) + } + + override def onChunkUnload() { + super.onChunkUnload() + MinecraftForge.EVENT_BUS.unregister(this) + } + + @ForgeSubscribe + def onReleasePressedKeys(e: ReleasePressedKeys) { + pressedKeys.get(e.player) match { + case Some(keys) => for ((code, char) <- keys) + node.sendToReachable("computer.signal", "key_up", char, code, e.player.getCommandSenderName) + case _ => + } + pressedKeys.remove(e.player) + } + + // ----------------------------------------------------------------------- // + override def readFromNBT(nbt: NBTTagCompound) { super.readFromNBT(nbt) node.load(nbt) @@ -36,15 +68,22 @@ class Keyboard extends Rotatable with Environment { override def onMessage(message: Message) = { message.data match { - case Array(p: Player, char: Character, code: Integer) if message.name == "keyboard.keyDown" => - if (isUseableByPlayer(p)) - node.sendToReachable("computer.signal", "key_down", char, code) - case Array(p: Player, char: Character, code: Integer) if message.name == "keyboard.keyUp" => - if (isUseableByPlayer(p)) - node.sendToReachable("computer.signal", "key_up", char, code) - case Array(p: Player, value: String) if message.name == "keyboard.clipboard" => - if (isUseableByPlayer(p)) - node.sendToReachable("computer.signal", "clipboard", value) + case Array(p: EntityPlayer, char: Character, code: Integer) if message.name == "keyboard.keyDown" => + if (isUseableByPlayer(p)) { + pressedKeys.getOrElseUpdate(p, mutable.Map.empty[Integer, Character]) += code -> char + node.sendToReachable("computer.signal", "key_down", char, code, p.getCommandSenderName) + } + case Array(p: EntityPlayer, char: Character, code: Integer) if message.name == "keyboard.keyUp" => + pressedKeys.get(p) match { + case Some(keys) if keys.contains(code) => + keys -= code + node.sendToReachable("computer.signal", "key_up", char, code, p.getCommandSenderName) + case _ => + } + case Array(p: EntityPlayer, value: String) if message.name == "keyboard.clipboard" => + if (isUseableByPlayer(p)) { + node.sendToReachable("computer.signal", "clipboard", value, p.getCommandSenderName) + } case _ => } super.onMessage(message) @@ -52,6 +91,6 @@ class Keyboard extends Rotatable with Environment { // ----------------------------------------------------------------------- // - def isUseableByPlayer(p: Player) = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this && - p.asInstanceOf[EntityPlayer].getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64 + def isUseableByPlayer(p: EntityPlayer) = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this && + p.getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64 } \ No newline at end of file