From 41f041f3f9014ca248404fd5a496fc5f11824f84 Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:36:08 +0530 Subject: [PATCH] implement chat (lobby) and fix marble sounds --- src/Marble.hx | 53 ++++++++++++++++++---------- src/gui/ChatCtrl.hx | 2 +- src/gui/GuiScrollCtrl.hx | 9 ++++- src/gui/MPPlayMissionGui.hx | 69 +++++++++++++++++++++++++++++++++++++ src/net/Net.hx | 2 ++ src/net/NetCommands.hx | 1 + 6 files changed, 116 insertions(+), 20 deletions(-) diff --git a/src/Marble.hx b/src/Marble.hx index 12a888aa..9f85b0a6 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -717,14 +717,22 @@ class Marble extends GameObject { for (contact in contacts) { if (contact.force != 0 && !forceObjects.contains(contact.otherObject)) { if (contact.otherObject is RoundBumper) { - if (!playedSounds.contains("data/sound/bumperding1.wav")) { - AudioManager.playSound(ResourceLoader.getResource("data/sound/bumperding1.wav", ResourceLoader.getAudio, this.soundResources)); + if (!playedSounds.contains("data/sound/bumperding1.wav") && !this.isNetUpdate) { + if (level.marble == cast this) + AudioManager.playSound(ResourceLoader.getResource("data/sound/bumperding1.wav", ResourceLoader.getAudio, this.soundResources)); + else + AudioManager.playSound(ResourceLoader.getResource("data/sound/bumperding1.wav", ResourceLoader.getAudio, this.soundResources), + this.getAbsPos().getPosition()); playedSounds.push("data/sound/bumperding1.wav"); } } if (contact.otherObject is TriangleBumper) { - if (!playedSounds.contains("data/sound/bumper1.wav")) { - AudioManager.playSound(ResourceLoader.getResource("data/sound/bumper1.wav", ResourceLoader.getAudio, this.soundResources)); + if (!playedSounds.contains("data/sound/bumper1.wav") && !this.isNetUpdate) { + if (level.marble == cast this) + AudioManager.playSound(ResourceLoader.getResource("data/sound/bumper1.wav", ResourceLoader.getAudio, this.soundResources)); + else + AudioManager.playSound(ResourceLoader.getResource("data/sound/bumper1.wav", ResourceLoader.getAudio, this.soundResources), + this.getAbsPos().getPosition()); playedSounds.push("data/sound/bumper1.wav"); } } @@ -1099,17 +1107,20 @@ class Marble extends GameObject { if (minVelocityBounceSoft <= contactVel) { var hardBounceSpeed = minVelocityBounceHard; var bounceSoundNum = Math.floor(Math.random() * 4); - var sndList = (time - this.megaMarbleEnableTime < 10) ? [ - "data/sound/mega_bouncehard1.wav", - "data/sound/mega_bouncehard2.wav", - "data/sound/mega_bouncehard3.wav", - "data/sound/mega_bouncehard4.wav" - ] : [ - "data/sound/bouncehard1.wav", - "data/sound/bouncehard2.wav", - "data/sound/bouncehard3.wav", - "data/sound/bouncehard4.wav" - ]; + var sndList = ((time - this.megaMarbleEnableTime < 10) + || (this.megaMarbleUseTick > 0 + && ((Net.isHost && (this.level.timeState.ticks - this.megaMarbleUseTick) <= 312) + || (Net.isClient && (this.serverTicks - this.megaMarbleUseTick) <= 312)))) ? [ + "data/sound/mega_bouncehard1.wav", + "data/sound/mega_bouncehard2.wav", + "data/sound/mega_bouncehard3.wav", + "data/sound/mega_bouncehard4.wav" + ] : [ + "data/sound/bouncehard1.wav", + "data/sound/bouncehard2.wav", + "data/sound/bouncehard3.wav", + "data/sound/bouncehard4.wav" + ]; var snd = ResourceLoader.getResource(sndList[bounceSoundNum], ResourceLoader.getAudio, this.soundResources); var gain = bounceMinGain; @@ -1120,7 +1131,10 @@ class Marble extends GameObject { // else // gain = (contactVel - minVelocityBounceSoft) / (hardBounceSpeed - minVelocityBounceSoft) * (1.0 - gain) + gain; - snd.play(false, Settings.optionsSettings.soundVolume * gain); + if (!this.controllable) + AudioManager.playSound(snd, this.getAbsPos().getPosition()); + else + snd.play(false, Settings.optionsSettings.soundVolume * gain); } } @@ -1159,7 +1173,10 @@ class Marble extends GameObject { if (slipVolume < 0) slipVolume = 0; - if (time.currentAttemptTime - this.megaMarbleEnableTime < 10) { + if (time.currentAttemptTime - this.megaMarbleEnableTime < 10 + || (this.megaMarbleUseTick > 0 + && ((Net.isHost && (this.level.timeState.ticks - this.megaMarbleUseTick) <= 312) + || (Net.isClient && (this.serverTicks - this.megaMarbleUseTick) <= 312)))) { if (this.rollMegaSound != null) { rollMegaSound.volume = rollVolume; rollSound.volume = 0; @@ -2378,7 +2395,7 @@ class Marble extends GameObject { var blastAmt = this.blastTicks / (25000 >> 5); var impulse = this.currentUp.multiply(Math.max(Math.sqrt(blastAmt), blastAmt) * 10); this.applyImpulse(impulse); - if (!isNetUpdate && level.marble == cast this) + if (!isNetUpdate && this.controllable) AudioManager.playSound(ResourceLoader.getResource('data/sound/blast.wav', ResourceLoader.getAudio, this.soundResources)); if (!isNetUpdate) this.level.particleManager.createEmitter(blastAmt > 1 ? blastMaxParticleOptions : blastParticleOptions, diff --git a/src/gui/ChatCtrl.hx b/src/gui/ChatCtrl.hx index 54324192..183d0e99 100644 --- a/src/gui/ChatCtrl.hx +++ b/src/gui/ChatCtrl.hx @@ -87,7 +87,7 @@ class ChatCtrl extends GuiControl { this.chatHudInput.text.onKeyDown = (e) -> { if (e.keyCode == Key.ENTER) { if (StringTools.trim(this.chatHudInput.text.text) != "") { - sendText = '${StringTools.htmlEscape(Settings.highscoreName.substr(0, 20))}: ${StringTools.htmlEscape(this.chatHudInput.text.text.substr(0, 50))}'; + sendText = '${StringTools.htmlEscape(Settings.highscoreName.substr(0, 20))}: ${StringTools.htmlEscape(this.chatHudInput.text.text.substr(0, 150))}'; if (Net.isClient) { NetCommands.sendChatMessage(StringTools.htmlEscape(sendText)); } diff --git a/src/gui/GuiScrollCtrl.hx b/src/gui/GuiScrollCtrl.hx index 7828fd54..8da41e74 100644 --- a/src/gui/GuiScrollCtrl.hx +++ b/src/gui/GuiScrollCtrl.hx @@ -16,6 +16,7 @@ class GuiScrollCtrl extends GuiControl { public var enabled:Bool = true; public var childrenHandleScroll:Bool = false; public var scrollSpeed = 500; + public var scrollToBottom:Bool = false; var maxScrollY:Float; @@ -96,7 +97,13 @@ class GuiScrollCtrl extends GuiControl { } public function setScrollMax(max:Float) { - this.scrollY = 0; + var renderRect = this.getRenderRectangle(); + if (scrollToBottom) { + var scrollBarYSize = renderRect.extent.y * renderRect.extent.y / (max * Settings.uiScale); + this.scrollY = renderRect.extent.y - scrollBarYSize * Settings.uiScale; + } else { + this.scrollY = 0; + } this.maxScrollY = max; this.dirty = true; this.updateScrollVisual(); diff --git a/src/gui/MPPlayMissionGui.hx b/src/gui/MPPlayMissionGui.hx index 5f32e139..1189aed9 100644 --- a/src/gui/MPPlayMissionGui.hx +++ b/src/gui/MPPlayMissionGui.hx @@ -24,6 +24,8 @@ class MPPlayMissionGui extends GuiImage { static var currentSelectionStatic:Int = -1; static var currentCategoryStatic:String = "beginner"; + public static var allChats:Array = []; + static var setLevelFn:(String, Int) -> Void; static var playSelectedLevel:(String, Int) -> Void; static var setLevelStr:String->Void; @@ -47,6 +49,9 @@ class MPPlayMissionGui extends GuiImage { #end var playerListCtrl:GuiTextListCtrl; + var chatInput:GuiTextInput; + var chatScroll:GuiScrollCtrl; + var chatBox:GuiMLText; public function new(isHost:Bool = true) { MissionList.buildMissionList(); @@ -362,6 +367,50 @@ class MPPlayMissionGui extends GuiImage { }; playersBox.addChild(playerListTitle); + chatScroll = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources).toTile()); + chatScroll.position = new Vector(47, 282); + chatScroll.extent = new Vector(407, 193); + chatScroll.childrenHandleScroll = true; + chatScroll.scrollToBottom = true; + window.addChild(chatScroll); + + chatBox = new GuiMLText(markerFelt18, mlFontLoader); + chatBox.text.textColor = 0x000000; + chatBox.horizSizing = Width; + chatBox.position = new Vector(0, 0); + chatBox.extent = new Vector(396, 1184); + chatScroll.addChild(chatBox); + + var chatInputContainer = new GuiControl(); + chatInputContainer.position = new Vector(50, 476); + chatInputContainer.extent = new Vector(402, 30); + window.addChild(chatInputContainer); + + chatInput = new GuiTextInput(markerFelt18); + chatInput.text.textColor = 0x000000; + chatInput.horizSizing = Width; + chatInput.position = new Vector(0, 0); + chatInput.extent = new Vector(402, 30); + chatInputContainer.addChild(chatInput); + @:privateAccess chatInput.text.interactive.forceAnywherefocus = true; + + chatInput.text.onKeyDown = (e) -> { + if (e.keyCode == Key.ENTER) { + if (StringTools.trim(chatInput.text.text) != "") { + var sendText = '${StringTools.htmlEscape(Settings.highscoreName.substr(0, 20))}: ${StringTools.htmlEscape(chatInput.text.text.substr(0, 100))}'; + if (Net.isClient) { + NetCommands.sendChatMessage(StringTools.htmlEscape(sendText)); + } + if (Net.isHost) { + NetCommands.sendServerChatMessage(StringTools.htmlEscape(sendText)); + } + } + chatInput.text.text = ""; + haxe.Timer.delay(() -> chatInput.text.focus(), 10); + } + @:privateAccess Key.keyPressed[e.keyCode] = 0; // consume keys + } + this.addChild(window); buttonHoldFunc = (dt:Float, mouseState:MouseState) -> { @@ -570,6 +619,7 @@ class MPPlayMissionGui extends GuiImage { setCategoryFunc(currentCategoryStatic, null, false); updateLobbyNames(); + redrawChat(); } public override function render(scene2d:Scene, ?parent:h2d.Flow) { @@ -629,4 +679,23 @@ class MPPlayMissionGui extends GuiImage { // return '${player.name}'; // })); } + + public static function addChatMessage(s:String) { + var realText = StringTools.htmlUnescape(s); + allChats.push(realText); + if (allChats.length > 100) { + allChats = allChats.slice(allChats.length - 100); + } + if (MarbleGame.canvas.content is MPPlayMissionGui) { + var mpp = cast(MarbleGame.canvas.content, MPPlayMissionGui); + mpp.redrawChat(); + } + } + + public function redrawChat() { + var joined = allChats.join("
"); + this.chatBox.text.text = StringTools.replace(joined, '#F29515', '#000000'); + this.chatScroll.setScrollMax(chatBox.text.textHeight); + this.chatScroll.updateScrollVisual(); + } } diff --git a/src/net/Net.hx b/src/net/Net.hx index 21db81e9..561c081c 100644 --- a/src/net/Net.hx +++ b/src/net/Net.hx @@ -379,6 +379,7 @@ class Net { Net.hostReady = false; Net.hostSpectate = false; Net.clientSpectate = false; + MPPlayMissionGui.allChats = []; // MultiplayerLevelSelectGui.custSelected = false; } if (Net.isHost) { @@ -402,6 +403,7 @@ class Net { Net.hostReady = false; Net.hostSpectate = false; Net.clientSpectate = false; + MPPlayMissionGui.allChats = []; // MultiplayerLevelSelectGui.custSelected = false; } } diff --git a/src/net/NetCommands.hx b/src/net/NetCommands.hx index 5ebf6405..94d0d8c6 100644 --- a/src/net/NetCommands.hx +++ b/src/net/NetCommands.hx @@ -445,5 +445,6 @@ class NetCommands { // cast(MarbleGame.canvas.content, MultiplayerLevelSelectGui).addChatMessage(msg); // } } + MPPlayMissionGui.addChatMessage(msg); } }