Merge branch 'master' of https://github.com/Regalis11/Barotrauma.git
This commit is contained in:
@@ -116,7 +116,7 @@ namespace Barotrauma
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
var skills = Job.Skills;
|
||||
var skills = Job.GetSkills().ToList();
|
||||
skills.Sort((s1, s2) => -s1.Level.CompareTo(s2.Level));
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), skillsArea.RectTransform), TextManager.AddPunctuation(':', TextManager.Get("skills"), string.Empty), font: font) { Padding = Vector4.Zero };
|
||||
@@ -560,17 +560,7 @@ namespace Barotrauma
|
||||
ch.SetPersonalityTrait();
|
||||
if (ch.Job != null)
|
||||
{
|
||||
foreach (KeyValuePair<Identifier, float> skill in skillLevels)
|
||||
{
|
||||
Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key);
|
||||
if (matchingSkill == null)
|
||||
{
|
||||
ch.Job.Skills.Add(new Skill(skill.Key, skill.Value));
|
||||
continue;
|
||||
}
|
||||
matchingSkill.Level = skill.Value;
|
||||
}
|
||||
ch.Job.Skills.RemoveAll(s => !skillLevels.ContainsKey(s.Identifier));
|
||||
ch.Job.OverrideSkills(skillLevels);
|
||||
}
|
||||
|
||||
ch.ExperiencePoints = inc.ReadUInt16();
|
||||
|
||||
@@ -694,6 +694,7 @@ namespace Barotrauma
|
||||
AssignRelayToServer("simulatedlatency", false);
|
||||
AssignRelayToServer("simulatedloss", false);
|
||||
AssignRelayToServer("simulatedduplicateschance", false);
|
||||
AssignRelayToServer("simulatedlongloadingtime", false);
|
||||
AssignRelayToServer("storeinfo", false);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using PlayerBalanceElement = Barotrauma.CampaignUI.PlayerBalanceElement;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -21,6 +22,8 @@ namespace Barotrauma
|
||||
private GUIButton validateHiresButton;
|
||||
private GUIButton clearAllButton;
|
||||
|
||||
private PlayerBalanceElement? playerBalanceElement;
|
||||
|
||||
private List<CharacterInfo> PendingHires => campaign.Map?.CurrentLocation?.HireManager?.PendingHires;
|
||||
private bool HasPermission => campaignUI.Campaign.AllowedToManageCampaign(ClientPermissions.ManageHires);
|
||||
|
||||
@@ -157,23 +160,7 @@ namespace Barotrauma
|
||||
RelativeSpacing = 0.02f
|
||||
};
|
||||
|
||||
var playerBalanceContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.75f / 14.0f), pendingAndCrewMainGroup.RectTransform), childAnchor: Anchor.TopRight)
|
||||
{
|
||||
RelativeSpacing = 0.005f
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
|
||||
TextManager.Get("campaignstore.balance"), font: GUIStyle.Font, textAlignment: Alignment.BottomRight)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
ForceUpperCase = ForceUpperCase.Yes
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
|
||||
"", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.TopRight)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
TextScale = 1.1f,
|
||||
TextGetter = () => TextManager.FormatCurrency(campaign.Wallet.Balance)
|
||||
};
|
||||
playerBalanceElement = CampaignUI.AddBalanceElement(pendingAndCrewMainGroup, new Vector2(1.0f, 0.75f / 14.0f));
|
||||
|
||||
var pendingAndCrewGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), anchor: Anchor.Center,
|
||||
parent: new GUIFrame(new RectTransform(new Vector2(1.0f, 13.25f / 14.0f), pendingAndCrewMainGroup.RectTransform)
|
||||
@@ -344,7 +331,7 @@ namespace Barotrauma
|
||||
Color? jobColor = null;
|
||||
if (characterInfo.Job != null)
|
||||
{
|
||||
skill = characterInfo.Job?.PrimarySkill ?? characterInfo.Job.Skills.OrderByDescending(s => s.Level).FirstOrDefault();
|
||||
skill = characterInfo.Job?.PrimarySkill ?? characterInfo.Job.GetSkills().OrderByDescending(s => s.Level).FirstOrDefault();
|
||||
jobColor = characterInfo.Job.Prefab.UIColor;
|
||||
}
|
||||
|
||||
@@ -547,8 +534,8 @@ namespace Barotrauma
|
||||
GUILayoutGroup skillGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.475f), mainGroup.RectTransform), isHorizontal: true);
|
||||
GUILayoutGroup skillNameGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1.0f), skillGroup.RectTransform));
|
||||
GUILayoutGroup skillLevelGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.2f, 1.0f), skillGroup.RectTransform));
|
||||
List<Skill> characterSkills = characterInfo.Job.Skills;
|
||||
blockHeight = 1.0f / characterSkills.Count;
|
||||
var characterSkills = characterInfo.Job.GetSkills();
|
||||
blockHeight = 1.0f / characterSkills.Count();
|
||||
foreach (Skill skill in characterSkills)
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), skillNameGroup.RectTransform), TextManager.Get("SkillName." + skill.Identifier));
|
||||
@@ -630,7 +617,7 @@ namespace Barotrauma
|
||||
total += ((InfoSkill)c.UserData).CharacterInfo.Salary;
|
||||
});
|
||||
totalBlock.Text = TextManager.FormatCurrency(total);
|
||||
bool enoughMoney = campaign == null || campaign.Wallet.CanAfford(total);
|
||||
bool enoughMoney = campaign == null || campaign.CanAfford(total);
|
||||
totalBlock.TextColor = enoughMoney ? Color.White : Color.Red;
|
||||
validateHiresButton.Enabled = enoughMoney && HasPermission && pendingList.Content.RectTransform.Children.Any();
|
||||
}
|
||||
@@ -652,7 +639,7 @@ namespace Barotrauma
|
||||
|
||||
int total = nonDuplicateHires.Aggregate(0, (total, info) => total + info.Salary);
|
||||
|
||||
if (!campaign.Wallet.CanAfford(total)) { return false; }
|
||||
if (!campaign.CanAfford(total)) { return false; }
|
||||
|
||||
bool atLeastOneHired = false;
|
||||
foreach (CharacterInfo ci in nonDuplicateHires)
|
||||
@@ -792,6 +779,10 @@ namespace Barotrauma
|
||||
CreateUI();
|
||||
UpdateLocationView(campaign.Map.CurrentLocation, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
playerBalanceElement = CampaignUI.UpdateBalanceElement(playerBalanceElement);
|
||||
}
|
||||
|
||||
(GUIComponent highlightedFrame, CharacterInfo highlightedInfo) = FindHighlightedCharacter(GUI.MouseOn);
|
||||
if (highlightedFrame != null && highlightedInfo != null)
|
||||
|
||||
@@ -567,9 +567,9 @@ namespace Barotrauma
|
||||
|
||||
GameMain.GameSession?.EventManager?.DrawPinnedEvent(spriteBatch);
|
||||
|
||||
if (HUDLayoutSettings.DebugDraw) HUDLayoutSettings.Draw(spriteBatch);
|
||||
if (HUDLayoutSettings.DebugDraw) { HUDLayoutSettings.Draw(spriteBatch); }
|
||||
|
||||
if (GameMain.Client != null) GameMain.Client.Draw(spriteBatch);
|
||||
GameMain.Client?.Draw(spriteBatch);
|
||||
|
||||
if (Character.Controlled?.Inventory != null)
|
||||
{
|
||||
@@ -616,28 +616,46 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
DrawSavingIndicator(spriteBatch);
|
||||
|
||||
if (GameMain.WindowActive && !HideCursor)
|
||||
{
|
||||
spriteBatch.End();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: SamplerStateClamp, rasterizerState: GameMain.ScissorTestEnable);
|
||||
|
||||
if (GameMain.GameSession?.CrewManager is { DraggedOrderPrefab: { SymbolSprite: { } orderSprite, Color: var color }, DragOrder: true })
|
||||
{
|
||||
float spriteSize = Math.Max(orderSprite.size.X, orderSprite.size.Y);
|
||||
orderSprite.Draw(spriteBatch, PlayerInput.LatestMousePosition, color, orderSprite.size / 2f, scale: 32f / spriteSize * Scale);
|
||||
}
|
||||
|
||||
var sprite = MouseCursorSprites[MouseCursor] ?? MouseCursorSprites[CursorState.Default];
|
||||
sprite.Draw(spriteBatch, PlayerInput.LatestMousePosition, Color.White, sprite.Origin, 0f, Scale / 1.5f);
|
||||
|
||||
spriteBatch.End();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: SamplerState, rasterizerState: GameMain.ScissorTestEnable);
|
||||
}
|
||||
DrawCursor(spriteBatch);
|
||||
HideCursor = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawMessageBoxesOnly(SpriteBatch spriteBatch)
|
||||
{
|
||||
bool anyDrawn = false;
|
||||
foreach (var component in updateList)
|
||||
{
|
||||
component.DrawAuto(spriteBatch);
|
||||
anyDrawn = true;
|
||||
}
|
||||
if (anyDrawn)
|
||||
{
|
||||
DrawCursor(spriteBatch);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawCursor(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (GameMain.WindowActive && !HideCursor && MouseCursorSprites.Prefabs.Any())
|
||||
{
|
||||
spriteBatch.End();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: SamplerStateClamp, rasterizerState: GameMain.ScissorTestEnable);
|
||||
|
||||
if (GameMain.GameSession?.CrewManager is { DraggedOrderPrefab: { SymbolSprite: { } orderSprite, Color: var color }, DragOrder: true })
|
||||
{
|
||||
float spriteSize = Math.Max(orderSprite.size.X, orderSprite.size.Y);
|
||||
orderSprite.Draw(spriteBatch, PlayerInput.LatestMousePosition, color, orderSprite.size / 2f, scale: 32f / spriteSize * Scale);
|
||||
}
|
||||
|
||||
var sprite = MouseCursorSprites[MouseCursor] ?? MouseCursorSprites[CursorState.Default];
|
||||
sprite.Draw(spriteBatch, PlayerInput.LatestMousePosition, Color.White, sprite.Origin, 0f, Scale / 1.5f);
|
||||
|
||||
spriteBatch.End();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: SamplerState, rasterizerState: GameMain.ScissorTestEnable);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawBackgroundSprite(SpriteBatch spriteBatch, Sprite backgroundSprite, float aberrationStrength = 1.0f)
|
||||
{
|
||||
double aberrationT = (Timing.TotalTime * 0.5f);
|
||||
@@ -1204,6 +1222,17 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateGUIMessageBoxesOnly(float deltaTime)
|
||||
{
|
||||
GUIMessageBox.AddActiveToGUIUpdateList();
|
||||
RefreshUpdateList();
|
||||
UpdateMouseOn();
|
||||
foreach (var c in updateList)
|
||||
{
|
||||
c.UpdateAuto(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateMessages(float deltaTime)
|
||||
{
|
||||
lock (mutex)
|
||||
|
||||
@@ -36,6 +36,8 @@ namespace Barotrauma
|
||||
public string Tag { get; private set; }
|
||||
public bool Closed { get; private set; }
|
||||
|
||||
public bool DisplayInLoadingScreens;
|
||||
|
||||
public GUIImage Icon
|
||||
{
|
||||
get;
|
||||
@@ -451,6 +453,10 @@ namespace Barotrauma
|
||||
continue;
|
||||
}
|
||||
if (messageBox.type != type) { continue; }
|
||||
if (!messageBox.DisplayInLoadingScreens && GameMain.Instance.LoadingScreenOpen)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// These are handled separately in GUI.HandlePersistingElements()
|
||||
if (MessageBoxes[i].UserData as string == "verificationprompt") { continue; }
|
||||
|
||||
@@ -395,14 +395,13 @@ namespace Barotrauma
|
||||
origin = TextSize * 0.5f;
|
||||
|
||||
origin.X = 0;
|
||||
if (textAlignment.HasFlag(Alignment.Left) && !overflowClipActive)
|
||||
if (textAlignment.HasFlag(Alignment.Left))
|
||||
{
|
||||
textPos.X = padding.X;
|
||||
}
|
||||
if (textAlignment.HasFlag(Alignment.Right) || overflowClipActive)
|
||||
if (textAlignment.HasFlag(Alignment.Right))
|
||||
{
|
||||
textPos.X = rect.Width - padding.Z;
|
||||
//origin.X = TextSize.X;
|
||||
}
|
||||
if (textAlignment.HasFlag(Alignment.Top))
|
||||
{
|
||||
|
||||
@@ -453,24 +453,7 @@ namespace Barotrauma
|
||||
|
||||
if (CaretEnabled)
|
||||
{
|
||||
if (textBlock.OverflowClipActive)
|
||||
{
|
||||
float left = textBlock.Rect.X + textBlock.Padding.X;
|
||||
if (CaretScreenPos.X < left)
|
||||
{
|
||||
float diff = left - CaretScreenPos.X;
|
||||
textBlock.TextPos = new Vector2(textBlock.TextPos.X + diff, textBlock.TextPos.Y);
|
||||
CalculateCaretPos();
|
||||
}
|
||||
|
||||
float right = textBlock.Rect.Right - textBlock.Padding.Z;
|
||||
if (CaretScreenPos.X > right)
|
||||
{
|
||||
float diff = CaretScreenPos.X - right;
|
||||
textBlock.TextPos = new Vector2(textBlock.TextPos.X - diff, textBlock.TextPos.Y);
|
||||
CalculateCaretPos();
|
||||
}
|
||||
}
|
||||
HandleCaretBoundsOverflow();
|
||||
caretTimer += deltaTime;
|
||||
caretVisible = ((caretTimer * 1000.0f) % 1000) < 500;
|
||||
if (caretVisible && caretPosDirty)
|
||||
@@ -496,6 +479,29 @@ namespace Barotrauma
|
||||
textBlock.State = State;
|
||||
}
|
||||
|
||||
private void HandleCaretBoundsOverflow()
|
||||
{
|
||||
if (textBlock.OverflowClipActive)
|
||||
{
|
||||
CalculateCaretPos();
|
||||
float left = textBlock.Rect.X + textBlock.Padding.X;
|
||||
if (CaretScreenPos.X < left)
|
||||
{
|
||||
float diff = left - CaretScreenPos.X;
|
||||
textBlock.TextPos = new Vector2(textBlock.TextPos.X + diff, textBlock.TextPos.Y);
|
||||
CalculateCaretPos();
|
||||
}
|
||||
|
||||
float right = textBlock.Rect.Right - textBlock.Padding.Z;
|
||||
if (CaretScreenPos.X > right)
|
||||
{
|
||||
float diff = CaretScreenPos.X - right;
|
||||
textBlock.TextPos = new Vector2(textBlock.TextPos.X - diff, textBlock.TextPos.Y);
|
||||
CalculateCaretPos();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCaretAndSelection(SpriteBatch spriteBatch, GUICustomComponent customComponent)
|
||||
{
|
||||
if (!Visible) { return; }
|
||||
@@ -564,15 +570,33 @@ namespace Barotrauma
|
||||
{
|
||||
RemoveSelectedText();
|
||||
}
|
||||
Vector2 textPos = textBlock.TextPos;
|
||||
bool wasOverflowClipActive = textBlock.OverflowClipActive;
|
||||
using var _ = new TextPosPreservation(this);
|
||||
if (SetText(Text.Insert(CaretIndex, input)))
|
||||
{
|
||||
CaretIndex = Math.Min(Text.Length, CaretIndex + input.Length);
|
||||
OnTextChanged?.Invoke(this, Text);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly ref struct TextPosPreservation
|
||||
{
|
||||
private readonly GUITextBox textBox;
|
||||
private GUITextBlock textBlock => textBox.TextBlock;
|
||||
private readonly bool wasOverflowClipActive;
|
||||
private readonly Vector2 textPos;
|
||||
|
||||
public TextPosPreservation(GUITextBox tb)
|
||||
{
|
||||
textBox = tb;
|
||||
wasOverflowClipActive = tb.TextBlock.OverflowClipActive;
|
||||
textPos = tb.TextBlock.TextPos;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (textBlock.OverflowClipActive && wasOverflowClipActive && !MathUtils.NearlyEqual(textBlock.TextPos, textPos))
|
||||
{
|
||||
textBlock.TextPos = textPos + Vector2.UnitX * Font.MeasureString(input).X * TextBlock.TextScale;
|
||||
textBlock.TextPos = textPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -587,6 +611,8 @@ namespace Barotrauma
|
||||
switch (command)
|
||||
{
|
||||
case '\b' when !Readonly: //backspace
|
||||
{
|
||||
using var _ = new TextPosPreservation(this);
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
|
||||
{
|
||||
SetText(string.Empty, false);
|
||||
@@ -605,6 +631,7 @@ namespace Barotrauma
|
||||
}
|
||||
OnTextChanged?.Invoke(this, Text);
|
||||
break;
|
||||
}
|
||||
case (char)0x3: // ctrl-c
|
||||
CopySelectedText();
|
||||
break;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Media;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Media;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -16,7 +14,7 @@ namespace Barotrauma
|
||||
private readonly Texture2D defaultBackgroundTexture, overlay;
|
||||
private readonly SpriteSheet decorativeGraph, decorativeMap;
|
||||
private Texture2D currentBackgroundTexture;
|
||||
private Sprite noiseSprite;
|
||||
private readonly Sprite noiseSprite;
|
||||
|
||||
private string randText = "";
|
||||
|
||||
@@ -250,8 +248,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
GUI.DrawMessageBoxesOnly(spriteBatch);
|
||||
spriteBatch.End();
|
||||
|
||||
spriteBatch.Begin(blendState: BlendState.Additive);
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using PlayerBalanceElement = Barotrauma.CampaignUI.PlayerBalanceElement;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -180,6 +181,8 @@ namespace Barotrauma
|
||||
private const float refreshTimerMax = 3f;
|
||||
private float refreshTimer = 0;
|
||||
|
||||
private PlayerBalanceElement? playerBalanceElement;
|
||||
|
||||
public MedicalClinicUI(MedicalClinic clinic, GUIComponent parent)
|
||||
{
|
||||
medicalClinic = clinic;
|
||||
@@ -271,7 +274,7 @@ namespace Barotrauma
|
||||
healList.PriceBlock.Text = TextManager.FormatCurrency(totalCost);
|
||||
healList.PriceBlock.TextColor = GUIStyle.Red;
|
||||
healList.HealButton.Enabled = false;
|
||||
if (medicalClinic.GetWallet().CanAfford(totalCost))
|
||||
if (medicalClinic.GetBalance() >= totalCost)
|
||||
{
|
||||
healList.PriceBlock.TextColor = GUIStyle.TextColorNormal;
|
||||
if (medicalClinic.PendingHeals.Any())
|
||||
@@ -428,6 +431,7 @@ namespace Barotrauma
|
||||
{
|
||||
container.ClearChildren();
|
||||
pendingHealList = null;
|
||||
playerBalanceElement = null;
|
||||
int panelMaxWidth = (int)(GUI.xScale * (GUI.HorizontalAspectRatio < 1.4f ? 650 : 560));
|
||||
|
||||
GUIFrame paddedParent = new GUIFrame(new RectTransform(new Vector2(0.95f), container.RectTransform, Anchor.Center), style: null);
|
||||
@@ -458,19 +462,7 @@ namespace Barotrauma
|
||||
RelativeSpacing = 0.01f
|
||||
};
|
||||
|
||||
GUILayoutGroup balanceLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), crewContent.RectTransform));
|
||||
GUITextBlock balanceLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), balanceLayout.RectTransform), TextManager.Get("campaignstore.balance"), textAlignment: Alignment.BottomRight, font: GUIStyle.Font)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
ForceUpperCase = ForceUpperCase.Yes
|
||||
};
|
||||
|
||||
GUITextBlock moneyLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), balanceLayout.RectTransform), string.Empty, textAlignment: Alignment.TopRight, font: GUIStyle.SubHeadingFont)
|
||||
{
|
||||
TextGetter = () => TextManager.FormatCurrency(medicalClinic.GetWallet().Balance),
|
||||
AutoScaleVertical = true,
|
||||
TextScale = 1.1f
|
||||
};
|
||||
playerBalanceElement = CampaignUI.AddBalanceElement(crewContent, new Vector2(1f, 0.1f));
|
||||
|
||||
GUIFrame crewBackground = new GUIFrame(new RectTransform(Vector2.One, crewContent.RectTransform));
|
||||
|
||||
@@ -577,7 +569,7 @@ namespace Barotrauma
|
||||
GUILayoutGroup buttonLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), footerLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterRight);
|
||||
GUIButton healButton = new GUIButton(new RectTransform(new Vector2(0.33f, 1f), buttonLayout.RectTransform), TextManager.Get("medicalclinic.heal"))
|
||||
{
|
||||
Enabled = medicalClinic.PendingHeals.Any() && medicalClinic.GetWallet().CanAfford(medicalClinic.GetTotalCost()),
|
||||
Enabled = medicalClinic.PendingHeals.Any() && medicalClinic.GetBalance() >= medicalClinic.GetTotalCost(),
|
||||
OnClicked = (button, _) =>
|
||||
{
|
||||
button.Enabled = false;
|
||||
@@ -1050,6 +1042,10 @@ namespace Barotrauma
|
||||
{
|
||||
CreateUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
playerBalanceElement = CampaignUI.UpdateBalanceElement(playerBalanceElement);
|
||||
}
|
||||
|
||||
refreshTimer += deltaTime;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using PlayerBalanceElement = Barotrauma.CampaignUI.PlayerBalanceElement;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -66,12 +67,15 @@ namespace Barotrauma
|
||||
|
||||
private Point resolutionWhenCreated;
|
||||
|
||||
private PlayerBalanceElement? playerBalanceElement;
|
||||
|
||||
private Dictionary<ItemPrefab, ItemQuantity> OwnedItems { get; } = new Dictionary<ItemPrefab, ItemQuantity>();
|
||||
private Location.StoreInfo ActiveStore { get; set; }
|
||||
|
||||
private CargoManager CargoManager => campaignUI.Campaign.CargoManager;
|
||||
private Location CurrentLocation => campaignUI.Campaign.Map?.CurrentLocation;
|
||||
private Wallet PlayerWallet => campaignUI.Campaign.Wallet;
|
||||
private int Balance => campaignUI.Campaign.GetBalance();
|
||||
|
||||
private bool IsBuying => activeTab switch
|
||||
{
|
||||
StoreTab.Buy => true,
|
||||
@@ -207,7 +211,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (CurrentLocation?.Stores != null)
|
||||
{
|
||||
if (CurrentLocation.GetStore(identifier) is { } store)
|
||||
if (!identifier.IsEmpty && CurrentLocation.GetStore(identifier) is { } store)
|
||||
{
|
||||
ActiveStore = store;
|
||||
if (storeNameBlock != null)
|
||||
@@ -223,14 +227,45 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
ActiveStore = null;
|
||||
string msg = $"Error selecting store with identifier \"{identifier}\" at {CurrentLocation}: store with the identifier doesn't exist at the location.";
|
||||
string errorId, msg;
|
||||
if (identifier.IsEmpty)
|
||||
{
|
||||
errorId = "Store.SelectStore:IdentifierEmpty";
|
||||
msg = $"Error selecting store at {CurrentLocation}: identifier is empty.";
|
||||
}
|
||||
else
|
||||
{
|
||||
errorId = "Store.SelectStore:StoreDoesntExist";
|
||||
msg = $"Error selecting store with identifier \"{identifier}\" at {CurrentLocation}: store with the identifier doesn't exist at the location.";
|
||||
}
|
||||
DebugConsole.ShowError(msg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("Store.SelectStore:StoreDoesntExist", GameAnalyticsManager.ErrorSeverity.Error, msg);
|
||||
GameAnalyticsManager.AddErrorEventOnce(errorId, GameAnalyticsManager.ErrorSeverity.Error, msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ActiveStore = null;
|
||||
string errorId = "", msg = "";
|
||||
if (campaignUI.Campaign.Map == null)
|
||||
{
|
||||
errorId = "Store.SelectStore:MapNull";
|
||||
msg = $"Error selecting store with identifier \"{identifier}\": Map is null.";
|
||||
}
|
||||
else if (CurrentLocation == null)
|
||||
{
|
||||
errorId = "Store.SelectStore:CurrentLocationNull";
|
||||
msg = $"Error selecting store with identifier \"{identifier}\": CurrentLocation is null.";
|
||||
}
|
||||
else if (CurrentLocation.Stores == null)
|
||||
{
|
||||
errorId = "Store.SelectStore:StoresNull";
|
||||
msg = $"Error selecting store with identifier \"{identifier}\": CurrentLocation.Stores is null.";
|
||||
}
|
||||
if (!msg.IsNullOrEmpty())
|
||||
{
|
||||
DebugConsole.ShowError(msg);
|
||||
GameAnalyticsManager.AddErrorEventOnce(errorId, GameAnalyticsManager.ErrorSeverity.Error, msg);
|
||||
}
|
||||
}
|
||||
RefreshItemsToSell();
|
||||
Refresh();
|
||||
@@ -615,23 +650,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
// Player balance ------------------------------------------------
|
||||
var playerBalanceContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.75f / 14.0f), shoppingCrateContent.RectTransform), childAnchor: Anchor.TopRight)
|
||||
{
|
||||
RelativeSpacing = 0.005f
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
|
||||
TextManager.Get("campaignstore.balance"), font: GUIStyle.Font, textAlignment: Alignment.BottomRight)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
ForceUpperCase = ForceUpperCase.Yes
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
|
||||
"", textColor: Color.White, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.TopRight)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
TextScale = 1.1f,
|
||||
TextGetter = GetPlayerBalanceText
|
||||
};
|
||||
playerBalanceElement = CampaignUI.AddBalanceElement(shoppingCrateContent, new Vector2(1.0f, 0.75f / 14.0f));
|
||||
|
||||
// Divider ------------------------------------------------
|
||||
var dividerFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.6f / 14.0f), shoppingCrateContent.RectTransform), style: null);
|
||||
@@ -663,7 +682,7 @@ namespace Barotrauma
|
||||
{
|
||||
CanBeFocused = false,
|
||||
TextScale = 1.1f,
|
||||
TextGetter = () => IsBuying ? GetPlayerBalanceText() : GetMerchantBalanceText()
|
||||
TextGetter = () => IsBuying ? CampaignUI.GetTotalBalance() : GetMerchantBalanceText()
|
||||
};
|
||||
|
||||
var totalContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), shoppingCrateInventoryContainer.RectTransform), isHorizontal: true)
|
||||
@@ -712,8 +731,6 @@ namespace Barotrauma
|
||||
|
||||
private LocalizedString GetMerchantBalanceText() => TextManager.FormatCurrency(ActiveStore?.Balance ?? 0);
|
||||
|
||||
private LocalizedString GetPlayerBalanceText() => TextManager.FormatCurrency(PlayerWallet.Balance);
|
||||
|
||||
private GUILayoutGroup CreateDealsGroup(GUIListBox parentList, int elementCount)
|
||||
{
|
||||
// Add 1 for the header
|
||||
@@ -2037,7 +2054,7 @@ namespace Barotrauma
|
||||
totalPrice += item.Quantity * ActiveStore.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo);
|
||||
}
|
||||
itemsToRemove.ForEach(i => itemsToPurchase.Remove(i));
|
||||
if (itemsToPurchase.None() || !PlayerWallet.CanAfford(totalPrice)) { return false; }
|
||||
if (itemsToPurchase.None() || Balance < totalPrice) { return false; }
|
||||
CargoManager.PurchaseItems(ActiveStore.Identifier, itemsToPurchase, true);
|
||||
GameMain.Client?.SendCampaignState();
|
||||
var dialog = new GUIMessageBox(
|
||||
@@ -2091,7 +2108,7 @@ namespace Barotrauma
|
||||
if (IsBuying)
|
||||
{
|
||||
shoppingCrateTotal.Text = TextManager.FormatCurrency(buyTotal);
|
||||
shoppingCrateTotal.TextColor = !PlayerWallet.CanAfford(buyTotal) ? Color.Red : Color.White;
|
||||
shoppingCrateTotal.TextColor = Balance < buyTotal ? Color.Red : Color.White;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2137,7 +2154,7 @@ namespace Barotrauma
|
||||
ActiveShoppingCrateList.Content.RectTransform.Children.Any() &&
|
||||
activeTab switch
|
||||
{
|
||||
StoreTab.Buy => PlayerWallet.CanAfford(buyTotal),
|
||||
StoreTab.Buy => Balance >= buyTotal,
|
||||
StoreTab.Sell => CurrentLocation != null && sellTotal <= ActiveStore.Balance,
|
||||
StoreTab.SellSub => CurrentLocation != null && sellFromSubTotal <= ActiveStore.Balance,
|
||||
_ => false
|
||||
@@ -2151,6 +2168,7 @@ namespace Barotrauma
|
||||
ActiveShoppingCrateList.Content.RectTransform.Children.Any();
|
||||
}
|
||||
|
||||
private int prevBalance;
|
||||
private float ownedItemsUpdateTimer = 0.0f, sellableItemsFromSubUpdateTimer = 0.0f;
|
||||
private const float timerUpdateInterval = 1.5f;
|
||||
private readonly Stopwatch updateStopwatch = new Stopwatch();
|
||||
@@ -2166,6 +2184,8 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
playerBalanceElement = CampaignUI.UpdateBalanceElement(playerBalanceElement);
|
||||
|
||||
// Update the owned items at short intervals and check if the interface should be refreshed
|
||||
ownedItemsUpdateTimer += deltaTime;
|
||||
if (ownedItemsUpdateTimer >= timerUpdateInterval)
|
||||
@@ -2202,6 +2222,16 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
// Refresh the interface if balance changes and the buy tab is open
|
||||
if (activeTab == StoreTab.Buy)
|
||||
{
|
||||
int currBalance = Balance;
|
||||
if (prevBalance != currBalance)
|
||||
{
|
||||
needsBuyingRefresh = true;
|
||||
prevBalance = currBalance;
|
||||
}
|
||||
}
|
||||
if (needsItemsToSellRefresh)
|
||||
{
|
||||
RefreshItemsToSell();
|
||||
|
||||
@@ -4,6 +4,8 @@ using Microsoft.Xna.Framework;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System.Globalization;
|
||||
using PlayerBalanceElement = Barotrauma.CampaignUI.PlayerBalanceElement;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -31,7 +33,7 @@ namespace Barotrauma
|
||||
private readonly List<SubmarineInfo> subsToShow;
|
||||
private readonly SubmarineDisplayContent[] submarineDisplays = new SubmarineDisplayContent[submarinesPerPage];
|
||||
private SubmarineInfo selectedSubmarine = null;
|
||||
private LocalizedString purchaseAndSwitchText, purchaseOnlyText, deliveryText, currentSubText, deliveryFeeText, priceText, switchText, missingPreviewText, currencyName;
|
||||
private LocalizedString purchaseAndSwitchText, purchaseOnlyText, deliveryText, currentSubText, switchText, missingPreviewText, currencyName;
|
||||
private readonly RectTransform parent;
|
||||
private readonly Action closeAction;
|
||||
private Sprite pageIndicator;
|
||||
@@ -44,6 +46,8 @@ namespace Barotrauma
|
||||
private static readonly Color indicatorColor = new Color(112, 149, 129);
|
||||
private Point createdForResolution;
|
||||
|
||||
private PlayerBalanceElement? playerBalanceElement;
|
||||
|
||||
private struct SubmarineDisplayContent
|
||||
{
|
||||
public GUIFrame background;
|
||||
@@ -85,12 +89,10 @@ namespace Barotrauma
|
||||
{
|
||||
initialized = true;
|
||||
currentSubText = TextManager.Get("currentsub");
|
||||
deliveryFeeText = TextManager.Get("deliveryfee");
|
||||
deliveryText = TextManager.Get("requestdeliverybutton");
|
||||
switchText = TextManager.Get("switchtosubmarinebutton");
|
||||
purchaseAndSwitchText = TextManager.Get("purchaseandswitch");
|
||||
purchaseOnlyText = TextManager.Get("purchase");
|
||||
priceText = TextManager.Get("price");
|
||||
if (transferService)
|
||||
{
|
||||
deliveryFee = CalculateDeliveryFee();
|
||||
@@ -126,10 +128,7 @@ namespace Barotrauma
|
||||
content = new GUILayoutGroup(new RectTransform(new Point(background.Rect.Width - HUDLayoutSettings.Padding * 4, background.Rect.Height - HUDLayoutSettings.Padding * 4), background.RectTransform, Anchor.Center)) { AbsoluteSpacing = (int)(HUDLayoutSettings.Padding * 1.5f) };
|
||||
GUITextBlock header = new GUITextBlock(new RectTransform(new Vector2(1f, 0.0f), content.RectTransform), transferService ? TextManager.Get("switchsubmarineheader") : TextManager.GetWithVariable("outpostshipyard", "[location]", GameMain.GameSession.Map.CurrentLocation.Name), font: GUIStyle.LargeFont);
|
||||
header.CalculateHeightFromText(0, true);
|
||||
GUITextBlock credits = new GUITextBlock(new RectTransform(Vector2.One, header.RectTransform), "", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterRight)
|
||||
{
|
||||
TextGetter = CampaignUI.GetMoney
|
||||
};
|
||||
playerBalanceElement = CampaignUI.AddBalanceElement(header, new Vector2(1.0f, 1.5f));
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), content.RectTransform), style: "HorizontalLine");
|
||||
|
||||
@@ -257,6 +256,10 @@ namespace Barotrauma
|
||||
{
|
||||
RefreshSubmarineDisplay(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
playerBalanceElement = CampaignUI.UpdateBalanceElement(playerBalanceElement);
|
||||
}
|
||||
|
||||
// Input
|
||||
if (PlayerInput.KeyHit(Keys.Left))
|
||||
@@ -271,9 +274,22 @@ namespace Barotrauma
|
||||
|
||||
public void RefreshSubmarineDisplay(bool updateSubs)
|
||||
{
|
||||
if (!initialized) Initialize();
|
||||
if (GameMain.GraphicsWidth != createdForResolution.X || GameMain.GraphicsHeight != createdForResolution.Y) CreateGUI();
|
||||
if (updateSubs) UpdateSubmarines();
|
||||
if (!initialized)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
if (GameMain.GraphicsWidth != createdForResolution.X || GameMain.GraphicsHeight != createdForResolution.Y)
|
||||
{
|
||||
CreateGUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
playerBalanceElement = CampaignUI.UpdateBalanceElement(playerBalanceElement);
|
||||
}
|
||||
if (updateSubs)
|
||||
{
|
||||
UpdateSubmarines();
|
||||
}
|
||||
|
||||
if (pageIndicators != null)
|
||||
{
|
||||
@@ -327,12 +343,12 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
submarineDisplays[i].submarineName.Text = subToDisplay.DisplayName;
|
||||
submarineDisplays[i].submarineClass.Text = $"{TextManager.GetWithVariable("submarineclass.classsuffixformat", "[type]", TextManager.Get($"submarineclass.{subToDisplay.SubmarineClass}"))}";
|
||||
submarineDisplays[i].submarineClass.Text = TextManager.GetWithVariable("submarineclass.classsuffixformat", "[type]", TextManager.Get($"submarineclass.{subToDisplay.SubmarineClass}"));
|
||||
|
||||
if (!GameMain.GameSession.IsSubmarineOwned(subToDisplay))
|
||||
{
|
||||
LocalizedString amountString = TextManager.FormatCurrency(subToDisplay.Price);
|
||||
submarineDisplays[i].submarineFee.Text = priceText.Replace("[amount]", amountString).Replace("[currencyname]", string.Empty).TrimEnd();
|
||||
submarineDisplays[i].submarineFee.Text = TextManager.GetWithVariable("price", "[amount]", amountString);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -341,7 +357,7 @@ namespace Barotrauma
|
||||
if (deliveryFee > 0)
|
||||
{
|
||||
LocalizedString amountString = TextManager.FormatCurrency(deliveryFee);
|
||||
submarineDisplays[i].submarineFee.Text = deliveryFeeText.Replace("[amount]", amountString).Replace("[currencyname]", string.Empty).TrimEnd();
|
||||
submarineDisplays[i].submarineFee.Text = TextManager.GetWithVariable("deliveryfee", "[amount]", amountString);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -577,7 +593,7 @@ namespace Barotrauma
|
||||
|
||||
private void ShowTransferPrompt()
|
||||
{
|
||||
if (!GameMain.GameSession.Campaign.Wallet.CanAfford(deliveryFee) && deliveryFee > 0)
|
||||
if (!GameMain.GameSession.Campaign.CanAfford(deliveryFee) && deliveryFee > 0)
|
||||
{
|
||||
new GUIMessageBox(TextManager.Get("deliveryrequestheader"), TextManager.GetWithVariables("notenoughmoneyfordeliverytext",
|
||||
("[currencyname]", currencyName),
|
||||
@@ -625,7 +641,7 @@ namespace Barotrauma
|
||||
|
||||
private void ShowBuyPrompt(bool purchaseOnly)
|
||||
{
|
||||
if (!GameMain.GameSession.Campaign.Wallet.CanAfford(selectedSubmarine.Price))
|
||||
if (!GameMain.GameSession.Campaign.CanAfford(selectedSubmarine.Price))
|
||||
{
|
||||
new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("notenoughmoneyforpurchasetext",
|
||||
("[currencyname]", currencyName),
|
||||
|
||||
@@ -698,6 +698,12 @@ namespace Barotrauma
|
||||
Color = Color.Transparent
|
||||
};
|
||||
|
||||
frame.OnSecondaryClicked += (component, data) =>
|
||||
{
|
||||
NetLobbyScreen.CreateModerationContextMenu(client);
|
||||
return true;
|
||||
};
|
||||
|
||||
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.9f), frame.RectTransform, Anchor.Center), isHorizontal: true)
|
||||
{
|
||||
AbsoluteSpacing = 2
|
||||
@@ -1057,7 +1063,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
bool hasMoneyPermissions = campaign.AllowedToManageCampaign(ClientPermissions.ManageMoney);
|
||||
bool hasMoneyPermissions = CampaignMode.AllowedToManageWallets();
|
||||
salarySlider.Enabled = hasMoneyPermissions;
|
||||
Wallet otherWallet;
|
||||
|
||||
@@ -1402,6 +1408,12 @@ namespace Barotrauma
|
||||
|
||||
private void CreateMissionInfo(GUIFrame infoFrame)
|
||||
{
|
||||
if (Level.Loaded?.LevelData == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to display mission info in the tab menu (no level loaded).\n" + Environment.StackTrace);
|
||||
return;
|
||||
}
|
||||
|
||||
infoFrame.ClearChildren();
|
||||
GUIFrame missionFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
||||
int padding = (int)(0.0245f * missionFrame.Rect.Height);
|
||||
@@ -2016,7 +2028,7 @@ namespace Barotrauma
|
||||
{
|
||||
parent.Content.ClearChildren();
|
||||
List<GUITextBlock> skillNames = new List<GUITextBlock>();
|
||||
foreach (Skill skill in character.Info.Job.Skills)
|
||||
foreach (Skill skill in character.Info.Job.GetSkills())
|
||||
{
|
||||
GUILayoutGroup skillContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.2f), parent.Content.RectTransform), isHorizontal: true) { CanBeFocused = false };
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using PlayerBalanceElement = Barotrauma.CampaignUI.PlayerBalanceElement;
|
||||
|
||||
// ReSharper disable UnusedVariable
|
||||
|
||||
@@ -41,7 +42,7 @@ namespace Barotrauma
|
||||
|
||||
private readonly CampaignUI campaignUI;
|
||||
private CampaignMode? Campaign => campaignUI.Campaign;
|
||||
private Wallet PlayerWallet => Campaign?.Wallet ?? Wallet.Invalid;
|
||||
private int PlayerBalance => Campaign?.GetBalance() ?? 0;
|
||||
private UpgradeTab selectedUpgradeTab = UpgradeTab.Upgrade;
|
||||
|
||||
private GUIMessageBox? currectConfirmation;
|
||||
@@ -75,6 +76,8 @@ namespace Barotrauma
|
||||
|
||||
private bool needsRefresh = true;
|
||||
|
||||
private PlayerBalanceElement? playerBalanceElement;
|
||||
|
||||
/// <summary>
|
||||
/// While set to true any call to <see cref="RefreshUpgradeList"/> will cause the buy button to be disabled and to not update the prices.
|
||||
/// This is to prevent us from buying another upgrade before the server has given us the new prices and causing potential syncing issues.
|
||||
@@ -293,9 +296,14 @@ namespace Barotrauma
|
||||
* |---------------------------------------------------------------------------------------------------|
|
||||
*/
|
||||
GUILayoutGroup rightLayout = new GUILayoutGroup(rectT(0.5f, 1, topHeaderLayout), childAnchor: Anchor.TopRight);
|
||||
GUILayoutGroup priceLayout = new GUILayoutGroup(rectT(1, 0.8f, rightLayout), childAnchor: Anchor.Center) { RelativeSpacing = 0.08f };
|
||||
new GUITextBlock(rectT(1f, 0f, priceLayout), TextManager.Get("CampaignStore.Balance"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right);
|
||||
new GUITextBlock(rectT(1f, 0f, priceLayout), TextManager.FormatCurrency(PlayerWallet.Balance), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right) { TextGetter = () => TextManager.FormatCurrency(PlayerWallet.Balance) };
|
||||
playerBalanceElement = CampaignUI.AddBalanceElement(rightLayout, new Vector2(1.0f, 0.8f));
|
||||
if (playerBalanceElement is { } balanceElement)
|
||||
{
|
||||
balanceElement.TotalBalanceContainer.OnAddedToGUIUpdateList += (_) =>
|
||||
{
|
||||
playerBalanceElement = CampaignUI.UpdateBalanceElement(playerBalanceElement);
|
||||
};
|
||||
}
|
||||
new GUIFrame(rectT(0.5f, 0.1f, rightLayout, Anchor.BottomRight), style: "HorizontalLine") { IgnoreLayoutGroups = true };
|
||||
|
||||
repairButton.OnClicked = upgradeButton.OnClicked = (button, o) =>
|
||||
@@ -435,14 +443,14 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PlayerWallet.CanAfford(hullRepairCost))
|
||||
if (PlayerBalance >= hullRepairCost)
|
||||
{
|
||||
LocalizedString body = TextManager.GetWithVariable("WallRepairs.PurchasePromptBody", "[amount]", hullRepairCost.ToString());
|
||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
|
||||
{
|
||||
if (PlayerWallet.Balance >= hullRepairCost)
|
||||
if (PlayerBalance >= hullRepairCost)
|
||||
{
|
||||
PlayerWallet.TryDeduct(hullRepairCost);
|
||||
Campaign.TryPurchase(null, hullRepairCost);
|
||||
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "hullrepairs");
|
||||
Campaign.PurchasedHullRepairs = true;
|
||||
button.Enabled = false;
|
||||
@@ -470,14 +478,14 @@ namespace Barotrauma
|
||||
|
||||
CreateRepairEntry(currentStoreLayout.Content, TextManager.Get("repairallitems"), "RepairItemsButton", itemRepairCost, (button, o) =>
|
||||
{
|
||||
if (PlayerWallet.Balance >= itemRepairCost && !Campaign.PurchasedItemRepairs)
|
||||
if (PlayerBalance >= itemRepairCost && !Campaign.PurchasedItemRepairs)
|
||||
{
|
||||
LocalizedString body = TextManager.GetWithVariable("ItemRepairs.PurchasePromptBody", "[amount]", itemRepairCost.ToString());
|
||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
|
||||
{
|
||||
if (PlayerWallet.Balance >= itemRepairCost && !Campaign.PurchasedItemRepairs)
|
||||
if (PlayerBalance >= itemRepairCost && !Campaign.PurchasedItemRepairs)
|
||||
{
|
||||
PlayerWallet.TryDeduct(itemRepairCost);
|
||||
Campaign.TryPurchase(null, itemRepairCost);
|
||||
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "devicerepairs");
|
||||
Campaign.PurchasedItemRepairs = true;
|
||||
button.Enabled = false;
|
||||
@@ -516,14 +524,14 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PlayerWallet.CanAfford(shuttleRetrieveCost) && !Campaign.PurchasedLostShuttles)
|
||||
if (PlayerBalance >= shuttleRetrieveCost && !Campaign.PurchasedLostShuttles)
|
||||
{
|
||||
LocalizedString body = TextManager.GetWithVariable("ReplaceLostShuttles.PurchasePromptBody", "[amount]", shuttleRetrieveCost.ToString());
|
||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
|
||||
{
|
||||
if (PlayerWallet.Balance >= shuttleRetrieveCost && !Campaign.PurchasedLostShuttles)
|
||||
if (PlayerBalance >= shuttleRetrieveCost && !Campaign.PurchasedLostShuttles)
|
||||
{
|
||||
PlayerWallet.TryDeduct(shuttleRetrieveCost);
|
||||
Campaign.TryPurchase(null, shuttleRetrieveCost);
|
||||
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "retrieveshuttle");
|
||||
Campaign.PurchasedLostShuttles = true;
|
||||
button.Enabled = false;
|
||||
@@ -581,13 +589,13 @@ namespace Barotrauma
|
||||
new GUITextBlock(rectT(1, 0, textLayout), title, font: GUIStyle.SubHeadingFont) { CanBeFocused = false, AutoScaleHorizontal = true };
|
||||
new GUITextBlock(rectT(1, 0, textLayout), TextManager.FormatCurrency(price));
|
||||
GUILayoutGroup buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, contentLayout), childAnchor: Anchor.Center) { UserData = "buybutton" };
|
||||
new GUIButton(rectT(0.7f, 0.5f, buyButtonLayout), string.Empty, style: "RepairBuyButton") { ClickSound = GUISoundType.HireRepairClick, Enabled = PlayerWallet.Balance >= price && !isDisabled, OnClicked = onPressed };
|
||||
new GUIButton(rectT(0.7f, 0.5f, buyButtonLayout), string.Empty, style: "RepairBuyButton") { ClickSound = GUISoundType.HireRepairClick, Enabled = PlayerBalance >= price && !isDisabled, OnClicked = onPressed };
|
||||
contentLayout.Recalculate();
|
||||
buyButtonLayout.Recalculate();
|
||||
|
||||
if (disableElement)
|
||||
{
|
||||
frameChild.Enabled = PlayerWallet.Balance >= price && !isDisabled;
|
||||
frameChild.Enabled = PlayerBalance >= price && !isDisabled;
|
||||
}
|
||||
|
||||
if (!HasPermission)
|
||||
@@ -972,7 +980,7 @@ namespace Barotrauma
|
||||
buttonStyle: isPurchased ? "WeaponInstallButton" : "StoreAddToCrateButton"));
|
||||
|
||||
if (!(frames.Last().FindChild(c => c is GUIButton, recursive: true) is GUIButton buyButton)) { continue; }
|
||||
if (PlayerWallet.CanAfford(price))
|
||||
if (PlayerBalance >= price)
|
||||
{
|
||||
buyButton.Enabled = true;
|
||||
buyButton.OnClicked += (button, o) =>
|
||||
@@ -1602,7 +1610,7 @@ namespace Barotrauma
|
||||
if (button != null)
|
||||
{
|
||||
button.Enabled = currentLevel < prefab.MaxLevel;
|
||||
if (WaitForServerUpdate || !campaign.Wallet.CanAfford(price))
|
||||
if (WaitForServerUpdate || campaign.GetBalance() < price)
|
||||
{
|
||||
button.Enabled = false;
|
||||
}
|
||||
|
||||
@@ -671,6 +671,8 @@ namespace Barotrauma
|
||||
if (!TitleScreen.PlayingSplashScreen)
|
||||
{
|
||||
SoundPlayer.Update((float)Timing.Step);
|
||||
GUI.ClearUpdateList();
|
||||
GUI.UpdateGUIMessageBoxesOnly((float)Timing.Step);
|
||||
}
|
||||
|
||||
if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen &&
|
||||
@@ -1117,10 +1119,10 @@ namespace Barotrauma
|
||||
var msgBox = new GUIMessageBox(TextManager.Get("EditorDisclaimerTitle"), TextManager.Get("EditorDisclaimerText"));
|
||||
var linkHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), msgBox.Content.RectTransform)) { Stretch = true, RelativeSpacing = 0.025f };
|
||||
linkHolder.RectTransform.MaxSize = new Point(int.MaxValue, linkHolder.Rect.Height);
|
||||
List<(LocalizedString Caption, LocalizedString Url)> links = new List<(LocalizedString, LocalizedString)>()
|
||||
List<(LocalizedString Caption, string Url)> links = new List<(LocalizedString, string)>()
|
||||
{
|
||||
(TextManager.Get("EditorDisclaimerWikiLink"), TextManager.Get("EditorDisclaimerWikiUrl")),
|
||||
(TextManager.Get("EditorDisclaimerDiscordLink"), TextManager.Get("EditorDisclaimerDiscordUrl")),
|
||||
(TextManager.Get("EditorDisclaimerWikiLink"), TextManager.Get("EditorDisclaimerWikiUrl").Fallback("https://barotraumagame.com/wiki").Value),
|
||||
(TextManager.Get("EditorDisclaimerDiscordLink"), TextManager.Get("EditorDisclaimerDiscordUrl").Fallback("https://discordapp.com/invite/undertow").Value),
|
||||
};
|
||||
foreach (var link in links)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -28,6 +29,8 @@ namespace Barotrauma
|
||||
protected GUIFrame campaignUIContainer;
|
||||
public CampaignUI CampaignUI;
|
||||
|
||||
public static CancellationTokenSource StartRoundCancellationToken { get; private set; }
|
||||
|
||||
public bool ForceMapUI
|
||||
{
|
||||
get;
|
||||
@@ -99,6 +102,16 @@ namespace Barotrauma
|
||||
GameMain.Client.ConnectedClients.None(c => c.InGame && (c.IsOwner || c.HasPermission(permissions)));
|
||||
}
|
||||
|
||||
public static bool AllowedToManageWallets()
|
||||
{
|
||||
if (GameMain.Client == null) { return true; }
|
||||
|
||||
return
|
||||
GameMain.Client.HasPermission(ClientPermissions.ManageMoney) ||
|
||||
GameMain.Client.HasPermission(ClientPermissions.ManageCampaign) ||
|
||||
GameMain.Client.IsServerOwner;
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (overlayColor.A > 0)
|
||||
@@ -245,10 +258,11 @@ namespace Barotrauma
|
||||
|
||||
GUI.ClearCursorWait();
|
||||
|
||||
StartRoundCancellationToken = new CancellationTokenSource();
|
||||
var loadTask = Task.Run(async () =>
|
||||
{
|
||||
await Task.Yield();
|
||||
Rand.ThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
|
||||
Rand.ThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
try
|
||||
{
|
||||
GameMain.GameSession.StartRound(newLevel, mirrorLevel: mirror);
|
||||
@@ -258,7 +272,7 @@ namespace Barotrauma
|
||||
roundSummaryScreen.LoadException = e;
|
||||
}
|
||||
Rand.ThreadId = 0;
|
||||
});
|
||||
}, StartRoundCancellationToken.Token);
|
||||
TaskPool.Add("AsyncCampaignStartRound", loadTask, (t) =>
|
||||
{
|
||||
overlayColor = Color.Transparent;
|
||||
|
||||
@@ -37,6 +37,16 @@ namespace Barotrauma
|
||||
public Wallet PersonalWallet => Character.Controlled?.Wallet ?? Wallet.Invalid;
|
||||
public override Wallet Wallet => GetWallet();
|
||||
|
||||
public override int GetBalance(Client client = null)
|
||||
{
|
||||
if (!AllowedToManageWallets())
|
||||
{
|
||||
return PersonalWallet.Balance;
|
||||
}
|
||||
|
||||
return PersonalWallet.Balance + Bank.Balance;
|
||||
}
|
||||
|
||||
public override Wallet GetWallet(Client client = null)
|
||||
{
|
||||
return PersonalWallet;
|
||||
@@ -913,6 +923,31 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public override bool TryPurchase(Client client, int price)
|
||||
{
|
||||
if (!AllowedToManageCampaign(ClientPermissions.ManageCampaign))
|
||||
{
|
||||
return PersonalWallet.TryDeduct(price);
|
||||
}
|
||||
|
||||
int balance = PersonalWallet.Balance;
|
||||
|
||||
if (balance >= price)
|
||||
{
|
||||
return PersonalWallet.TryDeduct(price);
|
||||
}
|
||||
|
||||
if (balance + Bank.Balance >= price)
|
||||
{
|
||||
int remainder = price - balance;
|
||||
if (balance > 0) { PersonalWallet.Deduct(balance); }
|
||||
Bank.Deduct(remainder);
|
||||
return true ;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Save(XElement element)
|
||||
{
|
||||
//do nothing, the clients get the save files from the server
|
||||
|
||||
@@ -56,10 +56,9 @@ namespace Barotrauma.Items.Components
|
||||
ContentXElement spriteElement = limbElement.GetChildElement("sprite");
|
||||
if (spriteElement == null) { continue; }
|
||||
|
||||
string spritePath = spriteElement.GetAttribute("texture").Value;
|
||||
|
||||
spritePath = characterInfo.ReplaceVars(spritePath);
|
||||
ContentPath contentPath = spriteElement.GetAttributeContentPath("texture");
|
||||
|
||||
string spritePath = characterInfo.ReplaceVars(contentPath.Value);
|
||||
string fileName = Path.GetFileNameWithoutExtension(spritePath);
|
||||
|
||||
//go through the files in the directory to find a matching sprite
|
||||
|
||||
@@ -584,19 +584,16 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
availableCharge = 0.0f;
|
||||
availableCapacity = 0.0f;
|
||||
if (item.Connections == null) { return; }
|
||||
foreach (Connection c in item.Connections)
|
||||
if (item.Connections == null || powerIn == null) { return; }
|
||||
var recipients = powerIn.Recipients;
|
||||
foreach (Connection recipient in recipients)
|
||||
{
|
||||
var recipients = c.Recipients;
|
||||
foreach (Connection recipient in recipients)
|
||||
{
|
||||
if (!recipient.IsPower || !recipient.IsOutput) { continue; }
|
||||
var battery = recipient.Item?.GetComponent<PowerContainer>();
|
||||
if (battery == null) { continue; }
|
||||
availableCharge += battery.Charge;
|
||||
availableCapacity += battery.Capacity;
|
||||
}
|
||||
}
|
||||
if (!recipient.IsPower || !recipient.IsOutput) { continue; }
|
||||
var battery = recipient.Item?.GetComponent<PowerContainer>();
|
||||
if (battery == null || battery.Item.Condition <= 0.0f) { continue; }
|
||||
availableCharge += battery.Charge;
|
||||
availableCapacity += battery.Capacity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -273,10 +273,16 @@ namespace Barotrauma
|
||||
foreach (string tag in readTags)
|
||||
{
|
||||
string[] s = tag.Split(':');
|
||||
if (s[0] == "name")
|
||||
idName = s[1];
|
||||
if (s[0] == "job")
|
||||
idJob = s[1];
|
||||
switch (s[0])
|
||||
{
|
||||
case "name":
|
||||
idName = s[1];
|
||||
break;
|
||||
case "job":
|
||||
case "jobid":
|
||||
idJob = s[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idName != null)
|
||||
{
|
||||
|
||||
@@ -1550,9 +1550,10 @@ namespace Barotrauma
|
||||
|
||||
DebugConsole.Log($"Received entity spawn message for item \"{itemName}\" (identifier: {itemIdentifier}, id: {itemId})");
|
||||
|
||||
var itemPrefab = string.IsNullOrEmpty(itemIdentifier) ?
|
||||
MapEntityPrefab.Find(itemName, null, showErrorMessages: false) as ItemPrefab :
|
||||
MapEntityPrefab.Find(itemName, itemIdentifier, showErrorMessages: false) as ItemPrefab;
|
||||
ItemPrefab itemPrefab =
|
||||
string.IsNullOrEmpty(itemIdentifier) ?
|
||||
ItemPrefab.Find(itemName, Identifier.Empty) :
|
||||
ItemPrefab.Find(itemName, itemIdentifier.ToIdentifier());
|
||||
|
||||
Vector2 pos = Vector2.Zero;
|
||||
Submarine sub = null;
|
||||
|
||||
@@ -18,8 +18,8 @@ namespace Barotrauma
|
||||
|
||||
foreach ((Identifier identifier, Rectangle rect) in DisplayEntities)
|
||||
{
|
||||
var entityPrefab = MapEntityPrefab.FindByIdentifier(identifier);
|
||||
if (entityPrefab is CoreEntityPrefab) { continue; }
|
||||
var entityPrefab = FindByIdentifier(identifier);
|
||||
if (entityPrefab is CoreEntityPrefab || entityPrefab == null) { continue; }
|
||||
var drawRect = new Rectangle(
|
||||
(int)(rect.X * scale) + drawArea.Center.X, (int)((rect.Y) * scale) - drawArea.Center.Y,
|
||||
(int)(rect.Width * scale), (int)(rect.Height * scale));
|
||||
@@ -32,11 +32,10 @@ namespace Barotrauma
|
||||
base.DrawPlacing(spriteBatch, cam);
|
||||
foreach ((Identifier identifier, Rectangle rect) in DisplayEntities)
|
||||
{
|
||||
var entityPrefab = MapEntityPrefab.Find(p => p.Identifier == identifier);
|
||||
var entityPrefab = FindByIdentifier(identifier);
|
||||
if (entityPrefab == null) { continue; }
|
||||
Rectangle drawRect = rect;
|
||||
|
||||
drawRect.Location += placePosition != Vector2.Zero ? placePosition.ToPoint() : Submarine.MouseToWorldGrid(cam, Submarine.MainSub).ToPoint();
|
||||
|
||||
drawRect.Location += placePosition != Vector2.Zero ? placePosition.ToPoint() : Submarine.MouseToWorldGrid(cam, Submarine.MainSub).ToPoint();
|
||||
entityPrefab.DrawPlacing(spriteBatch, drawRect, entityPrefab.Scale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using Barotrauma.IO;
|
||||
using System;
|
||||
using Barotrauma.IO;
|
||||
using Barotrauma.Items.Components;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -107,6 +109,25 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
var pathContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.2f), paddedFrame.RectTransform), isHorizontal: true);
|
||||
|
||||
string filePath = this.filePath;
|
||||
if (filePath.StartsWith("Submarines"))
|
||||
{
|
||||
//this is the old submarines path, try to find a local mod that has a submarine with this name
|
||||
string subName = Path.GetFileNameWithoutExtension(filePath);
|
||||
string foundPath = ContentPackageManager.LocalPackages.Concat(ContentPackageManager.VanillaCorePackage.ToEnumerable())
|
||||
.SelectMany(p => p.GetFiles<SubmarineFile>())
|
||||
.FirstOrDefault(f => Path.GetFileNameWithoutExtension(f.Path.Value).Equals(subName, StringComparison.OrdinalIgnoreCase))
|
||||
?.Path.Value;
|
||||
if (foundPath.IsNullOrEmpty())
|
||||
{
|
||||
//no such sub found among the local mods, just guess the correct path
|
||||
foundPath = Path.Combine(ContentPackage.LocalModsDir, subName, $"{subName}.sub");
|
||||
}
|
||||
|
||||
filePath = foundPath;
|
||||
}
|
||||
|
||||
var pathBox = new GUITextBox(new RectTransform(new Vector2(0.75f, 1.0f), pathContainer.RectTransform), filePath, font: GUIStyle.SmallFont);
|
||||
var reloadButton = new GUIButton(new RectTransform(new Vector2(0.25f / pathBox.RectTransform.RelativeSize.X, 1.0f), pathBox.RectTransform, Anchor.CenterRight, Pivot.CenterLeft),
|
||||
TextManager.Get("ReloadLinkedSub"), style: "GUIButtonSmall")
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Barotrauma
|
||||
visibleSubs.Clear();
|
||||
foreach (Submarine sub in Loaded)
|
||||
{
|
||||
if (sub.WorldPosition.Y < Level.MaxEntityDepth) { continue; }
|
||||
if (Level.Loaded != null && sub.WorldPosition.Y < Level.MaxEntityDepth) { continue; }
|
||||
|
||||
int margin = 500;
|
||||
Rectangle worldBorders = new Rectangle(
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Barotrauma.Networking
|
||||
VoipSound = null;
|
||||
}
|
||||
|
||||
public void SetPermissions(ClientPermissions permissions, List<string> permittedConsoleCommands)
|
||||
public void SetPermissions(ClientPermissions permissions, IEnumerable<string> permittedConsoleCommands)
|
||||
{
|
||||
List<DebugConsole.Command> permittedCommands = new List<DebugConsole.Command>();
|
||||
foreach (string commandName in permittedConsoleCommands)
|
||||
@@ -92,14 +92,18 @@ namespace Barotrauma.Networking
|
||||
SetPermissions(permissions, permittedCommands);
|
||||
}
|
||||
|
||||
public void SetPermissions(ClientPermissions permissions, List<DebugConsole.Command> permittedConsoleCommands)
|
||||
public void SetPermissions(ClientPermissions permissions, IEnumerable<DebugConsole.Command> permittedConsoleCommands)
|
||||
{
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Permissions = permissions;
|
||||
PermittedConsoleCommands.Clear(); PermittedConsoleCommands.AddRange(permittedConsoleCommands);
|
||||
PermittedConsoleCommands.Clear();
|
||||
foreach (var command in permittedConsoleCommands)
|
||||
{
|
||||
PermittedConsoleCommands.Add(command);
|
||||
}
|
||||
}
|
||||
|
||||
public void GivePermission(ClientPermissions permission)
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using Barotrauma.Networking;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class EntitySpawner : Entity, IServerSerializable
|
||||
{
|
||||
public readonly List<(Entity entity, bool isRemoval)> receivedEvents = new List<(Entity entity, bool isRemoval)>();
|
||||
|
||||
public void ClientEventRead(IReadMessage message, float sendingTime)
|
||||
{
|
||||
bool remove = message.ReadBoolean();
|
||||
@@ -12,7 +15,6 @@ namespace Barotrauma
|
||||
if (remove)
|
||||
{
|
||||
ushort entityId = message.ReadUInt16();
|
||||
|
||||
var entity = FindEntityByID(entityId);
|
||||
if (entity != null)
|
||||
{
|
||||
@@ -27,6 +29,7 @@ namespace Barotrauma
|
||||
{
|
||||
DebugConsole.Log("Received entity removal message for ID " + entityId + ". Entity with a matching ID not found.");
|
||||
}
|
||||
receivedEvents.Add((entity, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -34,13 +37,29 @@ namespace Barotrauma
|
||||
{
|
||||
case (byte)SpawnableType.Item:
|
||||
var newItem = Item.ReadSpawnData(message, true);
|
||||
if (newItem is Item item && item.Container?.GetComponent<Fabricator>() != null)
|
||||
if (newItem == null)
|
||||
{
|
||||
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none".ToIdentifier()) + ":" + item.Prefab.Identifier);
|
||||
DebugConsole.ThrowError("Received an item spawn message, but spawning the item failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (newItem.Container?.GetComponent<Fabricator>() != null)
|
||||
{
|
||||
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none".ToIdentifier()) + ":" + newItem.Prefab.Identifier);
|
||||
}
|
||||
receivedEvents.Add((newItem, false));
|
||||
}
|
||||
break;
|
||||
case (byte)SpawnableType.Character:
|
||||
Character.ReadSpawnData(message);
|
||||
var character = Character.ReadSpawnData(message);
|
||||
if (character == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Received character spawn message, but spawning the character failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
receivedEvents.Add((character, false));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DebugConsole.ThrowError("Received invalid entity spawn message (unknown spawnable type)");
|
||||
|
||||
@@ -79,13 +79,14 @@ namespace Barotrauma.Networking
|
||||
Starting,
|
||||
WaitingForStartGameFinalize,
|
||||
Started,
|
||||
TimedOut,
|
||||
Error,
|
||||
Interrupted
|
||||
}
|
||||
|
||||
private RoundInitStatus roundInitStatus = RoundInitStatus.NotStarted;
|
||||
|
||||
public bool RoundStarting => roundInitStatus == RoundInitStatus.Starting || roundInitStatus == RoundInitStatus.WaitingForStartGameFinalize;
|
||||
|
||||
private byte myID;
|
||||
|
||||
private readonly List<Client> otherClients;
|
||||
@@ -692,11 +693,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
GameMain.LuaCs.Networking.NetMessageReceived(inc, header);
|
||||
|
||||
if (roundInitStatus != RoundInitStatus.Started &&
|
||||
roundInitStatus != RoundInitStatus.NotStarted &&
|
||||
roundInitStatus != RoundInitStatus.Error &&
|
||||
roundInitStatus != RoundInitStatus.Interrupted &&
|
||||
header != ServerPacketHeader.STARTGAMEFINALIZE &&
|
||||
if (roundInitStatus == RoundInitStatus.WaitingForStartGameFinalize &&
|
||||
roundInitStatus == RoundInitStatus.Started &&
|
||||
header != ServerPacketHeader.ENDGAME &&
|
||||
header != ServerPacketHeader.PING_REQUEST &&
|
||||
header != ServerPacketHeader.FILE_TRANSFER)
|
||||
@@ -1688,12 +1686,15 @@ namespace Barotrauma.Networking
|
||||
roundInitStatus = RoundInitStatus.WaitingForStartGameFinalize;
|
||||
|
||||
DateTime? timeOut = null;
|
||||
TimeSpan timeOutDuration = new TimeSpan(0, 0, seconds: 30);
|
||||
DateTime requestFinalizeTime = DateTime.Now;
|
||||
TimeSpan requestFinalizeInterval = new TimeSpan(0, 0, 2);
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ClientPacketHeader.REQUEST_STARTGAMEFINALIZE);
|
||||
clientPeer.Send(msg, DeliveryMethod.Unreliable);
|
||||
|
||||
GUIMessageBox interruptPrompt = null;
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
@@ -1707,11 +1708,30 @@ namespace Barotrauma.Networking
|
||||
clientPeer.Send(msg, DeliveryMethod.Unreliable);
|
||||
requestFinalizeTime = DateTime.Now + requestFinalizeInterval;
|
||||
}
|
||||
if (DateTime.Now > timeOut)
|
||||
if (DateTime.Now > timeOut && interruptPrompt == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while starting the round (did not receive STARTGAMEFINALIZE message from the server). Stopping the round...");
|
||||
roundInitStatus = RoundInitStatus.TimedOut;
|
||||
break;
|
||||
interruptPrompt = new GUIMessageBox(string.Empty, TextManager.Get("WaitingForStartGameFinalizeTakingTooLong"),
|
||||
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") })
|
||||
{
|
||||
DisplayInLoadingScreens = true
|
||||
};
|
||||
interruptPrompt.Buttons[0].OnClicked += (btn, userData) =>
|
||||
{
|
||||
roundInitStatus = RoundInitStatus.Interrupted;
|
||||
DebugConsole.ThrowError("Error while starting the round (did not receive STARTGAMEFINALIZE message from the server). Returning to the lobby...");
|
||||
gameStarted = true;
|
||||
GameMain.NetLobbyScreen.Select();
|
||||
interruptPrompt.Close();
|
||||
interruptPrompt = null;
|
||||
return true;
|
||||
};
|
||||
interruptPrompt.Buttons[1].OnClicked += (btn, userData) =>
|
||||
{
|
||||
timeOut = DateTime.Now + timeOutDuration;
|
||||
interruptPrompt.Close();
|
||||
interruptPrompt = null;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1723,7 +1743,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
//wait for up to 30 seconds for the server to send the STARTGAMEFINALIZE message
|
||||
timeOut = DateTime.Now + new TimeSpan(0, 0, seconds: 30);
|
||||
timeOut = DateTime.Now + timeOutDuration;
|
||||
}
|
||||
|
||||
if (!connected)
|
||||
@@ -1745,6 +1765,9 @@ namespace Barotrauma.Networking
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
interruptPrompt?.Close();
|
||||
interruptPrompt = null;
|
||||
|
||||
if (roundInitStatus != RoundInitStatus.Started)
|
||||
{
|
||||
if (roundInitStatus != RoundInitStatus.Interrupted)
|
||||
@@ -2713,6 +2736,8 @@ namespace Barotrauma.Networking
|
||||
SteamManager.LeaveLobby();
|
||||
}
|
||||
|
||||
CampaignMode.StartRoundCancellationToken?.Cancel();
|
||||
|
||||
clientPeer?.Close();
|
||||
clientPeer = null;
|
||||
|
||||
@@ -3098,7 +3123,31 @@ namespace Barotrauma.Networking
|
||||
|
||||
protected GUIFrame inGameHUD;
|
||||
protected ChatBox chatBox;
|
||||
|
||||
public GUIButton ShowLogButton; //TODO: move to NetLobbyScreen
|
||||
private bool hasPermissionToUseLogButton;
|
||||
|
||||
public void UpdateLogButtonPermissions()
|
||||
{
|
||||
hasPermissionToUseLogButton = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
||||
UpdateLogButtonVisibility();
|
||||
}
|
||||
|
||||
private void UpdateLogButtonVisibility()
|
||||
{
|
||||
if (ShowLogButton != null)
|
||||
{
|
||||
if (Screen.Selected != GameMain.GameScreen)
|
||||
{
|
||||
ShowLogButton.Visible = hasPermissionToUseLogButton;
|
||||
}
|
||||
else
|
||||
{
|
||||
var campaign = GameMain.GameSession?.Campaign;
|
||||
ShowLogButton.Visible = hasPermissionToUseLogButton && (campaign == null || !campaign.ShowCampaignUI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GUIFrame InGameHUD
|
||||
{
|
||||
@@ -3178,6 +3227,8 @@ namespace Barotrauma.Networking
|
||||
msgBox = GameMain.NetLobbyScreen.ChatInput;
|
||||
}
|
||||
|
||||
UpdateLogButtonVisibility();
|
||||
|
||||
if (gameStarted && Screen.Selected == GameMain.GameScreen)
|
||||
{
|
||||
var controller = Character.Controlled?.SelectedConstruction?.GetComponent<Controller>();
|
||||
@@ -3653,6 +3704,19 @@ namespace Barotrauma.Networking
|
||||
errorLines.Add(e.ErrorLine);
|
||||
}
|
||||
|
||||
if (Entity.Spawner != null)
|
||||
{
|
||||
errorLines.Add("");
|
||||
errorLines.Add("EntitySpawner events:");
|
||||
foreach ((Entity entity, bool isRemoval) in Entity.Spawner.receivedEvents)
|
||||
{
|
||||
errorLines.Add(
|
||||
(isRemoval ? "Remove " : "Create ") +
|
||||
entity.ToString() +
|
||||
" (" + entity.ID + ")");
|
||||
}
|
||||
}
|
||||
|
||||
errorLines.Add("");
|
||||
errorLines.Add("Last debug messages:");
|
||||
for (int i = DebugConsole.Messages.Count - 1; i > 0 && i > DebugConsole.Messages.Count - 15; i--)
|
||||
|
||||
+4
-1
@@ -153,7 +153,10 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (!isActive) { return; }
|
||||
|
||||
timeout -= deltaTime;
|
||||
if (GameMain.Client == null || !GameMain.Client.RoundStarting)
|
||||
{
|
||||
timeout -= deltaTime;
|
||||
}
|
||||
heartbeatTimer -= deltaTime;
|
||||
|
||||
if (initializationStep != ConnectionInitialization.Password &&
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Campaign.Wallet.TryDeduct(CampaignMode.HullRepairCost))
|
||||
if (Campaign.TryPurchase(null, CampaignMode.HullRepairCost))
|
||||
{
|
||||
GameAnalyticsManager.AddMoneySpentEvent(CampaignMode.HullRepairCost, GameAnalyticsManager.MoneySink.Service, "hullrepairs");
|
||||
Campaign.PurchasedHullRepairs = true;
|
||||
@@ -194,7 +194,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Campaign.Wallet.TryDeduct(CampaignMode.ItemRepairCost))
|
||||
if (Campaign.TryPurchase(null, CampaignMode.ItemRepairCost))
|
||||
{
|
||||
GameAnalyticsManager.AddMoneySpentEvent(CampaignMode.ItemRepairCost, GameAnalyticsManager.MoneySink.Service, "devicerepairs");
|
||||
Campaign.PurchasedItemRepairs = true;
|
||||
@@ -246,7 +246,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Campaign.Wallet.TryDeduct(CampaignMode.ShuttleReplaceCost))
|
||||
if (Campaign.TryPurchase(null, CampaignMode.ShuttleReplaceCost))
|
||||
{
|
||||
GameAnalyticsManager.AddMoneySpentEvent(CampaignMode.ShuttleReplaceCost, GameAnalyticsManager.MoneySink.Service, "retrieveshuttle");
|
||||
Campaign.PurchasedLostShuttles = true;
|
||||
@@ -736,12 +736,115 @@ namespace Barotrauma
|
||||
|
||||
public static LocalizedString GetMoney()
|
||||
{
|
||||
return TextManager.GetWithVariable("PlayerCredits", "[credits]", (GameMain.GameSession?.Campaign == null) ? "0" : string.Format(CultureInfo.InvariantCulture, "{0:N0}", GameMain.GameSession.Campaign.Wallet.Balance));
|
||||
return TextManager.GetWithVariable("PlayerCredits", "[credits]", (GameMain.GameSession?.Campaign == null) ? "0" : string.Format(CultureInfo.InvariantCulture, "{0:N0}", GameMain.GameSession.Campaign.GetBalance()));
|
||||
}
|
||||
|
||||
public static LocalizedString GetTotalBalance()
|
||||
{
|
||||
return TextManager.FormatCurrency(GameMain.GameSession?.Campaign is { } campaign ? campaign.GetBalance() : 0);
|
||||
}
|
||||
|
||||
public static LocalizedString GetBankBalance()
|
||||
{
|
||||
return TextManager.FormatCurrency(GameMain.GameSession?.Campaign is { } campaign ? campaign.Bank.Balance : 0);
|
||||
}
|
||||
|
||||
public static LocalizedString GetWalletBalance()
|
||||
{
|
||||
return TextManager.FormatCurrency(GameMain.GameSession?.Campaign is { } campaign ? campaign.Wallet.Balance : 0);
|
||||
}
|
||||
|
||||
private void UpdateMaxMissions(Location location)
|
||||
{
|
||||
hasMaxMissions = Campaign.NumberOfMissionsAtLocation(location) >= Campaign.Settings.TotalMaxMissionCount;
|
||||
}
|
||||
|
||||
public readonly struct PlayerBalanceElement
|
||||
{
|
||||
public readonly bool DisplaySeparateBalances;
|
||||
public readonly GUILayoutGroup ParentComponent;
|
||||
public readonly GUILayoutGroup TotalBalanceContainer;
|
||||
public readonly GUILayoutGroup BankBalanceContainer;
|
||||
|
||||
public PlayerBalanceElement(bool displaySeparateBalances, GUILayoutGroup parentComponent, GUILayoutGroup totalBalanceContainer, GUILayoutGroup bankBalanceContainer)
|
||||
{
|
||||
DisplaySeparateBalances = displaySeparateBalances;
|
||||
ParentComponent = parentComponent;
|
||||
TotalBalanceContainer = totalBalanceContainer;
|
||||
BankBalanceContainer = bankBalanceContainer;
|
||||
}
|
||||
|
||||
public PlayerBalanceElement(PlayerBalanceElement element, bool displaySeparateBalances)
|
||||
{
|
||||
DisplaySeparateBalances = displaySeparateBalances;
|
||||
ParentComponent = element.ParentComponent;
|
||||
TotalBalanceContainer = element.TotalBalanceContainer;
|
||||
BankBalanceContainer = element.BankBalanceContainer;
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerBalanceElement? AddBalanceElement(GUIComponent elementParent, Vector2 relativeSize)
|
||||
{
|
||||
var parent = new GUILayoutGroup(new RectTransform(relativeSize, elementParent.RectTransform), isHorizontal: true, childAnchor: Anchor.TopRight);
|
||||
if (GameMain.IsSingleplayer)
|
||||
{
|
||||
AddBalance(parent, true, TextManager.Get("campaignstore.balance"), GetTotalBalance);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool displaySeparateBalances = CampaignMode.AllowedToManageWallets();
|
||||
var totalBalanceContainer = AddBalance(parent, displaySeparateBalances, TextManager.Get("campaignstore.total"), GetTotalBalance);
|
||||
var bankBalanceContainer = AddBalance(parent, displaySeparateBalances, TextManager.Get("crewwallet.bank"), GetBankBalance);
|
||||
AddBalance(parent, true, TextManager.Get("crewwallet.wallet"), GetWalletBalance);
|
||||
var playerBalanceElement = new PlayerBalanceElement(displaySeparateBalances, parent, totalBalanceContainer, bankBalanceContainer);
|
||||
parent.Recalculate();
|
||||
return playerBalanceElement;
|
||||
}
|
||||
|
||||
static GUILayoutGroup AddBalance(GUIComponent parent, bool visible, LocalizedString text, GUITextBlock.TextGetterHandler textGetter)
|
||||
{
|
||||
float balanceContainerWidth = GameMain.IsSingleplayer ? 1 : 1 / 3f;
|
||||
var rt = new RectTransform(new Vector2(balanceContainerWidth, 1.0f), parent.RectTransform)
|
||||
{
|
||||
MaxSize = new Point(GUI.IntScale(GUI.AdjustForTextScale(120)), int.MaxValue)
|
||||
};
|
||||
var balanceContainer = new GUILayoutGroup(rt, childAnchor: Anchor.TopRight)
|
||||
{
|
||||
RelativeSpacing = 0.005f,
|
||||
Visible = visible
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), balanceContainer.RectTransform), text,
|
||||
font: GUIStyle.Font, textAlignment: Alignment.BottomRight)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
ForceUpperCase = ForceUpperCase.Yes
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), balanceContainer.RectTransform), "",
|
||||
textColor: Color.White, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.TopRight)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
TextScale = 1.1f,
|
||||
TextGetter = textGetter
|
||||
};
|
||||
return balanceContainer;
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerBalanceElement? UpdateBalanceElement(PlayerBalanceElement? playerBalanceElement)
|
||||
{
|
||||
if (playerBalanceElement is { } balanceElement)
|
||||
{
|
||||
bool displaySeparateBalances = CampaignMode.AllowedToManageWallets();
|
||||
if (displaySeparateBalances != balanceElement.DisplaySeparateBalances)
|
||||
{
|
||||
balanceElement.TotalBalanceContainer.Visible = displaySeparateBalances;
|
||||
balanceElement.BankBalanceContainer.Visible = displaySeparateBalances;
|
||||
playerBalanceElement = new PlayerBalanceElement(balanceElement, displaySeparateBalances);
|
||||
balanceElement.ParentComponent.Recalculate();
|
||||
}
|
||||
}
|
||||
return playerBalanceElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -966,7 +966,15 @@ namespace Barotrauma
|
||||
{
|
||||
OnClicked = (_, __) =>
|
||||
{
|
||||
GameMain.Client?.RequestSelectMode(ModeList.Content.GetChildIndex(ModeList.Content.GetChildByUserData(GameModePreset.Sandbox)));
|
||||
if (GameMain.Client == null) { return false; }
|
||||
if (GameMain.Client.GameStarted)
|
||||
{
|
||||
GameMain.Client.RequestRoundEnd(save: false);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.Client.RequestSelectMode(ModeList.Content.GetChildIndex(ModeList.Content.GetChildByUserData(GameModePreset.Sandbox)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -1344,9 +1352,9 @@ namespace Barotrauma
|
||||
shuttleTickBox.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings) && !GameMain.Client.GameStarted;
|
||||
SubList.Enabled = !CampaignFrame.Visible && (GameMain.Client.ServerSettings.AllowSubVoting || GameMain.Client.HasPermission(ClientPermissions.SelectSub));
|
||||
ShuttleList.Enabled = ShuttleList.ButtonEnabled = GameMain.Client.HasPermission(ClientPermissions.SelectSub) && !GameMain.Client.GameStarted;
|
||||
ModeList.Enabled = GameMain.Client.ServerSettings.AllowModeVoting || GameMain.Client.HasPermission(ClientPermissions.SelectMode);
|
||||
ModeList.Enabled = !GameMain.Client.GameStarted && (GameMain.Client.ServerSettings.AllowModeVoting || GameMain.Client.HasPermission(ClientPermissions.SelectMode));
|
||||
LogButtons.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
||||
GameMain.Client.ShowLogButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
||||
GameMain.Client.UpdateLogButtonPermissions();
|
||||
roundControlsHolder.Children.ForEach(c => c.IgnoreLayoutGroups = !c.Visible);
|
||||
roundControlsHolder.Children.ForEach(c => c.RectTransform.RelativeSize = Vector2.One);
|
||||
roundControlsHolder.Recalculate();
|
||||
@@ -1559,7 +1567,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContainer.RectTransform), TextManager.Get("Skills"), font: GUIStyle.SubHeadingFont);
|
||||
foreach (Skill skill in characterInfo.Job.Skills)
|
||||
foreach (Skill skill in characterInfo.Job.GetSkills())
|
||||
{
|
||||
Color textColor = Color.White * (0.5f + skill.Level / 200.0f);
|
||||
var skillText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContainer.RectTransform),
|
||||
@@ -2190,17 +2198,17 @@ namespace Barotrauma
|
||||
canKick = canBan = canPromo = false;
|
||||
}
|
||||
|
||||
List<ContextMenuOption> options = new List<ContextMenuOption>();
|
||||
|
||||
options.Add(new ContextMenuOption("ViewSteamProfile", isEnabled: hasSteam, onSelected: delegate
|
||||
{
|
||||
Steamworks.SteamFriends.OpenWebOverlay($"https://steamcommunity.com/profiles/{client.SteamID}");
|
||||
}));
|
||||
|
||||
options.Add(new ContextMenuOption("ModerationMenu.ManagePlayer", isEnabled: true, onSelected: delegate
|
||||
List<ContextMenuOption> options = new List<ContextMenuOption>
|
||||
{
|
||||
GameMain.NetLobbyScreen?.SelectPlayer(client);
|
||||
}));
|
||||
new ContextMenuOption("ViewSteamProfile", isEnabled: hasSteam, onSelected: delegate
|
||||
{
|
||||
Steamworks.SteamFriends.OpenWebOverlay($"https://steamcommunity.com/profiles/{client.SteamID}");
|
||||
}),
|
||||
new ContextMenuOption("ModerationMenu.ManagePlayer", isEnabled: true, onSelected: delegate
|
||||
{
|
||||
GameMain.NetLobbyScreen?.SelectPlayer(client);
|
||||
})
|
||||
};
|
||||
|
||||
// Creates sub context menu options for all the ranks
|
||||
List<ContextMenuOption> rankOptions = new List<ContextMenuOption>();
|
||||
|
||||
@@ -1170,6 +1170,9 @@ namespace Barotrauma
|
||||
#endif
|
||||
CreateEntityElement(ep, entitiesPerRow, allEntityList.Content);
|
||||
}
|
||||
allEntityList.Content.RectTransform.SortChildren((i1, i2) =>
|
||||
string.Compare(((MapEntityPrefab)i1.GUIComponent.UserData)?.Name.Value, (i2.GUIComponent.UserData as MapEntityPrefab)?.Name.Value, StringComparison.Ordinal));
|
||||
|
||||
}
|
||||
|
||||
private void CreateEntityElement(MapEntityPrefab ep, int entitiesPerRow, GUIComponent parent)
|
||||
@@ -1911,6 +1914,7 @@ namespace Barotrauma
|
||||
}
|
||||
SubmarineInfo.RefreshSavedSub(savePath);
|
||||
if (prevSavePath != null && prevSavePath != savePath) { SubmarineInfo.RefreshSavedSub(prevSavePath); }
|
||||
MainSub.Info.PreviewImage = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.FilePath == savePath)?.PreviewImage;
|
||||
|
||||
string downloadFolder = Path.GetFullPath(SaveUtil.SubmarineDownloadFolder);
|
||||
linkedSubBox.ClearChildren();
|
||||
|
||||
+9
-2
@@ -73,11 +73,11 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
if (!SteamManager.IsInitialized) { return; }
|
||||
|
||||
uint numSubscribedMods = Steamworks.SteamUGC.NumSubscribedItems;
|
||||
uint numSubscribedMods = SteamManager.GetNumSubscribedItems();
|
||||
if (numSubscribedMods == memSubscribedModCount) { return; }
|
||||
memSubscribedModCount = numSubscribedMods;
|
||||
|
||||
var subscribedIds = Steamworks.SteamUGC.GetSubscribedItems().ToHashSet();
|
||||
var subscribedIds = SteamManager.GetSubscribedItems().ToHashSet();
|
||||
var installedIds = ContentPackageManager.WorkshopPackages.Select(p => p.SteamWorkshopId).ToHashSet();
|
||||
foreach (var id in subscribedIds.Where(id2 => !installedIds.Contains(id2)))
|
||||
{
|
||||
@@ -93,10 +93,17 @@ namespace Barotrauma.Steam
|
||||
if (!t.TryGetResult(out ISet<Steamworks.Ugc.Item> publishedItems)) { return; }
|
||||
|
||||
var allRequiredInstalled = subscribedIds.Union(publishedItems.Select(it => it.Id)).ToHashSet();
|
||||
bool needsRefresh = false;
|
||||
foreach (var id in installedIds.Where(id2 => !allRequiredInstalled.Contains(id2)))
|
||||
{
|
||||
Steamworks.Ugc.Item item = new Steamworks.Ugc.Item(id);
|
||||
SteamManager.Workshop.Uninstall(item);
|
||||
needsRefresh = true;
|
||||
}
|
||||
|
||||
if (needsRefresh)
|
||||
{
|
||||
PopulateInstalledModLists();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -214,9 +214,9 @@ namespace Barotrauma
|
||||
//try to place commands of the same texture
|
||||
//contiguously for optimal buffer generation
|
||||
//while maintaining the same visual result
|
||||
for (int i=1;i<commandList.Count;i++)
|
||||
for (int i = 1; i < commandList.Count; i++)
|
||||
{
|
||||
if (commandList[i].Texture != commandList[i-1].Texture)
|
||||
if (commandList[i].Texture != commandList[i - 1].Texture)
|
||||
{
|
||||
for (int j = i - 1; j >= 0; j--)
|
||||
{
|
||||
@@ -244,6 +244,7 @@ namespace Barotrauma
|
||||
//requires a vertex buffer to be rendered
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
if (isDisposed) { return; }
|
||||
if (commandList.Count == 0) { return; }
|
||||
int startIndex = 0;
|
||||
for (int i = 1; i < commandList.Count; i++)
|
||||
|
||||
Reference in New Issue
Block a user