Merge branch 'master' of https://github.com/Regalis11/Barotrauma.git
This commit is contained in:
@@ -44,12 +44,12 @@ namespace Barotrauma
|
||||
Waiting, // Hourglass
|
||||
WaitingBackground // Cursor + Hourglass
|
||||
}
|
||||
|
||||
|
||||
public static class GUI
|
||||
{
|
||||
public static GUICanvas Canvas => GUICanvas.Instance;
|
||||
public static CursorState MouseCursor = CursorState.Default;
|
||||
|
||||
|
||||
public static readonly SamplerState SamplerState = new SamplerState()
|
||||
{
|
||||
Filter = TextureFilter.Linear,
|
||||
@@ -116,14 +116,14 @@ namespace Barotrauma
|
||||
|
||||
public static float SlicedSpriteScale
|
||||
{
|
||||
get
|
||||
get
|
||||
{
|
||||
if (Math.Abs(1.0f - Scale) < 0.1f)
|
||||
{
|
||||
if (Math.Abs(1.0f - Scale) < 0.1f)
|
||||
{
|
||||
//don't scale if very close to the "reference resolution"
|
||||
return 1.0f;
|
||||
return 1.0f;
|
||||
}
|
||||
return Scale;
|
||||
return Scale;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ namespace Barotrauma
|
||||
t = new Texture2D(GraphicsDevice, 1, 1);
|
||||
t.SetData(new Color[] { Color.White });// fill the texture with white
|
||||
});
|
||||
|
||||
|
||||
SubmarineIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(452, 385, 182, 81), new Vector2(0.5f, 0.5f));
|
||||
arrow = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(393, 393, 49, 45), new Vector2(0.5f, 0.5f));
|
||||
SpeechBubbleIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(385, 449, 66, 60), new Vector2(0.5f, 0.5f));
|
||||
@@ -314,7 +314,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// By default, all the gui elements are drawn automatically in the same order they appear on the update list.
|
||||
/// By default, all the gui elements are drawn automatically in the same order they appear on the update list.
|
||||
/// </summary>
|
||||
public static void Draw(Camera cam, SpriteBatch spriteBatch)
|
||||
{
|
||||
@@ -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,
|
||||
@@ -706,11 +711,11 @@ namespace Barotrauma
|
||||
spriteBatch.Begin(SpriteSortMode.Immediate, effect: GameMain.GameScreen.PostProcessEffect);
|
||||
|
||||
float scale = Math.Max(
|
||||
(float)GameMain.GraphicsWidth / backgroundSprite.SourceRect.Width,
|
||||
(float)GameMain.GraphicsWidth / backgroundSprite.SourceRect.Width,
|
||||
(float)GameMain.GraphicsHeight / backgroundSprite.SourceRect.Height) * 1.1f;
|
||||
float paddingX = backgroundSprite.SourceRect.Width * scale - GameMain.GraphicsWidth;
|
||||
float paddingY = backgroundSprite.SourceRect.Height * scale - GameMain.GraphicsHeight;
|
||||
|
||||
|
||||
double noiseT = (Timing.TotalTime * 0.02f);
|
||||
Vector2 pos = new Vector2((float)PerlinNoise.CalculatePerlin(noiseT, noiseT, 0) - 0.5f, (float)PerlinNoise.CalculatePerlin(noiseT, noiseT, 0.5f) - 0.5f);
|
||||
pos = new Vector2(pos.X * paddingX, pos.Y * paddingY);
|
||||
@@ -719,7 +724,7 @@ namespace Barotrauma
|
||||
new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2 + pos,
|
||||
null, Color.White, 0.0f, backgroundSprite.size / 2,
|
||||
scale, SpriteEffects.None, 0.0f);
|
||||
|
||||
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
@@ -759,8 +764,8 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
additions.Enqueue(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -786,7 +791,7 @@ namespace Barotrauma
|
||||
component.Children.ForEach(c => RemoveFromUpdateList(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ClearUpdateList()
|
||||
@@ -900,7 +905,7 @@ namespace Barotrauma
|
||||
{
|
||||
GUIMessageBox.VisibleBox.AddToGUIUpdateList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -941,7 +946,7 @@ namespace Barotrauma
|
||||
inventoryIndex = updateList.IndexOf(CharacterHUD.HUDFrame);
|
||||
}
|
||||
|
||||
if ((!PlayerInput.PrimaryMouseButtonHeld() && !PlayerInput.PrimaryMouseButtonClicked()) ||
|
||||
if ((!PlayerInput.PrimaryMouseButtonHeld() && !PlayerInput.PrimaryMouseButtonClicked()) ||
|
||||
(prevMouseOn == null && !PlayerInput.SecondaryMouseButtonHeld() && !Inventory.DraggingItems.Any()))
|
||||
{
|
||||
for (var i = updateList.Count - 1; i > inventoryIndex; i--)
|
||||
@@ -967,7 +972,7 @@ namespace Barotrauma
|
||||
return MouseOn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static CursorState UpdateMouseCursorState(GUIComponent c)
|
||||
{
|
||||
lock (mutex)
|
||||
@@ -994,7 +999,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (Wire.DraggingWire != null) { return CursorState.Dragging; }
|
||||
}
|
||||
|
||||
|
||||
if (c == null || c is GUICustomComponent)
|
||||
{
|
||||
switch (Screen.Selected)
|
||||
@@ -1027,7 +1032,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (c != null && c.Visible)
|
||||
{
|
||||
if (c.AlwaysOverrideCursor) { return c.HoverCursor; }
|
||||
@@ -1036,20 +1041,20 @@ namespace Barotrauma
|
||||
// And this is of course picked up as clickable area.
|
||||
// There has to be a better way of checking this but for now this works.
|
||||
var monitorRect = new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
|
||||
|
||||
var parent = FindInteractParent(c);
|
||||
|
||||
|
||||
if (c.Enabled)
|
||||
{
|
||||
// Some parent elements take priority
|
||||
// but not when the child is a GUIButton or GUITickBox
|
||||
if (!(parent is GUIButton) && !(parent is GUIListBox) ||
|
||||
if (!(parent is GUIButton) && !(parent is GUIListBox) ||
|
||||
(c is GUIButton) || (c is GUITickBox))
|
||||
{
|
||||
if (!c.Rect.Equals(monitorRect)) { return c.HoverCursor; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Children in list boxes can be interacted with despite not having
|
||||
// a GUIButton inside of them so instead of hard coding we check if
|
||||
// the children can be interacted with by checking their hover state
|
||||
@@ -1084,7 +1089,7 @@ namespace Barotrauma
|
||||
{
|
||||
// Health menus
|
||||
if (character.CharacterHealth.MouseOnElement) { return CursorState.Hand; }
|
||||
|
||||
|
||||
if (character.SelectedCharacter != null)
|
||||
{
|
||||
if (character.SelectedCharacter.CharacterHealth.MouseOnElement)
|
||||
@@ -1096,7 +1101,7 @@ namespace Barotrauma
|
||||
// Character is hovering over an item placed in the world
|
||||
if (character.FocusedItem != null) { return CursorState.Hand; }
|
||||
}
|
||||
|
||||
|
||||
return CursorState.Default;
|
||||
|
||||
static GUIComponent FindInteractParent(GUIComponent component)
|
||||
@@ -1130,7 +1135,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool ContainsMouse(GUIComponent component)
|
||||
{
|
||||
// If component has a mouse rectangle then use that, if not use it's physical rect
|
||||
@@ -1138,7 +1143,7 @@ namespace Barotrauma
|
||||
component.MouseRect.Contains(PlayerInput.MousePosition) :
|
||||
component.Rect.Contains(PlayerInput.MousePosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1153,8 +1158,8 @@ namespace Barotrauma
|
||||
{
|
||||
MouseCursor = CursorState.Waiting;
|
||||
var timeOut = DateTime.Now + new TimeSpan(0, 0, waitSeconds);
|
||||
while (DateTime.Now < timeOut)
|
||||
{
|
||||
while (DateTime.Now < timeOut)
|
||||
{
|
||||
if (endCondition != null)
|
||||
{
|
||||
try
|
||||
@@ -1163,13 +1168,13 @@ namespace Barotrauma
|
||||
}
|
||||
catch { break; }
|
||||
}
|
||||
yield return CoroutineStatus.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
if (MouseCursor == CursorState.Waiting) { MouseCursor = CursorState.Default; }
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void ClearCursorWait()
|
||||
{
|
||||
lock (mutex)
|
||||
@@ -1208,7 +1213,7 @@ namespace Barotrauma
|
||||
{
|
||||
debugDrawMetadataOffset--;
|
||||
}
|
||||
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Down))
|
||||
{
|
||||
debugDrawMetadataOffset++;
|
||||
@@ -1240,17 +1245,20 @@ namespace Barotrauma
|
||||
debugDrawMetadataOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
HandlePersistingElements(deltaTime);
|
||||
RefreshUpdateList();
|
||||
UpdateMouseOn();
|
||||
Debug.Assert(updateList.Count == updateListSet.Count);
|
||||
updateList.ForEach(c => c.UpdateAuto(deltaTime));
|
||||
foreach (var c in updateList)
|
||||
{
|
||||
c.UpdateAuto(deltaTime);
|
||||
}
|
||||
UpdateMessages(deltaTime);
|
||||
UpdateSavingIndicator(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateMessages(float deltaTime)
|
||||
@@ -1281,17 +1289,16 @@ namespace Barotrauma
|
||||
//only the first message (the currently visible one) is updated at a time
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
foreach (GUIMessage msg in messages)
|
||||
{
|
||||
if (!msg.WorldSpace) { continue; }
|
||||
msg.Timer -= deltaTime;
|
||||
msg.Pos += msg.Velocity * deltaTime;
|
||||
msg.Timer -= deltaTime;
|
||||
msg.Pos += msg.Velocity * deltaTime;
|
||||
}
|
||||
|
||||
messages.RemoveAll(m => m.Timer <= 0.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void UpdateSavingIndicator(float deltaTime)
|
||||
@@ -1349,7 +1356,7 @@ namespace Barotrauma
|
||||
|
||||
#region Element drawing
|
||||
|
||||
private static List<float> usedIndicatorAngles = new List<float>();
|
||||
private static readonly List<float> usedIndicatorAngles = new List<float>();
|
||||
|
||||
/// <param name="createOffset">Should the indicator move based on the camera position?</param>
|
||||
/// <param name="overrideAlpha">Override the distance-based alpha value with the specified alpha value</param>
|
||||
@@ -1628,7 +1635,7 @@ namespace Barotrauma
|
||||
|
||||
private static void DrawMessages(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (messages.Count == 0) return;
|
||||
if (messages.Count == 0) { return; }
|
||||
|
||||
bool useScissorRect = messages.Any(m => !m.WorldSpace);
|
||||
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
|
||||
@@ -1647,7 +1654,7 @@ namespace Barotrauma
|
||||
|
||||
msg.Font.DrawString(spriteBatch, msg.Text, drawPos + msg.DrawPos + Vector2.One, Color.Black, 0, msg.Origin, 1.0f, SpriteEffects.None, 0);
|
||||
msg.Font.DrawString(spriteBatch, msg.Text, drawPos + msg.DrawPos, msg.Color, 0, msg.Origin, 1.0f, SpriteEffects.None, 0);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (useScissorRect)
|
||||
@@ -1656,11 +1663,11 @@ namespace Barotrauma
|
||||
spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred);
|
||||
}
|
||||
|
||||
|
||||
foreach (GUIMessage msg in messages)
|
||||
{
|
||||
if (!msg.WorldSpace) { continue; }
|
||||
|
||||
|
||||
if (cam != null)
|
||||
{
|
||||
float alpha = 1.0f;
|
||||
@@ -1669,7 +1676,7 @@ namespace Barotrauma
|
||||
Vector2 drawPos = cam.WorldToScreen(msg.DrawPos);
|
||||
msg.Font.DrawString(spriteBatch, msg.Text, drawPos + Vector2.One, Color.Black * alpha, 0, msg.Origin, 1.0f, SpriteEffects.None, 0);
|
||||
msg.Font.DrawString(spriteBatch, msg.Text, drawPos, msg.Color * alpha, 0, msg.Origin, 1.0f, SpriteEffects.None, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messages.RemoveAll(m => m.Timer <= 0.0f);
|
||||
@@ -1770,7 +1777,7 @@ namespace Barotrauma
|
||||
{
|
||||
int textureWidth = Math.Max(radius * 2, 1);
|
||||
int textureHeight = Math.Max(height + radius * 2, 1);
|
||||
|
||||
|
||||
Color[] data = new Color[textureWidth * textureHeight];
|
||||
|
||||
// Colour the entire texture transparent first.
|
||||
@@ -1880,9 +1887,9 @@ namespace Barotrauma
|
||||
/// Creates multiple elements with relative size and positions them automatically.
|
||||
/// </summary>
|
||||
public static List<T> CreateElements<T>(int count, Vector2 relativeSize, RectTransform parent, Func<RectTransform, T> constructor,
|
||||
Anchor anchor = Anchor.TopLeft, Pivot? pivot = null, Point? minSize = null, Point? maxSize = null,
|
||||
int absoluteSpacing = 0, float relativeSpacing = 0, Func<int, int> extraSpacing = null,
|
||||
int startOffsetAbsolute = 0, float startOffsetRelative = 0, bool isHorizontal = false)
|
||||
Anchor anchor = Anchor.TopLeft, Pivot? pivot = null, Point? minSize = null, Point? maxSize = null,
|
||||
int absoluteSpacing = 0, float relativeSpacing = 0, Func<int, int> extraSpacing = null,
|
||||
int startOffsetAbsolute = 0, float startOffsetRelative = 0, bool isHorizontal = false)
|
||||
where T : GUIComponent
|
||||
{
|
||||
return CreateElements(count, parent, constructor, relativeSize, null, anchor, pivot, minSize, maxSize, absoluteSpacing, relativeSpacing, extraSpacing, startOffsetAbsolute, startOffsetRelative, isHorizontal);
|
||||
@@ -1891,8 +1898,8 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Creates multiple elements with absolute size and positions them automatically.
|
||||
/// </summary>
|
||||
public static List<T> CreateElements<T>(int count, Point absoluteSize, RectTransform parent, Func<RectTransform, T> constructor,
|
||||
Anchor anchor = Anchor.TopLeft, Pivot? pivot = null,
|
||||
public static List<T> CreateElements<T>(int count, Point absoluteSize, RectTransform parent, Func<RectTransform, T> constructor,
|
||||
Anchor anchor = Anchor.TopLeft, Pivot? pivot = null,
|
||||
int absoluteSpacing = 0, float relativeSpacing = 0, Func<int, int> extraSpacing = null,
|
||||
int startOffsetAbsolute = 0, float startOffsetRelative = 0, bool isHorizontal = false)
|
||||
where T : GUIComponent
|
||||
@@ -1991,7 +1998,7 @@ namespace Barotrauma
|
||||
if (i == 0)
|
||||
numberInput.IntValue = value.X;
|
||||
else
|
||||
numberInput.IntValue = value.Y;
|
||||
numberInput.IntValue = value.Y;
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
@@ -2028,6 +2035,16 @@ namespace Barotrauma
|
||||
return frame;
|
||||
}
|
||||
|
||||
public static void NotifyPrompt(string header, string body)
|
||||
{
|
||||
GUIMessageBox msgBox = new GUIMessageBox(header, body, new[] { TextManager.Get("Ok") }, new Vector2(0.2f, 0.175f), minSize: new Point(300, 175));
|
||||
msgBox.Buttons[0].OnClicked = delegate
|
||||
{
|
||||
msgBox.Close();
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
public static GUIMessageBox AskForConfirmation(string header, string body, Action onConfirm, Action onDeny = null)
|
||||
{
|
||||
string[] buttons = { TextManager.Get("Ok"), TextManager.Get("Cancel") };
|
||||
@@ -2051,6 +2068,32 @@ namespace Barotrauma
|
||||
return msgBox;
|
||||
}
|
||||
|
||||
public static GUIMessageBox PromptTextInput(string header, string body, Action<string> onConfirm)
|
||||
{
|
||||
string[] buttons = { TextManager.Get("Ok"), TextManager.Get("Cancel") };
|
||||
GUIMessageBox msgBox = new GUIMessageBox(header, string.Empty, buttons, new Vector2(0.2f, 0.175f), minSize: new Point(300, 175));
|
||||
GUITextBox textBox = new GUITextBox(new RectTransform(Vector2.One, msgBox.Content.RectTransform), text: body)
|
||||
{
|
||||
OverflowClip = true
|
||||
};
|
||||
|
||||
// Cancel button
|
||||
msgBox.Buttons[1].OnClicked = delegate
|
||||
{
|
||||
msgBox.Close();
|
||||
return true;
|
||||
};
|
||||
|
||||
// Ok button
|
||||
msgBox.Buttons[0].OnClicked = delegate
|
||||
{
|
||||
onConfirm.Invoke(textBox.Text);
|
||||
msgBox.Close();
|
||||
return true;
|
||||
};
|
||||
return msgBox;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Element positioning
|
||||
@@ -2210,7 +2253,7 @@ namespace Barotrauma
|
||||
if (disallowedAreas == null) { continue; }
|
||||
foreach (Rectangle rect2 in disallowedAreas)
|
||||
{
|
||||
if (!rect1.Intersects(rect2)) { continue; }
|
||||
if (!rect1.Intersects(rect2)) { continue; }
|
||||
intersections = true;
|
||||
|
||||
Point centerDiff = rect1.Center - rect2.Center;
|
||||
@@ -2330,8 +2373,8 @@ namespace Barotrauma
|
||||
});
|
||||
}
|
||||
|
||||
CreateButton(GameMain.GameSession.GameMode is CampaignMode ? "ReturnToServerlobby" : "EndRound", buttonContainer,
|
||||
verificationTextTag: GameMain.GameSession.GameMode is CampaignMode ? "PauseMenuReturnToServerLobbyVerification" : "EndRoundSubNotAtLevelEnd",
|
||||
CreateButton(GameMain.GameSession.GameMode is CampaignMode ? "ReturnToServerlobby" : "EndRound", buttonContainer,
|
||||
verificationTextTag: GameMain.GameSession.GameMode is CampaignMode ? "PauseMenuReturnToServerLobbyVerification" : "EndRoundSubNotAtLevelEnd",
|
||||
action: () =>
|
||||
{
|
||||
GameMain.Client?.RequestRoundEnd(save: false);
|
||||
@@ -2397,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;
|
||||
}
|
||||
|
||||
@@ -2448,7 +2496,10 @@ namespace Barotrauma
|
||||
|
||||
public static void ClearMessages()
|
||||
{
|
||||
messages.Clear();
|
||||
lock (mutex)
|
||||
{
|
||||
messages.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsFourByThree()
|
||||
|
||||
@@ -219,12 +219,6 @@ namespace Barotrauma
|
||||
|
||||
GUI.Style.ButtonPulse.Draw(spriteBatch, expandRect, ToolBox.GradientLerp(pulseExpand, Color.White, Color.White, Color.Transparent));
|
||||
}
|
||||
|
||||
if (UserData is string s && s == "ReadyCheckButton" && ReadyCheck.lastReadyCheck > DateTime.Now)
|
||||
{
|
||||
float progress = (ReadyCheck.lastReadyCheck - DateTime.Now).Seconds / 60.0f;
|
||||
Frame.Color = ToolBox.GradientLerp(progress, Color.White, GUI.Style.Red);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update(float deltaTime)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,7 +317,10 @@ namespace Barotrauma
|
||||
set
|
||||
{
|
||||
selected = value;
|
||||
Children.ForEach(c => c.Selected = value);
|
||||
foreach (var child in Children)
|
||||
{
|
||||
child.Selected = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
public virtual ComponentState State
|
||||
@@ -537,7 +540,10 @@ namespace Barotrauma
|
||||
//would be real nice to un-jank this some day
|
||||
ForceUpdate();
|
||||
ForceUpdate();
|
||||
foreach (var child in Children) { child.ForceLayoutRecalculation(); }
|
||||
foreach (var child in Children)
|
||||
{
|
||||
child.ForceLayoutRecalculation();
|
||||
}
|
||||
}
|
||||
|
||||
public void ForceUpdate() => Update((float)Timing.Step);
|
||||
@@ -547,7 +553,10 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public void UpdateChildren(float deltaTime, bool recursive)
|
||||
{
|
||||
RectTransform.Children.ForEach(c => c.GUIComponent.UpdateManually(deltaTime, recursive, recursive));
|
||||
foreach (var child in RectTransform.Children)
|
||||
{
|
||||
child.GUIComponent.UpdateManually(deltaTime, recursive, recursive);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -583,7 +592,10 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public virtual void DrawChildren(SpriteBatch spriteBatch, bool recursive)
|
||||
{
|
||||
RectTransform.Children.ForEach(c => c.GUIComponent.DrawManually(spriteBatch, recursive, recursive));
|
||||
foreach (RectTransform child in RectTransform.Children)
|
||||
{
|
||||
child.GUIComponent.DrawManually(spriteBatch, recursive, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
protected Color _currentColor;
|
||||
@@ -764,8 +776,8 @@ namespace Barotrauma
|
||||
{
|
||||
toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), richTextData, toolTip, font: GUI.SmallFont, wrap: true, style: "GUIToolTip");
|
||||
toolTipBlock.RectTransform.NonScaledSize = new Point(
|
||||
(int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).X + padding.X + toolTipBlock.Padding.X + toolTipBlock.Padding.Z),
|
||||
(int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
|
||||
(int)(toolTipBlock.Font.MeasureString(toolTipBlock.WrappedText).X + padding.X + toolTipBlock.Padding.X + toolTipBlock.Padding.Z),
|
||||
(int)(toolTipBlock.Font.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
|
||||
toolTipBlock.userData = toolTip;
|
||||
}
|
||||
|
||||
@@ -1007,8 +1019,10 @@ namespace Barotrauma
|
||||
case "gridtext":
|
||||
LoadGridText(element, parent);
|
||||
return null;
|
||||
case "conditional":
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException("Loading GUI component \""+element.Name+"\" from XML is not implemented.");
|
||||
throw new NotImplementedException("Loading GUI component \"" + element.Name + "\" from XML is not implemented.");
|
||||
}
|
||||
|
||||
if (component != null)
|
||||
@@ -1079,6 +1093,29 @@ namespace Barotrauma
|
||||
var maxVersion = new Version(attribute.Value);
|
||||
if (GameMain.Version > maxVersion) { return false; }
|
||||
break;
|
||||
case "buildconfiguration":
|
||||
switch (attribute.Value.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "debug":
|
||||
#if DEBUG
|
||||
return true;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case "unstable":
|
||||
#if UNSTABLE
|
||||
return true;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case "release":
|
||||
#if !DEBUG && !UNSTABLE
|
||||
return true;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -431,7 +439,7 @@ namespace Barotrauma
|
||||
for (int i = 0; i < Content.CountChildren; i++)
|
||||
{
|
||||
GUIComponent child = Content.GetChild(i);
|
||||
if (!child.Visible) { continue; }
|
||||
if (child == null || !child.Visible) { continue; }
|
||||
if (RectTransform != null)
|
||||
{
|
||||
callback(i, new Point(x, y));
|
||||
@@ -837,7 +845,6 @@ namespace Barotrauma
|
||||
UpdateScrollBarSize();
|
||||
}
|
||||
|
||||
|
||||
if (FadeElements)
|
||||
{
|
||||
foreach (var (component, _) in childVisible)
|
||||
|
||||
@@ -319,28 +319,29 @@ namespace Barotrauma
|
||||
AbsoluteSpacing = absoluteSpacing.Y,
|
||||
};
|
||||
|
||||
var bottomContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.3f), verticalLayoutGroup.RectTransform), style: null);
|
||||
|
||||
var tickBoxLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.67f, 1.0f), bottomContainer.RectTransform, anchor: Anchor.CenterLeft),
|
||||
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||
var bottomContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.3f), verticalLayoutGroup.RectTransform), style: null)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.02f
|
||||
CanBeFocused = true
|
||||
};
|
||||
|
||||
var dontShowAgainTickBox = new GUITickBox(new RectTransform(new Vector2(0.5f, 1.0f), tickBoxLayoutGroup.RectTransform),
|
||||
var tickBoxLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.67f, 1.0f), bottomContainer.RectTransform, anchor: Anchor.CenterLeft))
|
||||
{
|
||||
CanBeFocused = true,
|
||||
Stretch = true
|
||||
};
|
||||
Vector2 tickBoxRelativeSize = new Vector2(1.0f, 0.5f);
|
||||
var dontShowAgainTickBox = new GUITickBox(new RectTransform(tickBoxRelativeSize, tickBoxLayoutGroup.RectTransform),
|
||||
TextManager.Get("hintmessagebox.dontshowagain"))
|
||||
{
|
||||
ToolTip = TextManager.Get("hintmessagebox.dontshowagaintooltip"),
|
||||
UserData = "dontshowagain"
|
||||
};
|
||||
|
||||
//var disableHintsTickBox = new GUITickBox(new RectTransform(new Vector2(0.33f, 1.0f), tickBoxLayoutGroup.RectTransform),
|
||||
// TextManager.Get("hintmessagebox.disablehints"))
|
||||
//{
|
||||
// ToolTip = TextManager.Get("hintmessagebox.disablehintstooltip"),
|
||||
// UserData = "disablehints"
|
||||
//};
|
||||
var disableHintsTickBox = new GUITickBox(new RectTransform(tickBoxRelativeSize, tickBoxLayoutGroup.RectTransform),
|
||||
TextManager.Get("hintmessagebox.disablehints"))
|
||||
{
|
||||
ToolTip = TextManager.Get("hintmessagebox.disablehintstooltip"),
|
||||
UserData = "disablehints"
|
||||
};
|
||||
|
||||
Buttons = new List<GUIButton>(1)
|
||||
{
|
||||
@@ -379,12 +380,16 @@ namespace Barotrauma
|
||||
upperContainerHeight = Math.Max(upperContainerHeight, Icon.Rect.Height);
|
||||
height += upperContainerHeight;
|
||||
height += absoluteSpacing.Y;
|
||||
height += (int)((bottomContainer.RectTransform.RelativeSize.Y / topHorizontalLayoutGroup.RectTransform.RelativeSize.Y) * upperContainerHeight);
|
||||
int bottomContainerHeight = dontShowAgainTickBox.Rect.Height + disableHintsTickBox.Rect.Height;
|
||||
height += bottomContainerHeight;
|
||||
height += absoluteSpacing.Y;
|
||||
if (minSize.HasValue) { height = Math.Max(height, minSize.Value.Y); }
|
||||
|
||||
InnerFrame.RectTransform.NonScaledSize = new Point(InnerFrame.Rect.Width, height);
|
||||
verticalLayoutGroup.RectTransform.NonScaledSize = GetVerticalLayoutGroupSize();
|
||||
float upperContainerRelativeHeight = (float)upperContainerHeight / (upperContainerHeight + bottomContainerHeight);
|
||||
topHorizontalLayoutGroup.RectTransform.RelativeSize = new Vector2(topHorizontalLayoutGroup.RectTransform.RelativeSize.X, upperContainerRelativeHeight);
|
||||
bottomContainer.RectTransform.RelativeSize = new Vector2(bottomContainer.RectTransform.RelativeSize.X, 1.0f - upperContainerRelativeHeight);
|
||||
verticalLayoutGroup.Recalculate();
|
||||
topHorizontalLayoutGroup.Recalculate();
|
||||
Content.Recalculate();
|
||||
@@ -613,6 +618,7 @@ namespace Barotrauma
|
||||
|
||||
public bool Close(GUIButton button, object obj)
|
||||
{
|
||||
RectTransform.Parent = null;
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,12 @@ namespace Barotrauma
|
||||
ClampChildMouseRects(Content);
|
||||
}
|
||||
|
||||
public override void DrawChildren(SpriteBatch spriteBatch, bool recursive)
|
||||
{
|
||||
//do nothing (the children have to be drawn in the Draw method after the ScissorRectangle has been set)
|
||||
return;
|
||||
}
|
||||
|
||||
protected override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (!Visible) { return; }
|
||||
|
||||
@@ -204,6 +204,12 @@ namespace Barotrauma
|
||||
set { textColor = value; }
|
||||
}
|
||||
|
||||
public Color DisabledTextColor
|
||||
{
|
||||
get => disabledTextColor;
|
||||
set => disabledTextColor = value;
|
||||
}
|
||||
|
||||
private Color? hoverTextColor;
|
||||
public Color HoverTextColor
|
||||
{
|
||||
@@ -303,6 +309,10 @@ namespace Barotrauma
|
||||
if (parseRichText)
|
||||
{
|
||||
RichTextData = Barotrauma.RichTextData.GetRichTextData(text, out text);
|
||||
if (RichTextData != null && RichTextData.Count == 0)
|
||||
{
|
||||
RichTextData = null;
|
||||
}
|
||||
}
|
||||
|
||||
//if the text is in chinese/korean/japanese and we're not using a CJK-compatible font,
|
||||
@@ -457,7 +467,7 @@ namespace Barotrauma
|
||||
while (size == Vector2.Zero)
|
||||
{
|
||||
try { size = Font.MeasureString(string.IsNullOrEmpty(text) ? " " : text); }
|
||||
catch { text = text.Substring(0, text.Length - 1); }
|
||||
catch { text = text.Length > 0 ? text.Substring(0, text.Length - 1) : ""; }
|
||||
}
|
||||
|
||||
return size;
|
||||
|
||||
@@ -80,6 +80,8 @@ namespace Barotrauma
|
||||
private Vector2 selectionEndPos;
|
||||
private Vector2 selectionRectSize;
|
||||
|
||||
private GUICustomComponent caretAndSelectionRenderer;
|
||||
|
||||
private bool mouseHeldInside;
|
||||
|
||||
private readonly Memento<string> memento = new Memento<string>();
|
||||
@@ -188,8 +190,7 @@ namespace Barotrauma
|
||||
}
|
||||
set
|
||||
{
|
||||
base.ToolTip = value;
|
||||
textBlock.ToolTip = value;
|
||||
base.ToolTip = textBlock.ToolTip = caretAndSelectionRenderer.ToolTip = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +279,7 @@ namespace Barotrauma
|
||||
CaretEnabled = true;
|
||||
caretPosDirty = true;
|
||||
|
||||
new GUICustomComponent(new RectTransform(Vector2.One, frame.RectTransform), onDraw: DrawCaretAndSelection);
|
||||
caretAndSelectionRenderer = new GUICustomComponent(new RectTransform(Vector2.One, frame.RectTransform), onDraw: DrawCaretAndSelection);
|
||||
|
||||
int clearButtonWidth = 0;
|
||||
if (createClearButton)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
@@ -637,7 +637,15 @@ namespace Barotrauma
|
||||
|
||||
public bool IsParentOf(RectTransform rectT, bool recursive = true)
|
||||
{
|
||||
return children.Contains(rectT) || (recursive && children.Any(c => c.IsParentOf(rectT)));
|
||||
if (children.Contains(rectT)) { return true; }
|
||||
if (recursive)
|
||||
{
|
||||
foreach (var child in children)
|
||||
{
|
||||
if (child.IsParentOf(rectT)) { return true; }
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsChildOf(RectTransform rectT, bool recursive = true)
|
||||
|
||||
@@ -43,36 +43,42 @@ namespace Barotrauma
|
||||
private bool needsRefresh, needsBuyingRefresh, needsSellingRefresh, needsItemsToSellRefresh, needsSellingFromSubRefresh, needsItemsToSellFromSubRefresh;
|
||||
|
||||
private Point resolutionWhenCreated;
|
||||
private bool hadPermissions;
|
||||
|
||||
private Dictionary<ItemPrefab, int> OwnedItems { get; } = new Dictionary<ItemPrefab, int>();
|
||||
|
||||
private CargoManager CargoManager => campaignUI.Campaign.CargoManager;
|
||||
private Location CurrentLocation => campaignUI.Campaign.Map?.CurrentLocation;
|
||||
private int PlayerMoney => campaignUI.Campaign.Money;
|
||||
private bool HasPermissions => campaignUI.Campaign.AllowedToManageCampaign();
|
||||
|
||||
private bool IsBuying => activeTab switch
|
||||
{
|
||||
StoreTab.Buy => true,
|
||||
StoreTab.Sell => false,
|
||||
StoreTab.SellFromSub => false,
|
||||
StoreTab.SellSub => false,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
private GUIListBox ActiveShoppingCrateList => activeTab switch
|
||||
{
|
||||
StoreTab.Buy => shoppingCrateBuyList,
|
||||
StoreTab.Sell => shoppingCrateSellList,
|
||||
StoreTab.SellFromSub => shoppingCrateSellFromSubList,
|
||||
StoreTab.SellSub => shoppingCrateSellFromSubList,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
private bool IsTabUnavailable(StoreTab tab) => !tabLists.ContainsKey(tab);
|
||||
|
||||
public enum StoreTab
|
||||
{
|
||||
/// <summary>
|
||||
/// Buy items from the store
|
||||
/// </summary>
|
||||
Buy,
|
||||
/// <summary>
|
||||
/// Sell items from the character inventory
|
||||
/// </summary>
|
||||
Sell,
|
||||
SellFromSub
|
||||
/// <summary>
|
||||
/// Sell items from the sub
|
||||
/// </summary>
|
||||
SellSub
|
||||
}
|
||||
|
||||
private enum SortingMethod
|
||||
@@ -84,11 +90,117 @@ namespace Barotrauma
|
||||
CategoryAsc
|
||||
}
|
||||
|
||||
#region Permissions
|
||||
|
||||
private bool hadPermissions, hadBuyPermissions, hadSellInventoryPermissions, hadSellSubPermissions;
|
||||
|
||||
private bool HasPermissions
|
||||
{
|
||||
get => GetPermissions();
|
||||
set => hadPermissions = value;
|
||||
}
|
||||
private bool HasBuyPermissions
|
||||
{
|
||||
get => HasPermissions || GetPermissions(StoreTab.Buy);
|
||||
set => hadBuyPermissions = value;
|
||||
}
|
||||
private bool HasSellInventoryPermissions
|
||||
{
|
||||
get => HasPermissions || GetPermissions(StoreTab.Sell);
|
||||
set => hadSellInventoryPermissions = value;
|
||||
}
|
||||
private bool HasSellSubPermissions
|
||||
{
|
||||
get => HasPermissions || GetPermissions(StoreTab.SellSub);
|
||||
set => hadSellSubPermissions = value;
|
||||
}
|
||||
|
||||
private bool GetPermissions(StoreTab? tab = null)
|
||||
{
|
||||
if (!tab.HasValue)
|
||||
{
|
||||
return campaignUI.Campaign.AllowedToManageCampaign() || campaignUI.Campaign.AllowedToManageCampaign(Networking.ClientPermissions.CampaignStore);
|
||||
}
|
||||
else
|
||||
{
|
||||
return tab.Value switch
|
||||
{
|
||||
StoreTab.Buy => campaignUI.Campaign.AllowedToManageCampaign(Networking.ClientPermissions.BuyItems),
|
||||
StoreTab.Sell => campaignUI.Campaign.AllowedToManageCampaign(Networking.ClientPermissions.SellInventoryItems),
|
||||
StoreTab.SellSub => campaignUI.Campaign.AllowedToManageCampaign(Networking.ClientPermissions.SellSubItems),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePermissions(StoreTab? tab = null)
|
||||
{
|
||||
HasPermissions = GetPermissions();
|
||||
if (!tab.HasValue)
|
||||
{
|
||||
HasBuyPermissions = GetPermissions(StoreTab.Buy);
|
||||
HasSellInventoryPermissions = GetPermissions(StoreTab.Sell);
|
||||
HasSellSubPermissions = GetPermissions(StoreTab.SellSub);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (tab.Value)
|
||||
{
|
||||
case StoreTab.Buy:
|
||||
HasBuyPermissions = GetPermissions(tab.Value);
|
||||
break;
|
||||
case StoreTab.Sell:
|
||||
HasSellInventoryPermissions = GetPermissions(tab.Value);
|
||||
break;
|
||||
case StoreTab.SellSub:
|
||||
HasSellSubPermissions = GetPermissions(tab.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasTabPermissions(StoreTab tab)
|
||||
{
|
||||
return tab switch
|
||||
{
|
||||
StoreTab.Buy => HasBuyPermissions,
|
||||
StoreTab.Sell => HasSellInventoryPermissions,
|
||||
StoreTab.SellSub => HasSellSubPermissions,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
private bool HasActiveTabPermissions()
|
||||
{
|
||||
return HasTabPermissions(activeTab);
|
||||
}
|
||||
|
||||
private bool HavePermissionsChanged(StoreTab? tab = null)
|
||||
{
|
||||
if (!tab.HasValue)
|
||||
{
|
||||
return hadPermissions != HasPermissions;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool hadTabPermissions = tab.Value switch
|
||||
{
|
||||
StoreTab.Buy => hadBuyPermissions,
|
||||
StoreTab.Sell => hadSellInventoryPermissions,
|
||||
StoreTab.SellSub => hadSellSubPermissions,
|
||||
_ => false
|
||||
};
|
||||
return hadTabPermissions != HasTabPermissions(tab.Value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Store(CampaignUI campaignUI, GUIComponent parentComponent)
|
||||
{
|
||||
this.campaignUI = campaignUI;
|
||||
this.parentComponent = parentComponent;
|
||||
hadPermissions = HasPermissions;
|
||||
UpdatePermissions();
|
||||
CreateUI();
|
||||
campaignUI.Campaign.Map.OnLocationChanged += UpdateLocation;
|
||||
if (CurrentLocation?.Reputation != null)
|
||||
@@ -109,7 +221,7 @@ namespace Barotrauma
|
||||
|
||||
public void Refresh(bool updateOwned = true)
|
||||
{
|
||||
hadPermissions = HasPermissions;
|
||||
UpdatePermissions();
|
||||
if (updateOwned) { UpdateOwnedItems(); }
|
||||
RefreshBuying(updateOwned: false);
|
||||
RefreshSelling(updateOwned: false);
|
||||
@@ -122,7 +234,7 @@ namespace Barotrauma
|
||||
if (updateOwned) { UpdateOwnedItems(); }
|
||||
RefreshShoppingCrateBuyList();
|
||||
RefreshStoreBuyList();
|
||||
var hasPermissions = HasPermissions;
|
||||
bool hasPermissions = HasTabPermissions(StoreTab.Buy);
|
||||
storeBuyList.Enabled = hasPermissions;
|
||||
shoppingCrateBuyList.Enabled = hasPermissions;
|
||||
needsBuyingRefresh = false;
|
||||
@@ -133,7 +245,7 @@ namespace Barotrauma
|
||||
if (updateOwned) { UpdateOwnedItems(); }
|
||||
RefreshShoppingCrateSellList();
|
||||
RefreshStoreSellList();
|
||||
var hasPermissions = HasPermissions;
|
||||
bool hasPermissions = HasTabPermissions(StoreTab.Sell);
|
||||
storeSellList.Enabled = hasPermissions;
|
||||
shoppingCrateSellList.Enabled = hasPermissions;
|
||||
needsSellingRefresh = false;
|
||||
@@ -141,13 +253,11 @@ namespace Barotrauma
|
||||
|
||||
private void RefreshSellingFromSub(bool updateOwned = true, bool updateItemsToSellFromSub = true)
|
||||
{
|
||||
if (IsTabUnavailable(StoreTab.SellFromSub)) { return; }
|
||||
if (updateOwned) { UpdateOwnedItems(); }
|
||||
if (updateItemsToSellFromSub) RefreshItemsToSellFromSub();
|
||||
RefreshShoppingCrateSellFromSubList();
|
||||
RefreshStoreSellFromSubList();
|
||||
// TODO: Separate permissions from regular campaign permissions
|
||||
var hasPermissions = HasPermissions;
|
||||
bool hasPermissions = HasTabPermissions(StoreTab.SellSub);
|
||||
storeSellFromSubList.Enabled = hasPermissions;
|
||||
shoppingCrateSellFromSubList.Enabled = hasPermissions;
|
||||
needsSellingFromSubRefresh = false;
|
||||
@@ -261,7 +371,7 @@ namespace Barotrauma
|
||||
{
|
||||
StoreTab.Buy => CurrentLocation.StoreCurrentBalance + buyTotal,
|
||||
StoreTab.Sell => CurrentLocation.StoreCurrentBalance - sellTotal,
|
||||
StoreTab.SellFromSub => CurrentLocation.StoreCurrentBalance - sellFromSubTotal,
|
||||
StoreTab.SellSub => CurrentLocation.StoreCurrentBalance - sellFromSubTotal,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
if (balanceAfterTransaction != CurrentLocation.StoreCurrentBalance)
|
||||
@@ -325,10 +435,9 @@ namespace Barotrauma
|
||||
tabSortingMethods.Clear();
|
||||
foreach (StoreTab tab in tabs)
|
||||
{
|
||||
if (tab == StoreTab.SellFromSub && GameMain.IsMultiplayer) { continue; }
|
||||
string text = tab switch
|
||||
{
|
||||
StoreTab.SellFromSub => TextManager.Get("submarine"),
|
||||
StoreTab.SellSub => TextManager.Get("submarine"),
|
||||
_ => TextManager.Get("campaignstoretab." + tab)
|
||||
};
|
||||
var tabButton = new GUIButton(new RectTransform(new Vector2(1.0f / (tabs.Length + 1), 1.0f), modeButtonContainer.RectTransform),
|
||||
@@ -456,16 +565,13 @@ namespace Barotrauma
|
||||
storeRequestedGoodGroup = CreateDealsGroup(storeSellList);
|
||||
tabLists.Add(StoreTab.Sell, storeSellList);
|
||||
|
||||
if (GameMain.IsSingleplayer)
|
||||
storeSellFromSubList = new GUIListBox(new RectTransform(Vector2.One, storeItemListContainer.RectTransform))
|
||||
{
|
||||
storeSellFromSubList = new GUIListBox(new RectTransform(Vector2.One, storeItemListContainer.RectTransform))
|
||||
{
|
||||
AutoHideScrollBar = false,
|
||||
Visible = false
|
||||
};
|
||||
storeRequestedSubGoodGroup = CreateDealsGroup(storeSellFromSubList);
|
||||
tabLists.Add(StoreTab.SellFromSub, storeSellFromSubList);
|
||||
}
|
||||
AutoHideScrollBar = false,
|
||||
Visible = false
|
||||
};
|
||||
storeRequestedSubGoodGroup = CreateDealsGroup(storeSellFromSubList);
|
||||
tabLists.Add(StoreTab.SellSub, storeSellFromSubList);
|
||||
|
||||
// Shopping Crate ------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -526,10 +632,7 @@ namespace Barotrauma
|
||||
var shoppingCrateListContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.8f), shoppingCrateInventoryContainer.RectTransform), style: null);
|
||||
shoppingCrateBuyList = new GUIListBox(new RectTransform(Vector2.One, shoppingCrateListContainer.RectTransform)) { Visible = false };
|
||||
shoppingCrateSellList = new GUIListBox(new RectTransform(Vector2.One, shoppingCrateListContainer.RectTransform)) { Visible = false };
|
||||
if (GameMain.IsSingleplayer)
|
||||
{
|
||||
shoppingCrateSellFromSubList = new GUIListBox(new RectTransform(Vector2.One, shoppingCrateListContainer.RectTransform)) { Visible = false };
|
||||
}
|
||||
shoppingCrateSellFromSubList = new GUIListBox(new RectTransform(Vector2.One, shoppingCrateListContainer.RectTransform)) { Visible = false };
|
||||
|
||||
var relevantBalanceContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), shoppingCrateInventoryContainer.RectTransform), isHorizontal: true)
|
||||
{
|
||||
@@ -569,16 +672,16 @@ namespace Barotrauma
|
||||
clearAllButton = new GUIButton(new RectTransform(new Vector2(0.35f, 1.0f), buttonContainer.RectTransform), TextManager.Get("campaignstore.clearall"))
|
||||
{
|
||||
ClickSound = GUISoundType.DecreaseQuantity,
|
||||
Enabled = HasPermissions,
|
||||
Enabled = HasActiveTabPermissions(),
|
||||
ForceUpperCase = true,
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
if (!HasPermissions) { return false; }
|
||||
if (!HasActiveTabPermissions()) { return false; }
|
||||
var itemsToRemove = activeTab switch
|
||||
{
|
||||
StoreTab.Buy => new List<PurchasedItem>(CargoManager.ItemsInBuyCrate),
|
||||
StoreTab.Sell => new List<PurchasedItem>(CargoManager.ItemsInSellCrate),
|
||||
StoreTab.SellFromSub => new List<PurchasedItem>(CargoManager.ItemsInSellFromSubCrate),
|
||||
StoreTab.SellSub => new List<PurchasedItem>(CargoManager.ItemsInSellFromSubCrate),
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
itemsToRemove.ForEach(i => ClearFromShoppingCrate(i));
|
||||
@@ -637,7 +740,6 @@ namespace Barotrauma
|
||||
|
||||
private void ChangeStoreTab(StoreTab tab)
|
||||
{
|
||||
if (IsTabUnavailable(tab)) { return; }
|
||||
activeTab = tab;
|
||||
foreach (GUIButton tabButton in storeTabButtons)
|
||||
{
|
||||
@@ -680,7 +782,7 @@ namespace Barotrauma
|
||||
}
|
||||
shoppingCrateSellList.Visible = true;
|
||||
break;
|
||||
case StoreTab.SellFromSub:
|
||||
case StoreTab.SellSub:
|
||||
storeBuyList.Visible = false;
|
||||
storeSellList.Visible = false;
|
||||
if (storeSellFromSubList != null)
|
||||
@@ -699,7 +801,6 @@ namespace Barotrauma
|
||||
|
||||
private void FilterStoreItems(MapEntityCategory? category, string filter)
|
||||
{
|
||||
if (IsTabUnavailable(activeTab)) { return; }
|
||||
selectedItemCategory = category;
|
||||
var list = tabLists[activeTab];
|
||||
filter = filter?.ToLower();
|
||||
@@ -733,7 +834,7 @@ namespace Barotrauma
|
||||
float prevBuyListScroll = storeBuyList.BarScroll;
|
||||
float prevShoppingCrateScroll = shoppingCrateBuyList.BarScroll;
|
||||
|
||||
bool hasPermissions = HasPermissions;
|
||||
bool hasPermissions = HasBuyPermissions;
|
||||
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||
|
||||
int dailySpecialCount = CurrentLocation?.DailySpecials.Count() ?? 3;
|
||||
@@ -816,7 +917,7 @@ namespace Barotrauma
|
||||
{
|
||||
float prevSellListScroll = storeSellList.BarScroll;
|
||||
float prevShoppingCrateScroll = shoppingCrateSellList.BarScroll;
|
||||
bool hasPermissions = HasPermissions;
|
||||
bool hasPermissions = HasTabPermissions(StoreTab.Sell);
|
||||
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||
|
||||
if ((storeRequestedGoodGroup != null) != CurrentLocation.RequestedGoods.Any())
|
||||
@@ -894,7 +995,7 @@ namespace Barotrauma
|
||||
{
|
||||
float prevSellListScroll = storeSellFromSubList.BarScroll;
|
||||
float prevShoppingCrateScroll = shoppingCrateSellFromSubList.BarScroll;
|
||||
bool hasPermissions = HasPermissions;
|
||||
bool hasPermissions = HasSellSubPermissions;
|
||||
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||
|
||||
if ((storeRequestedSubGoodGroup != null) != CurrentLocation.RequestedGoods.Any())
|
||||
@@ -938,12 +1039,12 @@ namespace Barotrauma
|
||||
if (itemFrame == null)
|
||||
{
|
||||
var parentComponent = isRequestedGood ? storeRequestedSubGoodGroup : storeSellFromSubList as GUIComponent;
|
||||
itemFrame = CreateItemFrame(new PurchasedItem(itemPrefab, itemQuantity), parentComponent, StoreTab.SellFromSub, forceDisable: !hasPermissions);
|
||||
itemFrame = CreateItemFrame(new PurchasedItem(itemPrefab, itemQuantity), parentComponent, StoreTab.SellSub, forceDisable: !hasPermissions);
|
||||
}
|
||||
else
|
||||
{
|
||||
(itemFrame.UserData as PurchasedItem).Quantity = itemQuantity;
|
||||
SetQuantityLabelText(StoreTab.SellFromSub, itemFrame);
|
||||
SetQuantityLabelText(StoreTab.SellSub, itemFrame);
|
||||
SetOwnedLabelText(itemFrame);
|
||||
SetPriceGetters(itemFrame, false);
|
||||
}
|
||||
@@ -961,8 +1062,8 @@ namespace Barotrauma
|
||||
removedItemFrames.AddRange(storeRequestedSubGoodGroup.Children.Where(c => c.UserData is PurchasedItem).Except(existingItemFrames).ToList());
|
||||
}
|
||||
removedItemFrames.ForEach(f => f.RectTransform.Parent = null);
|
||||
if (activeTab == StoreTab.SellFromSub) { FilterStoreItems(); }
|
||||
SortItems(StoreTab.SellFromSub);
|
||||
if (activeTab == StoreTab.SellSub) { FilterStoreItems(); }
|
||||
SortItems(StoreTab.SellSub);
|
||||
|
||||
storeSellFromSubList.BarScroll = prevSellListScroll;
|
||||
shoppingCrateSellFromSubList.BarScroll = prevShoppingCrateScroll;
|
||||
@@ -1062,17 +1163,14 @@ namespace Barotrauma
|
||||
|
||||
private void RefreshShoppingCrateList(List<PurchasedItem> items, GUIListBox listBox, StoreTab tab)
|
||||
{
|
||||
bool hasPermissions = HasPermissions;
|
||||
bool hasPermissions = HasTabPermissions(tab);
|
||||
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||
int totalPrice = 0;
|
||||
foreach (PurchasedItem item in items)
|
||||
{
|
||||
PriceInfo priceInfo = item.ItemPrefab.GetPriceInfo(CurrentLocation);
|
||||
if (priceInfo == null) { continue; }
|
||||
|
||||
var itemFrame = listBox.Content.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab.Identifier == item.ItemPrefab.Identifier);
|
||||
if (!(item.ItemPrefab.GetPriceInfo(CurrentLocation) is { } priceInfo)) { continue; }
|
||||
GUINumberInput numInput = null;
|
||||
if (itemFrame == null)
|
||||
if (!(listBox.Content.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab.Identifier == item.ItemPrefab.Identifier) is { } itemFrame))
|
||||
{
|
||||
itemFrame = CreateItemFrame(item, listBox, tab, forceDisable: !hasPermissions);
|
||||
numInput = itemFrame.FindChild(c => c is GUINumberInput, recursive: true) as GUINumberInput;
|
||||
@@ -1100,10 +1198,21 @@ namespace Barotrauma
|
||||
}
|
||||
suppressBuySell = false;
|
||||
|
||||
var price = tab == StoreTab.Buy ?
|
||||
CurrentLocation.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo) :
|
||||
CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo);
|
||||
totalPrice += item.Quantity * price;
|
||||
try
|
||||
{
|
||||
int price = tab switch
|
||||
{
|
||||
StoreTab.Buy => CurrentLocation.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo),
|
||||
StoreTab.Sell => CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo),
|
||||
StoreTab.SellSub => CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
totalPrice += item.Quantity * price;
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error getting item price: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
}
|
||||
}
|
||||
|
||||
var removedItemFrames = listBox.Content.Children.Except(existingItemFrames).ToList();
|
||||
@@ -1119,7 +1228,7 @@ namespace Barotrauma
|
||||
case StoreTab.Sell:
|
||||
sellTotal = totalPrice;
|
||||
break;
|
||||
case StoreTab.SellFromSub:
|
||||
case StoreTab.SellSub:
|
||||
sellFromSubTotal = totalPrice;
|
||||
break;
|
||||
}
|
||||
@@ -1135,7 +1244,7 @@ namespace Barotrauma
|
||||
|
||||
private void RefreshShoppingCrateSellList() => RefreshShoppingCrateList(CargoManager.ItemsInSellCrate, shoppingCrateSellList, StoreTab.Sell);
|
||||
|
||||
private void RefreshShoppingCrateSellFromSubList() => RefreshShoppingCrateList(CargoManager.ItemsInSellFromSubCrate, shoppingCrateSellFromSubList, StoreTab.SellFromSub);
|
||||
private void RefreshShoppingCrateSellFromSubList() => RefreshShoppingCrateList(CargoManager.ItemsInSellFromSubCrate, shoppingCrateSellFromSubList, StoreTab.SellSub);
|
||||
|
||||
private void SortItems(GUIListBox list, SortingMethod sortingMethod)
|
||||
{
|
||||
@@ -1286,14 +1395,12 @@ namespace Barotrauma
|
||||
|
||||
private void SortItems(StoreTab tab, SortingMethod sortingMethod)
|
||||
{
|
||||
if (IsTabUnavailable(tab)) { return; }
|
||||
tabSortingMethods[tab] = sortingMethod;
|
||||
SortItems(tabLists[tab], sortingMethod);
|
||||
}
|
||||
|
||||
private void SortItems(StoreTab tab)
|
||||
{
|
||||
if (IsTabUnavailable(tab)) { return; }
|
||||
SortItems(tab, tabSortingMethods[tab]);
|
||||
}
|
||||
|
||||
@@ -1301,12 +1408,6 @@ namespace Barotrauma
|
||||
|
||||
private GUIComponent CreateItemFrame(PurchasedItem pi, GUIComponent parentComponent, StoreTab containingTab, bool forceDisable = false)
|
||||
{
|
||||
var tooltip = pi.ItemPrefab.Name;
|
||||
if (!string.IsNullOrWhiteSpace(pi.ItemPrefab.Description))
|
||||
{
|
||||
tooltip += "\n" + pi.ItemPrefab.Description;
|
||||
}
|
||||
|
||||
GUIListBox parentListBox = parentComponent as GUIListBox;
|
||||
int width = 0;
|
||||
RectTransform parent = null;
|
||||
@@ -1320,7 +1421,11 @@ namespace Barotrauma
|
||||
width = parentComponent.Rect.Width;
|
||||
parent = parentComponent.RectTransform;
|
||||
}
|
||||
|
||||
string tooltip = pi.ItemPrefab.Name;
|
||||
if (!string.IsNullOrWhiteSpace(pi.ItemPrefab.Description))
|
||||
{
|
||||
tooltip += $"\n{pi.ItemPrefab.Description}";
|
||||
}
|
||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(width, (int)(GUI.yScale * 80)), parent: parent), style: "ListBoxElement")
|
||||
{
|
||||
ToolTip = tooltip,
|
||||
@@ -1338,8 +1443,7 @@ namespace Barotrauma
|
||||
var iconRelativeWidth = 0.0f;
|
||||
var priceAndButtonRelativeWidth = 1.0f - nameAndIconRelativeWidth;
|
||||
|
||||
Sprite itemIcon = pi.ItemPrefab.InventoryIcon ?? pi.ItemPrefab.sprite;
|
||||
if (itemIcon != null)
|
||||
if ((pi.ItemPrefab.InventoryIcon ?? pi.ItemPrefab.sprite) is { } itemIcon)
|
||||
{
|
||||
iconRelativeWidth = (0.9f * mainGroup.Rect.Height) / mainGroup.Rect.Width;
|
||||
GUIImage img = new GUIImage(new RectTransform(new Vector2(iconRelativeWidth, 0.9f), mainGroup.RectTransform), itemIcon, scaleToFit: true)
|
||||
@@ -1425,7 +1529,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (suppressBuySell) { return; }
|
||||
PurchasedItem purchasedItem = numberInput.UserData as PurchasedItem;
|
||||
if (!HasPermissions)
|
||||
if (!HasActiveTabPermissions())
|
||||
{
|
||||
numberInput.IntValue = purchasedItem.Quantity;
|
||||
return;
|
||||
@@ -1528,11 +1632,16 @@ namespace Barotrauma
|
||||
OwnedItems.Clear();
|
||||
|
||||
// Add items on the sub(s)
|
||||
Submarine.MainSub?.GetItems(true)
|
||||
.Where(i => i.Components.All(c => !(c is Holdable h) || !h.Attachable || !h.Attached) &&
|
||||
i.Components.All(c => !(c is Wire w) || w.Connections.All(c => c == null)) &&
|
||||
ItemAndAllContainersInteractable(i))
|
||||
.ForEach(i => AddToOwnedItems(i.Prefab));
|
||||
if (Submarine.MainSub?.GetItems(true) is List<Item> subItems)
|
||||
{
|
||||
foreach (var subItem in subItems)
|
||||
{
|
||||
if (!subItem.Components.All(c => !(c is Holdable h) || !h.Attachable || !h.Attached)) { continue; }
|
||||
if (!subItem.Components.All(c => !(c is Wire w) || w.Connections.All(c => c == null))) { continue; }
|
||||
if (!ItemAndAllContainersInteractable(subItem)) { continue; }
|
||||
AddToOwnedItems(subItem.Prefab);
|
||||
}
|
||||
}
|
||||
|
||||
// Add items in character inventories
|
||||
foreach (var item in Item.ItemList)
|
||||
@@ -1574,8 +1683,9 @@ namespace Barotrauma
|
||||
|
||||
private void SetItemFrameStatus(GUIComponent itemFrame, bool enabled)
|
||||
{
|
||||
if (itemFrame == null || !(itemFrame.UserData is PurchasedItem pi)) { return; }
|
||||
|
||||
if (!(itemFrame?.UserData is PurchasedItem pi)) { return; }
|
||||
bool refreshFrameStatus = !pi.IsStoreComponentEnabled.HasValue || pi.IsStoreComponentEnabled.Value != enabled;
|
||||
if (!refreshFrameStatus) { return; }
|
||||
if (itemFrame.FindChild("icon", recursive: true) is GUIImage icon)
|
||||
{
|
||||
if (pi.ItemPrefab?.InventoryIcon != null)
|
||||
@@ -1587,14 +1697,11 @@ namespace Barotrauma
|
||||
icon.Color = pi.ItemPrefab.SpriteColor * (enabled ? 1.0f : 0.5f);
|
||||
}
|
||||
};
|
||||
|
||||
var color = Color.White * (enabled ? 1.0f : 0.5f);
|
||||
|
||||
if (itemFrame.FindChild("name", recursive: true) is GUITextBlock name)
|
||||
{
|
||||
name.TextColor = color;
|
||||
}
|
||||
|
||||
if (itemFrame.FindChild("quantitylabel", recursive: true) is GUITextBlock qty)
|
||||
{
|
||||
qty.TextColor = color;
|
||||
@@ -1603,25 +1710,21 @@ namespace Barotrauma
|
||||
{
|
||||
numberInput.Enabled = enabled;
|
||||
}
|
||||
|
||||
if (itemFrame.FindChild("owned", recursive: true) is GUITextBlock ownedBlock)
|
||||
{
|
||||
ownedBlock.TextColor = color;
|
||||
}
|
||||
|
||||
var isDiscounted = false;
|
||||
bool isDiscounted = false;
|
||||
if (itemFrame.FindChild("undiscountedprice", recursive: true) is GUITextBlock undiscountedPriceBlock)
|
||||
{
|
||||
undiscountedPriceBlock.TextColor = color;
|
||||
undiscountedPriceBlock.Strikethrough.Color = color;
|
||||
isDiscounted = true;
|
||||
}
|
||||
|
||||
if (itemFrame.FindChild("price", recursive: true) is GUITextBlock priceBlock)
|
||||
{
|
||||
priceBlock.TextColor = isDiscounted ? storeSpecialColor * (enabled ? 1.0f : 0.5f) : color;
|
||||
}
|
||||
|
||||
if (itemFrame.FindChild("addbutton", recursive: true) is GUIButton addButton)
|
||||
{
|
||||
addButton.Enabled = enabled;
|
||||
@@ -1630,6 +1733,8 @@ namespace Barotrauma
|
||||
{
|
||||
removeButton.Enabled = enabled;
|
||||
}
|
||||
pi.IsStoreComponentEnabled = enabled;
|
||||
itemFrame.UserData = pi;
|
||||
}
|
||||
|
||||
private void SetQuantityLabelText(StoreTab mode, GUIComponent itemFrame)
|
||||
@@ -1664,14 +1769,22 @@ namespace Barotrauma
|
||||
|
||||
private int GetMaxAvailable(ItemPrefab itemPrefab, StoreTab mode)
|
||||
{
|
||||
var list = mode switch
|
||||
List<PurchasedItem> list = null;
|
||||
try
|
||||
{
|
||||
StoreTab.Buy => CurrentLocation.StoreStock,
|
||||
StoreTab.Sell => itemsToSell,
|
||||
StoreTab.SellFromSub => itemsToSellFromSub,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
if (list.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem item)
|
||||
list = mode switch
|
||||
{
|
||||
StoreTab.Buy => CurrentLocation?.StoreStock,
|
||||
StoreTab.Sell => itemsToSell,
|
||||
StoreTab.SellSub => itemsToSellFromSub,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error getting item availability: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
}
|
||||
if (list != null && list.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem item)
|
||||
{
|
||||
if (mode == StoreTab.Buy)
|
||||
{
|
||||
@@ -1691,8 +1804,8 @@ namespace Barotrauma
|
||||
|
||||
private bool ModifyBuyQuantity(PurchasedItem item, int quantity)
|
||||
{
|
||||
if (item == null || item.ItemPrefab == null) { return false; }
|
||||
if (!HasPermissions) { return false; }
|
||||
if (item?.ItemPrefab == null) { return false; }
|
||||
if (!HasBuyPermissions) { return false; }
|
||||
if (quantity > 0)
|
||||
{
|
||||
var itemInCrate = CargoManager.ItemsInBuyCrate.Find(i => i.ItemPrefab == item.ItemPrefab);
|
||||
@@ -1703,13 +1816,13 @@ namespace Barotrauma
|
||||
}
|
||||
CargoManager.ModifyItemQuantityInBuyCrate(item.ItemPrefab, quantity);
|
||||
GameMain.Client?.SendCampaignState();
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ModifySellQuantity(PurchasedItem item, int quantity)
|
||||
{
|
||||
if (item == null || item.ItemPrefab == null) { return false; }
|
||||
if (!HasPermissions) { return false; }
|
||||
if (item?.ItemPrefab == null) { return false; }
|
||||
if (!HasSellInventoryPermissions) { return false; }
|
||||
if (quantity > 0)
|
||||
{
|
||||
// Make sure there's enough available to sell
|
||||
@@ -1718,45 +1831,68 @@ namespace Barotrauma
|
||||
if (totalQuantityToSell > GetMaxAvailable(item.ItemPrefab, StoreTab.Sell)) { return false; }
|
||||
}
|
||||
CargoManager.ModifyItemQuantityInSellCrate(item.ItemPrefab, quantity);
|
||||
//GameMain.Client?.SendCampaignState();
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ModifySellFromSubQuantity(PurchasedItem item, int quantity)
|
||||
{
|
||||
if (item == null || item.ItemPrefab == null) { return false; }
|
||||
if (!HasPermissions) { return false; }
|
||||
if (item?.ItemPrefab == null) { return false; }
|
||||
if (!HasSellSubPermissions) { return false; }
|
||||
if (quantity > 0)
|
||||
{
|
||||
// Make sure there's enough available to sell
|
||||
var itemToSell = CargoManager.ItemsInSellFromSubCrate.Find(i => i.ItemPrefab == item.ItemPrefab);
|
||||
var totalQuantityToSell = itemToSell != null ? itemToSell.Quantity + quantity : quantity;
|
||||
if (totalQuantityToSell > GetMaxAvailable(item.ItemPrefab, StoreTab.SellFromSub)) { return false; }
|
||||
if (totalQuantityToSell > GetMaxAvailable(item.ItemPrefab, StoreTab.SellSub)) { return false; }
|
||||
}
|
||||
CargoManager.ModifyItemQuantityInSellFromSubCrate(item.ItemPrefab, quantity);
|
||||
// TODO: GameMain.Client?.SendCampaignState();
|
||||
return false;
|
||||
GameMain.Client?.SendCampaignState();
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool AddToShoppingCrate(PurchasedItem item, int quantity = 1) => activeTab switch
|
||||
private bool AddToShoppingCrate(PurchasedItem item, int quantity = 1)
|
||||
{
|
||||
StoreTab.Buy => ModifyBuyQuantity(item, quantity),
|
||||
StoreTab.Sell => ModifySellQuantity(item, quantity),
|
||||
StoreTab.SellFromSub => ModifySellFromSubQuantity(item, quantity),
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
if (item == null) { return false; }
|
||||
try
|
||||
{
|
||||
return activeTab switch
|
||||
{
|
||||
StoreTab.Buy => ModifyBuyQuantity(item, quantity),
|
||||
StoreTab.Sell => ModifySellQuantity(item, quantity),
|
||||
StoreTab.SellSub => ModifySellFromSubQuantity(item, quantity),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error adding an item to the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ClearFromShoppingCrate(PurchasedItem item) => activeTab switch
|
||||
private bool ClearFromShoppingCrate(PurchasedItem item)
|
||||
{
|
||||
StoreTab.Buy => ModifyBuyQuantity(item, -item.Quantity),
|
||||
StoreTab.Sell => ModifySellQuantity(item, -item.Quantity),
|
||||
StoreTab.SellFromSub => ModifySellFromSubQuantity(item, -item.Quantity),
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
if (item == null) { return false; }
|
||||
try
|
||||
{
|
||||
return activeTab switch
|
||||
{
|
||||
StoreTab.Buy => ModifyBuyQuantity(item, -item.Quantity),
|
||||
StoreTab.Sell => ModifySellQuantity(item, -item.Quantity),
|
||||
StoreTab.SellSub => ModifySellFromSubQuantity(item, -item.Quantity),
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error clearing the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool BuyItems()
|
||||
{
|
||||
if (!HasPermissions) { return false; }
|
||||
if (!HasBuyPermissions) { return false; }
|
||||
|
||||
var itemsToPurchase = new List<PurchasedItem>(CargoManager.ItemsInBuyCrate);
|
||||
var itemsToRemove = new List<PurchasedItem>();
|
||||
@@ -1788,15 +1924,24 @@ namespace Barotrauma
|
||||
|
||||
private bool SellItems()
|
||||
{
|
||||
if (!HasPermissions) { return false; }
|
||||
var itemsToSell = activeTab switch
|
||||
if (!HasActiveTabPermissions()) { return false; }
|
||||
List<PurchasedItem> itemsToSell;
|
||||
try
|
||||
{
|
||||
StoreTab.Sell => new List<PurchasedItem>(CargoManager.ItemsInSellCrate),
|
||||
StoreTab.SellFromSub => new List<PurchasedItem>(CargoManager.ItemsInSellFromSubCrate),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
itemsToSell = activeTab switch
|
||||
{
|
||||
StoreTab.Sell => new List<PurchasedItem>(CargoManager.ItemsInSellCrate),
|
||||
StoreTab.SellSub => new List<PurchasedItem>(CargoManager.ItemsInSellFromSubCrate),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error confirming the store transaction: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
return false;
|
||||
}
|
||||
var itemsToRemove = new List<PurchasedItem>();
|
||||
var totalValue = 0;
|
||||
int totalValue = 0;
|
||||
foreach (PurchasedItem item in itemsToSell)
|
||||
{
|
||||
if (item?.ItemPrefab?.GetPriceInfo(CurrentLocation) is PriceInfo priceInfo)
|
||||
@@ -1811,11 +1956,7 @@ namespace Barotrauma
|
||||
itemsToRemove.ForEach(i => itemsToSell.Remove(i));
|
||||
if (itemsToSell.None() || totalValue > CurrentLocation.StoreCurrentBalance) { return false; }
|
||||
CargoManager.SellItems(itemsToSell, activeTab);
|
||||
if (activeTab == StoreTab.Sell)
|
||||
{
|
||||
// TODO: Implement selling sub items in multiplayer
|
||||
GameMain.Client?.SendCampaignState();
|
||||
}
|
||||
GameMain.Client?.SendCampaignState();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1831,7 +1972,7 @@ namespace Barotrauma
|
||||
int total = activeTab switch
|
||||
{
|
||||
StoreTab.Sell => sellTotal,
|
||||
StoreTab.SellFromSub => sellFromSubTotal,
|
||||
StoreTab.SellSub => sellFromSubTotal,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
shoppingCrateTotal.Text = GetCurrencyFormatted(total);
|
||||
@@ -1863,21 +2004,29 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void SetConfirmButtonStatus() => confirmButton.Enabled =
|
||||
HasPermissions && ActiveShoppingCrateList.Content.RectTransform.Children.Any() &&
|
||||
activeTab switch
|
||||
{
|
||||
StoreTab.Buy => buyTotal <= PlayerMoney,
|
||||
StoreTab.Sell => CurrentLocation != null && sellTotal <= CurrentLocation.StoreCurrentBalance,
|
||||
StoreTab.SellFromSub => CurrentLocation != null && sellFromSubTotal <= CurrentLocation.StoreCurrentBalance,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
private void SetConfirmButtonStatus()
|
||||
{
|
||||
confirmButton.Enabled =
|
||||
HasActiveTabPermissions() &&
|
||||
ActiveShoppingCrateList.Content.RectTransform.Children.Any() &&
|
||||
activeTab switch
|
||||
{
|
||||
StoreTab.Buy => buyTotal <= PlayerMoney,
|
||||
StoreTab.Sell => CurrentLocation != null && sellTotal <= CurrentLocation.StoreCurrentBalance,
|
||||
StoreTab.SellSub => CurrentLocation != null && sellFromSubTotal <= CurrentLocation.StoreCurrentBalance,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
private void SetClearAllButtonStatus() => clearAllButton.Enabled =
|
||||
HasPermissions && ActiveShoppingCrateList.Content.RectTransform.Children.Any();
|
||||
private void SetClearAllButtonStatus()
|
||||
{
|
||||
clearAllButton.Enabled =
|
||||
HasActiveTabPermissions() &&
|
||||
ActiveShoppingCrateList.Content.RectTransform.Children.Any();
|
||||
}
|
||||
|
||||
private float ownedItemsUpdateTimer = 0.0f, sellableItemsFromSubUpdateTimer = 0.0f;
|
||||
private readonly float timerUpdateInterval = 1.5f;
|
||||
private const float timerUpdateInterval = 1.5f;
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
@@ -1914,10 +2063,10 @@ namespace Barotrauma
|
||||
|
||||
if (needsItemsToSellRefresh) { RefreshItemsToSell(); }
|
||||
if (needsItemsToSellFromSubRefresh) { RefreshItemsToSellFromSub(); }
|
||||
if (needsRefresh || hadPermissions != HasPermissions) { Refresh(updateOwned: ownedItemsUpdateTimer > 0.0f); }
|
||||
if (needsBuyingRefresh) { RefreshBuying(); }
|
||||
if (needsSellingRefresh) { RefreshSelling(); }
|
||||
if (needsSellingFromSubRefresh) { RefreshSellingFromSub(updateItemsToSellFromSub: sellableItemsFromSubUpdateTimer > 0.0f); }
|
||||
if (needsRefresh || HavePermissionsChanged()) { Refresh(updateOwned: ownedItemsUpdateTimer > 0.0f); }
|
||||
if (needsBuyingRefresh || HavePermissionsChanged(StoreTab.Buy)) { RefreshBuying(updateOwned: ownedItemsUpdateTimer > 0.0f); }
|
||||
if (needsSellingRefresh || HavePermissionsChanged(StoreTab.Sell)) { RefreshSelling(updateOwned: ownedItemsUpdateTimer > 0.0f); }
|
||||
if (needsSellingFromSubRefresh || HavePermissionsChanged(StoreTab.SellSub)) { RefreshSellingFromSub(updateItemsToSellFromSub: sellableItemsFromSubUpdateTimer > 0.0f); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,15 +414,8 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
subsToShow.AddRange(SubmarineInfo.SavedSubmarines.Where(s => s.IsCampaignCompatible && !GameMain.GameSession.OwnedSubmarines.Any(os => os.Name == s.Name)));
|
||||
}
|
||||
else
|
||||
{
|
||||
subsToShow.AddRange(GameMain.NetLobbyScreen.CampaignSubmarines.Where(s => !GameMain.GameSession.OwnedSubmarines.Any(os => os.Name == s.Name)));
|
||||
}
|
||||
|
||||
subsToShow.AddRange((GameMain.Client is null ? SubmarineInfo.SavedSubmarines : MultiPlayerCampaign.GetCampaignSubs())
|
||||
.Where(s => s.IsCampaignCompatible && !GameMain.GameSession.OwnedSubmarines.Any(os => os.Name == s.Name)));
|
||||
subsToShow.Sort((x, y) => x.SubmarineClass.CompareTo(y.SubmarineClass));
|
||||
}
|
||||
|
||||
@@ -446,20 +439,11 @@ namespace Barotrauma
|
||||
|
||||
if (preview == null)
|
||||
{
|
||||
SubmarineInfo potentialMatch;
|
||||
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
potentialMatch = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.EqualityCheckVal == info.EqualityCheckVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
potentialMatch = GameMain.NetLobbyScreen.CampaignSubmarines.FirstOrDefault(s => s.EqualityCheckVal == info.EqualityCheckVal);
|
||||
}
|
||||
SubmarineInfo potentialMatch = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.EqualityCheckVal == info.EqualityCheckVal);
|
||||
|
||||
preview = potentialMatch?.PreviewImage;
|
||||
|
||||
// Try from savedsubmarines with name comparison as a backup
|
||||
// Try name comparison as a backup
|
||||
if (preview == null)
|
||||
{
|
||||
potentialMatch = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == info.Name);
|
||||
|
||||
@@ -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>();
|
||||
@@ -129,9 +129,8 @@ namespace Barotrauma
|
||||
public TabMenu()
|
||||
{
|
||||
if (!initialized) { Initialize(); }
|
||||
|
||||
CreateInfoFrame(selectedTab);
|
||||
SelectInfoFrameTab(null, selectedTab);
|
||||
CreateInfoFrame(SelectedTab);
|
||||
SelectInfoFrameTab(SelectedTab);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
@@ -147,8 +146,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 +225,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 +276,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);
|
||||
@@ -300,7 +299,7 @@ namespace Barotrauma
|
||||
CreateMissionInfo(infoFrameHolder);
|
||||
break;
|
||||
case InfoFrameTab.Reputation:
|
||||
if (GameMain.GameSession.RoundSummary != null && GameMain.GameSession.GameMode is CampaignMode campaignMode)
|
||||
if (GameMain.GameSession?.RoundSummary != null && GameMain.GameSession?.GameMode is CampaignMode campaignMode)
|
||||
{
|
||||
infoFrameHolder.ClearChildren();
|
||||
GUIFrame reputationFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrameHolder.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
||||
@@ -308,9 +307,9 @@ namespace Barotrauma
|
||||
}
|
||||
break;
|
||||
case InfoFrameTab.Traitor:
|
||||
TraitorMissionPrefab traitorMission = GameMain.Client.TraitorMission;
|
||||
Character traitor = GameMain.Client.Character;
|
||||
if (traitor == null || traitorMission == null) return false;
|
||||
TraitorMissionPrefab traitorMission = GameMain.Client?.TraitorMission;
|
||||
Character traitor = GameMain.Client?.Character;
|
||||
if (traitor == null || traitorMission == null) { return; }
|
||||
CreateTraitorInfo(infoFrameHolder, traitorMission, traitor);
|
||||
break;
|
||||
case InfoFrameTab.Submarine:
|
||||
@@ -320,8 +319,6 @@ namespace Barotrauma
|
||||
CreateTalentInfo(infoFrameHolder);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private const float jobColumnWidthPercentage = 0.138f;
|
||||
@@ -755,7 +752,7 @@ namespace Barotrauma
|
||||
|
||||
if (character != null)
|
||||
{
|
||||
if (GameMain.NetworkMember == null)
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
GUIComponent preview = character.Info.CreateInfoFrame(background, false, null);
|
||||
}
|
||||
@@ -859,7 +856,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);
|
||||
@@ -1023,13 +1020,15 @@ namespace Barotrauma
|
||||
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
|
||||
Point iconSize = new Point(iconWidth, iconHeight);*/
|
||||
|
||||
new GUIImage(new RectTransform(new Point(iconSize), missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true)
|
||||
var icon = new GUIImage(new RectTransform(new Point(iconSize), missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true)
|
||||
{
|
||||
Color = mission.Prefab.IconColor,
|
||||
HoverColor = mission.Prefab.IconColor,
|
||||
SelectedColor = mission.Prefab.IconColor,
|
||||
CanBeFocused = false
|
||||
};
|
||||
UpdateMissionStateIcon(mission, icon);
|
||||
mission.OnMissionStateChanged += (mission) => UpdateMissionStateIcon(mission, icon);
|
||||
}
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameRichTextData, missionNameString, font: GUI.LargeFont);
|
||||
GUILayoutGroup difficultyIndicatorGroup = null;
|
||||
@@ -1066,6 +1065,33 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMissionStateIcon(Mission mission, GUIImage missionIcon)
|
||||
{
|
||||
if (mission == null || missionIcon == null) { return; }
|
||||
string style = string.Empty;
|
||||
if (mission.DisplayAsFailed)
|
||||
{
|
||||
style = "MissionFailedIcon";
|
||||
}
|
||||
else if (mission.DisplayAsCompleted)
|
||||
{
|
||||
style = "MissionCompletedIcon";
|
||||
}
|
||||
GUIImage stateIcon = missionIcon.GetChild<GUIImage>();
|
||||
if (string.IsNullOrEmpty(style))
|
||||
{
|
||||
if (stateIcon != null)
|
||||
{
|
||||
stateIcon.Visible = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stateIcon ??= new GUIImage(new RectTransform(Vector2.One, missionIcon.RectTransform), style, scaleToFit: true);
|
||||
stateIcon.Visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateTraitorInfo(GUIFrame infoFrame, TraitorMissionPrefab traitorMission, Character traitor)
|
||||
{
|
||||
GUIFrame missionFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
||||
@@ -1443,7 +1469,7 @@ namespace Barotrauma
|
||||
selectedTalents.Remove(talentIdentifier);
|
||||
}
|
||||
|
||||
UpdateTalentButtons();
|
||||
UpdateTalentInfo();
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1508,7 +1534,7 @@ namespace Barotrauma
|
||||
};
|
||||
GUITextBlock.AutoScaleAndNormalize(talentResetButton.TextBlock, talentApplyButton.TextBlock);
|
||||
|
||||
UpdateTalentButtons();
|
||||
UpdateTalentInfo();
|
||||
}
|
||||
|
||||
private void CreateTalentSkillList(Character character, GUIListBox parent)
|
||||
@@ -1543,30 +1569,14 @@ namespace Barotrauma
|
||||
GUITextBlock.AutoScaleAndNormalize(skillNames);
|
||||
}
|
||||
|
||||
private bool HasUnlockedAllTalents(Character controlledCharacter)
|
||||
{
|
||||
if (TalentTree.JobTalentTrees.TryGetValue(controlledCharacter.Info.Job.Prefab.Identifier, out TalentTree talentTree))
|
||||
{
|
||||
foreach (TalentSubTree talentSubTree in talentTree.TalentSubTrees)
|
||||
{
|
||||
foreach (TalentOption talentOption in talentSubTree.TalentOptionStages)
|
||||
{
|
||||
if (talentOption.Talents.None(t => controlledCharacter.HasTalent(t.Identifier)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateTalentButtons()
|
||||
private void UpdateTalentInfo()
|
||||
{
|
||||
Character controlledCharacter = Character.Controlled;
|
||||
if (controlledCharacter?.Info == null) { return; }
|
||||
|
||||
bool unlockedAllTalents = HasUnlockedAllTalents(controlledCharacter);
|
||||
if (SelectedTab != InfoFrameTab.Talents) { return; }
|
||||
|
||||
bool unlockedAllTalents = controlledCharacter.HasUnlockedAllTalents();
|
||||
|
||||
if (unlockedAllTalents)
|
||||
{
|
||||
@@ -1646,7 +1656,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
selectedTalents = controlledCharacter.Info.GetUnlockedTalentsInTree().ToList();
|
||||
UpdateTalentButtons();
|
||||
UpdateTalentInfo();
|
||||
}
|
||||
|
||||
private bool ApplyTalentSelection(GUIButton guiButton, object userData)
|
||||
@@ -1660,63 +1670,14 @@ namespace Barotrauma
|
||||
{
|
||||
Character controlledCharacter = Character.Controlled;
|
||||
selectedTalents = controlledCharacter.Info.GetUnlockedTalentsInTree().ToList();
|
||||
UpdateTalentButtons();
|
||||
UpdateTalentInfo();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnExperienceChanged(Character character)
|
||||
{
|
||||
if (character != Character.Controlled) { return; }
|
||||
UpdateTalentButtons();
|
||||
}
|
||||
|
||||
private readonly StatTypes[] basicStats = new StatTypes[]
|
||||
{
|
||||
StatTypes.MaximumHealthMultiplier,
|
||||
StatTypes.MovementSpeed,
|
||||
StatTypes.SwimmingSpeed,
|
||||
StatTypes.RepairSpeed,
|
||||
};
|
||||
|
||||
private readonly StatTypes[] combatStats = new StatTypes[]
|
||||
{
|
||||
StatTypes.MeleeAttackMultiplier,
|
||||
StatTypes.MeleeAttackSpeed,
|
||||
StatTypes.RangedAttackSpeed,
|
||||
StatTypes.TurretAttackSpeed,
|
||||
};
|
||||
|
||||
private readonly StatTypes[] miscStats = new StatTypes[]
|
||||
{
|
||||
StatTypes.ReputationGainMultiplier,
|
||||
StatTypes.MissionMoneyGainMultiplier,
|
||||
StatTypes.ExperienceGainMultiplier,
|
||||
StatTypes.MissionExperienceGainMultiplier,
|
||||
};
|
||||
|
||||
private void CreateCharacterSheet(GUILayoutGroup characterInfoColumn)
|
||||
{
|
||||
Character controlledCharacter = Character.Controlled;
|
||||
|
||||
CreateRow(basicStats);
|
||||
CreateRow(combatStats);
|
||||
CreateRow(miscStats);
|
||||
|
||||
void CreateRow(StatTypes[] statTypes)
|
||||
{
|
||||
GUILayoutGroup characterInfoRow = new GUILayoutGroup(new RectTransform(new Vector2(0.33f, 1.0f), characterInfoColumn.RectTransform, anchor: Anchor.TopLeft), childAnchor: Anchor.TopCenter);
|
||||
foreach (StatTypes statType in statTypes)
|
||||
{
|
||||
ShowStat(statType, characterInfoRow);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowStat(StatTypes statType, GUILayoutGroup characterInfoRow)
|
||||
{
|
||||
GUIFrame textInfoFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.33f), characterInfoRow.RectTransform, Anchor.TopCenter), style: null);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1f, 1f), textInfoFrame.RectTransform, Anchor.TopLeft), statType.ToString(), font: GUI.SmallFont, textAlignment: Alignment.TopLeft);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1f, 1f), textInfoFrame.RectTransform, Anchor.TopLeft), (int)(100f * (1 + controlledCharacter.GetStatValue(statType))) + "%", font: GUI.Font, textAlignment: Alignment.TopRight);
|
||||
}
|
||||
UpdateTalentInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
|
||||
internal class UpgradeStore
|
||||
{
|
||||
public readonly struct CategoryData
|
||||
@@ -168,6 +167,7 @@ namespace Barotrauma
|
||||
//TODO: move this somewhere else
|
||||
public static void UpdateCategoryList(GUIListBox categoryList, CampaignMode campaign, Submarine? drawnSubmarine, IEnumerable<UpgradeCategory> applicableCategories)
|
||||
{
|
||||
var subItems = GetSubItems();
|
||||
foreach (GUIComponent component in categoryList.Content.Children)
|
||||
{
|
||||
if (!(component.UserData is CategoryData data)) { continue; }
|
||||
@@ -179,7 +179,7 @@ namespace Barotrauma
|
||||
var customizeButton = component.FindChild("customizebutton", true);
|
||||
if (customizeButton != null)
|
||||
{
|
||||
customizeButton.Visible = HasSwappableItems(data.Category);
|
||||
customizeButton.Visible = HasSwappableItems(data.Category, subItems);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,6 +434,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);
|
||||
@@ -468,6 +469,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);
|
||||
@@ -513,6 +515,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);
|
||||
@@ -717,16 +720,19 @@ namespace Barotrauma
|
||||
|
||||
private bool customizeTabOpen;
|
||||
|
||||
private static bool HasSwappableItems(UpgradeCategory category)
|
||||
private static bool HasSwappableItems(UpgradeCategory category, List<Item>? subItems = null)
|
||||
{
|
||||
if (Submarine.MainSub == null) { return false; }
|
||||
return Submarine.MainSub.GetItems(true).Any(i =>
|
||||
subItems ??= GetSubItems();
|
||||
return subItems.Any(i =>
|
||||
i.Prefab.SwappableItem != null &&
|
||||
!i.HiddenInGame && i.AllowSwapping &&
|
||||
(i.Prefab.SwappableItem.CanBeBought || ItemPrefab.Prefabs.Any(ip => ip.SwappableItem?.ReplacementOnUninstall == i.Prefab.Identifier)) &&
|
||||
Submarine.MainSub.IsEntityFoundOnThisSub(i, true) && category.ItemTags.Any(t => i.HasTag(t)));
|
||||
}
|
||||
|
||||
private static List<Item> GetSubItems() => Submarine.MainSub?.GetItems(true) ?? new List<Item>();
|
||||
|
||||
private void SelectUpgradeCategory(List<UpgradePrefab> prefabs, UpgradeCategory category, Submarine submarine)
|
||||
{
|
||||
if (selectedUpgradeCategoryLayout == null) { return; }
|
||||
@@ -1688,7 +1694,7 @@ namespace Barotrauma
|
||||
|
||||
private bool HasPermission => campaignUI.Campaign.AllowedToManageCampaign();
|
||||
|
||||
private static string FormatCurrency(int money, bool format = true)
|
||||
public static string FormatCurrency(int money, bool format = true)
|
||||
{
|
||||
return TextManager.GetWithVariable("CurrencyFormat", "[credits]", format ? string.Format(CultureInfo.InvariantCulture, "{0:N0}", money) : money.ToString());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user