Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into upstream-merge-41
Browse files Browse the repository at this point in the history
  • Loading branch information
Werzet committed Dec 5, 2023
2 parents 6fa9ab9 + 858474d commit 15c5dfc
Show file tree
Hide file tree
Showing 184 changed files with 3,253 additions and 900 deletions.
151 changes: 122 additions & 29 deletions Content.Client/Chat/UI/SpeechBubble.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
using System.Numerics;
using Content.Client.Chat.Managers;
using Content.Shared.CCVar;
using Content.Shared.Chat;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Client.Chat.UI
{
public abstract class SpeechBubble : Control
{
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] protected readonly IConfigurationManager ConfigManager = default!;

public enum SpeechType : byte
{
Emote,
Expand All @@ -34,10 +41,12 @@ public enum SpeechType : byte
/// </summary>
private const float EntityVerticalOffset = 0.5f;

private readonly IEyeManager _eyeManager;
/// <summary>
/// The default maximum width for speech bubbles.
/// </summary>
public const float SpeechMaxWidth = 256;

private readonly EntityUid _senderEntity;
private readonly IChatManager _chatManager;
private readonly IEntityManager _entityManager;

private float _timeLeft = TotalTime;

Expand All @@ -49,38 +58,36 @@ public enum SpeechType : byte
// man down
public event Action<EntityUid, SpeechBubble>? OnDied;

public static SpeechBubble CreateSpeechBubble(SpeechType type, string text, EntityUid senderEntity, IEyeManager eyeManager, IChatManager chatManager, IEntityManager entityManager)
public static SpeechBubble CreateSpeechBubble(SpeechType type, ChatMessage message, EntityUid senderEntity)
{
switch (type)
{
case SpeechType.Emote:
return new TextSpeechBubble(text, senderEntity, eyeManager, chatManager, entityManager, "emoteBox");
return new TextSpeechBubble(message, senderEntity, "emoteBox");

case SpeechType.Say:
return new TextSpeechBubble(text, senderEntity, eyeManager, chatManager, entityManager, "sayBox");
return new FancyTextSpeechBubble(message, senderEntity, "sayBox");

case SpeechType.Whisper:
return new TextSpeechBubble(text, senderEntity, eyeManager, chatManager, entityManager, "whisperBox");
return new FancyTextSpeechBubble(message, senderEntity, "whisperBox");

case SpeechType.Looc:
return new TextSpeechBubble(text, senderEntity, eyeManager, chatManager, entityManager, "emoteBox", Color.FromHex("#48d1cc"));
return new TextSpeechBubble(message, senderEntity, "emoteBox", Color.FromHex("#48d1cc"));

default:
throw new ArgumentOutOfRangeException();
}
}

public SpeechBubble(string text, EntityUid senderEntity, IEyeManager eyeManager, IChatManager chatManager, IEntityManager entityManager, string speechStyleClass, Color? fontColor = null)
public SpeechBubble(ChatMessage message, EntityUid senderEntity, string speechStyleClass, Color? fontColor = null)
{
_chatManager = chatManager;
IoCManager.InjectDependencies(this);
_senderEntity = senderEntity;
_eyeManager = eyeManager;
_entityManager = entityManager;

// Use text clipping so new messages don't overlap old ones being pushed up.
RectClipContent = true;

var bubble = BuildBubble(text, speechStyleClass, fontColor);
var bubble = BuildBubble(message, speechStyleClass, fontColor);

AddChild(bubble);

Expand All @@ -91,7 +98,7 @@ public SpeechBubble(string text, EntityUid senderEntity, IEyeManager eyeManager,
_verticalOffsetAchieved = -ContentSize.Y;
}

protected abstract Control BuildBubble(string text, string speechStyleClass, Color? fontColor = null);
protected abstract Control BuildBubble(ChatMessage message, string speechStyleClass, Color? fontColor = null);

protected override void FrameUpdate(FrameEventArgs args)
{
Expand Down Expand Up @@ -165,33 +172,47 @@ public void FadeNow()
_timeLeft = FadeTime;
}
}

protected FormattedMessage FormatSpeech(string message, Color? fontColor = null)
{
var msg = new FormattedMessage();
if (fontColor != null)
msg.PushColor(fontColor.Value);
msg.AddMarkup(message);
return msg;
}

protected string ExtractSpeechSubstring(ChatMessage message, string tag)
{
var rawmsg = message.WrappedMessage;
var tagStart = rawmsg.IndexOf($"[{tag}]");
var tagEnd = rawmsg.IndexOf($"[/{tag}]");
tagStart += tag.Length + 2;
return rawmsg.Substring(tagStart, tagEnd - tagStart);
}

protected FormattedMessage ExtractAndFormatSpeechSubstring(ChatMessage message, string tag, Color? fontColor = null)
{
return FormatSpeech(ExtractSpeechSubstring(message, tag), fontColor);
}

}

public sealed class TextSpeechBubble : SpeechBubble
{
public TextSpeechBubble(string text, EntityUid senderEntity, IEyeManager eyeManager, IChatManager chatManager, IEntityManager entityManager, string speechStyleClass, Color? fontColor = null)
: base(text, senderEntity, eyeManager, chatManager, entityManager, speechStyleClass, fontColor)
public TextSpeechBubble(ChatMessage message, EntityUid senderEntity, string speechStyleClass, Color? fontColor = null)
: base(message, senderEntity, speechStyleClass, fontColor)
{
}

protected override Control BuildBubble(string text, string speechStyleClass, Color? fontColor = null)
protected override Control BuildBubble(ChatMessage message, string speechStyleClass, Color? fontColor = null)
{
var label = new RichTextLabel
{
MaxWidth = 256,
MaxWidth = SpeechMaxWidth,
};

if (fontColor != null)
{
var msg = new FormattedMessage();
msg.PushColor(fontColor.Value);
msg.AddMarkup(text);
label.SetMessage(msg);
}
else
{
label.SetMessage(text);
}
label.SetMessage(FormatSpeech(message.WrappedMessage, fontColor));

var panel = new PanelContainer
{
Expand All @@ -203,4 +224,76 @@ protected override Control BuildBubble(string text, string speechStyleClass, Col
return panel;
}
}

public sealed class FancyTextSpeechBubble : SpeechBubble
{

public FancyTextSpeechBubble(ChatMessage message, EntityUid senderEntity, string speechStyleClass, Color? fontColor = null)
: base(message, senderEntity, speechStyleClass, fontColor)
{
}

protected override Control BuildBubble(ChatMessage message, string speechStyleClass, Color? fontColor = null)
{
if (!ConfigManager.GetCVar(CCVars.ChatEnableFancyBubbles))
{
var label = new RichTextLabel
{
MaxWidth = SpeechMaxWidth
};

label.SetMessage(ExtractAndFormatSpeechSubstring(message, "BubbleContent", fontColor));

var unfanciedPanel = new PanelContainer
{
StyleClasses = { "speechBox", speechStyleClass },
Children = { label },
ModulateSelfOverride = Color.White.WithAlpha(0.75f)
};
return unfanciedPanel;
}

var bubbleHeader = new RichTextLabel
{
Margin = new Thickness(1, 1, 1, 1)
};

var bubbleContent = new RichTextLabel
{
MaxWidth = SpeechMaxWidth,
Margin = new Thickness(2, 6, 2, 2)
};

//We'll be honest. *Yes* this is hacky. Doing this in a cleaner way would require a bottom-up refactor of how saycode handles sending chat messages. -Myr
bubbleHeader.SetMessage(ExtractAndFormatSpeechSubstring(message, "BubbleHeader", fontColor));
bubbleContent.SetMessage(ExtractAndFormatSpeechSubstring(message, "BubbleContent", fontColor));

//As for below: Some day this could probably be converted to xaml. But that is not today. -Myr
var mainPanel = new PanelContainer
{
StyleClasses = { "speechBox", speechStyleClass },
Children = { bubbleContent },
ModulateSelfOverride = Color.White.WithAlpha(0.75f),
HorizontalAlignment = HAlignment.Center,
VerticalAlignment = VAlignment.Bottom,
Margin = new Thickness(4, 14, 4, 2)
};

var headerPanel = new PanelContainer
{
StyleClasses = { "speechBox", speechStyleClass },
Children = { bubbleHeader },
ModulateSelfOverride = Color.White.WithAlpha(ConfigManager.GetCVar(CCVars.ChatFancyNameBackground) ? 0.75f : 0f),
HorizontalAlignment = HAlignment.Center,
VerticalAlignment = VAlignment.Top
};

var panel = new PanelContainer
{
Children = { mainPanel, headerPanel }
};

return panel;
}
}
}
2 changes: 2 additions & 0 deletions Content.Client/Input/ContentContexts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public static void SetupContexts(IInputContextContainer contexts)
common.AddFunction(ContentKeyFunctions.TakeScreenshot);
common.AddFunction(ContentKeyFunctions.TakeScreenshotNoUI);
common.AddFunction(ContentKeyFunctions.ToggleFullscreen);
common.AddFunction(ContentKeyFunctions.MoveStoredItem);
common.AddFunction(ContentKeyFunctions.RotateStoredItem);
common.AddFunction(ContentKeyFunctions.Point);
common.AddFunction(ContentKeyFunctions.ZoomOut);
common.AddFunction(ContentKeyFunctions.ZoomIn);
Expand Down
2 changes: 2 additions & 0 deletions Content.Client/Options/UI/Tabs/GraphicsTab.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
<CheckBox Name="ShowHeldItemCheckBox" Text="{Loc 'ui-options-show-held-item'}" />
<CheckBox Name="ShowCombatModeIndicatorsCheckBox" Text="{Loc 'ui-options-show-combat-mode-indicators'}" />
<CheckBox Name="ShowLoocAboveHeadCheckBox" Text="{Loc 'ui-options-show-looc-on-head'}" />
<CheckBox Name="FancySpeechBubblesCheckBox" Text="{Loc 'ui-options-fancy-speech'}" />
<CheckBox Name="FancyNameBackgroundsCheckBox" Text="{Loc 'ui-options-fancy-name-background'}" />
<BoxContainer Orientation="Horizontal">
<CheckBox Name="ViewportStretchCheckBox" Text="{Loc 'ui-options-vp-stretch'}" />
<BoxContainer Name="ViewportScaleBox" Orientation="Horizontal">
Expand Down
10 changes: 10 additions & 0 deletions Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ public GraphicsTab()
ShowHeldItemCheckBox.OnToggled += OnCheckBoxToggled;
ShowCombatModeIndicatorsCheckBox.OnToggled += OnCheckBoxToggled;
ShowLoocAboveHeadCheckBox.OnToggled += OnCheckBoxToggled;
FancySpeechBubblesCheckBox.OnToggled += OnCheckBoxToggled;
FancyNameBackgroundsCheckBox.OnToggled += OnCheckBoxToggled;
IntegerScalingCheckBox.OnToggled += OnCheckBoxToggled;
ViewportLowResCheckBox.OnToggled += OnCheckBoxToggled;
ParallaxLowQualityCheckBox.OnToggled += OnCheckBoxToggled;
Expand All @@ -163,6 +165,8 @@ public GraphicsTab()
ShowHeldItemCheckBox.Pressed = _cfg.GetCVar(CCVars.HudHeldItemShow);
ShowCombatModeIndicatorsCheckBox.Pressed = _cfg.GetCVar(CCVars.CombatModeIndicatorsPointShow);
ShowLoocAboveHeadCheckBox.Pressed = _cfg.GetCVar(CCVars.LoocAboveHeadShow);
FancySpeechBubblesCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
FancyNameBackgroundsCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatFancyNameBackground);
ViewportWidthSlider.Value = _cfg.GetCVar(CCVars.ViewportWidth);

_cfg.OnValueChanged(CCVars.ViewportMinimumWidth, _ => UpdateViewportWidthRange());
Expand Down Expand Up @@ -211,6 +215,8 @@ private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args)
_cfg.SetCVar(CCVars.HudHeldItemShow, ShowHeldItemCheckBox.Pressed);
_cfg.SetCVar(CCVars.CombatModeIndicatorsPointShow, ShowCombatModeIndicatorsCheckBox.Pressed);
_cfg.SetCVar(CCVars.LoocAboveHeadShow, ShowLoocAboveHeadCheckBox.Pressed);
_cfg.SetCVar(CCVars.ChatEnableFancyBubbles, FancySpeechBubblesCheckBox.Pressed);
_cfg.SetCVar(CCVars.ChatFancyNameBackground, FancyNameBackgroundsCheckBox.Pressed);
_cfg.SetCVar(CCVars.HudFpsCounterVisible, FpsCounterCheckBox.Pressed);
_cfg.SetCVar(CCVars.ViewportWidth, (int) ViewportWidthSlider.Value);

