Build 0.18.5.0

This commit is contained in:
Markus Isberg
2022-06-03 22:29:04 +09:00
parent 64db1a6a44
commit 6be757a45b
72 changed files with 869 additions and 439 deletions
@@ -266,7 +266,7 @@ namespace Barotrauma
disguisedSkinColor = idCard.StoredOwnerAppearance.SkinColor;
}
partial void LoadAttachmentSprites(bool omitJob)
partial void LoadAttachmentSprites()
{
if (attachmentSprites == null)
{
@@ -280,14 +280,6 @@ namespace Barotrauma
Head.BeardElement?.GetChildElements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Beard)));
Head.MoustacheElement?.GetChildElements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Moustache)));
Head.HairElement?.GetChildElements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Hair)));
if (omitJob)
{
JobPrefab.NoJobElement?.GetChildElement("PortraitClothing")?.GetChildElements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
}
else
{
Job?.Prefab.ClothingElement?.GetChildElements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
}
}
// Doesn't work if the head's source rect does not start at 0,0.
@@ -651,6 +651,8 @@ namespace Barotrauma
GameMain.LightManager.LosEnabled = true;
GameMain.LightManager.LosAlpha = 1f;
GameMain.NetLobbyScreen.CampaignCharacterDiscarded = false;
character.memInput.Clear();
character.memState.Clear();
character.memLocalState.Clear();
@@ -172,6 +172,7 @@ namespace Barotrauma
isOpen = false;
GUI.ForceMouseOn(null);
textBox.Deselect();
SoundPlayer.PlayUISound(GUISoundType.Select);
}
if (isOpen)
@@ -209,7 +210,7 @@ namespace Barotrauma
isOpen = !isOpen;
if (isOpen)
{
textBox.Select();
textBox.Select(ignoreSelectSound: true);
AddToGUIUpdateList();
}
else
@@ -217,6 +218,7 @@ namespace Barotrauma
GUI.ForceMouseOn(null);
textBox.Deselect();
}
SoundPlayer.PlayUISound(GUISoundType.Select);
}
private static bool IsCommandPermitted(string command, GameClient client)
@@ -81,6 +81,8 @@ namespace Barotrauma
public const int ToggleButtonWidthRaw = 30;
private int popupMessageOffset;
private GUIDropDown ChatModeDropDown { get; set; }
public ChatBox(GUIComponent parent, bool isSinglePlayer)
{
this.IsSinglePlayer = isSinglePlayer;
@@ -226,7 +228,53 @@ namespace Barotrauma
// ---------------------------------------------------------------------------------------------
InputBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.125f), hideableElements.RectTransform, Anchor.BottomLeft),
var bottomContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.125f), hideableElements.RectTransform, Anchor.BottomLeft), isHorizontal: true)
{
Stretch = true
};
var dropdownRt = new RectTransform(new Vector2(0.1f, 1.0f), bottomContainer.RectTransform)
{
// The chat mode selection dropdown will take a maximum of 45% of the horizontal space
MaxSize = new Point((int)(0.45f * bottomContainer.RectTransform.NonScaledSize.X), int.MaxValue)
};
var chatModes = new ChatMode[] { ChatMode.Local, ChatMode.Radio };
ChatModeDropDown = new GUIDropDown(dropdownRt, elementCount: chatModes.Length, dropAbove: true)
{
OnSelected = (component, userdata) =>
{
GameMain.ActiveChatMode = (ChatMode)userdata;
if (InputBox != null && InputBox.Text.StartsWith(RadioChatString) && GameMain.ActiveChatMode == ChatMode.Local)
{
string text = InputBox.Text;
InputBox.Text = text.Remove(0, RadioChatString.Length);
}
return true;
}
};
float longestDropDownOption = 0.0f;
foreach (ChatMode mode in chatModes)
{
var text = TextManager.Get($"chatmode.{mode}");
ChatModeDropDown.AddItem(text, userData: mode);
if (ChatModeDropDown.ListBox.Content.GetChildByUserData(mode) is GUITextBlock textBlock)
{
if (textBlock.TextSize.X > longestDropDownOption)
{
longestDropDownOption = textBlock.TextSize.X;
}
}
}
ChatModeDropDown.SelectItem(GameMain.ActiveChatMode);
float minDropDownWidth = longestDropDownOption + ChatModeDropDown.Padding.X +
(ChatModeDropDown.DropDownIcon?.RectTransform.NonScaledSize.X ?? 0) +
(ChatModeDropDown.DropDownIcon?.RectTransform.AbsoluteOffset.X ?? 0) * 2;
ChatModeDropDown.RectTransform.MinSize = new Point(
Math.Max((int)minDropDownWidth, ChatModeDropDown.RectTransform.MinSize.X),
ChatModeDropDown.RectTransform.MinSize.Y);
InputBox = new GUITextBox(new RectTransform(new Vector2(0.9f, 1.0f), bottomContainer.RectTransform),
style: "ChatTextBox")
{
OverflowClip = true,
@@ -248,8 +296,6 @@ namespace Barotrauma
CloseAfterMessageSent = false;
}
}
//gui.Text = "";
};
var chatSendButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.7f), InputBox.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.BothHeight), style: "GUIButtonToggleRight");
@@ -306,6 +352,10 @@ namespace Barotrauma
{
textColor = ChatMessage.MessageColor[(int)ChatMessageType.Private];
}
else if (GameMain.ActiveChatMode == ChatMode.Radio)
{
textColor = ChatMessage.MessageColor[(int)ChatMessageType.Radio];
}
else
{
textColor = ChatMessage.MessageColor[(int)ChatMessageType.Default];
@@ -550,6 +600,25 @@ namespace Barotrauma
showNewMessagesButton.Visible = false;
}
if (PlayerInput.KeyHit(InputType.ToggleChatMode) && GUI.KeyboardDispatcher.Subscriber == null && Screen.Selected == GameMain.GameScreen)
{
try
{
var mode = GameMain.ActiveChatMode switch
{
ChatMode.Local => ChatMode.Radio,
ChatMode.Radio => ChatMode.Local,
_ => throw new NotImplementedException()
};
ChatModeDropDown.SelectItem(mode);
// TODO: Play a sound?
}
catch (NotImplementedException)
{
DebugConsole.ThrowError($"Error toggling chat mode: not implemented for current mode \"{GameMain.ActiveChatMode}\"");
}
}
if (ToggleButton != null)
{
ToggleButton.Selected = ToggleOpen;
@@ -700,5 +769,70 @@ namespace Barotrauma
}
}
}
public void ApplySelectionInputs() => ApplySelectionInputs(InputBox, true, ChatKeyStates.GetChatKeyStates());
public struct ChatKeyStates
{
public bool ActiveChatKeyHit { get; set; }
public bool LocalChatKeyHit { get; set; }
public bool RadioChatKeyHit { get; set; }
public bool AnyHit => ActiveChatKeyHit || LocalChatKeyHit || RadioChatKeyHit;
private ChatKeyStates(bool active, bool local, bool radio)
{
ActiveChatKeyHit = active;
LocalChatKeyHit = local;
RadioChatKeyHit = radio;
}
public static ChatKeyStates GetChatKeyStates()
{
return new ChatKeyStates(PlayerInput.KeyHit(InputType.ActiveChat),
PlayerInput.KeyHit(InputType.Chat),
PlayerInput.KeyHit(InputType.RadioChat) && (Character.Controlled == null || Character.Controlled.SpeechImpediment < 100));
}
public (bool active, bool local, bool radio) Deconstruct()
{
return (ActiveChatKeyHit, LocalChatKeyHit, RadioChatKeyHit);
}
}
public void ApplySelectionInputs(GUITextBox inputBox, bool selectInputBox, ChatKeyStates chatKeyStates)
{
inputBox ??= InputBox;
var (activeChatKeyHit, localChatKeyHit, radioChatKeyHit) = chatKeyStates.Deconstruct();
if (localChatKeyHit || (activeChatKeyHit && GameMain.ActiveChatMode == ChatMode.Local))
{
ChatModeDropDown.SelectItem(ChatMode.Local);
inputBox.AddToGUIUpdateList();
GUIFrame.Flash(Color.DarkGreen, 0.5f);
if (!ToggleOpen)
{
CloseAfterMessageSent = !ToggleOpen;
ToggleOpen = true;
}
if (selectInputBox)
{
inputBox.Select(inputBox.Text.Length);
}
}
else if (radioChatKeyHit || (activeChatKeyHit && GameMain.ActiveChatMode == ChatMode.Radio))
{
ChatModeDropDown.SelectItem(ChatMode.Radio);
inputBox.AddToGUIUpdateList();
GUIFrame.Flash(Color.YellowGreen, 0.5f);
if (!ToggleOpen)
{
CloseAfterMessageSent = !ToggleOpen;
ToggleOpen = true;
}
if (selectInputBox)
{
inputBox.Select(inputBox.Text.Length);
}
}
}
}
}
@@ -183,6 +183,10 @@ namespace Barotrauma
Width = null;
Height = null;
GetSize(Element);
foreach (var childStyle in ChildStyles.Values)
{
childStyle.RefreshSize();
}
}
private void GetSize(XElement element)
@@ -356,7 +356,7 @@ namespace Barotrauma
GUIStyle.Green, Color.Black * 0.8f, font: GUIStyle.SmallFont);
y += yStep;
GameMain.PerformanceCounter.DrawTimeGraph.Draw(spriteBatch, new Rectangle((int)x, (int)y, 170, 50), color: GUIStyle.Green);
y += yStep * 3;
y += yStep * 4;
DrawString(spriteBatch, new Vector2(x, y),
"Update - Avg: " + GameMain.PerformanceCounter.UpdateTimeGraph.Average().ToString("0.00") + " ms" +
@@ -364,39 +364,33 @@ namespace Barotrauma
Color.LightBlue, Color.Black * 0.8f, font: GUIStyle.SmallFont);
y += yStep;
GameMain.PerformanceCounter.UpdateTimeGraph.Draw(spriteBatch, new Rectangle((int)x, (int)y, 170, 50), color: Color.LightBlue);
y += yStep * 3;
foreach (string key in GameMain.PerformanceCounter.GetSavedIdentifiers)
y += yStep * 4;
foreach (string key in GameMain.PerformanceCounter.GetSavedIdentifiers.OrderBy(i => i))
{
float elapsedMillisecs = GameMain.PerformanceCounter.GetAverageElapsedMillisecs(key);
DrawString(spriteBatch, new Vector2(x, y),
key + ": " + elapsedMillisecs.ToString("0.00"),
Color.Lerp(Color.LightGreen, GUIStyle.Red, elapsedMillisecs / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
y += yStep;
foreach (string childKey in GameMain.PerformanceCounter.GetSavedPartialIdentifiers(key))
{
elapsedMillisecs = GameMain.PerformanceCounter.GetPartialAverageElapsedMillisecs(key, childKey);
DrawString(spriteBatch, new Vector2(x + 15, y),
childKey + ": " + elapsedMillisecs.ToString("0.00"),
Color.Lerp(Color.LightGreen, GUIStyle.Red, elapsedMillisecs / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
y += yStep;
}
}
int categoryDepth = key.Count(c => c == ':');
//color the more fine-grained counters red more easily (ok for the whole Update to take a longer time than specific part of the update)
float runningSlowThreshold = 10.0f / categoryDepth;
DrawString(spriteBatch, new Vector2(x + categoryDepth * 15, y),
key.Split(':').Last() + ": " + elapsedMillisecs.ToString("0.00"),
ToolBox.GradientLerp(elapsedMillisecs / runningSlowThreshold, Color.LightGreen, GUIStyle.Yellow, GUIStyle.Orange, GUIStyle.Red, Color.Magenta), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
y += yStep;
}
if (Powered.Grids != null)
{
DrawString(spriteBatch, new Vector2(x, y), "Grids: " + Powered.Grids.Count, Color.LightGreen, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
y += yStep;
}
if (Settings.EnableDiagnostics)
{
x += yStep * 2;
DrawString(spriteBatch, new Vector2(x, y), "ContinuousPhysicsTime: " + GameMain.World.ContinuousPhysicsTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.ContinuousPhysicsTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(x, y + yStep), "ControllersUpdateTime: " + GameMain.World.ControllersUpdateTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.ControllersUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(x, y + yStep * 2), "AddRemoveTime: " + GameMain.World.AddRemoveTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.AddRemoveTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(x, y + yStep * 3), "NewContactsTime: " + GameMain.World.NewContactsTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.NewContactsTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(x, y + yStep * 4), "ContactsUpdateTime: " + GameMain.World.ContactsUpdateTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.ContactsUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(x, y + yStep * 5), "SolveUpdateTime: " + GameMain.World.SolveUpdateTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.SolveUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(x, y), "ContinuousPhysicsTime: " + GameMain.World.ContinuousPhysicsTime.TotalMilliseconds.ToString("0.00"), Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.ContinuousPhysicsTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(x, y + yStep), "ControllersUpdateTime: " + GameMain.World.ControllersUpdateTime.TotalMilliseconds.ToString("0.00"), Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.ControllersUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(x, y + yStep * 2), "AddRemoveTime: " + GameMain.World.AddRemoveTime.TotalMilliseconds.ToString("0.00"), Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.AddRemoveTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(x, y + yStep * 3), "NewContactsTime: " + GameMain.World.NewContactsTime.TotalMilliseconds.ToString("0.00"), Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.NewContactsTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(x, y + yStep * 4), "ContactsUpdateTime: " + GameMain.World.ContactsUpdateTime.TotalMilliseconds.ToString("0.00"), Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.ContactsUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(x, y + yStep * 5), "SolveUpdateTime: " + GameMain.World.SolveUpdateTime.TotalMilliseconds.ToString("0.00"), Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.SolveUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
}
}
@@ -111,6 +111,11 @@ namespace Barotrauma
set { textBlock.SelectedTextColor = value; }
}
public Color DisabledTextColor
{
get { return textBlock.DisabledTextColor; }
}
public override float FlashTimer
{
get { return Frame.FlashTimer; }
@@ -160,6 +160,10 @@ namespace Barotrauma
listBox.ToolTip = value;
}
}
public GUIImage DropDownIcon => icon;
public Vector4 Padding => button.TextBlock.Padding;
public GUIDropDown(RectTransform rectT, LocalizedString text = null, int elementCount = 4, string style = "", bool selectMultiple = false, bool dropAbove = false, Alignment textAlignment = Alignment.CenterLeft) : base(style, rectT)
{
@@ -352,7 +352,7 @@ namespace Barotrauma
caretPosDirty = false;
}
public void Select(int forcedCaretIndex = -1)
public void Select(int forcedCaretIndex = -1, bool ignoreSelectSound = false)
{
skipUpdate = true;
if (memento.Current == null)
@@ -362,10 +362,11 @@ namespace Barotrauma
CaretIndex = forcedCaretIndex == - 1 ? textBlock.GetCaretIndexFromScreenPos(PlayerInput.MousePosition) : forcedCaretIndex;
CalculateCaretPos();
ClearSelection();
bool wasSelected = selected;
selected = true;
GUI.KeyboardDispatcher.Subscriber = this;
OnSelected?.Invoke(this, Keys.None);
if (PlaySoundOnSelect)
if (!wasSelected && PlaySoundOnSelect && !ignoreSelectSound)
{
SoundPlayer.PlayUISound(GUISoundType.Select);
}
@@ -1,6 +1,7 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Linq;
namespace Barotrauma
{
@@ -122,7 +123,17 @@ namespace Barotrauma
//horizontal slices at the corners of the screen for health bar and affliction icons
int afflictionAreaHeight = (int)(50 * GUI.Scale);
int healthBarWidth = (int)(BottomRightInfoArea.Width * 1.3f);
int healthBarWidth = BottomRightInfoArea.Width;
var healthBarChildStyles = GUIStyle.GetComponentStyle("CharacterHealthBar")?.ChildStyles;
if (healthBarChildStyles!= null && healthBarChildStyles.TryGetValue("GUIFrame".ToIdentifier(), out var style))
{
if (style.Sprites.TryGetValue(GUIComponent.ComponentState.None, out var uiSprites) && uiSprites.FirstOrDefault() is { } uiSprite)
{
// The default health bar uses a sliced sprite so let's make sure the health bar area is calculated accordingly
healthBarWidth += (int)(uiSprite.NonSliceSize.X * Math.Min(GUI.Scale, 1f));
}
}
int healthBarHeight = (int)(50f * GUI.Scale);
HealthBarArea = new Rectangle(BottomRightInfoArea.Right - healthBarWidth + (int)Math.Floor(1 / GUI.Scale), BottomRightInfoArea.Y - healthBarHeight + GUI.IntScale(10), healthBarWidth, healthBarHeight);
AfflictionAreaLeft = new Rectangle(HealthBarArea.X, HealthBarArea.Y - Padding - afflictionAreaHeight, HealthBarArea.Width, afflictionAreaHeight);
@@ -2208,7 +2208,7 @@ namespace Barotrauma
}
updateStopwatch.Stop();
GameMain.PerformanceCounter.AddPartialElapsedTicks("GameSessionUpdate", "StoreUpdate", updateStopwatch.ElapsedTicks);
GameMain.PerformanceCounter.AddElapsedTicks("Update:GameSession:Store", updateStopwatch.ElapsedTicks);
}
}
}
@@ -1858,14 +1858,18 @@ namespace Barotrauma
});
GUILayoutGroup nameLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 1f), talentInfoLayoutGroup.RectTransform)) { RelativeSpacing = 0.05f };
Vector2 nameSize = GUIStyle.SubHeadingFont.MeasureString(info.Name);
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), info.Name, font: GUIStyle.SubHeadingFont) { TextColor = job.Prefab.UIColor };
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), info.Name, font: GUIStyle.SubHeadingFont);
nameBlock.RectTransform.NonScaledSize = nameSize.Pad(nameBlock.Padding).ToPoint();
Vector2 jobSize = GUIStyle.SmallFont.MeasureString(job.Name);
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), job.Name, font: GUIStyle.SmallFont) { TextColor = job.Prefab.UIColor };
jobBlock.RectTransform.NonScaledSize = jobSize.Pad(jobBlock.Padding).ToPoint();
if (!info.OmitJobInMenus)
{
nameBlock.TextColor = job.Prefab.UIColor;
Vector2 jobSize = GUIStyle.SmallFont.MeasureString(job.Name);
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), job.Name, font: GUIStyle.SmallFont) { TextColor = job.Prefab.UIColor };
jobBlock.RectTransform.NonScaledSize = jobSize.Pad(jobBlock.Padding).ToPoint();
}
LocalizedString traitString = TextManager.AddPunctuation(':', TextManager.Get("PersonalityTrait"), TextManager.Get("personalitytrait." + info.PersonalityTrait.Name.Replace(" ", "")));
Vector2 traitSize = GUIStyle.SmallFont.MeasureString(traitString);
@@ -1876,7 +1880,8 @@ namespace Barotrauma
if (!(GameMain.NetworkMember is null))
{
GUIButton newCharacterBox = new GUIButton(new RectTransform(new Vector2(0.675f, 1f), talentsOutsideTreeFrame.RectTransform, Anchor.TopLeft), text: GameMain.NetLobbyScreen.CampaignCharacterDiscarded ? TextManager.Get("settings") : TextManager.Get("createnew"))
GUIButton newCharacterBox = new GUIButton(new RectTransform(new Vector2(0.675f, 1f), talentsOutsideTreeFrame.RectTransform, Anchor.TopLeft),
text: GameMain.NetLobbyScreen.CampaignCharacterDiscarded ? TextManager.Get("settings") : TextManager.Get("createnew"))
{
IgnoreLayoutGroups = true
};
@@ -1915,7 +1920,7 @@ namespace Barotrauma
{
OnClicked = (button, o) =>
{
GameMain.Client?.SendCharacterInfo();
GameMain.Client?.SendCharacterInfo(GameMain.Client.PendingName);
characterSettingsFrame!.Visible = false;
talentFrameMain.Visible = true;
return true;
@@ -27,6 +27,11 @@ namespace Barotrauma
set;
}
/// <summary>
/// The size of fixed area around the slice area
/// </summary>
public Point NonSliceSize { get; set; }
public bool MaintainAspectRatio
{
get;
@@ -72,6 +77,7 @@ namespace Barotrauma
maxBorderScale = element.GetAttributeFloat("minborderscale", 10.0f);
Rectangle slice = new Rectangle((int)sliceVec.X, (int)sliceVec.Y, (int)(sliceVec.Z - sliceVec.X), (int)(sliceVec.W - sliceVec.Y));
NonSliceSize = new Point(Sprite.SourceRect.Width - slice.Width, Sprite.SourceRect.Height - slice.Height);
Slices = new Rectangle[9];
@@ -202,6 +202,8 @@ namespace Barotrauma
public static bool CancelQuickStart;
#endif
public static ChatMode ActiveChatMode { get; set; } = ChatMode.Radio;
public GameMain(string[] args)
{
Content.RootDirectory = "Content";
@@ -924,7 +926,7 @@ namespace Barotrauma
updateCount++;
sw.Stop();
PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks);
PerformanceCounter.AddElapsedTicks("Update", sw.ElapsedTicks);
PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks * 1000.0f / (float)Stopwatch.Frequency);
}
@@ -1026,7 +1028,7 @@ namespace Barotrauma
}
sw.Stop();
PerformanceCounter.AddElapsedTicks("Draw total", sw.ElapsedTicks);
PerformanceCounter.AddElapsedTicks("Draw", sw.ElapsedTicks);
PerformanceCounter.DrawTimeGraph.Update(sw.ElapsedTicks * 1000.0f / (float)Stopwatch.Frequency);
}
@@ -147,9 +147,10 @@ namespace Barotrauma
string msgCommand = ChatMessage.GetChatMessageCommand(text, out string msg);
// add to local history
ChatBox.ChatManager.Store(text);
WifiComponent headset = null;
ChatMessageType messageType =
((msgCommand == "r" || msgCommand == "radio") && ChatMessage.CanUseRadio(Character.Controlled, out headset)) ? ChatMessageType.Radio : ChatMessageType.Default;
bool isUsingRadioMode = GameMain.ActiveChatMode == ChatMode.Radio;
bool containsRadioCommand = msgCommand == "r" || msgCommand == "radio";
bool canUseRadio = ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent headset);
ChatMessageType messageType = ((isUsingRadioMode && msgCommand == "") || containsRadioCommand) && canUseRadio ? ChatMessageType.Radio : ChatMessageType.Default;
AddSinglePlayerChatMessage(
Character.Controlled.Info.Name,
msg, messageType,
@@ -1553,40 +1554,9 @@ namespace Barotrauma
{
ChatBox.Update(deltaTime);
ChatBox.InputBox.Visible = Character.Controlled != null;
if (!DebugConsole.IsOpen && ChatBox.InputBox.Visible && GUI.KeyboardDispatcher.Subscriber == null)
if (!DebugConsole.IsOpen && ChatBox.InputBox.Visible && GUI.KeyboardDispatcher.Subscriber == null && !ChatBox.InputBox.Selected)
{
if (PlayerInput.KeyHit(InputType.Chat) && !ChatBox.InputBox.Selected)
{
ChatBox.InputBox.AddToGUIUpdateList();
ChatBox.GUIFrame.Flash(Color.DarkGreen, 0.5f);
if (!ChatBox.ToggleOpen)
{
ChatBox.CloseAfterMessageSent = !ChatBox.ToggleOpen;
ChatBox.ToggleOpen = true;
}
ChatBox.InputBox.Select(ChatBox.InputBox.Text.Length);
}
if (PlayerInput.KeyHit(InputType.RadioChat) && !ChatBox.InputBox.Selected)
{
if (Character.Controlled == null || Character.Controlled.SpeechImpediment < 100)
{
ChatBox.InputBox.AddToGUIUpdateList();
ChatBox.GUIFrame.Flash(Color.YellowGreen, 0.5f);
if (!ChatBox.ToggleOpen)
{
ChatBox.CloseAfterMessageSent = !ChatBox.ToggleOpen;
ChatBox.ToggleOpen = true;
}
if (!ChatBox.InputBox.Text.StartsWith(ChatBox.RadioChatString))
{
ChatBox.InputBox.Text = ChatBox.RadioChatString;
}
ChatBox.InputBox.Select(ChatBox.InputBox.Text.Length);
}
}
ChatBox.ApplySelectionInputs();
}
}
@@ -35,11 +35,7 @@ namespace Barotrauma
}
}
if (CrewManager.ChatBox != null)
{
CrewManager.ChatBox.Update(deltaTime);
}
CrewManager.ChatBox?.Update(deltaTime);
CrewManager.UpdateReports();
}
@@ -43,6 +43,31 @@ namespace Barotrauma.Items.Components
corners[2] = center + new Vector2(shadowSize.X, shadowSize.Y) / 2;
corners[3] = center + new Vector2(shadowSize.X, -shadowSize.Y) / 2;
if (IsHorizontal)
{
if (item.FlippedX)
{
Vector2 itemCenter = new Vector2(item.Rect.Center.X, item.Rect.Y - item.Rect.Height / 2);
for (int i = 0; i < corners.Length; i++)
{
corners[i].X = itemCenter.X * 2 - corners[i].X;
}
Array.Reverse(corners);
}
}
else
{
if (item.FlippedY)
{
Vector2 itemCenter = new Vector2(item.Rect.Center.X, item.Rect.Y - item.Rect.Height / 2);
for (int i = 0; i < corners.Length; i++)
{
corners[i].Y = itemCenter.Y * 2 - corners[i].Y;
}
Array.Reverse(corners);
}
}
return corners;
}
@@ -163,69 +188,67 @@ namespace Barotrauma.Items.Components
if (stuck > 0.0f && weldedSprite != null)
{
Vector2 weldSpritePos = new Vector2(item.Rect.Center.X, item.Rect.Y - item.Rect.Height / 2.0f) + shakePos;
if (item.Submarine != null) weldSpritePos += item.Submarine.DrawPosition;
if (item.Submarine != null) { weldSpritePos += item.Submarine.DrawPosition; }
weldSpritePos.Y = -weldSpritePos.Y;
weldedSprite.Draw(spriteBatch,
weldSpritePos, item.SpriteColor * (stuck / 100.0f), scale: item.Scale);
}
if (openState >= 1.0f)
{
return;
}
if (openState >= 1.0f) { return; }
Vector2 pos;
if (IsHorizontal)
{
Vector2 pos = new Vector2(item.Rect.X, item.Rect.Y - item.Rect.Height / 2) + shakePos;
if (item.Submarine != null) pos += item.Submarine.DrawPosition;
pos.Y = -pos.Y;
if (brokenSprite == null || !IsBroken)
{
spriteBatch.Draw(doorSprite.Texture, pos,
new Rectangle((int) (doorSprite.SourceRect.X + doorSprite.size.X * openState),
(int) doorSprite.SourceRect.Y,
(int) (doorSprite.size.X * (1.0f - openState)), (int) doorSprite.size.Y),
color, 0.0f, doorSprite.Origin, item.Scale, SpriteEffects.None, doorSprite.Depth);
}
if (brokenSprite != null && item.Health < item.MaxCondition)
{
Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f, 1.0f - item.Health / item.MaxCondition) : Vector2.One;
float alpha = fadeBrokenSprite ? 1.0f - item.Health / item.MaxCondition : 1.0f;
spriteBatch.Draw(brokenSprite.Texture, pos,
new Rectangle((int)(brokenSprite.SourceRect.X + brokenSprite.size.X * openState), brokenSprite.SourceRect.Y,
(int)(brokenSprite.size.X * (1.0f - openState)), (int)brokenSprite.size.Y),
color * alpha, 0.0f, brokenSprite.Origin, scale * item.Scale, SpriteEffects.None,
brokenSprite.Depth);
}
pos = new Vector2(item.Rect.X, item.Rect.Y - item.Rect.Height / 2);
if (item.FlippedX) { pos.X += (int)(doorSprite.size.X * item.Scale * openState); }
}
else
{
Vector2 pos = new Vector2(item.Rect.Center.X, item.Rect.Y) + shakePos;
if (item.Submarine != null) pos += item.Submarine.DrawPosition;
pos.Y = -pos.Y;
if (brokenSprite == null || !IsBroken)
{
spriteBatch.Draw(doorSprite.Texture, pos,
new Rectangle(doorSprite.SourceRect.X,
(int) (doorSprite.SourceRect.Y + doorSprite.size.Y * openState),
(int) doorSprite.size.X, (int) (doorSprite.size.Y * (1.0f - openState))),
color, 0.0f, doorSprite.Origin, item.Scale, SpriteEffects.None, doorSprite.Depth);
}
if (brokenSprite != null && item.Health < item.MaxCondition)
{
Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f - item.Health / item.MaxCondition, 1.0f) : Vector2.One;
float alpha = fadeBrokenSprite ? 1.0f - item.Health / item.MaxCondition : 1.0f;
spriteBatch.Draw(brokenSprite.Texture, pos,
new Rectangle(brokenSprite.SourceRect.X, (int)(brokenSprite.SourceRect.Y + brokenSprite.size.Y * openState),
(int)brokenSprite.size.X, (int)(brokenSprite.size.Y * (1.0f - openState))),
color * alpha, 0.0f, brokenSprite.Origin, scale * item.Scale, SpriteEffects.None, brokenSprite.Depth);
}
pos = new Vector2(item.Rect.Center.X, item.Rect.Y);
if (item.FlippedY) { pos.Y -= (int)(doorSprite.size.Y * item.Scale * openState); }
}
pos += shakePos;
if (item.Submarine != null) { pos += item.Submarine.DrawPosition; }
pos.Y = -pos.Y;
if (brokenSprite == null || !IsBroken)
{
spriteBatch.Draw(doorSprite.Texture, pos,
getSourceRect(doorSprite, openState, IsHorizontal),
color, 0.0f, doorSprite.Origin, item.Scale, item.SpriteEffects, doorSprite.Depth);
}
if (brokenSprite != null && item.Health < item.MaxCondition)
{
Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f, 1.0f - item.Health / item.MaxCondition) : Vector2.One;
float alpha = fadeBrokenSprite ? 1.0f - item.Health / item.MaxCondition : 1.0f;
spriteBatch.Draw(brokenSprite.Texture, pos,
getSourceRect(brokenSprite, openState, IsHorizontal),
color * alpha, 0.0f, brokenSprite.Origin, scale * item.Scale, item.SpriteEffects,
brokenSprite.Depth);
}
static Rectangle getSourceRect(Sprite sprite, float openState, bool horizontal)
{
if (horizontal)
{
return new Rectangle(
(int)(sprite.SourceRect.X + sprite.size.X * openState),
sprite.SourceRect.Y,
(int)(sprite.size.X * (1.0f - openState)),
(int)sprite.size.Y);
}
else
{
return new Rectangle(
sprite.SourceRect.X,
(int)(sprite.SourceRect.Y + sprite.size.Y * openState),
(int)sprite.size.X,
(int)(sprite.size.Y * (1.0f - openState)));
}
}
}
partial void OnFailedToOpen()
@@ -116,12 +116,6 @@ namespace Barotrauma.Items.Components
loadAttachments(Attachments, disguisedBeardElement, WearableType.Beard);
loadAttachments(Attachments, disguisedMoustacheElement, WearableType.Moustache);
loadAttachments(Attachments, disguisedHairElement, WearableType.Hair);
loadAttachments(Attachments,
characterInfo.OmitJobInPortraitClothing
? JobPrefab.NoJobElement?.GetChildElement("PortraitClothing")
: JobPrefab?.ClothingElement,
WearableType.JobIndicator);
}
HairColor = hairColor;
@@ -1,55 +1,61 @@
using Barotrauma.Networking;
using Barotrauma.RuinGeneration;
using Barotrauma.Sounds;
using Barotrauma.Items.Components;
using Barotrauma.Networking;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using Barotrauma.IO;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Items.Components;
namespace Barotrauma
{
partial class Submarine : Entity, IServerPositionSync
{
public static Vector2 MouseToWorldGrid(Camera cam, Submarine sub)
{
Vector2 position = PlayerInput.MousePosition;
position = cam.ScreenToWorld(position);
Vector2 worldGridPos = VectorToWorldGrid(position);
if (sub != null)
{
worldGridPos.X += sub.Position.X % GridSize.X;
worldGridPos.Y += sub.Position.Y % GridSize.Y;
}
return worldGridPos;
}
//drawing ----------------------------------------------------
private static readonly HashSet<Submarine> visibleSubs = new HashSet<Submarine>();
private static double prevCullTime;
private static Rectangle prevCullArea;
/// <summary>
/// Interval at which we force culled entites to be updated, regardless if the camera has moved
/// </summary>
private const float CullInterval = 0.25f;
/// <summary>
/// Margin applied around the view area when culling entities (i.e. entities that are this far outside the view are still considered visible)
/// </summary>
private const int CullMargin = 500;
/// <summary>
/// Update entity culling when any corner of the view has moved more than this
/// </summary>
private const int CullMoveThreshold = 50;
public static void CullEntities(Camera cam)
{
Rectangle camView = cam.WorldView;
camView = new Rectangle(camView.X - CullMargin, camView.Y + CullMargin, camView.Width + CullMargin * 2, camView.Height + CullMargin * 2);
if (Math.Abs(camView.X - prevCullArea.X) < CullMoveThreshold &&
Math.Abs(camView.Y - prevCullArea.Y) < CullMoveThreshold &&
Math.Abs(camView.Right - prevCullArea.Right) < CullMoveThreshold &&
Math.Abs(camView.Bottom - prevCullArea.Bottom) < CullMoveThreshold &&
prevCullTime > Timing.TotalTime - CullInterval)
{
return;
}
visibleSubs.Clear();
foreach (Submarine sub in Loaded)
{
if (Level.Loaded != null && sub.WorldPosition.Y < Level.MaxEntityDepth) { continue; }
int margin = 500;
Rectangle worldBorders = new Rectangle(
sub.VisibleBorders.X + (int)sub.WorldPosition.X - margin,
sub.VisibleBorders.Y + (int)sub.WorldPosition.Y + margin,
sub.VisibleBorders.Width + margin * 2,
sub.VisibleBorders.Height + margin * 2);
sub.VisibleBorders.X + (int)sub.WorldPosition.X,
sub.VisibleBorders.Y + (int)sub.WorldPosition.Y,
sub.VisibleBorders.Width,
sub.VisibleBorders.Height);
if (RectsOverlap(worldBorders, cam.WorldView))
if (RectsOverlap(worldBorders, camView))
{
visibleSubs.Add(sub);
}
@@ -64,16 +70,22 @@ namespace Barotrauma
visibleEntities.Clear();
}
Rectangle worldView = cam.WorldView;
foreach (MapEntity entity in MapEntity.mapEntityList)
{
if (entity.Submarine != null)
{
if (!visibleSubs.Contains(entity.Submarine)) { continue; }
}
if (entity.IsVisible(worldView)) { visibleEntities.Add(entity); }
if (entity.IsVisible(camView)) { visibleEntities.Add(entity); }
}
prevCullArea = camView;
prevCullTime = Timing.TotalTime;
}
public static void ForceVisibilityRecheck()
{
prevCullTime = 0;
}
public static void Draw(SpriteBatch spriteBatch, bool editing = false)
@@ -148,7 +160,7 @@ namespace Barotrauma
{
if (predicate != null)
{
if (!predicate(e)) continue;
if (!predicate(e)) { continue; }
}
float drawDepth = structure.GetDrawDepth();
int i = 0;
@@ -679,6 +691,22 @@ namespace Barotrauma
return GameMain.LightManager.Lights.Count(l => l.CastShadows && !l.IsBackground) - disabledItemLightCount;
}
public static Vector2 MouseToWorldGrid(Camera cam, Submarine sub)
{
Vector2 position = PlayerInput.MousePosition;
position = cam.ScreenToWorld(position);
Vector2 worldGridPos = VectorToWorldGrid(position);
if (sub != null)
{
worldGridPos.X += sub.Position.X % GridSize.X;
worldGridPos.Y += sub.Position.Y % GridSize.Y;
}
return worldGridPos;
}
public void ClientReadPosition(IReadMessage msg, float sendingTime)
{
var posInfo = PhysicsBody.ClientRead(msg, sendingTime, parentDebugName: Info.Name);
@@ -10,14 +10,15 @@ namespace Barotrauma.Networking
{
msg.Write((byte)ClientNetObject.CHAT_MESSAGE);
msg.Write(NetStateID);
msg.Write((byte)Type);
msg.WriteRangedInteger((int)Type, 0, Enum.GetValues(typeof(ChatMessageType)).Length - 1);
msg.WriteRangedInteger((int)ChatMode, 0, Enum.GetValues(typeof(ChatMode)).Length - 1);
msg.Write(Text);
}
public static void ClientRead(IReadMessage msg)
{
UInt16 id = msg.ReadUInt16();
ChatMessageType type = (ChatMessageType)msg.ReadByte();
ChatMessageType type = (ChatMessageType)msg.ReadRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length - 1);
PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None;
string txt = "";
string styleSetting = string.Empty;
@@ -1831,7 +1831,8 @@ namespace Barotrauma.Networking
GameMain.GameScreen.Select();
AddChatMessage($"ServerMessage.HowToCommunicate~[chatbutton]={GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Chat)}~[radiobutton]={GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.RadioChat)}", ChatMessageType.Server);
// TODO: Re-enable the server message once it's been edited and translated
//AddChatMessage($"ServerMessage.HowToCommunicate~[chatbutton]={GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Chat)}~[radiobutton]={GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.RadioChat)}", ChatMessageType.Server);
yield return CoroutineStatus.Success;
}
@@ -2503,6 +2504,7 @@ namespace Barotrauma.Networking
message,
type,
gameStarted && myCharacter != null ? myCharacter : null);
chatMessage.ChatMode = GameMain.ActiveChatMode;
lastQueueChatMsgID++;
chatMessage.NetStateID = lastQueueChatMsgID;
@@ -2788,19 +2790,21 @@ namespace Barotrauma.Networking
GameMain.GameSession = null;
}
public void SendCharacterInfo()
public void SendCharacterInfo(string newName = null)
{
IWriteMessage msg = new WriteOnlyMessage();
msg.Write((byte)ClientPacketHeader.UPDATE_CHARACTERINFO);
WriteCharacterInfo(msg);
WriteCharacterInfo(msg, newName);
msg.Write((byte)ServerNetObject.END_OF_MESSAGE);
clientPeer?.Send(msg, DeliveryMethod.Reliable);
}
public void WriteCharacterInfo(IWriteMessage msg)
public void WriteCharacterInfo(IWriteMessage msg, string newName = null)
{
msg.Write(characterInfo == null);
if (characterInfo == null) return;
if (characterInfo == null) { return; }
msg.Write(newName ?? string.Empty);
msg.Write((byte)characterInfo.Head.Preset.TagSet.Count);
foreach (Identifier tag in characterInfo.Head.Preset.TagSet)
@@ -3284,10 +3288,8 @@ namespace Barotrauma.Networking
{
if (GUI.KeyboardDispatcher.Subscriber == null)
{
bool chatKeyHit = PlayerInput.KeyHit(InputType.Chat);
bool radioKeyHit = PlayerInput.KeyHit(InputType.RadioChat) && (Character.Controlled == null || Character.Controlled.SpeechImpediment < 100);
if (chatKeyHit || radioKeyHit)
var chatKeyStates = ChatBox.ChatKeyStates.GetChatKeyStates();
if (chatKeyStates.AnyHit)
{
if (msgBox.Selected)
{
@@ -3298,34 +3300,8 @@ namespace Barotrauma.Networking
{
if (Screen.Selected == GameMain.GameScreen)
{
if (chatKeyHit)
{
msgBox.AddToGUIUpdateList();
ChatBox.GUIFrame.Flash(Color.DarkGreen, 0.5f);
if (!chatBox.ToggleOpen)
{
ChatBox.CloseAfterMessageSent = !ChatBox.ToggleOpen;
ChatBox.ToggleOpen = true;
}
}
if (radioKeyHit)
{
msgBox.AddToGUIUpdateList();
ChatBox.GUIFrame.Flash(Color.YellowGreen, 0.5f);
if (!chatBox.ToggleOpen)
{
ChatBox.CloseAfterMessageSent = !ChatBox.ToggleOpen;
ChatBox.ToggleOpen = true;
}
if (!msgBox.Text.StartsWith(ChatBox.RadioChatString))
{
msgBox.Text = ChatBox.RadioChatString;
}
}
ChatBox.ApplySelectionInputs(msgBox, false, chatKeyStates);
}
msgBox.Select(msgBox.Text.Length);
}
}
@@ -1,4 +1,6 @@
namespace Barotrauma.Networking
using System;
namespace Barotrauma.Networking
{
partial class OrderChatMessage : ChatMessage
{
@@ -6,7 +8,7 @@
{
msg.Write((byte)ClientNetObject.CHAT_MESSAGE);
msg.Write(NetStateID);
msg.Write((byte)ChatMessageType.Order);
msg.WriteRangedInteger((int)ChatMessageType.Order, 0, Enum.GetValues(typeof(ChatMessageType)).Length - 1);
WriteOrder(msg);
}
}
@@ -227,20 +227,10 @@ namespace Barotrauma.Networking
bool allowEnqueue = overrideSound != null;
if (GameMain.WindowActive && SettingsMenu.Instance is null)
{
ForceLocal = captureTimer > 0 ? ForceLocal : GameSettings.CurrentConfig.Audio.UseLocalVoiceByDefault;
bool pttDown = false;
if ((PlayerInput.KeyDown(InputType.Voice) || PlayerInput.KeyDown(InputType.LocalVoice)) &&
GUI.KeyboardDispatcher.Subscriber == null)
bool pttDown = PlayerInput.KeyDown(InputType.Voice) && GUI.KeyboardDispatcher.Subscriber == null;
if (pttDown || captureTimer <= 0)
{
pttDown = true;
if (PlayerInput.KeyDown(InputType.LocalVoice))
{
ForceLocal = true;
}
else
{
ForceLocal = false;
}
ForceLocal = GameMain.ActiveChatMode == ChatMode.Local;
}
if (GameSettings.CurrentConfig.Audio.VoiceSetting == VoiceMode.Activity)
{
@@ -257,7 +247,6 @@ namespace Barotrauma.Networking
}
}
}
if (allowEnqueue || captureTimer > 0)
{
LastEnqueueAudio = DateTime.Now;
@@ -205,7 +205,10 @@ namespace Barotrauma
SettingCarouselElement<GameDifficulty> prevDifficulty = difficultyOptions.FirstOrNull(element => element.Value == prevSettings.Difficulty) ?? difficultyOptions[1];
SettingValue<GameDifficulty> difficultyInput = CreateSelectionCarousel(settingsList.Content, TextManager.Get("leveldifficulty"), TextManager.Get("leveldifficultyexplanation"), prevDifficulty, verticalSize, difficultyOptions);
SettingValue<int> maxMissionCountInput = CreateGUINumberInputCarousel(settingsList.Content, TextManager.Get("maxmissioncount"), TextManager.Get("maxmissioncounttooltip"), prevSettings.MaxMissionCount, valueStep: 1, verticalSize);
SettingValue<int> maxMissionCountInput = CreateGUINumberInputCarousel(settingsList.Content, TextManager.Get("maxmissioncount"), TextManager.Get("maxmissioncounttooltip"),
prevSettings.MaxMissionCount,
valueStep: 1, minValue: CampaignSettings.MinMissionCountLimit, maxValue: CampaignSettings.MaxMissionCountLimit,
verticalSize);
presetDropdown.OnSelected = (selected, o) =>
{
@@ -231,7 +234,7 @@ namespace Barotrauma
};
// Create a number input with plus and minus buttons because for some reason the default GUINumberInput buttons don't work when in a GUIMessageBox
static SettingValue<int> CreateGUINumberInputCarousel(GUIComponent parent, LocalizedString description, LocalizedString tooltip, int defaultValue, int valueStep, float verticalSize)
static SettingValue<int> CreateGUINumberInputCarousel(GUIComponent parent, LocalizedString description, LocalizedString tooltip, int defaultValue, int valueStep, int minValue, int maxValue, float verticalSize)
{
GUILayoutGroup inputContainer = CreateSettingBase(parent, description, tooltip, horizontalSize: 0.55f, verticalSize: verticalSize);
@@ -243,7 +246,9 @@ namespace Barotrauma
GUINumberInput numberInput = new GUINumberInput(new RectTransform(Vector2.One, inputContainer.RectTransform, Anchor.Center), NumberType.Int, textAlignment: Alignment.Center, style: "GUITextBox",
hidePlusMinusButtons: true)
{
IntValue = defaultValue
IntValue = defaultValue,
MinValueInt = minValue,
MaxValueInt = maxValue
};
inputContainer.RectTransform.Parent.MinSize = new Point(0, numberInput.RectTransform.MinSize.Y);
GUIButton plusButton = new GUIButton(new RectTransform(Vector2.One, inputContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIPlusButton", textAlignment: Alignment.Center)
@@ -126,7 +126,7 @@ namespace Barotrauma
DrawMap(graphics, spriteBatch, deltaTime);
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("DrawMap", sw.ElapsedTicks);
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map", sw.ElapsedTicks);
sw.Restart();
spriteBatch.Begin(SpriteSortMode.Deferred, null, GUI.SamplerState, null, GameMain.ScissorTestEnable);
@@ -165,7 +165,7 @@ namespace Barotrauma
spriteBatch.End();
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("DrawHUD", sw.ElapsedTicks);
GameMain.PerformanceCounter.AddElapsedTicks("Draw:HUD", sw.ElapsedTicks);
sw.Restart();
}
@@ -178,6 +178,9 @@ namespace Barotrauma
GameMain.ParticleManager.UpdateTransforms();
Stopwatch sw = new Stopwatch();
sw.Start();
GameMain.LightManager.ObstructVision =
Character.Controlled != null &&
Character.Controlled.ObstructVision &&
@@ -185,6 +188,10 @@ namespace Barotrauma
GameMain.LightManager.UpdateObstructVision(graphics, spriteBatch, cam, Character.Controlled?.CursorWorldPosition ?? Vector2.Zero);
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:LOS", sw.ElapsedTicks);
sw.Restart();
//------------------------------------------------------------------------
graphics.SetRenderTarget(renderTarget);
graphics.Clear(Color.Transparent);
@@ -196,9 +203,17 @@ namespace Barotrauma
Submarine.DrawPaintedColors(spriteBatch, false);
spriteBatch.End();
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:BackStructures", sw.ElapsedTicks);
sw.Restart();
graphics.SetRenderTarget(null);
GameMain.LightManager.RenderLightMap(graphics, spriteBatch, cam, renderTarget);
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:Lighting", sw.ElapsedTicks);
sw.Restart();
//------------------------------------------------------------------------
graphics.SetRenderTarget(renderTargetBackground);
if (Level.Loaded == null)
@@ -228,6 +243,10 @@ namespace Barotrauma
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
spriteBatch.End();
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:BackLevel", sw.ElapsedTicks);
sw.Restart();
//----------------------------------------------------------------------------
//Start drawing to the normal render target (stuff that can't be seen through the LOS effect)
@@ -248,6 +267,10 @@ namespace Barotrauma
}
spriteBatch.End();
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:BackCharactersItems", sw.ElapsedTicks);
sw.Restart();
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, null, DepthStencilState.None, null, null, cam.Transform);
DrawDeformed(firstPass: true);
DrawDeformed(firstPass: false);
@@ -266,8 +289,16 @@ namespace Barotrauma
}
}
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:DeformableCharacters", sw.ElapsedTicks);
sw.Restart();
Level.Loaded?.DrawFront(spriteBatch, cam);
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:FrontLevel", sw.ElapsedTicks);
sw.Restart();
//draw the rendertarget and particles that are only supposed to be drawn in water into renderTargetWater
graphics.SetRenderTarget(renderTargetWater);
@@ -302,6 +333,10 @@ namespace Barotrauma
WaterRenderer.Instance.RenderAir(graphics, cam, renderTarget, Cam.ShaderTransform);
graphics.DepthStencilState = DepthStencilState.None;
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:FrontParticles", sw.ElapsedTicks);
sw.Restart();
spriteBatch.Begin(SpriteSortMode.Immediate,
BlendState.NonPremultiplied, SamplerState.LinearWrap,
null, null,
@@ -310,10 +345,18 @@ namespace Barotrauma
Submarine.DrawDamageable(spriteBatch, damageEffect, false);
spriteBatch.End();
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:FrontDamageable", sw.ElapsedTicks);
sw.Restart();
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, null, DepthStencilState.None, null, null, cam.Transform);
Submarine.DrawFront(spriteBatch, false, null);
spriteBatch.End();
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:FrontStructuresItems", sw.ElapsedTicks);
sw.Restart();
//draw additive particles that are inside a sub
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, null, DepthStencilState.Default, null, null, cam.Transform);
GameMain.ParticleManager.Draw(spriteBatch, true, true, Particles.ParticleBlendState.Additive);
@@ -349,6 +392,10 @@ namespace Barotrauma
}
spriteBatch.End();
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:FrontMisc", sw.ElapsedTicks);
sw.Restart();
if (GameMain.LightManager.LosEnabled && GameMain.LightManager.LosMode != LosMode.None && Lights.LightManager.ViewTarget != null)
{
GameMain.LightManager.LosEffect.CurrentTechnique = GameMain.LightManager.LosEffect.Techniques["LosShader"];
@@ -457,6 +504,10 @@ namespace Barotrauma
GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Lerp(Color.TransparentBlack, Color.Black, fadeToBlackState), isFilled: true);
spriteBatch.End();
}
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Draw:Map:PostProcess", sw.ElapsedTicks);
sw.Restart();
}
partial void UpdateProjSpecific(double deltaTime)
@@ -110,7 +110,7 @@ namespace Barotrauma
public bool CampaignCharacterDiscarded
{
get;
private set;
set;
}
//elements that can only be used by the host
@@ -1253,9 +1253,6 @@ namespace Barotrauma
CharacterAppearanceCustomizationMenu?.Dispose();
JobSelectionFrame = null;
/*foreach (Sprite sprite in jobPreferenceSprites) { sprite.Remove(); }
jobPreferenceSprites.Clear();*/
}
public override void Select()
@@ -1417,7 +1414,7 @@ namespace Barotrauma
characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, GameMain.Client.Name, null);
characterInfo.RecreateHead(MultiplayerPreferences.Instance);
GameMain.Client.CharacterInfo = characterInfo;
characterInfo.OmitJobInPortraitClothing = false;
characterInfo.OmitJobInMenus = true;
}
parent.ClearChildren();
@@ -1870,7 +1870,8 @@ namespace Barotrauma
}
addSubAndSaveModProject(modProject, savePath, fileListPath);
}
else if (MainSub?.Info != null
else if (MainSub?.Info?.FilePath != null
&& MainSub.Info.Name != null
&& MainSub.Info.FilePath.StartsWith(ContentPackage.LocalModsDir)
&& MainSub.Info.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
{
@@ -2321,7 +2322,7 @@ namespace Barotrauma
};
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), beaconMinDifficultyGroup.RectTransform),
TextManager.Get("minleveldifficulty"), textAlignment: Alignment.CenterLeft, wrap: true);
new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), beaconMinDifficultyGroup.RectTransform), NumberType.Int)
var numInput = new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), beaconMinDifficultyGroup.RectTransform), NumberType.Int)
{
IntValue = (int)(MainSub?.Info?.BeaconStationInfo?.MinLevelDifficulty ?? 0),
MinValueInt = 0,
@@ -2331,13 +2332,14 @@ namespace Barotrauma
MainSub.Info.BeaconStationInfo.MinLevelDifficulty = numberInput.IntValue;
}
};
beaconMinDifficultyGroup.RectTransform.MaxSize = numInput.TextBox.RectTransform.MaxSize;
var beaconMaxDifficultyGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), beaconSettingsContainer.RectTransform), isHorizontal: true)
{
Stretch = true
};
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), beaconMaxDifficultyGroup.RectTransform),
TextManager.Get("maxleveldifficulty"), textAlignment: Alignment.CenterLeft, wrap: true);
new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), beaconMaxDifficultyGroup.RectTransform), NumberType.Int)
numInput = new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), beaconMaxDifficultyGroup.RectTransform), NumberType.Int)
{
IntValue = (int)(MainSub?.Info?.BeaconStationInfo?.MaxLevelDifficulty ?? 100),
MinValueInt = 0,
@@ -2347,7 +2349,7 @@ namespace Barotrauma
MainSub.Info.BeaconStationInfo.MaxLevelDifficulty = numberInput.IntValue;
}
};
beaconMaxDifficultyGroup.RectTransform.MaxSize = numInput.TextBox.RectTransform.MaxSize;
new GUITickBox(new RectTransform(new Vector2(1.0f, 0.25f), beaconSettingsContainer.RectTransform), TextManager.Get("allowdamagedwalls"))
{
Selected = MainSub?.Info?.BeaconStationInfo?.AllowDamagedWalls ?? true,
@@ -2545,6 +2547,10 @@ namespace Barotrauma
{
MainSub.Info.OutpostModuleInfo ??= new OutpostModuleInfo(MainSub.Info);
}
else if (type == SubmarineType.BeaconStation)
{
MainSub.Info.BeaconStationInfo ??= new BeaconStationInfo(MainSub.Info);
}
previewImageButtonHolder.Children.ForEach(c => c.Enabled = type != SubmarineType.OutpostModule);
outpostSettingsContainer.Visible = type == SubmarineType.OutpostModule;
@@ -1,6 +1,7 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using Barotrauma.Extensions;
@@ -36,6 +37,8 @@ namespace Barotrauma
public readonly WorkshopMenu WorkshopMenu;
private static readonly ImmutableHashSet<InputType> LegacyInputTypes = new List<InputType>() { InputType.Chat, InputType.RadioChat }.ToImmutableHashSet();
public static SettingsMenu Create(RectTransform mainParent)
{
Instance?.Close();
@@ -392,6 +395,9 @@ namespace Barotrauma
Label(audio, TextManager.Get("MusicVolume"), GUIStyle.SubHeadingFont);
Slider(audio, (0, 1), 101, Percentage, unsavedConfig.Audio.MusicVolume, (v) => unsavedConfig.Audio.MusicVolume = v);
Label(audio, TextManager.Get("UiSoundVolume"), GUIStyle.SubHeadingFont);
Slider(audio, (0, 1), 101, Percentage, unsavedConfig.Audio.UiVolume, (v) => unsavedConfig.Audio.UiVolume = v);
Tickbox(audio, TextManager.Get("MuteOnFocusLost"), TextManager.Get("MuteOnFocusLostTooltip"), unsavedConfig.Audio.MuteOnFocusLost, (v) => unsavedConfig.Audio.MuteOnFocusLost = v);
Tickbox(audio, TextManager.Get("DynamicRangeCompression"), TextManager.Get("DynamicRangeCompressionTooltip"), unsavedConfig.Audio.DynamicRangeCompressionEnabled, (v) => unsavedConfig.Audio.DynamicRangeCompressionEnabled = v);
Spacer(audio);
@@ -481,10 +487,14 @@ namespace Barotrauma
HashSet<GUIButton> inputButtons = new HashSet<GUIButton>();
Action<KeyOrMouse>? currentSetter = null;
void addInputToRow(GUILayoutGroup currRow, LocalizedString labelText, Func<LocalizedString> valueNameGetter, Action<KeyOrMouse> valueSetter)
void addInputToRow(GUILayoutGroup currRow, LocalizedString labelText, Func<LocalizedString> valueNameGetter, Action<KeyOrMouse> valueSetter, bool isLegacyBind = false)
{
var inputFrame = new GUIFrame(new RectTransform((0.5f, 1.0f), currRow.RectTransform),
style: null);
if (isLegacyBind)
{
labelText = TextManager.GetWithVariable("legacyitemformat", "[name]", labelText);
}
var label = new GUITextBlock(new RectTransform((0.6f, 1.0f), inputFrame.RectTransform), labelText,
font: GUIStyle.SmallFont) {ForceUpperCase = ForceUpperCase.Yes};
var inputBox = new GUIButton(
@@ -515,6 +525,12 @@ namespace Barotrauma
return true;
}
};
if (isLegacyBind)
{
label.TextColor = Color.Lerp(label.TextColor, label.DisabledTextColor, 0.5f);
inputBox.Color = Color.Lerp(inputBox.Color, inputBox.DisabledColor, 0.5f);
inputBox.TextColor = Color.Lerp(inputBox.TextColor, label.DisabledTextColor, 0.5f);
}
inputButtons.Add(inputBox);
}
@@ -594,7 +610,8 @@ namespace Barotrauma
currRow,
TextManager.Get($"InputType.{input}"),
() => unsavedConfig.KeyMap.Bindings[input].Name,
(v) => unsavedConfig.KeyMap = unsavedConfig.KeyMap.WithBinding(input, v));
(v) => unsavedConfig.KeyMap = unsavedConfig.KeyMap.WithBinding(input, v),
LegacyInputTypes.Contains(input));
}
}
@@ -609,30 +626,29 @@ namespace Barotrauma
var input = unsavedConfig.InventoryKeyMap.Bindings[currIndex];
addInputToRow(
currRow,
TextManager.GetWithVariable("inventoryslotkeybind", "[slotnumber]", (currIndex+1).ToString(CultureInfo.InvariantCulture)),
TextManager.GetWithVariable("inventoryslotkeybind", "[slotnumber]", (currIndex + 1).ToString(CultureInfo.InvariantCulture)),
() => unsavedConfig.InventoryKeyMap.Bindings[currIndex].Name,
(v) => unsavedConfig.InventoryKeyMap = unsavedConfig.InventoryKeyMap.WithBinding(currIndex, v));
}
}
GUILayoutGroup resetControlsHolder =
new GUILayoutGroup(new RectTransform((1.75f, 0.1f), layout.RectTransform), isHorizontal: true)
new GUILayoutGroup(new RectTransform((1.75f, 0.1f), layout.RectTransform), isHorizontal: true, childAnchor: Anchor.Center)
{
RelativeSpacing = 0.1f
};
var defaultBindingsButton =
new GUIButton(new RectTransform(new Vector2(0.45f, 1.0f), resetControlsHolder.RectTransform),
TextManager.Get("SetDefaultBindings"), style: "GUIButtonSmall")
TextManager.Get("Reset"), style: "GUIButtonSmall")
{
ToolTip = TextManager.Get("SetDefaultBindingsTooltip")
};
var legacyBindingsButton =
new GUIButton(new RectTransform(new Vector2(0.45f, 1.0f), resetControlsHolder.RectTransform),
TextManager.Get("SetLegacyBindings"), style: "GUIButtonSmall")
{
ToolTip = TextManager.Get("SetLegacyBindingsTooltip")
ToolTip = TextManager.Get("SetDefaultBindingsTooltip"),
OnClicked = (btn, userdata) =>
{
unsavedConfig.InventoryKeyMap = GameSettings.Config.InventoryKeyMapping.GetDefault();
unsavedConfig.KeyMap = GameSettings.Config.KeyMapping.GetDefault();
return true;
}
};
}
@@ -705,7 +705,7 @@ namespace Barotrauma.Sounds
public void ApplySettings()
{
SetCategoryGainMultiplier("default", GameSettings.CurrentConfig.Audio.SoundVolume, 0);
SetCategoryGainMultiplier("ui", GameSettings.CurrentConfig.Audio.SoundVolume, 0);
SetCategoryGainMultiplier("ui", GameSettings.CurrentConfig.Audio.UiVolume, 0);
SetCategoryGainMultiplier("waterambience", GameSettings.CurrentConfig.Audio.SoundVolume, 0);
SetCategoryGainMultiplier("music", GameSettings.CurrentConfig.Audio.MusicVolume, 0);
SetCategoryGainMultiplier("voip", Math.Min(GameSettings.CurrentConfig.Audio.VoiceChatVolume, 1.0f), 0);