Unstable 0.16.1.0

This commit is contained in:
Markus Isberg
2022-01-27 00:30:32 +09:00
parent 7d6421a548
commit b259af5911
161 changed files with 1913 additions and 638 deletions
@@ -1,7 +1,11 @@
namespace Barotrauma
using Microsoft.Xna.Framework;
namespace Barotrauma
{
abstract partial class AIObjective
{
public static Color ObjectiveIconColor => Color.LightGray;
public static Sprite GetSprite(string identifier, string option, Entity targetEntity)
{
if (string.IsNullOrEmpty(identifier))
@@ -154,7 +154,7 @@ namespace Barotrauma
public bool PlaySound;
public GUIMessage(string rawText, Color color, float delay, string identifier = null, int? value = null)
public GUIMessage(string rawText, Color color, float delay, string identifier = null, int? value = null, float lifeTime = 3.0f)
{
RawText = Text = rawText;
if (value.HasValue)
@@ -166,7 +166,7 @@ namespace Barotrauma
Size = GUI.Font.MeasureString(Text);
Color = color;
Identifier = identifier;
Lifetime = 3.0f;
Lifetime = lifeTime;
}
}
@@ -997,7 +997,7 @@ namespace Barotrauma
return nameColor;
}
public void AddMessage(string rawText, Color color, bool playSound, string identifier = null, int? value = null)
public void AddMessage(string rawText, Color color, bool playSound, string identifier = null, int? value = null, float lifetime = 3.0f)
{
GUIMessage existingMessage = null;
@@ -1026,7 +1026,7 @@ namespace Barotrauma
}
if (existingMessage == null || !value.HasValue)
{
var newMessage = new GUIMessage(rawText, color, delay, identifier, value);
var newMessage = new GUIMessage(rawText, color, delay, identifier, value, lifetime);
guiMessages.Insert(0, newMessage);
if (playSound)
{
@@ -113,7 +113,7 @@ namespace Barotrauma
return
character?.Inventory != null &&
character.AllowInput &&
!character.Removed && !character.IsKnockedDown &&
(controller?.User != character || !controller.HideHUD) &&
!IsCampaignInterfaceOpen &&
!ConversationAction.FadeScreenToBlack;
@@ -16,6 +16,7 @@ namespace Barotrauma
private static Sprite infoAreaPortraitBG;
public bool LastControlled;
public int CrewListIndex { get; set; } = -1;
#warning TODO: Refactor
private Sprite disguisedPortrait;
@@ -831,7 +832,7 @@ namespace Barotrauma
};
new GUIFrame(
new RectTransform(new Vector2(1.25f, 1.25f), HeadSelectionList.RectTransform, Anchor.Center),
new RectTransform(new Vector2(1.25f, 1.25f), HeadSelectionList.ContentBackground.RectTransform, Anchor.Center),
style: "OuterGlow", color: Color.Black)
{
UserData = "outerglow",
@@ -966,10 +967,15 @@ namespace Barotrauma
foreach (Sprite sprite in characterSprites) { sprite.Remove(); }
characterSprites.Clear();
}
public void Dispose()
{
ClearSprites();
if (HeadSelectionList != null)
{
HeadSelectionList.RectTransform.Parent = null;
HeadSelectionList = null;
}
}
~AppearanceCustomizationMenu()
@@ -143,7 +143,7 @@ namespace Barotrauma
Hull fireHull = Hull.hullList.GetRandom(h => h.Submarine == character.Submarine);
if (fireHull != null)
{
var fakeFire = new DummyFireSource(Vector2.One * 500.0f, new Vector2(Rand.Range(fireHull.WorldRect.X, fireHull.WorldRect.Right), fireHull.WorldPosition.Y), fireHull, isNetworkMessage: true)
var fakeFire = new DummyFireSource(Vector2.One * 500.0f, new Vector2(Rand.Range(fireHull.WorldRect.X, fireHull.WorldRect.Right), fireHull.WorldPosition.Y + 1), fireHull, isNetworkMessage: true)
{
CausedByPsychosis = true,
DamagesItems = false,
@@ -2018,6 +2018,27 @@ namespace Barotrauma
limbIndicatorOverlay?.Remove();
limbIndicatorOverlay = null;
if (healthWindow != null)
{
healthWindow.RectTransform.Parent = null;
healthWindow = null;
}
if (healthBarHolder != null)
{
healthBarHolder.RectTransform.Parent = null;
healthBarHolder = null;
}
if (SuicideButton != null)
{
SuicideButton.RectTransform.Parent = null;
SuicideButton = null;
}
if (afflictionTooltip != null)
{
afflictionTooltip.RectTransform.Parent = null;
afflictionTooltip = null;
}
}
}
}
@@ -389,6 +389,12 @@ namespace Barotrauma
DrawString(spriteBatch, new Vector2(10, 10),
"FPS: " + Math.Round(GameMain.PerformanceCounter.AverageFramesPerSecond),
Color.White, Color.Black * 0.5f, 0, SmallFont);
if (GameMain.GameSession != null && Timing.TotalTime > GameMain.GameSession.RoundStartTime + 1.0)
{
DrawString(spriteBatch, new Vector2(10, 25),
$"Physics: {GameMain.CurrentUpdateRate}",
(GameMain.CurrentUpdateRate < Timing.FixedUpdateRate) ? Color.Red : Color.White, Color.Black * 0.5f, 0, SmallFont);
}
}
if (GameMain.ShowPerf)
@@ -397,7 +403,7 @@ namespace Barotrauma
DrawString(spriteBatch, new Vector2(300, y),
"Draw - Avg: " + GameMain.PerformanceCounter.DrawTimeGraph.Average().ToString("0.00") + " ms" +
" Max: " + GameMain.PerformanceCounter.DrawTimeGraph.LargestValue().ToString("0.00") + " ms",
GUI.Style.Green, Color.Black * 0.8f, font: SmallFont);
Style.Green, Color.Black * 0.8f, font: SmallFont);
y += 15;
GameMain.PerformanceCounter.DrawTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), color: Style.Green);
y += 50;
@@ -408,7 +414,6 @@ namespace Barotrauma
Color.LightBlue, Color.Black * 0.8f, font: SmallFont);
y += 15;
GameMain.PerformanceCounter.UpdateTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), color: Color.LightBlue);
GameMain.PerformanceCounter.UpdateIterationsGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), maxValue: 20, color: Style.Red);
y += 50;
foreach (string key in GameMain.PerformanceCounter.GetSavedIdentifiers)
{
@@ -431,7 +436,7 @@ namespace Barotrauma
}
}
if (GameMain.DebugDraw)
if (GameMain.DebugDraw && !Submarine.Unloading && !(Screen.Selected is RoundSummaryScreen))
{
DrawString(spriteBatch, new Vector2(10, 25),
"Physics: " + GameMain.World.UpdateTime,
@@ -2435,6 +2440,11 @@ namespace Barotrauma
private static bool TogglePauseMenu(GUIButton button, object obj)
{
pauseMenuOpen = !pauseMenuOpen;
if (!pauseMenuOpen && PauseMenu != null)
{
PauseMenu.RectTransform.Parent = null;
PauseMenu = null;
}
return true;
}
@@ -22,13 +22,14 @@ namespace Barotrauma
{
GameMain.Instance.ResolutionChanged += RecalculateSize;
}
_instance.ItemComponentHolder = new GUIFrame(new RectTransform(Vector2.One, _instance, Anchor.Center)).RectTransform;
_instance.ChildrenChanged += OnChildrenChanged;
}
return _instance;
}
}
public RectTransform ItemComponentHolder;
//GUICanvas stores the children as weak references, to allow elements that we no longer need to get garbage collected
private readonly List<WeakReference<RectTransform>> childrenWeakRef = new List<WeakReference<RectTransform>>();
private static Vector2 size => new Vector2(GameMain.GraphicsWidth / (float)GUI.UIWidth, 1f);
@@ -36,16 +37,41 @@ namespace Barotrauma
private enum ResizeAxis { Both = 0, X = 1, Y = 2 }
private static void OnChildrenChanged(RectTransform _)
{
//add weak reference if we don't have one yet
foreach (var child in _instance.Children)
{
if (!_instance.childrenWeakRef.Any(c => c.TryGetTarget(out var existingChild) && existingChild == child))
{
_instance.childrenWeakRef.Add(new WeakReference<RectTransform>(child));
}
}
//get rid of strong references
_instance.children.Clear();
//remove dead children
for (int i = _instance.childrenWeakRef.Count - 2; i >= 0; i--)
{
if (!_instance.childrenWeakRef[i].TryGetTarget(out var child) || child.Parent != _instance)
{
_instance.childrenWeakRef.RemoveAt(i);
}
}
}
// Turn public, if there is a need to call this manually.
private static void RecalculateSize()
{
Vector2 recalculatedSize = size;
// Scale children that are supposed to encompass the whole screen so that they are properly scaled on ultrawide as well
for (int i = 0; i < Instance.Children.Count(); i++)
for (int i = 0; i < Instance.childrenWeakRef.Count; i++)
{
RectTransform target = Instance.GetChild(i);
if (target == null || target.RelativeSize.X < 1 && target.RelativeSize.Y < 1) continue;
if (!_instance.childrenWeakRef[i].TryGetTarget(out RectTransform target) || target == null) { continue; };
_instance.children.Add(target);
if (target.RelativeSize.X < 1 && target.RelativeSize.Y < 1) { continue; }
ResizeAxis axis;
@@ -80,6 +106,7 @@ namespace Barotrauma
Instance.Resize(size, resizeChildren: true);
Instance.GetAllChildren().Select(c => c.GUIComponent as GUITextBlock).ForEach(t => t?.SetTextPos());
_instance.children.Clear();
}
}
}
@@ -362,6 +362,14 @@ namespace Barotrauma
RectTransform.ScaleChanged += () => dimensionsNeedsRecalculation = true;
RectTransform.SizeChanged += () => dimensionsNeedsRecalculation = true;
UpdateDimensions();
rectT.ChildrenChanged += CheckForChildren;
}
private void CheckForChildren(RectTransform rectT)
{
if (rectT == ScrollBar.RectTransform || rectT == Content.RectTransform || rectT == ContentBackground.RectTransform) { return; }
throw new InvalidOperationException($"Children were added to {nameof(GUIListBox)}, Add them to {nameof(GUIListBox)}.{nameof(Content)} instead.");
}
public void UpdateDimensions()
@@ -827,13 +835,6 @@ namespace Barotrauma
protected override void Update(float deltaTime)
{
foreach (GUIComponent child in Children)
{
if (child == ScrollBar || child == Content || child == ContentBackground) { continue; }
throw new InvalidOperationException($"Children were found in {nameof(GUIListBox)}, Add them to {nameof(GUIListBox)}.{nameof(Content)} instead.");
}
if (!Visible) { return; }
UpdateChildrenRect();
@@ -618,6 +618,7 @@ namespace Barotrauma
public bool Close(GUIButton button, object obj)
{
RectTransform.Parent = null;
Close();
return true;
}
@@ -347,7 +347,7 @@ namespace Barotrauma
// sum up all the afflictions and their strengths
Dictionary<AfflictionPrefab, float> afflictionAndStrength = new Dictionary<AfflictionPrefab, float>();
foreach (Affliction affliction in health.GetAllAfflictions().Where(a => !a.Prefab.IsBuff && a.Strength > 0))
foreach (Affliction affliction in health.GetAllAfflictions().Where(a => MedicalClinic.IsHealable(a)))
{
if (afflictionAndStrength.TryGetValue(affliction.Prefab, out float strength))
{
@@ -581,7 +581,6 @@ namespace Barotrauma
OnClicked = (button, _) =>
{
button.Enabled = false;
ClosePopup();
medicalClinic.HealAllButtonAction(request =>
{
switch (request.HealResult)
@@ -595,7 +594,9 @@ namespace Barotrauma
}
button.Enabled = true;
ClosePopup();
});
ClosePopup();
return true;
}
};
@@ -993,7 +994,7 @@ namespace Barotrauma
}
}
private void ClosePopup()
public void ClosePopup()
{
if (selectedCrewElement is { } popup)
{
@@ -58,7 +58,7 @@ namespace Barotrauma
}
}
private readonly List<RectTransform> children = new List<RectTransform>();
protected readonly List<RectTransform> children = new List<RectTransform>();
public IEnumerable<RectTransform> Children => children;
public int CountChildren => children.Count;
@@ -20,7 +20,7 @@ namespace Barotrauma
private static Sprite ownerIcon, moderatorIcon;
public enum InfoFrameTab { Crew, Mission, Reputation, Traitor, Submarine, Talents };
public static InfoFrameTab selectedTab;
public static InfoFrameTab SelectedTab { get; private set; }
private GUIFrame infoFrame, contentFrame;
private readonly List<GUIButton> tabButtons = new List<GUIButton>();
@@ -130,8 +130,8 @@ namespace Barotrauma
{
if (!initialized) { Initialize(); }
CreateInfoFrame(selectedTab);
SelectInfoFrameTab(null, selectedTab);
CreateInfoFrame(SelectedTab);
SelectInfoFrameTab(SelectedTab);
}
public void Update()
@@ -147,8 +147,8 @@ namespace Barotrauma
}
}
if (selectedTab != InfoFrameTab.Crew) return;
if (linkedGUIList == null) return;
if (SelectedTab != InfoFrameTab.Crew) { return; }
if (linkedGUIList == null) { return; }
if (GameMain.IsMultiplayer)
{
@@ -226,7 +226,7 @@ namespace Barotrauma
{
UserData = tab,
ToolTip = TextManager.Get(textTag),
OnClicked = SelectInfoFrameTab
OnClicked = (btn, userData) => { SelectInfoFrameTab((InfoFrameTab)userData); return true; }
};
tabButtons.Add(newButton);
return newButton;
@@ -277,16 +277,16 @@ namespace Barotrauma
talentsButton.Enabled = Character.Controlled?.Info != null;
if (!talentsButton.Enabled && selectedTab == InfoFrameTab.Talents)
{
SelectInfoFrameTab(null, InfoFrameTab.Crew);
SelectInfoFrameTab(InfoFrameTab.Crew);
}
};
talentPointNotification = GameSession.CreateTalentIconNotification(talentsButton);
}
private bool SelectInfoFrameTab(GUIButton button, object userData)
public void SelectInfoFrameTab(InfoFrameTab selectedTab)
{
selectedTab = (InfoFrameTab)userData;
SelectedTab = selectedTab;
CreateInfoFrame(selectedTab);
tabButtons.ForEach(tb => tb.Selected = (InfoFrameTab)tb.UserData == selectedTab);
@@ -310,7 +310,7 @@ namespace Barotrauma
case InfoFrameTab.Traitor:
TraitorMissionPrefab traitorMission = GameMain.Client.TraitorMission;
Character traitor = GameMain.Client.Character;
if (traitor == null || traitorMission == null) return false;
if (traitor == null || traitorMission == null) { return; }
CreateTraitorInfo(infoFrameHolder, traitorMission, traitor);
break;
case InfoFrameTab.Submarine:
@@ -320,8 +320,6 @@ namespace Barotrauma
CreateTalentInfo(infoFrameHolder);
break;
}
return true;
}
private const float jobColumnWidthPercentage = 0.138f;
@@ -859,7 +857,7 @@ namespace Barotrauma
string msg = ChatMessage.GetTimeStamp() + message.TextWithSender;
storedMessages.Add(new Pair<string, PlayerConnectionChangeType>(msg, message.ChangeType));
if (GameSession.IsTabMenuOpen && selectedTab == InfoFrameTab.Crew)
if (GameSession.IsTabMenuOpen && SelectedTab == InfoFrameTab.Crew)
{
TabMenu instance = GameSession.TabMenuInstance;
instance.AddLineToLog(msg, message.ChangeType);
@@ -433,6 +433,7 @@ namespace Barotrauma
if (AvailableMoney >= hullRepairCost)
{
Campaign.Money -= hullRepairCost;
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "hullrepairs");
Campaign.PurchasedHullRepairs = true;
button.Enabled = false;
SelectTab(UpgradeTab.Repairs);
@@ -467,6 +468,7 @@ namespace Barotrauma
if (AvailableMoney >= itemRepairCost && !Campaign.PurchasedItemRepairs)
{
Campaign.Money -= itemRepairCost;
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "devicerepairs");
Campaign.PurchasedItemRepairs = true;
button.Enabled = false;
SelectTab(UpgradeTab.Repairs);
@@ -512,6 +514,7 @@ namespace Barotrauma
if (AvailableMoney >= shuttleRetrieveCost && !Campaign.PurchasedLostShuttles)
{
Campaign.Money -= shuttleRetrieveCost;
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "retrieveshuttle");
Campaign.PurchasedLostShuttles = true;
button.Enabled = false;
SelectTab(UpgradeTab.Repairs);
@@ -5,7 +5,7 @@ using System.Linq;
namespace Barotrauma
{
public static partial class GameAnalyticsManager
static partial class GameAnalyticsManager
{
static partial void CreateConsentPrompt()
{
@@ -30,6 +30,13 @@ namespace Barotrauma
public static PerformanceCounter PerformanceCounter;
private static Stopwatch performanceCounterTimer;
private static int updateCount = 0;
public static int CurrentUpdateRate
{
get; private set;
}
public static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
public static string[] ConsoleArguments;
@@ -122,6 +129,12 @@ namespace Barotrauma
private bool exiting;
public static bool IsFirstLaunch
{
get;
private set;
}
public static GameMain Instance
{
get;
@@ -349,6 +362,8 @@ namespace Barotrauma
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Item));
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Items.Components.ItemComponent));
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Hull));
performanceCounterTimer = Stopwatch.StartNew();
}
/// <summary>
@@ -579,6 +594,18 @@ namespace Barotrauma
{
Steamworks.SteamFriends.OnGameRichPresenceJoinRequested += OnInvitedToGame;
Steamworks.SteamFriends.OnGameLobbyJoinRequested += OnLobbyJoinRequested;
if (SteamManager.TryGetUnlockedAchievements(out List<Steamworks.Data.Achievement> achievements))
{
//check the achievements too, so we don't consider people who've played the game before this "gamelaunchcount" stat was added as being 1st-time-players
//(people who have played previous versions, but not unlocked any achievements, will be incorrectly considered 1st-time-players, but that should be a small enough group to not skew the statistics)
if (!achievements.Any() && SteamManager.GetStatInt("gamelaunchcount") <= 0)
{
IsFirstLaunch = true;
GameAnalyticsManager.AddDesignEvent("FirstLaunch");
}
}
SteamManager.IncrementStat("gamelaunchcount", 1);
}
#endif
@@ -696,11 +723,10 @@ namespace Barotrauma
protected override void Update(GameTime gameTime)
{
Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step);
if (Timing.Accumulator > Timing.Step * 6.0)
if (Timing.Accumulator > Timing.AccumulatorMax)
{
//if the game's running too slowly then we have no choice
//but to skip a bunch of steps
//prevent spiral of death:
//if the game's running too slowly then we have no choice but to skip a bunch of steps
//otherwise it snowballs and becomes unplayable
Timing.Accumulator = Timing.Step;
}
@@ -736,7 +762,6 @@ namespace Barotrauma
PlayerInput.Update(Timing.Step);
if (loadingScreenOpen)
{
//reset accumulator if loading
@@ -975,13 +1000,21 @@ namespace Barotrauma
Timing.Accumulator -= Timing.Step;
updateCount++;
sw.Stop();
PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks);
PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks * 1000.0f / (float)Stopwatch.Frequency);
PerformanceCounter.UpdateIterationsGraph.Update(updateIterations);
}
if (!Paused) Timing.Alpha = Timing.Accumulator / Timing.Step;
if (!Paused) { Timing.Alpha = Timing.Accumulator / Timing.Step; }
if (performanceCounterTimer.ElapsedMilliseconds > 1000)
{
CurrentUpdateRate = (int)Math.Round(updateCount / (double)(performanceCounterTimer.ElapsedMilliseconds / 1000.0));
performanceCounterTimer.Restart();
updateCount = 0;
}
}
public static void ResetFrameTime()
@@ -1086,8 +1119,15 @@ namespace Barotrauma
{
double roundDuration = Timing.TotalTime - GameSession.RoundStartTime;
GameAnalyticsManager.AddProgressionEvent(GameAnalyticsManager.ProgressionStatus.Fail,
GameSession.GameMode?.Name ?? "none",
GameSession.GameMode?.Preset.Identifier ?? "none",
roundDuration);
string eventId = "QuitRound:" + (GameSession.GameMode?.Preset.Identifier ?? "none") + ":";
GameAnalyticsManager.AddDesignEvent(eventId + "EventManager:CurrentIntensity", GameSession.EventManager.CurrentIntensity);
foreach (var activeEvent in GameSession.EventManager.ActiveEvents)
{
GameAnalyticsManager.AddDesignEvent(eventId + "EventManager:ActiveEvents:" + activeEvent.ToString());
}
GameSession.LogEndRoundStats(eventId);
if (Tutorial.Initialized)
{
((TutorialMode)GameSession.GameMode).Tutorial?.Stop();
@@ -232,6 +232,8 @@ namespace Barotrauma
Location.StoreCurrentBalance -= itemValue;
campaign.Money += itemValue;
GameAnalyticsManager.AddMoneyGainedEvent(itemValue, GameAnalyticsManager.MoneySource.Store, item.ItemPrefab.Identifier);
// Remove from the sell crate
// TODO: Simplify duplicate logic?
if (sellingMode == Store.StoreTab.Sell && ItemsInSellCrate.Find(pi => pi.ItemPrefab == item.ItemPrefab) is { } inventoryItem)
@@ -83,7 +83,7 @@ namespace Barotrauma
partial void InitProjectSpecific()
{
guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent)
guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), null, Color.Transparent)
{
CanBeFocused = false
};
@@ -302,7 +302,7 @@ namespace Barotrauma
/// </summary>
/// <param name="character">The character to remove</param>
/// <param name="removeInfo">If the character info is also removed, the character will not be visible in the round summary.</param>
public void RemoveCharacter(Character character, bool removeInfo = false)
public void RemoveCharacter(Character character, bool removeInfo = false, bool resetCrewListIndex = true)
{
if (character == null)
{
@@ -311,14 +311,15 @@ namespace Barotrauma
}
characters.Remove(character);
if (removeInfo) { characterInfos.Remove(character.Info); }
if (resetCrewListIndex) { ResetCrewListIndex(character); }
}
/// <summary>
/// Add character to the list without actually adding it to the crew
/// </summary>
public void AddCharacterToCrewList(Character character)
public GUIComponent AddCharacterToCrewList(Character character)
{
if (character == null) { return; }
if (character == null) { return null; }
var background = new GUIFrame(
new RectTransform(crewListEntrySize, parent: crewList.Content.RectTransform, anchor: Anchor.TopRight),
@@ -510,6 +511,8 @@ namespace Barotrauma
return true;
}
};
return background;
}
private void SetCharacterComponentTooltip(GUIComponent characterComponent)
@@ -549,13 +552,13 @@ namespace Barotrauma
if (characterInfos.Contains(revivedCharacter.Info)) { AddCharacter(revivedCharacter); }
}
public void KillCharacter(Character killedCharacter)
public void KillCharacter(Character killedCharacter, bool resetCrewListIndex = true)
{
if (crewList.Content.GetChildByUserData(killedCharacter) is GUIComponent characterComponent)
{
CoroutineManager.StartCoroutine(KillCharacterAnim(characterComponent));
}
RemoveCharacter(killedCharacter);
RemoveCharacter(killedCharacter, resetCrewListIndex: resetCrewListIndex);
}
private IEnumerable<CoroutineStatus> KillCharacterAnim(GUIComponent component)
@@ -601,9 +604,53 @@ namespace Barotrauma
{
if (crewList != this.crewList) { return; }
if (!(draggedElementData is Character)) { return; }
if (crewList.HasDraggedElementIndexChanged) { return; }
if (!IsSinglePlayer) { return; }
CharacterClicked(crewList.DraggedElement, draggedElementData);
if (crewList.HasDraggedElementIndexChanged)
{
UpdateCrewListIndices();
}
else
{
CharacterClicked(crewList.DraggedElement, draggedElementData);
}
}
private void ResetCrewListIndex(Character c)
{
if (c?.Info == null) { return; }
c.Info.CrewListIndex = -1;
UpdateCrewListIndices();
}
private void UpdateCrewListIndices()
{
if (crewList == null) { return; }
for (int i = 0; i < crewList.Content.CountChildren; i++)
{
var characterComponent = crewList.Content.GetChild(i);
if (!(characterComponent?.UserData is Character c)) { continue; }
if (c.Info == null) { continue; }
c.Info.CrewListIndex = i;
}
}
private void SortCrewList()
{
if (crewList == null) { return; }
crewList.Content.RectTransform.SortChildren((x, y) =>
{
var infoX = (x.GUIComponent.UserData as Character)?.Info?.CrewListIndex;
var infoY = (y.GUIComponent.UserData as Character)?.Info?.CrewListIndex;
if (infoX.HasValue)
{
return infoY.HasValue ? infoX.Value.CompareTo(infoY.Value) : -1;
}
else
{
return infoY.HasValue ? 1 : 0;
}
});
UpdateCrewListIndices();
}
#endregion
@@ -1077,7 +1124,13 @@ namespace Barotrauma
private string CreateOrderTooltip(Order orderPrefab, string option, Entity targetEntity)
{
if (orderPrefab == null) { return ""; }
if (!string.IsNullOrEmpty(option))
if (orderPrefab.DisplayGiverInTooltip && orderPrefab.OrderGiver != null)
{
return TextManager.GetWithVariables("crewlistordericontooltip",
new string[2] { "[ordername]", "[orderoption]" },
new string[2] { orderPrefab.Name, orderPrefab.OrderGiver.DisplayName });
}
else if (!string.IsNullOrEmpty(option))
{
return TextManager.GetWithVariables("crewlistordericontooltip",
new string[2] { "[ordername]", "[orderoption]" },
@@ -1210,6 +1263,10 @@ namespace Barotrauma
DisableCommandUI();
Character.Controlled = character;
HintManager.OnChangeCharacter();
if (GameSession.TabMenuInstance != null && TabMenu.SelectedTab == TabMenu.InfoFrameTab.Talents)
{
GameSession.TabMenuInstance.SelectInfoFrameTab(TabMenu.SelectedTab);
}
}
private int TryAdjustIndex(int amount)
@@ -1566,10 +1623,28 @@ namespace Barotrauma
{
crewList.Select(character, force: true);
}
// Icon colors might change based on the target so we check if they need to be updated
if (GetCurrentOrderIconList(characterComponent) is GUIListBox currentOrderIconList)
{
foreach (var orderIcon in currentOrderIconList.Content.Children)
{
if (!(orderIcon.UserData is OrderInfo orderInfo)) { continue; }
if (!(orderInfo.Order is Order order)) { continue; }
if (order.ColoredWhenControllingGiver && order.OrderGiver != Character.Controlled)
{
orderIcon.Color = AIObjective.ObjectiveIconColor;
}
else
{
orderIcon.Color = order.Color;
}
}
}
// Only update the order highlights and objective icons here in singleplayer
// The server will let the clients know when they need to update in multiplayer
if (GameMain.IsSingleplayer && character.IsBot && character.AIController is HumanAIController controller &&
controller.ObjectiveManager is AIObjectiveManager objectiveManager)
{
// In multiplayer, these are set through character networking (the server lets the clients now when these are updated)
if (objectiveManager.CurrentObjective is AIObjective currentObjective)
{
if (objectiveManager.IsOrder(currentObjective))
@@ -1638,8 +1713,8 @@ namespace Barotrauma
bool foundMatch = false;
foreach (var orderIcon in currentOrderIconList.Content.Children)
{
var glowComponent = orderIcon.GetChildByUserData("glow");
if (glowComponent == null) { continue; }
if (!(orderIcon.GetChildByUserData("glow") is GUIComponent glowComponent)) { continue; }
glowComponent.Color = orderIcon.Color;
if (foundMatch)
{
glowComponent.Visible = false;
@@ -1684,11 +1759,11 @@ namespace Barotrauma
objectiveIconFrame.ClearChildren();
if (sprite != null)
{
var objectiveIcon = CreateNodeIcon(Vector2.One, objectiveIconFrame.RectTransform, sprite, Color.LightGray, tooltip: tooltip);
var objectiveIcon = CreateNodeIcon(Vector2.One, objectiveIconFrame.RectTransform, sprite, AIObjective.ObjectiveIconColor, tooltip: tooltip);
new GUIFrame(new RectTransform(new Vector2(1.5f), objectiveIcon.RectTransform, anchor: Anchor.Center), style: "OuterGlowCircular")
{
CanBeFocused = false,
Color = Color.LightGray
Color = AIObjective.ObjectiveIconColor
};
objectiveIconFrame.Visible = true;
}
@@ -1909,7 +1984,7 @@ namespace Barotrauma
ScaleCommandUI();
commandFrame = new GUIFrame(
new RectTransform(Vector2.One, GUICanvas.Instance, anchor: Anchor.Center),
new RectTransform(Vector2.One, GUI.Canvas, anchor: Anchor.Center),
style: null,
color: Color.Transparent);
background = new GUIImage(
@@ -3530,12 +3605,14 @@ namespace Barotrauma
public void Save(XElement parentElement)
{
XElement element = new XElement("crew");
foreach (CharacterInfo ci in characterInfos)
for (int i = 0; i < characterInfos.Count; i++)
{
var ci = characterInfos[i];
var infoElement = ci.Save(element);
if (ci.InventoryData != null) { infoElement.Add(ci.InventoryData); }
if (ci.HealthData != null) { infoElement.Add(ci.HealthData); }
if (ci.OrderData != null) { infoElement.Add(ci.OrderData); }
infoElement.Add(new XAttribute("crewlistindex", ci.CrewListIndex));
if (ci.LastControlled) { infoElement.Add(new XAttribute("lastcontrolled", true)); }
}
SaveActiveOrders(element);
@@ -97,7 +97,7 @@ namespace Barotrauma
partial void InitProjSpecific()
{
var buttonContainer = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, GUICanvas.Instance),
var buttonContainer = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, GUI.Canvas),
isHorizontal: true, childAnchor: Anchor.CenterRight)
{
CanBeFocused = false
@@ -108,7 +108,7 @@ namespace Barotrauma
buttonCenter = buttonHeight / 2,
screenMiddle = GameMain.GraphicsWidth / 2;
endRoundButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle(screenMiddle - buttonWidth / 2, HUDLayoutSettings.ButtonAreaTop.Center.Y - buttonCenter, buttonWidth, buttonHeight), GUICanvas.Instance),
endRoundButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle(screenMiddle - buttonWidth / 2, HUDLayoutSettings.ButtonAreaTop.Center.Y - buttonCenter, buttonWidth, buttonHeight), GUI.Canvas),
TextManager.Get("EndRound"), textAlignment: Alignment.Center, style: "EndRoundButton")
{
Pulse = true,
@@ -145,7 +145,7 @@ namespace Barotrauma
int readyButtonHeight = buttonHeight;
int readyButtonWidth = (int) (GUI.Scale * 50);
ReadyCheckButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle(screenMiddle + (buttonWidth / 2) + GUI.IntScale(16), HUDLayoutSettings.ButtonAreaTop.Center.Y - buttonCenter, readyButtonWidth, readyButtonHeight), GUICanvas.Instance),
ReadyCheckButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle(screenMiddle + (buttonWidth / 2) + GUI.IntScale(16), HUDLayoutSettings.ButtonAreaTop.Center.Y - buttonCenter, readyButtonWidth, readyButtonHeight), GUI.Canvas),
style: "RepairBuyButton")
{
ToolTip = TextManager.Get("ReadyCheck.Tooltip"),
@@ -108,6 +108,9 @@ namespace Barotrauma
case "pets":
petsElement = subElement;
break;
case "stats":
LoadStats(subElement);
break;
}
}
@@ -167,7 +170,7 @@ namespace Barotrauma
int buttonHeight = (int)(GUI.Scale * 40);
int buttonWidth = GUI.IntScale(450);
endRoundButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle((GameMain.GraphicsWidth / 2) - (buttonWidth / 2), HUDLayoutSettings.ButtonAreaTop.Center.Y - (buttonHeight / 2), buttonWidth, buttonHeight), GUICanvas.Instance),
endRoundButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle((GameMain.GraphicsWidth / 2) - (buttonWidth / 2), HUDLayoutSettings.ButtonAreaTop.Center.Y - (buttonHeight / 2), buttonWidth, buttonHeight), GUI.Canvas),
TextManager.Get("EndRound"), textAlignment: Alignment.Center, style: "EndRoundButton")
{
Pulse = true,
@@ -412,6 +415,10 @@ namespace Barotrauma
break;
case TransitionType.ProgressToNextLocation:
Map.MoveToNextLocation();
TotalPassedLevels++;
break;
case TransitionType.ProgressToNextEmptyLocation:
TotalPassedLevels++;
break;
}
@@ -728,6 +735,7 @@ namespace Barotrauma
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
new XAttribute("cheatsenabled", CheatsEnabled));
modeElement.Add(Settings.Save());
modeElement.Add(SaveStats());
//save and remove all items that are in someone's inventory so they don't get included in the sub file as well
foreach (Character c in Character.CharacterList)
@@ -205,6 +205,11 @@ namespace Barotrauma
return;
}
if (campaign?.CampaignUI?.MedicalClinic is { } ui)
{
ui.ClosePopup();
}
healAllRequests.Add(new RequestAction<HealRequest>(onReceived, GetTimeout()));
ClientSend(null, NetworkHeader.HEAL_PENDING, DeliveryMethod.Reliable);
}
@@ -600,6 +600,10 @@ namespace Barotrauma
OnClicked = (bt, userdata) => { SelectTab((Tab)userdata); return true; }
};
tabButtons[(int)tab].Text = ToolBox.LimitString(buttonText, tabButtons[(int)tab].Font, (int)(0.75f * tabWidth * tabButtonHolder.Rect.Width));
if (tabButtons[(int)tab].Text != buttonText)
{
tabButtons[(int)tab].ToolTip = buttonText;
}
}
/// Graphics tab --------------------------------------------------------------
@@ -796,7 +796,7 @@ namespace Barotrauma
if (quickUseAction != QuickUseAction.Drop)
{
slot.QuickUseButtonToolTip = quickUseAction == QuickUseAction.None ?
"" : TextManager.GetWithVariable("QuickUseAction." + quickUseAction.ToString(), "[equippeditem]", item?.Name);
"" : TextManager.GetWithVariable("QuickUseAction." + quickUseAction.ToString(), "[equippeditem]", character.HeldItems.FirstOrDefault()?.Name ?? item?.Name);
if (PlayerInput.PrimaryMouseButtonDown()) { slot.EquipButtonState = GUIComponent.ComponentState.Pressed; }
if (PlayerInput.PrimaryMouseButtonClicked())
{
@@ -970,7 +970,9 @@ namespace Barotrauma
{
return QuickUseAction.TakeFromCharacter;
}
else if (character.HeldItems.Any(i => i.OwnInventory != null && i.OwnInventory.CanBePut(item)) && allowInventorySwap)
else if (character.HeldItems.Any(i =>
i.OwnInventory != null &&
(i.OwnInventory.CanBePut(item) || (i.OwnInventory.Capacity == 1 && i.OwnInventory.AllowSwappingContainedItems && i.OwnInventory.Container.CanBeContained(item)))))
{
return QuickUseAction.PutToEquippedItem;
}
@@ -1136,7 +1138,8 @@ namespace Barotrauma
foreach (Item heldItem in character.HeldItems)
{
if (heldItem.OwnInventory != null &&
heldItem.OwnInventory.TryPutItem(item, Character.Controlled))
heldItem.OwnInventory.TryPutItem(item, Character.Controlled) ||
(heldItem.OwnInventory.Capacity == 1 && heldItem.OwnInventory.TryPutItem(item, 0, allowSwapping: true, allowCombine: false, user: Character.Controlled)))
{
success = true;
for (int j = 0; j < capacity; j++)
@@ -256,6 +256,10 @@ namespace Barotrauma.Items.Components
{
targetHull.IncreaseSectionColorOrStrength(targetSections[i], color, sizeAdjustedSprayStrength * deltaTime, true, false);
}
if (GameMain.GameSession != null)
{
GameMain.GameSession.TimeSpentCleaning += deltaTime;
}
}
else
{
@@ -263,6 +267,10 @@ namespace Barotrauma.Items.Components
{
targetHull.CleanSection(targetSections[i], -sizeAdjustedSprayStrength * deltaTime, true);
}
if (GameMain.GameSession != null)
{
GameMain.GameSession.TimeSpentPainting += deltaTime;
}
}
Vector2 particleStartPos = item.WorldPosition + ConvertUnits.ToDisplayUnits(TransformedBarrelPos);
@@ -143,7 +143,7 @@ namespace Barotrauma.Items.Components
}
}
public GUIFrame GuiFrame { get; protected set; }
public GUIFrame GuiFrame { get; set; }
[Serialize(false, false)]
public bool AllowUIOverlap
@@ -554,7 +554,7 @@ namespace Barotrauma.Items.Components
color = GuiFrameSource.GetAttributeColor("color", Color.White);
}
string style = GuiFrameSource.Attribute("style") == null ? null : GuiFrameSource.GetAttributeString("style", "");
GuiFrame = new GUIFrame(RectTransform.Load(GuiFrameSource, GUI.Canvas.ItemComponentHolder, Anchor.Center), style, color);
GuiFrame = new GUIFrame(RectTransform.Load(GuiFrameSource, GUI.Canvas, Anchor.Center), style, color);
DefaultLayout = GUILayoutSettings.Load(GuiFrameSource);
if (GuiFrame != null)
{
@@ -76,6 +76,9 @@ namespace Barotrauma.Items.Components
set;
}
[Serialize(false, false, description: "If true, the contained state indicator calculates how full the item is based on the total amount of items that can be stacked inside it, as opposed to how many of the inventory slots are occupied.")]
public bool ShowTotalStackCapacityInContainedStateIndicator { get; set; }
[Serialize(false, false, description: "Should the inventory of this item be kept open when the item is equipped by a character.")]
public bool KeepOpenWhenEquipped { get; set; }
@@ -63,7 +63,7 @@ namespace Barotrauma.Items.Components
Stretch = true,
RelativeSpacing = 0.05f
};
var inputLabel = new GUITextBlock(new RectTransform(Vector2.One, inputLabelArea.RectTransform), TextManager.Get("uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
var inputLabel = new GUITextBlock(new RectTransform(Vector2.One, inputLabelArea.RectTransform), TextManager.Get("deconstructor.input", fallBackTag: "uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
inputLabel.RectTransform.Resize(new Point((int) inputLabel.Font.MeasureString(inputLabel.Text).X, inputLabel.RectTransform.Rect.Height));
new GUIFrame(new RectTransform(Vector2.One, inputLabelArea.RectTransform), style: "HorizontalLine");
@@ -132,7 +132,7 @@ namespace Barotrauma.Items.Components
Stretch = true,
RelativeSpacing = 0.03f
};
var inputLabel = new GUITextBlock(new RectTransform(Vector2.One, separatorArea.RectTransform), TextManager.Get("uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
var inputLabel = new GUITextBlock(new RectTransform(Vector2.One, separatorArea.RectTransform), TextManager.Get("fabricator.input", fallBackTag: "uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
inputLabel.RectTransform.Resize(new Point((int) inputLabel.Font.MeasureString(inputLabel.Text).X, inputLabel.RectTransform.Rect.Height));
new GUIFrame(new RectTransform(Vector2.One, separatorArea.RectTransform), style: "HorizontalLine");
@@ -507,7 +507,7 @@ namespace Barotrauma.Items.Components
{
Vector2 origin = weaponSprite.Origin;
float scale = parentWidth / Math.Max(weaponSprite.size.X, weaponSprite.size.Y);
Color color = !hasPower ? NoPowerColor : turret.ActiveUser is null ? GUI.Style.Red : GUI.Style.Green;
Color color = !hasPower ? NoPowerColor : turret.ActiveUser is null ? Color.DimGray : GUI.Style.Green;
weaponSprite.Draw(batch, center, color, origin, rotation, scale, it.SpriteEffects);
}
});
@@ -1335,7 +1335,7 @@ namespace Barotrauma.Items.Components
RectangleF entityRect = ScaleRectToUI(structure, parent, border);
Vector2 spriteScale = new Vector2(entityRect.Size.X / sprite.size.X, entityRect.Size.Y / sprite.size.Y);
sprite.Draw(spriteBatch, new Vector2(entityRect.Location.X + inflate, entityRect.Location.Y + inflate), structure.SpriteColor, Vector2.Zero, 0f, spriteScale, structure.SpriteEffects);
sprite.Draw(spriteBatch, new Vector2(entityRect.Location.X + inflate, entityRect.Location.Y + inflate), structure.SpriteColor, Vector2.Zero, 0f, spriteScale, sprite.effects ^ structure.SpriteEffects);
}
private static RectangleF ScaleRectToUI(MapEntity entity, RectangleF parentRect, RectangleF worldBorders)
@@ -1718,5 +1718,20 @@ namespace Barotrauma.Items.Components
return new MiniMapHullData(scaledPolygon, worldRect, parentRect.Size, snappedRectangles, hullRefs.ToImmutableArray());
}
protected override void RemoveComponentSpecific()
{
base.RemoveComponentSpecific();
if (searchAutoComplete != null)
{
searchAutoComplete.RectTransform.Parent = null;
searchAutoComplete = null;
}
if (hullInfoFrame != null)
{
hullInfoFrame.RectTransform.Parent = null;
hullInfoFrame = null;
}
}
}
}
@@ -14,7 +14,7 @@ namespace Barotrauma.Items.Components
if (selectionUI == null)
{
selectionUI = new SubmarineSelection(true, null, GUICanvas.Instance.ItemComponentHolder);
selectionUI = new SubmarineSelection(true, null, GUI.Canvas);
}
GuiFrame = selectionUI.GuiFrame;
@@ -35,5 +35,15 @@ namespace Barotrauma.Items.Components
selectionUI?.Update();
}
protected override void RemoveComponentSpecific()
{
base.RemoveComponentSpecific();
if (selectionUI != null)
{
selectionUI.GuiFrame.RectTransform.Parent = null;
selectionUI = null;
}
}
}
}
@@ -348,6 +348,27 @@ namespace Barotrauma.Items.Components
}
}
private Vector2 GetTransducerPos()
{
if (!UseTransducers || connectedTransducers.Count == 0)
{
//use the position of the sub if the item is static (no body) and inside a sub
return item.Submarine != null && item.body == null ? item.Submarine.WorldPosition : item.WorldPosition;
}
Vector2 transducerPosSum = Vector2.Zero;
foreach (ConnectedTransducer transducer in connectedTransducers)
{
if (transducer.Transducer.Item.Submarine != null && !CenterOnTransducers)
{
return transducer.Transducer.Item.Submarine.WorldPosition;
}
transducerPosSum += transducer.Transducer.Item.WorldPosition;
}
return transducerPosSum / connectedTransducers.Count;
}
public override void OnItemLoaded()
{
base.OnItemLoaded();
@@ -10,6 +10,12 @@ namespace Barotrauma.Items.Components
private GUIProgressBar chargeIndicator;
private GUIScrollBar rechargeSpeedSlider;
[Serialize(0.0f, true)]
public float RechargeWarningIndicatorLow { get; set; }
[Serialize(0.0f, true)]
public float RechargeWarningIndicatorHigh { get; set; }
public Vector2 DrawSize
{
//use the extents of the item as the draw size
@@ -28,19 +34,38 @@ namespace Barotrauma.Items.Components
var upperArea = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), paddedFrame.RectTransform, Anchor.TopCenter), style: null);
var lowerArea = new GUIFrame(new RectTransform(new Vector2(1, 0.6f), paddedFrame.RectTransform, Anchor.BottomCenter), style: null);
string rechargeStr = TextManager.Get("PowerContainerRechargeRate");
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), upperArea.RectTransform, Anchor.TopCenter),
"RechargeRate", textColor: GUI.Style.TextColor, font: GUI.SubHeadingFont, textAlignment: Alignment.Center)
var rechargeRateContainer = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), upperArea.RectTransform), style: null);
var rechargeLabel = new GUITextBlock(new RectTransform(new Vector2(0.4f, 0.0f), rechargeRateContainer.RectTransform, Anchor.CenterLeft),
TextManager.Get("rechargerate"), textColor: GUI.Style.TextColor, font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft);
string kW = TextManager.Get("kilowatt");
var rechargeText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1), rechargeRateContainer.RectTransform, Anchor.CenterRight),
"", textColor: GUI.Style.TextColor, font: GUI.Font, textAlignment: Alignment.CenterRight)
{
TextGetter = () =>
{
return rechargeStr.Replace("[rate]", ((int)((rechargeSpeed / maxRechargeSpeed) * 100.0f)).ToString());
}
TextGetter = () => $"{(int)MathF.Round(currPowerConsumption)} {kW} ({(int)MathF.Round(RechargeRatio * 100)} %)"
};
if (rechargeText.TextSize.X > rechargeText.Rect.Width) { rechargeText.Font = GUI.SmallFont; }
rechargeSpeedSlider = new GUIScrollBar(new RectTransform(new Vector2(0.9f, 0.4f), upperArea.RectTransform, Anchor.BottomCenter),
barSize: 0.15f, style: "DeviceSlider")
var rechargeSliderContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.4f), upperArea.RectTransform, Anchor.BottomCenter));
if (RechargeWarningIndicatorLow > 0.0f || RechargeWarningIndicatorHigh > 0.0f)
{
var rechargeSliderFill = new GUICustomComponent(new RectTransform(new Vector2(0.95f, 0.9f), rechargeSliderContainer.RectTransform, Anchor.Center), (SpriteBatch sb, GUICustomComponent c) =>
{
if (RechargeWarningIndicatorLow > 0.0f)
{
float warningLow = c.Rect.Width * RechargeWarningIndicatorLow;
GUI.DrawRectangle(sb, new Vector2(c.Rect.X + warningLow, c.Rect.Y), new Vector2(c.Rect.Width - warningLow, c.Rect.Height), GUI.Style.Orange, isFilled: true);
}
if (RechargeWarningIndicatorHigh > 0.0f)
{
float warningHigh = c.Rect.Width * RechargeWarningIndicatorHigh;
GUI.DrawRectangle(sb, new Vector2(c.Rect.X + warningHigh, c.Rect.Y), new Vector2(c.Rect.Width - warningHigh, c.Rect.Height), GUI.Style.Red, isFilled: true);
}
});
}
rechargeSpeedSlider = new GUIScrollBar(new RectTransform(Vector2.One, rechargeSliderContainer.RectTransform, Anchor.Center),
barSize: 0.15f, style: "DeviceSliderSeeThrough")
{
Step = 0.1f,
OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
@@ -61,17 +86,17 @@ namespace Barotrauma.Items.Components
// lower area --------------------------
var textArea = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), lowerArea.RectTransform), style: null);
var chargeLabel = new GUITextBlock(new RectTransform(new Vector2(0.4f, 0.0f), textArea.RectTransform, Anchor.CenterLeft),
var chargeTextContainer = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), lowerArea.RectTransform), style: null);
var chargeLabel = new GUITextBlock(new RectTransform(new Vector2(0.4f, 0.0f), chargeTextContainer.RectTransform, Anchor.CenterLeft),
TextManager.Get("charge"), textColor: GUI.Style.TextColor, font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft)
{
ToolTip = TextManager.Get("PowerTransferTipPower")
};
string kWmin = TextManager.Get("kilowattminute");
var chargeText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1), textArea.RectTransform, Anchor.CenterRight),
var chargeText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1), chargeTextContainer.RectTransform, Anchor.CenterRight),
"", textColor: GUI.Style.TextColor, font: GUI.Font, textAlignment: Alignment.CenterRight)
{
TextGetter = () => $"{(int)Math.Round(charge)}/{(int)capacity} {kWmin} ({(int)Math.Round(MathUtils.Percentage(charge, capacity))} %)"
TextGetter = () => $"{(int)MathF.Round(charge)}/{(int)capacity} {kWmin} ({(int)MathF.Round(MathUtils.Percentage(charge, capacity))} %)"
};
if (chargeText.TextSize.X > chargeText.Rect.Width) { chargeText.Font = GUI.SmallFont; }
@@ -1,4 +1,5 @@
using Microsoft.Xna.Framework;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Barotrauma.Items.Components
@@ -19,5 +20,10 @@ namespace Barotrauma.Items.Components
ShapeExtensions.DrawLine(spriteBatch, pos + Vector2.UnitX * range, pos - Vector2.UnitX * range, Color.Cyan * 0.5f, 2);
ShapeExtensions.DrawCircle(spriteBatch, pos, range, 32, Color.Cyan * 0.5f, 3);
}
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
{
Channel = msg.ReadRangedInteger(MinChannel, MaxChannel);
}
}
}
@@ -1584,6 +1584,10 @@ namespace Barotrauma
{
containedState = item.Condition / item.MaxCondition;
}
else if (itemContainer.ShowTotalStackCapacityInContainedStateIndicator)
{
containedState = itemContainer.Inventory.AllItems.Count() / (float)(itemContainer.GetMaxStackSize(0) * itemContainer.Capacity);
}
else
{
var containedItem = itemContainer.Inventory.slots[Math.Max(itemContainer.ContainedStateIndicatorSlot, 0)].FirstOrDefault();
@@ -315,7 +315,7 @@ namespace Barotrauma.MapCreatures.Behavior
}
else
{
RemoveClaim(itemId);
RemoveClaim(item);
}
}
else
@@ -128,13 +128,13 @@ namespace Barotrauma
{
//no flow particles between linked hulls (= rooms consisting of multiple hulls)
if (hull1.linkedTo.Contains(hull2)) { return; }
foreach (Hull h in hull1.linkedTo)
foreach (var linkedEntity in hull1.linkedTo)
{
if (h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2)) { return; }
if (linkedEntity is Hull h && h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2)) { return; }
}
foreach (Hull h in hull2.linkedTo)
foreach (var linkedEntity in hull2.linkedTo)
{
if (h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2)) { return; }
if (linkedEntity is Hull h && h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2)) { return; }
}
}
@@ -244,7 +244,7 @@ namespace Barotrauma
float emitInterval = 1.0f / particlesPerSec;
while (particleTimer > emitInterval)
{
pos.X = Rand.Range(rect.X, rect.X + rect.Width);
pos.X = Rand.Range(rect.X, rect.X + rect.Width + 1);
Vector2 velocity = new Vector2(
lerpedFlowForce.X * Rand.Range(0.5f, 0.7f),
MathHelper.Clamp(lerpedFlowForce.Y, -500.0f, 1000.0f) * Rand.Range(0.5f, 0.7f));
@@ -95,7 +95,7 @@ namespace Barotrauma
var prefab = ToolBox.SelectWeightedRandom(availablePrefabs, availablePrefabs.Select(p => p.GetCommonness(level.GenerationParams)).ToList(), Rand.RandSync.ClientOnly);
if (prefab == null) { break; }
int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax, Rand.RandSync.ClientOnly);
int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax + 1, Rand.RandSync.ClientOnly);
List<BackgroundCreature> swarmMembers = new List<BackgroundCreature>();
for (int n = 0; n < amount; n++)
{
@@ -5,6 +5,7 @@ using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Barotrauma.Lights;
@@ -36,9 +37,6 @@ namespace Barotrauma
private static List<MapEntity> highlightedList = new List<MapEntity>();
// Test feature. Not yet saved.
public static Dictionary<MapEntity, HashSet<MapEntity>> SelectionGroups { get; private set; } = new Dictionary<MapEntity, HashSet<MapEntity>>();
private static float highlightTimer;
private static GUIListBox highlightedListBox;
@@ -197,7 +195,7 @@ namespace Barotrauma
{
Paste(cam.ScreenToWorld(PlayerInput.MousePosition));
}
else if (PlayerInput.KeyHit(Keys.G))
/*else if (PlayerInput.KeyHit(Keys.G))
{
if (SelectedList.Any())
{
@@ -217,7 +215,7 @@ namespace Barotrauma
}
}
}
}
}*/
}
}
@@ -360,14 +358,15 @@ namespace Barotrauma
{
if (highLightedEntity != null)
{
if (SelectionGroups.TryGetValue(highLightedEntity, out HashSet<MapEntity> group))
if (SubEditorScreen.IsLayerLinked(highLightedEntity)/*SelectionGroups.TryGetValue(highLightedEntity, out HashSet<MapEntity> group)*/)
{
foreach (MapEntity entity in group.Where(e => !newSelection.Contains(e)))
ImmutableHashSet<MapEntity> entitiesInSameLayer = SubEditorScreen.GetEntitiesInSameLayer(highLightedEntity);
foreach (MapEntity entity in entitiesInSameLayer.Where(e => !newSelection.Contains(e)))
{
newSelection.Add(entity);
}
foreach (MapEntity entity in group)
foreach (MapEntity entity in entitiesInSameLayer)
{
entity.IsIncludedInSelection = true;
}
@@ -1197,14 +1196,24 @@ namespace Barotrauma
Rectangle selectionRect = Submarine.AbsRect(pos, size);
foreach (MapEntity e in mapEntityList)
foreach (MapEntity entity in mapEntityList)
{
if (!e.SelectableInEditor) continue;
if (!entity.SelectableInEditor) { continue; }
if (Submarine.RectsOverlap(selectionRect, e.rect))
if (Submarine.RectsOverlap(selectionRect, entity.rect))
{
foundEntities.Add(e);
e.IsIncludedInSelection = true;
foundEntities.Add(entity);
entity.IsIncludedInSelection = true;
if (SubEditorScreen.IsLayerLinked(entity))
{
ImmutableHashSet<MapEntity> entitiesInSameLayer = SubEditorScreen.GetEntitiesInSameLayer(entity);
foreach (MapEntity layerEntity in entitiesInSameLayer.Where(e => !foundEntities.Contains(e)))
{
foundEntities.Add(layerEntity);
layerEntity.IsIncludedInSelection = true;
}
}
}
}
@@ -651,7 +651,11 @@ namespace Barotrauma
public void Dispose()
{
previewFrame = null;
if (previewFrame != null)
{
previewFrame.RectTransform.Parent = null;
previewFrame = null;
}
spriteRecorder?.Dispose();
isDisposed = true;
}
@@ -46,6 +46,13 @@ namespace Barotrauma.Networking
senderName = senderCharacter.Name;
}
}
Color? textColor = null;
if (msg.ReadBoolean())
{
textColor = msg.ReadColorR8G8B8A8();
}
msg.ReadPadBits();
switch (type)
@@ -135,14 +142,18 @@ namespace Barotrauma.Networking
//only show the message box if the text differs from the text in the currently visible box
if ((GUIMessageBox.VisibleBox as GUIMessageBox)?.Text?.Text != txt)
{
new GUIMessageBox("", txt);
GUIMessageBox messageBox = new GUIMessageBox("", txt);
if (textColor != null) { messageBox.Text.TextColor = textColor.Value; }
}
break;
case ChatMessageType.ServerMessageBoxInGame:
new GUIMessageBox("", txt, new string[0], type: GUIMessageBox.Type.InGame, iconStyle: styleSetting);
{
GUIMessageBox messageBox = new GUIMessageBox("", txt, new string[0], type: GUIMessageBox.Type.InGame, iconStyle: styleSetting);
if (textColor != null) { messageBox.Text.TextColor = textColor.Value; }
}
break;
case ChatMessageType.Console:
DebugConsole.NewMessage(txt, MessageColor[(int)ChatMessageType.Console]);
DebugConsole.NewMessage(txt, textColor == null ? MessageColor[(int)ChatMessageType.Console] : textColor.Value);
break;
case ChatMessageType.ServerLog:
if (!Enum.TryParse(senderName, out ServerLog.MessageType messageType))
@@ -152,7 +163,7 @@ namespace Barotrauma.Networking
GameMain.Client.ServerSettings.ServerLog?.WriteLine(txt, messageType);
break;
default:
GameMain.Client.AddChatMessage(txt, type, senderName, senderClient, senderCharacter, changeType);
GameMain.Client.AddChatMessage(txt, type, senderName, senderClient, senderCharacter, changeType, textColor: textColor);
break;
}
LastID = id;
@@ -857,7 +857,7 @@ namespace Barotrauma.Networking
}
break;
case ServerPacketHeader.STARTGAMEFINALIZE:
DebugConsole.Log("Received STARTGAMEFINALIZE packet.");
DebugConsole.NewMessage("Received STARTGAMEFINALIZE packet. Round init status: " + roundInitStatus);
if (roundInitStatus == RoundInitStatus.WaitingForStartGameFinalize)
{
//waiting for a save file
@@ -1,13 +1,10 @@
using Barotrauma.Tutorials;
using Barotrauma.Extensions;
using Barotrauma.IO;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using Barotrauma.IO;
using System.Linq;
using System.Xml.Linq;
using System.Globalization;
using Barotrauma.Extensions;
using Barotrauma.Networking;
using System.Linq;
namespace Barotrauma
{
@@ -64,6 +61,7 @@ namespace Barotrauma
maxMissionCount = MathHelper.Clamp(maxMissionCount,
CampaignSettings.MinMissionCountLimit,
CampaignSettings.MaxMissionCountLimit);
maxMissionCountText.Text = maxMissionCount.ToString(CultureInfo.InvariantCulture);
}
maxMissionCountButtons[1]
@@ -151,6 +151,7 @@ namespace Barotrauma
if (Campaign.Money >= CampaignMode.HullRepairCost)
{
Campaign.Money -= CampaignMode.HullRepairCost;
GameAnalyticsManager.AddMoneySpentEvent(CampaignMode.HullRepairCost, GameAnalyticsManager.MoneySink.Service, "hullrepairs");
Campaign.PurchasedHullRepairs = true;
}
}
@@ -196,6 +197,7 @@ namespace Barotrauma
if (Campaign.Money >= CampaignMode.ItemRepairCost)
{
Campaign.Money -= CampaignMode.ItemRepairCost;
GameAnalyticsManager.AddMoneySpentEvent(CampaignMode.ItemRepairCost, GameAnalyticsManager.MoneySink.Service, "devicerepairs");
Campaign.PurchasedItemRepairs = true;
}
}
@@ -248,6 +250,7 @@ namespace Barotrauma
if (Campaign.Money >= CampaignMode.ShuttleReplaceCost)
{
Campaign.Money -= CampaignMode.ShuttleReplaceCost;
GameAnalyticsManager.AddMoneySpentEvent(CampaignMode.ShuttleReplaceCost, GameAnalyticsManager.MoneySink.Service, "retrieveshuttle");
Campaign.PurchasedLostShuttles = true;
}
}
@@ -54,7 +54,7 @@ namespace Barotrauma
private void CreateGUI()
{
GuiFrame = new GUIFrame(new RectTransform(new Vector2(0.2f, 0.4f), GUICanvas.Instance) { MinSize = new Point(300, 400) });
GuiFrame = new GUIFrame(new RectTransform(new Vector2(0.2f, 0.4f), GUI.Canvas) { MinSize = new Point(300, 400) });
GUILayoutGroup layoutGroup = new GUILayoutGroup(RectTransform(0.9f, 0.9f, GuiFrame, Anchor.Center)) { Stretch = true };
// === BUTTONS === //
@@ -501,8 +501,6 @@ namespace Barotrauma
ResetButtonStates(null);
GameAnalyticsManager.SetCustomDimension01("");
if (GameMain.SteamWorkshopScreen != null)
{
CoroutineManager.StartCoroutine(GameMain.SteamWorkshopScreen.RefreshDownloadState());
@@ -1019,7 +1017,10 @@ namespace Barotrauma
if (backgroundSprite == null)
{
backgroundSprite = (LocationType.List.Where(l => l.UseInMainMenu).GetRandom())?.GetPortrait(0);
#if UNSTABLE
backgroundSprite = new Sprite("Content/UnstableBackground.png", sourceRectangle: null);
#endif
backgroundSprite ??= LocationType.List.Where(l => l.UseInMainMenu).GetRandom()?.GetPortrait(0);
}
if (backgroundSprite != null)
@@ -1159,7 +1160,7 @@ namespace Barotrauma
//GameMain.LobbyScreen.Select();
}
#region UI Methods
#region UI Methods
private void CreateCampaignSetupUI()
{
menuTabs[(int)Tab.NewGame].ClearChildren();
@@ -1432,7 +1433,7 @@ namespace Barotrauma
playstyleDescription.TextAlignment = playstyleDescription.WrappedText.Contains('\n') ?
Alignment.CenterLeft : Alignment.Center;
}
#endregion
#endregion
private void FetchRemoteContent()
{
@@ -14,7 +14,7 @@ namespace Barotrauma
{
if (frame == null)
{
frame = new GUIFrame(new RectTransform(GUICanvas.Instance.RelativeSize, GUICanvas.Instance), style: null)
frame = new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas), style: null)
{
CanBeFocused = false
};
@@ -4,6 +4,7 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
@@ -21,6 +22,38 @@ namespace Barotrauma
{
class SubEditorScreen : EditorScreen
{
private enum LayerVisibility
{
Visible,
Invisible
}
private enum LayerLinkage
{
Unlinked,
Linked
}
private readonly struct LayerData
{
public readonly LayerVisibility Visible;
public readonly LayerLinkage Linkage;
public static readonly LayerData Default = new LayerData(LayerVisibility.Visible, LayerLinkage.Unlinked);
public LayerData(LayerVisibility visible, LayerLinkage linkage)
{
Visible = visible;
Linkage = linkage;
}
public void Deconstruct(out LayerVisibility isvisible, out LayerLinkage islinked)
{
isvisible = Visible;
islinked = Linkage;
}
}
private static readonly string[] crewExperienceLevels =
{
"CrewExperienceLow",
@@ -94,6 +127,7 @@ namespace Barotrauma
private GUIFrame hullVolumeFrame;
private GUIFrame saveAssemblyFrame;
private GUIFrame snapToGridFrame;
const int PreviouslyUsedCount = 10;
private GUIFrame previouslyUsedPanel;
@@ -238,7 +272,7 @@ namespace Barotrauma
public bool WiringMode => mode == Mode.Wiring;
public static readonly Dictionary<string, bool> Layers = new Dictionary<string, bool>();
private static readonly Dictionary<string, LayerData> Layers = new Dictionary<string, LayerData>();
public SubEditorScreen()
{
@@ -507,7 +541,7 @@ namespace Barotrauma
//-----------------------------------------------
layerPanel = new GUIFrame(new RectTransform(new Vector2(0.175f, 0.4f), GUI.Canvas))
layerPanel = new GUIFrame(new RectTransform(new Vector2(0.2f, 0.4f), GUI.Canvas))
{
Visible = false
};
@@ -520,6 +554,7 @@ namespace Barotrauma
AutoHideScrollBar = false,
OnSelected = (component, o) =>
{
if (GUI.MouseOn is GUITickBox) { return false; } // lol
if (!(o is string layer)) { return false; }
MapEntity.SelectedList.Clear();
@@ -847,6 +882,19 @@ namespace Barotrauma
};
saveAssemblyFrame.RectTransform.MinSize = new Point(saveAssemblyFrame.Rect.Width, (int)(saveAssemblyButton.Rect.Height / saveAssemblyButton.RectTransform.RelativeSize.Y));
snapToGridFrame = new GUIFrame(new RectTransform(new Vector2(0.08f, 0.5f), TopPanel.RectTransform, Anchor.BottomLeft, Pivot.TopLeft)
{ MinSize = new Point((int)(250 * GUI.Scale), (int)(80 * GUI.Scale)), AbsoluteOffset = new Point((int)(10 * GUI.Scale), -saveAssemblyFrame.Rect.Height - entityCountPanel.Rect.Height - (int)(10 * GUI.Scale)) }, "InnerFrame")
{
Visible = false
};
var saveStampButton = new GUIButton(new RectTransform(new Vector2(0.9f, 0.8f), snapToGridFrame.RectTransform, Anchor.Center), TextManager.Get("subeditor.snaptogrid", fallBackTag: "spriteeditor.snaptogrid"));
saveStampButton.TextBlock.AutoScaleHorizontal = true;
saveStampButton.OnClicked += (btn, userdata) =>
{
SnapToGrid();
return true;
};
snapToGridFrame.RectTransform.MinSize = new Point(snapToGridFrame.Rect.Width, (int)(saveStampButton.Rect.Height / saveStampButton.RectTransform.RelativeSize.Y));
//Entity menu
//------------------------------------------------
@@ -941,7 +989,7 @@ namespace Barotrauma
};
paddedTab.Recalculate();
UpdateLayerPanel();
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
}
@@ -1161,6 +1209,7 @@ namespace Barotrauma
{
CanBeFocused = false,
LoadAsynchronously = true,
SpriteEffects = icon.effects,
Color = legacy ? iconColor * 0.6f : iconColor
};
}
@@ -1344,8 +1393,8 @@ namespace Barotrauma
}
ImageManager.OnEditorSelected();
ReconstructLayers();
GameAnalyticsManager.SetCustomDimension01("editor");
if (!GameMain.Config.EditorDisclaimerShown)
{
GameMain.Instance.ShowEditorDisclaimer();
@@ -1455,7 +1504,6 @@ namespace Barotrauma
loadFrame = null;
MapEntity.DeselectAll();
MapEntity.SelectionGroups.Clear();
ClearUndoBuffer();
SetMode(Mode.Default);
@@ -2205,7 +2253,7 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), priceGroup.RectTransform),
TextManager.Get("subeditor.price"), textAlignment: Alignment.CenterLeft, wrap: true);
int basePrice = GameMain.DebugDraw ? 0 : Submarine.MainSub?.CalculateBasePrice() ?? 1000;
int basePrice = (GameMain.DebugDraw ? 0 : Submarine.MainSub?.CalculateBasePrice()) ?? 1000;
new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), priceGroup.RectTransform), GUINumberInput.NumberType.Int, hidePlusMinusButtons: true)
{
IntValue = Math.Max(Submarine.MainSub?.Info?.Price ?? basePrice, basePrice),
@@ -2682,6 +2730,38 @@ namespace Barotrauma
return false;
}
private void SnapToGrid()
{
// First move components
foreach (Item item in MapEntity.SelectedList.Where(entity => entity is Item).Cast<Item>())
{
var wire = item.GetComponent<Wire>();
if (wire == null)
{
// Items snap to centre of nearest grid square
Vector2 offset = item.Position;
offset = new Vector2((MathF.Floor(offset.X / Submarine.GridSize.X) + .5f) * Submarine.GridSize.X - offset.X, (MathF.Floor(offset.Y / Submarine.GridSize.Y) + .5f) * Submarine.GridSize.Y - offset.Y);
item.Move(offset);
}
}
// Then move wires, separated as moving components also moves the start and end node of wires
foreach (Item item in MapEntity.SelectedList.Where(entity => entity is Item).Cast<Item>())
{
var wire = item.GetComponent<Wire>();
if (wire != null)
{
for (int i = 0; i < wire.GetNodes().Count; i++)
{
// Items wire nodes to centre of nearest grid square
Vector2 offset = wire.GetNodes()[i] + Submarine.MainSub.HiddenSubPosition;
offset = new Vector2((MathF.Floor(offset.X / Submarine.GridSize.X) + .5f) * Submarine.GridSize.X - offset.X, (MathF.Floor(offset.Y / Submarine.GridSize.Y) + .5f) * Submarine.GridSize.Y - offset.Y);
wire.MoveNode(i, offset);
}
}
}
}
private void CreateLoadScreen()
{
CloseItem();
@@ -3232,7 +3312,6 @@ namespace Barotrauma
}),
new ContextMenuOption("editor.layer.openlayermenu", isEnabled: true, onSelected: () =>
{
if (visibilityButton is null) { return; }
previouslyUsedPanel.Visible = false;
undoBufferPanel.Visible = false;
showEntitiesPanel.Visible = false;
@@ -3289,7 +3368,7 @@ namespace Barotrauma
MoveToLayer(name, content);
}
Layers.Add(name, true);
Layers.Add(name, LayerData.Default);
UpdateLayerPanel();
}
@@ -3304,7 +3383,7 @@ namespace Barotrauma
if (!string.IsNullOrWhiteSpace(newName))
{
Layers.TryAdd(newName, true);
Layers.TryAdd(newName, LayerData.Default);
}
UpdateLayerPanel();
}
@@ -3316,7 +3395,7 @@ namespace Barotrauma
{
if (!string.IsNullOrWhiteSpace(entity.Layer))
{
Layers.TryAdd(entity.Layer, true);
Layers.TryAdd(entity.Layer, LayerData.Default);
}
}
UpdateLayerPanel();
@@ -4352,8 +4431,13 @@ namespace Barotrauma
layerList.Content.ClearChildren();
layerList.Deselect();
GUILayoutGroup buttonHeaders = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.075f), layerList.Content.RectTransform), isHorizontal: true, childAnchor: Anchor.BottomLeft);
foreach (var (layer, isVisible) in Layers)
new GUIButton(new RectTransform(new Vector2(0.25f, 1f), buttonHeaders.RectTransform), TextManager.Get("editor.layer.headervisible"), style: "GUIButtonSmallFreeScale") { CanBeFocused = false, ForceUpperCase = true };
new GUIButton(new RectTransform(new Vector2(0.15f, 1f), buttonHeaders.RectTransform), TextManager.Get("editor.layer.headerlink"), style: "GUIButtonSmallFreeScale") { CanBeFocused = false, ForceUpperCase = true };
new GUIButton(new RectTransform(new Vector2(0.65f, 1f), buttonHeaders.RectTransform), TextManager.Get("name"), style: "GUIButtonSmallFreeScale") { CanBeFocused = false, ForceUpperCase = true };
foreach (var (layer, (visibility, linkage)) in Layers)
{
GUIFrame parent = new GUIFrame(new RectTransform(new Vector2(1f, 0.1f), layerList.Content.RectTransform), style: "ListBoxElement")
{
@@ -4362,33 +4446,54 @@ namespace Barotrauma
GUILayoutGroup layerGroup = new GUILayoutGroup(new RectTransform(Vector2.One, parent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
GUITickBox layerVisibleButton = new GUITickBox(new RectTransform(Vector2.One, layerGroup.RectTransform, scaleBasis: ScaleBasis.BothHeight), string.Empty)
GUILayoutGroup layerVisibilityLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.25f, 1f), layerGroup.RectTransform), childAnchor: Anchor.Center);
GUITickBox layerVisibleButton = new GUITickBox(new RectTransform(Vector2.One, layerVisibilityLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), string.Empty)
{
Selected = isVisible,
Selected = visibility == LayerVisibility.Visible,
OnSelected = box =>
{
if (!Layers.TryGetValue(layer, out bool _))
if (!Layers.TryGetValue(layer, out LayerData data))
{
UpdateLayerPanel();
return false;
}
Layers[layer] = box.Selected;
Layers[layer] = new LayerData(box.Selected ? LayerVisibility.Visible : LayerVisibility.Invisible, data.Linkage);
return true;
}
};
GUILayoutGroup layerChainLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.15f, 1f), layerGroup.RectTransform), childAnchor: Anchor.Center);
GUITickBox layerChainButton = new GUITickBox(new RectTransform(Vector2.One, layerChainLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), string.Empty)
{
Selected = linkage == LayerLinkage.Linked,
OnSelected = box =>
{
if (!Layers.TryGetValue(layer, out LayerData data))
{
UpdateLayerPanel();
return false;
}
Layers[layer] = new LayerData(data.Visible, box.Selected ? LayerLinkage.Linked : LayerLinkage.Unlinked);
return true;
}
};
layerGroup.Recalculate();
new GUITextBlock(new RectTransform(new Vector2(1.0f - layerVisibleButton.RectTransform.RelativeSize.X, 1f), layerGroup.RectTransform), layer, textAlignment: Alignment.CenterLeft)
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1f), layerGroup.RectTransform), layer, textAlignment: Alignment.CenterLeft)
{
CanBeFocused = false
};
layerGroup.Recalculate();
layerChainLayout.Recalculate();
layerVisibilityLayout.Recalculate();
}
layerList.RecalculateChildren();
buttonHeaders.Recalculate();
}
public void UpdateUndoHistoryPanel()
@@ -4454,6 +4559,7 @@ namespace Barotrauma
saveFrame = null;
loadFrame = null;
saveAssemblyFrame = null;
snapToGridFrame = null;
CreateUI();
UpdateEntityList();
}
@@ -4501,6 +4607,7 @@ namespace Barotrauma
hullVolumeFrame.Visible = MapEntity.SelectedList.Any(s => s is Hull);
hullVolumeFrame.RectTransform.AbsoluteOffset = new Point(Math.Max(showEntitiesPanel.Rect.Right, previouslyUsedPanel.Rect.Right), 0);
saveAssemblyFrame.Visible = MapEntity.SelectedList.Count > 0;
snapToGridFrame.Visible = MapEntity.SelectedList.Count > 0;
var offset = cam.WorldView.Top - cam.ScreenToWorld(new Vector2(0, GameMain.GraphicsHeight - EntityMenu.Rect.Top)).Y;
@@ -4962,7 +5069,8 @@ namespace Barotrauma
MouseDragStart = Vector2.Zero;
}
if (!saveAssemblyFrame.Rect.Contains(PlayerInput.MousePosition) && dummyCharacter?.SelectedConstruction == null && !WiringMode && GUI.MouseOn == null)
if (!saveAssemblyFrame.Rect.Contains(PlayerInput.MousePosition) && !snapToGridFrame.Rect.Contains(PlayerInput.MousePosition) &&
dummyCharacter?.SelectedConstruction == null && !WiringMode && GUI.MouseOn == null)
{
if (layerList is { Visible: true } && GUI.KeyboardDispatcher.Subscriber == layerList)
{
@@ -5338,17 +5446,34 @@ namespace Barotrauma
public static bool IsLayerVisible(MapEntity entity)
{
if (!IsSubEditor()) { return true; }
if (!IsSubEditor() || string.IsNullOrWhiteSpace(entity.Layer)) { return true; }
if (string.IsNullOrWhiteSpace(entity.Layer)) { return true; }
if (!Layers.TryGetValue(entity.Layer, out bool isVisible))
if (!Layers.TryGetValue(entity.Layer, out LayerData data))
{
Layers.TryAdd(entity.Layer, true);
Layers.TryAdd(entity.Layer, LayerData.Default);
return true;
}
return isVisible;
return data.Visible == LayerVisibility.Visible;
}
public static bool IsLayerLinked(MapEntity entity)
{
if (!IsSubEditor() || string.IsNullOrWhiteSpace(entity.Layer)) { return false; }
if (!Layers.TryGetValue(entity.Layer, out LayerData data))
{
Layers.TryAdd(entity.Layer, LayerData.Default);
return true;
}
return data.Linkage == LayerLinkage.Linked;
}
public static ImmutableHashSet<MapEntity> GetEntitiesInSameLayer(MapEntity entity)
{
if (string.IsNullOrWhiteSpace(entity.Layer)) { return ImmutableHashSet<MapEntity>.Empty; }
return MapEntity.mapEntityList.Where(me => me.Layer == entity.Layer).ToImmutableHashSet();
}
}
}
@@ -65,7 +65,6 @@ namespace Barotrauma
Character.Controlled = dummyCharacter;
GameMain.World.ProcessChanges();
TabMenu.selectedTab = TabMenu.InfoFrameTab.Talents;
tabMenu = new TabMenu();
}
@@ -1157,7 +1157,7 @@ namespace Barotrauma
public static void PlaySplashSound(Vector2 worldPosition, float strength)
{
if (SplashSounds.Count == 0) { return; }
int splashIndex = MathHelper.Clamp((int)(strength + Rand.Range(-2, 2)), 0, SplashSounds.Count - 1);
int splashIndex = MathHelper.Clamp((int)(strength + Rand.Range(-2.0f, 2.0f)), 0, SplashSounds.Count - 1);
float range = 800.0f;
var channel = SplashSounds[splashIndex].Play(1.0f, range, worldPosition, muffle: ShouldMuffleSound(Character.Controlled, worldPosition, range, null));
}
@@ -148,14 +148,8 @@ namespace Barotrauma
return t;
}
string fullPath = Path.GetFullPath(file);
foreach (Sprite s in LoadedSprites)
{
if (s.FullPath == fullPath && s.texture != null && !s.texture.IsDisposed)
{
reusedSprite = s;
return s.texture;
}
}
reusedSprite = FindMatchingSprite(fullPath, requireTexture: true);
if (reusedSprite != null) { return reusedSprite.texture; }
if (File.Exists(file))
{
@@ -176,6 +170,22 @@ namespace Barotrauma
return null;
}
private static Sprite FindMatchingSprite(string fullPath, bool requireTexture)
{
lock (list)
{
foreach (var wRef in list)
{
if (wRef.TryGetTarget(out Sprite sprite))
{
bool hasTexture = sprite.texture != null && !sprite.texture.IsDisposed;
if (sprite.FullPath == fullPath && (hasTexture || !requireTexture)) { return sprite; }
}
}
}
return null;
}
public void Draw(ISpriteBatch spriteBatch, Vector2 pos, float rotate = 0.0f, float scale = 1.0f, SpriteEffects spriteEffect = SpriteEffects.None)
{
this.Draw(spriteBatch, pos, Color.White, rotate, scale, spriteEffect);
@@ -371,15 +381,9 @@ namespace Barotrauma
//check if another sprite is using the same texture
if (!string.IsNullOrEmpty(FilePath)) //file can be empty if the sprite is created directly from a Texture2D instance
{
lock (list)
{
foreach (Sprite s in LoadedSprites)
{
if (s.FullPath == FullPath) { return; }
}
}
if (FindMatchingSprite(FullPath, requireTexture: false) != null) { return; }
}
//if not, free the texture
if (texture != null)
{
@@ -89,7 +89,17 @@ namespace Barotrauma
for (int j = 0; j < infoTextFiles.Count; j++)
{
List<string> xmlContent = ConvertInfoTextToXML(File.ReadAllLines(infoTextFiles[j], Encoding.UTF8), language);
List<string> xmlContent = null;
try
{
xmlContent = ConvertInfoTextToXML(File.ReadAllLines(infoTextFiles[j], Encoding.UTF8), language);
}
catch (Exception e)
{
DebugConsole.ThrowError("InfoText Localization .csv to .xml conversion failed for: " + infoTextFiles[j], e);
continue;
}
if (xmlContent == null)
{
DebugConsole.ThrowError("InfoText Localization .csv to .xml conversion failed for: " + infoTextFiles[j]);
@@ -122,7 +122,7 @@ namespace Barotrauma
{
int width = 4096; int height = 4096;
Rectangle subDimensions = sub.Borders;
Rectangle subDimensions = sub.CalculateDimensions(false);
Vector2 viewPos = subDimensions.Center.ToVector2();
float scale = Math.Min(width / (float)subDimensions.Width, height / (float)subDimensions.Height);