diff --git a/src/Marble.hx b/src/Marble.hx index 67325e47..9d1098cd 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -360,7 +360,7 @@ class Marble extends GameObject { this.rollSound.volume = 0; this.slipSound.volume = 0; this.helicopterSound = AudioManager.playSound(ResourceLoader.getResource("data/sound/use_gyrocopter.wav", ResourceLoader.getAudio, - this.soundResources), null, true); + this.soundResources), this.getAbsPos().getPosition(), true); this.helicopterSound.pause = true; } @@ -2092,7 +2092,8 @@ class Marble extends GameObject { this._radius = this._prevRadius; this.collider.radius = this._radius; this._marbleScale = this._defaultScale; - AudioManager.playSound(ResourceLoader.getResource("data/sound/MegaShrink.wav", ResourceLoader.getAudio, this.soundResources), null, false); + if (this.controllable) + AudioManager.playSound(ResourceLoader.getResource("data/sound/MegaShrink.wav", ResourceLoader.getAudio, this.soundResources), null, false); } } diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 6af5f865..75077c67 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -1,5 +1,6 @@ package src; +import net.NetPacket.ScoreboardPacket; import net.NetPacket.PowerupPickupPacket; import net.Move; import net.NetPacket.GemSpawnPacket; @@ -678,7 +679,8 @@ class MarbleWorld extends Scheduler { this.deselectPowerUp(this.marble); playGui.setCenterText(''); - AudioManager.playSound(ResourceLoader.getResource('data/sound/spawn_alternate.wav', ResourceLoader.getAudio, this.soundResources)); + if (marble == this.marble) + AudioManager.playSound(ResourceLoader.getResource('data/sound/spawn_alternate.wav', ResourceLoader.getAudio, this.soundResources)); if (!this.isMultiplayer) this.gameMode.onRestart(); @@ -1192,6 +1194,16 @@ class MarbleWorld extends Scheduler { } } + // Scoreboard! + var b = new OutputBitStream(); + b.writeByte(NetPacketType.ScoreBoardInfo); + var sbPacket = new ScoreboardPacket(); + for (player in @:privateAccess this.playGui.playerList) { + sbPacket.scoreBoard.set(player.id, player.score); + } + sbPacket.serialize(b); + packets.push(b.getBytes()); + return packets; } diff --git a/src/gui/PlayGui.hx b/src/gui/PlayGui.hx index 7622c38b..97f80c79 100644 --- a/src/gui/PlayGui.hx +++ b/src/gui/PlayGui.hx @@ -1,5 +1,6 @@ package gui; +import net.NetPacket.ScoreboardPacket; import net.Net; import h3d.Matrix; import src.ProfilerUI; @@ -32,6 +33,7 @@ import hxd.res.Sound; import h3d.mat.Texture; import src.Settings; import src.Util; +import src.AudioManager; typedef MiddleMessage = { ctrl:GuiText, @@ -833,11 +835,21 @@ class PlayGui { if (score == 5 && MarbleGame.instance.world.mission.title == "Marble It Up!") { AchievementsGui.queueMPAchievement(4096); } - } + if (Net.isClient) + AudioManager.playSound(ResourceLoader.getResource('data/sound/gem_collect.wav', ResourceLoader.getAudio, this.soundResources)); + } else if (Net.isClient) + AudioManager.playSound(ResourceLoader.getResource('data/sound/opponent_gem_collect.wav', ResourceLoader.getAudio, this.soundResources)); redrawPlayerList(); } + public function updatePlayerScores(scoreboardPacket:ScoreboardPacket) { + for (player in playerList) { + player.score = scoreboardPacket.scoreBoard.exists(player.id) ? scoreboardPacket.scoreBoard.get(player.id) : 0; + } + redrawPlayerList(); + } + public function resetPlayerScores() { for (player in playerList) { player.score = 0; diff --git a/src/modes/HuntMode.hx b/src/modes/HuntMode.hx index 879f1eb0..f095f8b5 100644 --- a/src/modes/HuntMode.hx +++ b/src/modes/HuntMode.hx @@ -313,7 +313,7 @@ class HuntMode extends NullMode { } override function onGemPickup(marble:Marble, gem:Gem) { - if (@:privateAccess !marble.isNetUpdate) { + if (@:privateAccess !marble.isNetUpdate && Net.isHost) { if (marble == level.marble) AudioManager.playSound(ResourceLoader.getResource('data/sound/gem_collect.wav', ResourceLoader.getAudio, @:privateAccess this.level.soundResources)); diff --git a/src/net/Net.hx b/src/net/Net.hx index 34d076c9..3ac76348 100644 --- a/src/net/Net.hx +++ b/src/net/Net.hx @@ -1,5 +1,6 @@ package net; +import net.NetPacket.ScoreboardPacket; import gui.MultiplayerLevelSelectGui; import gui.Canvas; import net.MasterServerClient.RemoteServerInfo; @@ -34,6 +35,7 @@ enum abstract NetPacketType(Int) from Int to Int { var GemSpawn; var GemPickup; var PlayerInfo; + var ScoreBoardInfo; } @:publicFields @@ -427,6 +429,7 @@ class Net { clients.set(c, cc); cc.isPrivate = joiningPrivate; clientIdMap[clientId] = clients[c]; + cc.lastRecvTime = Console.time(); // So it doesnt get timed out var closing = false; @@ -507,10 +510,15 @@ class Net { static function onClientLeave(cc:ClientConnection) { if (!Net.isMP) return; - serverInfo.players--; - MasterServerClient.instance.sendServerInfo(serverInfo); // notify the server of the player leave NetCommands.clientDisconnected(cc.id); + serverInfo.players = 1; + for (k => v in clientIdMap) { // Recount + serverInfo.players++; + } + + MasterServerClient.instance.sendServerInfo(serverInfo); // notify the server of the player leave + AudioManager.playSound(ResourceLoader.getAudio("data/sound/infotutorial.wav").resource); if (MarbleGame.canvas.content is MultiplayerLevelSelectGui) { @@ -698,6 +706,13 @@ class Net { cast(MarbleGame.canvas.content, MultiplayerLevelSelectGui).updateLobbyNames(); } + case ScoreBoardInfo: + var scoreboardPacket = new ScoreboardPacket(); + scoreboardPacket.deserialize(input); + if (MarbleGame.instance.world != null && !MarbleGame.instance.world._disposed) { + @:privateAccess MarbleGame.instance.world.playGui.updatePlayerScores(scoreboardPacket); + } + case _: Console.log("unknown command: " + packetType); } diff --git a/src/net/NetPacket.hx b/src/net/NetPacket.hx index 2456c0e3..6695e51e 100644 --- a/src/net/NetPacket.hx +++ b/src/net/NetPacket.hx @@ -220,3 +220,30 @@ class GemPickupPacket implements NetPacket { b.writeInt(scoreIncr, 4); } } + +@:publicFields +class ScoreboardPacket implements NetPacket { + var scoreBoard:Map; + + public function new() { + scoreBoard = new Map(); + } + + public inline function deserialize(b:InputBitStream) { + var count = b.readInt(4); + for (i in 0...count) { + scoreBoard[b.readInt(6)] = b.readInt(10); + } + } + + public inline function serialize(b:OutputBitStream) { + var keycount = 0; + for (k => v in scoreBoard) + keycount++; + b.writeInt(keycount, 4); + for (key => v in scoreBoard) { + b.writeInt(key, 6); + b.writeInt(v, 10); + } + } +}