Fancy speech bubbles - Names over speech bubbles, and 1:1 chat parity for emotes and LOOC! (#21999)
This commit is contained in:
@@ -369,7 +369,7 @@ public sealed class ChatUIController : UIController
|
||||
UpdateChannelPermissions();
|
||||
}
|
||||
|
||||
private void AddSpeechBubble(ChatMessage msg, SpeechBubble.SpeechType speechType, string? prefixText = null, string? prefixEndText = null)
|
||||
private void AddSpeechBubble(ChatMessage msg, SpeechBubble.SpeechType speechType)
|
||||
{
|
||||
var ent = EntityManager.GetEntity(msg.SenderEntity);
|
||||
|
||||
@@ -379,22 +379,13 @@ public sealed class ChatUIController : UIController
|
||||
return;
|
||||
}
|
||||
|
||||
// Kind of shitty way to add prefixes but hey it works!
|
||||
string Message = prefixText + msg.Message + prefixEndText;
|
||||
|
||||
// msg.Message should be the string that a user sent over text, without any added markup.
|
||||
var messages = SplitMessage(Message);
|
||||
|
||||
foreach (var message in messages)
|
||||
{
|
||||
EnqueueSpeechBubble(ent, message, speechType);
|
||||
}
|
||||
EnqueueSpeechBubble(ent, msg, speechType);
|
||||
}
|
||||
|
||||
private void CreateSpeechBubble(EntityUid entity, SpeechBubbleData speechData)
|
||||
{
|
||||
var bubble =
|
||||
SpeechBubble.CreateSpeechBubble(speechData.Type, speechData.Message, entity, _eye, _manager, EntityManager);
|
||||
SpeechBubble.CreateSpeechBubble(speechData.Type, speechData.Message, entity);
|
||||
|
||||
bubble.OnDied += SpeechBubbleDied;
|
||||
|
||||
@@ -428,7 +419,7 @@ public sealed class ChatUIController : UIController
|
||||
RemoveSpeechBubble(entity, bubble);
|
||||
}
|
||||
|
||||
private void EnqueueSpeechBubble(EntityUid entity, string contents, SpeechBubble.SpeechType speechType)
|
||||
private void EnqueueSpeechBubble(EntityUid entity, ChatMessage message, SpeechBubble.SpeechType speechType)
|
||||
{
|
||||
// Don't enqueue speech bubbles for other maps. TODO: Support multiple viewports/maps?
|
||||
if (EntityManager.GetComponent<TransformComponent>(entity).MapID != _eye.CurrentMap)
|
||||
@@ -440,7 +431,7 @@ public sealed class ChatUIController : UIController
|
||||
_queuedSpeechBubbles.Add(entity, queueData);
|
||||
}
|
||||
|
||||
queueData.MessageQueue.Enqueue(new SpeechBubbleData(contents, speechType));
|
||||
queueData.MessageQueue.Enqueue(new SpeechBubbleData(message, speechType));
|
||||
}
|
||||
|
||||
public void RemoveSpeechBubble(EntityUid entityUid, SpeechBubble bubble)
|
||||
@@ -568,7 +559,7 @@ public sealed class ChatUIController : UIController
|
||||
|
||||
var msg = queueData.MessageQueue.Dequeue();
|
||||
|
||||
queueData.TimeLeft += BubbleDelayBase + msg.Message.Length * BubbleDelayFactor;
|
||||
queueData.TimeLeft += BubbleDelayBase + msg.Message.Message.Length * BubbleDelayFactor;
|
||||
|
||||
// We keep the queue around while it has 0 items. This allows us to keep the timer.
|
||||
// When the timer hits 0 and there's no messages left, THEN we can clear it up.
|
||||
@@ -621,52 +612,6 @@ public sealed class ChatUIController : UIController
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> SplitMessage(string msg)
|
||||
{
|
||||
// Split message into words separated by spaces.
|
||||
var words = msg.Split(' ');
|
||||
var messages = new List<string>();
|
||||
var currentBuffer = new List<string>();
|
||||
|
||||
// Really shoddy way to approximate word length.
|
||||
// Yes, I am aware of all the crimes here.
|
||||
// TODO: Improve this to use actual glyph width etc..
|
||||
var currentWordLength = 0;
|
||||
foreach (var word in words)
|
||||
{
|
||||
// +1 for the space.
|
||||
currentWordLength += word.Length + 1;
|
||||
|
||||
if (currentWordLength > SingleBubbleCharLimit)
|
||||
{
|
||||
// Too long for the current speech bubble, flush it.
|
||||
messages.Add(string.Join(" ", currentBuffer));
|
||||
currentBuffer.Clear();
|
||||
|
||||
currentWordLength = word.Length;
|
||||
|
||||
if (currentWordLength > SingleBubbleCharLimit)
|
||||
{
|
||||
// Word is STILL too long.
|
||||
// Truncate it with an ellipse.
|
||||
messages.Add($"{word.Substring(0, SingleBubbleCharLimit - 3)}...");
|
||||
currentWordLength = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
currentBuffer.Add(word);
|
||||
}
|
||||
|
||||
if (currentBuffer.Count != 0)
|
||||
{
|
||||
// Don't forget the last bubble.
|
||||
messages.Add(string.Join(" ", currentBuffer));
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
public ChatSelectChannel MapLocalIfGhost(ChatSelectChannel channel)
|
||||
{
|
||||
if (channel == ChatSelectChannel.Local && _ghost is {IsGhost: true})
|
||||
@@ -849,11 +794,7 @@ public sealed class ChatUIController : UIController
|
||||
|
||||
case ChatChannel.LOOC:
|
||||
if (_cfg.GetCVar(CCVars.LoocAboveHeadShow))
|
||||
{
|
||||
const string prefixText = "(LOOC: ";
|
||||
const string prefixEndText = ")";
|
||||
AddSpeechBubble(msg, SpeechBubble.SpeechType.Looc, prefixText, prefixEndText);
|
||||
}
|
||||
AddSpeechBubble(msg, SpeechBubble.SpeechType.Looc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -896,7 +837,7 @@ public sealed class ChatUIController : UIController
|
||||
}
|
||||
}
|
||||
|
||||
private readonly record struct SpeechBubbleData(string Message, SpeechBubble.SpeechType Type);
|
||||
private readonly record struct SpeechBubbleData(ChatMessage Message, SpeechBubble.SpeechType Type);
|
||||
|
||||
private sealed class SpeechBubbleQueueData
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user