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);
}
}