Expand Down Expand Up @@ -249,6 +255,8 @@ private void UpdateApplyButton()
var isShowHeldItemSame = ShowHeldItemCheckBox.Pressed == _cfg.GetCVar(CCVars.HudHeldItemShow);
var isCombatModeIndicatorsSame = ShowCombatModeIndicatorsCheckBox.Pressed == _cfg.GetCVar(CCVars.CombatModeIndicatorsPointShow);
var isLoocShowSame = ShowLoocAboveHeadCheckBox.Pressed == _cfg.GetCVar(CCVars.LoocAboveHeadShow);
var isFancyChatSame = FancySpeechBubblesCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
var isFancyBackgroundSame = FancyNameBackgroundsCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatFancyNameBackground);
var isFpsCounterVisibleSame = FpsCounterCheckBox.Pressed == _cfg.GetCVar(CCVars.HudFpsCounterVisible);
var isWidthSame = (int) ViewportWidthSlider.Value == _cfg.GetCVar(CCVars.ViewportWidth);
var isLayoutSame = HudLayoutOption.SelectedMetadata is string opt && opt == _cfg.GetCVar(CCVars.UILayout);
Expand All @@ -266,6 +274,8 @@ private void UpdateApplyButton()
isShowHeldItemSame &&
isCombatModeIndicatorsSame &&
isLoocShowSame &&
isFancyChatSame &&
isFancyBackgroundSame &&
isFpsCounterVisibleSame &&
isWidthSame &&
isLayoutSame;
Expand Down
9 changes: 9 additions & 0 deletions Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ private void HandleToggleWalk(BaseButton.ButtonToggledEventArgs args)
_deferCommands.Add(_inputManager.SaveToUserData);
}

private void HandleStaticStorageUI(BaseButton.ButtonToggledEventArgs args)
{
_cfg.SetCVar(CCVars.StaticStorageUI, args.Pressed);
_cfg.SaveToFile();
}

public KeyRebindTab()
{
IoCManager.InjectDependencies(this);
Expand Down Expand Up @@ -175,6 +181,9 @@ void AddCheckBox(string checkBoxName, bool currentState, Action<BaseButton.Butto
AddButton(ContentKeyFunctions.Drop);
AddButton(ContentKeyFunctions.ExamineEntity);
AddButton(ContentKeyFunctions.SwapHands);
AddButton(ContentKeyFunctions.MoveStoredItem);
AddButton(ContentKeyFunctions.RotateStoredItem);
AddCheckBox("ui-options-static-storage-ui", _cfg.GetCVar(CCVars.StaticStorageUI), HandleStaticStorageUI);

AddHeader("ui-options-header-interaction-adv");
AddButton(ContentKeyFunctions.SmartEquipBackpack);
Expand Down
Loading

0 comments on commit 15c5dfc

Please sign in to comment.