OBT/1.2.1(Summer update)
Sync with upstream
This commit is contained in:
@@ -258,7 +258,9 @@ namespace Barotrauma
|
||||
//RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
InventorySlotContainer = new GUICustomComponent(new RectTransform(new Vector2(0.1f, 1.0f), characterIndicatorArea.RectTransform, Anchor.TopLeft, Pivot.TopRight),
|
||||
GUIFrame left = new(new RectTransform(new Vector2(0.25f, 1f), characterIndicatorArea.RectTransform), style: null);
|
||||
|
||||
InventorySlotContainer = new GUICustomComponent(new RectTransform(Vector2.One, left.RectTransform),
|
||||
(spriteBatch, component) =>
|
||||
{
|
||||
for (int i = 0; i < character.Inventory.Capacity; i++)
|
||||
@@ -266,6 +268,10 @@ namespace Barotrauma
|
||||
if (character.Inventory.SlotTypes[i] != InvSlotType.HealthInterface) { continue; }
|
||||
if (character.Inventory.HideSlot(i)) { continue; }
|
||||
|
||||
int width = Character.Inventory.visualSlots[i].Rect.Width;
|
||||
left.RectTransform.MinSize = new Point(width, left.RectTransform.MinSize.Y);
|
||||
if (afflictionIconList != null) { afflictionIconList.RectTransform.MinSize = new Point(width, afflictionIconList.RectTransform.MinSize.Y); }
|
||||
|
||||
//don't draw the item if it's being dragged out of the slot
|
||||
bool drawItem = !Inventory.DraggingItems.Any() || !Character.Inventory.GetItemsAt(i).All(it => Inventory.DraggingItems.Contains(it)) || character.Inventory.visualSlots[i].MouseOn();
|
||||
|
||||
@@ -292,8 +298,7 @@ namespace Barotrauma
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
cprButton = new GUIButton(new RectTransform(new Vector2(0.17f, 0.17f), characterIndicatorArea.RectTransform, Anchor.BottomLeft, scaleBasis: ScaleBasis.Smallest), text: "", style: "CPRButton")
|
||||
cprButton = new GUIButton(new RectTransform(new Vector2(0.75f), left.RectTransform, Anchor.BottomLeft, scaleBasis: ScaleBasis.Smallest), text: "", style: "CPRButton")
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.CPRButton,
|
||||
OnClicked = (button, userData) =>
|
||||
@@ -316,12 +321,11 @@ namespace Barotrauma
|
||||
|
||||
return true;
|
||||
},
|
||||
ToolTip = TextManager.Get("doctor.cprobjective"),
|
||||
IgnoreLayoutGroups = true,
|
||||
ToolTip = TextManager.Get("tutorial.roles.medic.objective.cpr"),
|
||||
Visible = false
|
||||
};
|
||||
|
||||
var limbSelection = new GUICustomComponent(new RectTransform(new Vector2(0.4f, 1.0f), characterIndicatorArea.RectTransform),
|
||||
var limbSelection = new GUICustomComponent(new RectTransform(new Vector2(0.5f, 1.0f), characterIndicatorArea.RectTransform),
|
||||
(spriteBatch, component) =>
|
||||
{
|
||||
DrawHealthWindow(spriteBatch, component.RectTransform.Rect, true);
|
||||
@@ -368,8 +372,6 @@ namespace Barotrauma
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
characterIndicatorArea.Recalculate();
|
||||
|
||||
healthBarHolder = new GUIFrame(new RectTransform(Point.Zero, GUI.Canvas), style: null)
|
||||
{
|
||||
HoverCursor = CursorState.Hand
|
||||
|
||||
@@ -866,7 +866,20 @@ namespace Barotrauma
|
||||
GameSettings.SaveCurrentConfig();
|
||||
});
|
||||
}, isCheat: false));
|
||||
|
||||
|
||||
commands.Add(new Command("togglespoofeventmanagerid", "togglespoofeventmanagerid: Forces the client to report the last received event ID as always being 1, making the server believe the client is always behind.", (string[] args) =>
|
||||
{
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
GameMain.Client.SpoofEntityManagerReceivedId = !GameMain.Client.SpoofEntityManagerReceivedId;
|
||||
DebugConsole.NewMessage(GameMain.Client.SpoofEntityManagerReceivedId ? "Spoofing enabled ": "Spoofing disabled", Color.Green);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.NewMessage("Not connected to server", Color.Red);
|
||||
}
|
||||
}));
|
||||
|
||||
commands.Add(new Command("togglegrid", "Toggle visual snap grid in sub editor.", (string[] args) =>
|
||||
{
|
||||
SubEditorScreen.ShouldDrawGrid = !SubEditorScreen.ShouldDrawGrid;
|
||||
@@ -4454,17 +4467,24 @@ namespace Barotrauma
|
||||
|
||||
public static void StartLocalMPSession(int numClients = 2)
|
||||
{
|
||||
string extraArguments = "-multiclienttestmode";
|
||||
if (NetConfig.UseLenientHandshake)
|
||||
{
|
||||
extraArguments += " -lenienthandshake";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Process.GetProcessesByName("DedicatedServer").Length == 0)
|
||||
{
|
||||
#if WINDOWS
|
||||
Process.Start("DedicatedServer.exe", arguments: "-multiclienttestmode");
|
||||
Process.Start("DedicatedServer.exe", arguments: extraArguments);
|
||||
#else
|
||||
Process.Start("./DedicatedServer", arguments: "-multiclienttestmode");
|
||||
Process.Start("./DedicatedServer", arguments: extraArguments);
|
||||
#endif
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
GameClient.MultiClientTestMode = true;
|
||||
#endif
|
||||
@@ -4478,10 +4498,13 @@ namespace Barotrauma
|
||||
for (int i = 2; i <= numClients; i++)
|
||||
{
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
|
||||
string clientArguments = $"-connect server localhost -username client{i} -skipintro";
|
||||
|
||||
#if WINDOWS
|
||||
Process.Start("Barotrauma.exe", arguments: "-connect server localhost -username client" + i + " -multiclienttestmode");
|
||||
Process.Start("Barotrauma.exe", arguments: $"{clientArguments} {extraArguments}");
|
||||
#else
|
||||
Process.Start("./Barotrauma", arguments: "-connect server localhost -username client" + i + " -multiclienttestmode");
|
||||
Process.Start("./Barotrauma", arguments: $"{clientArguments} {extraArguments}");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -649,12 +650,12 @@ namespace Barotrauma
|
||||
DrawMessages(spriteBatch, cam);
|
||||
|
||||
if (MouseOn != null)
|
||||
{
|
||||
{
|
||||
MouseOn.OnDrawToolTip?.Invoke(MouseOn);
|
||||
if (!MouseOn.ToolTip.IsNullOrWhiteSpace())
|
||||
{
|
||||
MouseOn.DrawToolTip(spriteBatch);
|
||||
}
|
||||
MouseOn.OnDrawToolTip?.Invoke(MouseOn);
|
||||
}
|
||||
|
||||
if (SubEditorScreen.IsSubEditor())
|
||||
@@ -2323,10 +2324,10 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Creates a 7-segment display.
|
||||
/// </summary>
|
||||
/// <param name="leftLabel">Returns <see langword="null"/> if <paramref name="leftLabelText"/> is <see langword="null"/> or empty.</param>
|
||||
/// <param name="leftLabel">Returns <see langword="null"/> if <paramref name="leftLabelText"/> is <see langword="null"/>.</param>
|
||||
/// <param name="rightLabelText">Defaults to <c>TextManager.Get("kilowatt")</c>.</param>
|
||||
/// <param name="leftLabelFont">Defaults to <see cref="GUIStyle.LargeFont"/>.</param>
|
||||
public static GUITextBlock CreateDigitalDisplay(RectTransform rect, out GUITextBlock? leftLabel, out GUITextBlock rightLabel, LocalizedString? leftLabelText = null, LocalizedString? rightLabelText = null, LocalizedString? tooltip = null, GUIFont? leftLabelFont = null)
|
||||
public static GUITextBlock CreateDigitalDisplay(RectTransform rect, [NotNullIfNotNull(nameof(leftLabelText))] out GUITextBlock? leftLabel, out GUITextBlock rightLabel, LocalizedString? leftLabelText = null, LocalizedString? rightLabelText = null, LocalizedString? tooltip = null, GUIFont? leftLabelFont = null)
|
||||
{
|
||||
GUILayoutGroup textArea = new(rect, isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||
{
|
||||
@@ -2337,7 +2338,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
leftLabel = null;
|
||||
if (!leftLabelText.IsNullOrEmpty())
|
||||
if (leftLabelText != null)
|
||||
{
|
||||
leftLabel = new GUITextBlock(new RectTransform(new Vector2(0.4f, 1f), textArea.RectTransform), leftLabelText, textColor: GUIStyle.TextColorBright, font: leftLabelFont ?? GUIStyle.LargeFont, textAlignment: Alignment.CenterRight);
|
||||
}
|
||||
|
||||
@@ -384,14 +384,14 @@ namespace Barotrauma
|
||||
CaretIndex = forcedCaretIndex == - 1 ? textBlock.GetCaretIndexFromScreenPos(PlayerInput.MousePosition) : forcedCaretIndex;
|
||||
CalculateCaretPos();
|
||||
ClearSelection();
|
||||
bool wasSelected = selected;
|
||||
selected = true;
|
||||
GUI.KeyboardDispatcher.Subscriber = this;
|
||||
OnSelected?.Invoke(this, Keys.None);
|
||||
if (!wasSelected && PlaySoundOnSelect && !ignoreSelectSound)
|
||||
if (!selected && PlaySoundOnSelect && !ignoreSelectSound)
|
||||
{
|
||||
SoundPlayer.PlayUISound(GUISoundType.Select);
|
||||
}
|
||||
selected = true;
|
||||
//set this after we've set selected to true -> otherwise the textbox taking keyboard focus will trigger Select again
|
||||
GUI.KeyboardDispatcher.Subscriber = this;
|
||||
}
|
||||
|
||||
public void Deselect()
|
||||
|
||||
@@ -113,7 +113,10 @@ namespace Barotrauma
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, samplerState: GUI.SamplerState);
|
||||
|
||||
GUI.DrawBackgroundSprite(spriteBatch, currentBackgroundTexture, Color.White, drawArea);
|
||||
if (currentBackgroundTexture.Texture != null)
|
||||
{
|
||||
GUI.DrawBackgroundSprite(spriteBatch, currentBackgroundTexture, Color.White, drawArea);
|
||||
}
|
||||
overlay.Draw(spriteBatch, Vector2.Zero, scale: overlayScale);
|
||||
|
||||
double noiseT = Timing.TotalTime * 0.02f;
|
||||
|
||||
@@ -278,6 +278,12 @@ namespace Barotrauma
|
||||
GameClient.MultiClientTestMode = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ConsoleArguments.Contains("-lenienthandshake"))
|
||||
{
|
||||
NetConfig.UseLenientHandshake = true;
|
||||
}
|
||||
|
||||
GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window);
|
||||
|
||||
PerformanceCounter = new PerformanceCounter();
|
||||
|
||||
@@ -127,12 +127,6 @@ namespace Barotrauma
|
||||
(int)SlotPositions[i].X,
|
||||
(int)SlotPositions[i].Y,
|
||||
(int)(slotSprite.size.X * multiplier), (int)(slotSprite.size.Y * multiplier));
|
||||
|
||||
if (SlotTypes[i] == InvSlotType.HealthInterface &&
|
||||
character.CharacterHealth?.InventorySlotContainer != null)
|
||||
{
|
||||
slotRect.Width = slotRect.Height = (int)(character.CharacterHealth.InventorySlotContainer.Rect.Width * 1.2f);
|
||||
}
|
||||
|
||||
ItemContainer itemContainer = slots[i].FirstOrDefault()?.GetComponent<ItemContainer>();
|
||||
if (itemContainer != null)
|
||||
@@ -622,6 +616,7 @@ namespace Barotrauma
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (HideSlot(i)) { continue; }
|
||||
var item = slots[i].FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayMsg = TextManager.ParseInputTypes(TextManager.Get(Msg));
|
||||
DisplayMsg = TextManager.ParseInputTypes(TextManager.Get(Msg)).Fallback(Msg);
|
||||
}
|
||||
|
||||
CharacterHUD.RecreateHudTextsIfControlling(Character.Controlled);
|
||||
|
||||
+42
-8
@@ -12,9 +12,12 @@ namespace Barotrauma.Items.Components
|
||||
private partial class PowerGroup
|
||||
{
|
||||
private GUIFrame? frame;
|
||||
private GUIFrame? groupContent;
|
||||
private GUILayoutGroup? nameGroup;
|
||||
private GUITextBox? nameBox;
|
||||
private GUITextBlock? loadDisplayNameLabel;
|
||||
private GUIScrollBar? ratioSlider;
|
||||
private readonly List<GUITextBlock> powerUnitLabels = new List<GUITextBlock>();
|
||||
private readonly List<GUITextBlock> powerUnitLabels = [];
|
||||
private GUIFrame? divider;
|
||||
|
||||
public bool IsVisible { get; private set; } = true;
|
||||
@@ -22,9 +25,9 @@ namespace Barotrauma.Items.Components
|
||||
public void CreateGUI()
|
||||
{
|
||||
frame = new GUIFrame(new RectTransform(new Vector2(1f, 0.25f), distributor.groupList!.Content.RectTransform, minSize: (0, 130)), style: null);
|
||||
GUIFrame groupContent = new(new RectTransform(frame.Rect.Size - new Point(10), frame.RectTransform, Anchor.Center), style: null);
|
||||
groupContent = new GUIFrame(new RectTransform(frame.Rect.Size - new Point(10), frame.RectTransform, Anchor.Center), style: null);
|
||||
|
||||
GUILayoutGroup nameGroup = new(new RectTransform(new Vector2(0.65f, 0.33f), groupContent.RectTransform, Anchor.TopLeft), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||
nameGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.65f, 0.33f), groupContent.RectTransform, Anchor.TopLeft), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||
{
|
||||
Stretch = true
|
||||
};
|
||||
@@ -37,7 +40,7 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
};
|
||||
nameBox = new GUITextBox(new RectTransform(Vector2.One, nameGroup.RectTransform), Name, font: GUIStyle.SubHeadingFont, style: "GUITextBoxNoStyle")
|
||||
nameBox = new GUITextBox(new RectTransform(Vector2.One, nameGroup.RectTransform), Screen.Selected == GameMain.SubEditorScreen ? Name : DisplayName.Value, font: GUIStyle.SubHeadingFont, style: "GUITextBoxNoStyle")
|
||||
{
|
||||
MaxTextLength = MaxNameLength,
|
||||
OverflowClip = true,
|
||||
@@ -48,17 +51,40 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
};
|
||||
nameBox.OnSelected += (tb, _) =>
|
||||
{
|
||||
if (tb.Selected) { return; }
|
||||
tb.Text = Name;
|
||||
};
|
||||
nameBox.OnDeselected += (tb, _) =>
|
||||
{
|
||||
Name = tb.Text;
|
||||
tb.CaretIndex = 0;
|
||||
if (GameMain.Client == null) { return; }
|
||||
distributor.item.CreateClientEvent(distributor, new EventData(this, EventType.NameChange));
|
||||
};
|
||||
nameBox.GetChild<GUIFrame>().GetChild<GUICustomComponent>().OnDrawToolTip = comp =>
|
||||
{
|
||||
if (Screen.Selected != GameMain.SubEditorScreen && !nameBox.Selected)
|
||||
{
|
||||
comp.ToolTip = null;
|
||||
return;
|
||||
}
|
||||
|
||||
LocalizedString localizedText = TextManager.Get(nameBox.Text);
|
||||
comp.ToolTip = localizedText.IsNullOrEmpty()
|
||||
? TextManager.GetWithVariable("StringPropertyCannotTranslate", "[tag]", nameBox.Text)
|
||||
: TextManager.GetWithVariable("StringPropertyTranslate", "[translation]", localizedText);
|
||||
};
|
||||
|
||||
GUITextBlock loadDisplay = GUI.CreateDigitalDisplay(new RectTransform(new Vector2(0.35f, 0.33f), groupContent.RectTransform, Anchor.TopRight) { AbsoluteOffset = (5, 0) },
|
||||
out GUITextBlock? _, out GUITextBlock loadDisplayUnitLabel, TextManager.Get("PowerTransferLoadLabel"), tooltip: TextManager.Get("PowerTransferTipLoad"), leftLabelFont: GUIStyle.Font);
|
||||
out loadDisplayNameLabel, out GUITextBlock loadDisplayUnitLabel, TextManager.Get("PowerTransferLoadLabel"), tooltip: TextManager.Get("PowerTransferTipLoad"), leftLabelFont: GUIStyle.Font);
|
||||
loadDisplay.TextGetter = () => MathUtils.RoundToInt(Load).ToString();
|
||||
|
||||
float textAndPaddingWidth = loadDisplayNameLabel!.Font.MeasureString(loadDisplayNameLabel!.Text).X + loadDisplayNameLabel.Padding.X + loadDisplayNameLabel.Padding.Z;
|
||||
float availableWidth = groupContent!.Rect.Width - loadDisplayNameLabel.Parent.Rect.Width + loadDisplayNameLabel.Rect.Width - textAndPaddingWidth;
|
||||
nameGroup!.RectTransform.Resize(new Point((int)availableWidth, nameGroup.Rect.Height));
|
||||
|
||||
ratioSlider = new GUIScrollBar(new RectTransform(new Vector2(1f, 0.33f), groupContent.RectTransform, Anchor.Center), barSize: 0.15f, style: "DeviceSlider")
|
||||
{
|
||||
Step = SupplyRatioStep,
|
||||
@@ -78,16 +104,17 @@ namespace Barotrauma.Items.Components
|
||||
ratioSlider.Bar.RectTransform.MaxSize = new Point(ratioSlider.Bar.Rect.Height);
|
||||
|
||||
GUITextBlock ratioDisplay = GUI.CreateDigitalDisplay(new RectTransform(new Vector2(0.2f, 0.33f), groupContent.RectTransform, Anchor.BottomLeft),
|
||||
out GUITextBlock? _, out GUITextBlock _,
|
||||
out GUITextBlock? _, out GUITextBlock ratioDisplayUnitLabel,
|
||||
rightLabelText: "%");
|
||||
ratioDisplay.TextGetter = () => DisplayRatio.ToString();
|
||||
|
||||
GUITextBlock outputDisplay = GUI.CreateDigitalDisplay(new RectTransform(new Vector2(0.35f, 0.33f), groupContent.RectTransform, Anchor.BottomRight) { AbsoluteOffset = (5, 0) },
|
||||
out GUITextBlock? _, out GUITextBlock outputDisplayUnitLabel,
|
||||
out GUITextBlock? outputDisplayNameLabel, out GUITextBlock outputDisplayUnitLabel,
|
||||
TextManager.Get("powerdistributor.supplylabel"), tooltip: TextManager.Get("PowerTransferTipPower"), leftLabelFont: GUIStyle.Font);
|
||||
outputDisplay.TextGetter = () => distributor.IsShortCircuited(PowerOut) ? "err" : MathUtils.RoundToInt(distributor.CalculatePowerOut(this)).ToString();
|
||||
|
||||
powerUnitLabels.Add(loadDisplayUnitLabel);
|
||||
powerUnitLabels.Add(ratioDisplayUnitLabel);
|
||||
powerUnitLabels.Add(outputDisplayUnitLabel);
|
||||
GUITextBlock.AutoScaleAndNormalize(powerUnitLabels);
|
||||
|
||||
@@ -111,7 +138,14 @@ namespace Barotrauma.Items.Components
|
||||
IsVisible = PowerOut.Wires.Count >= 1;
|
||||
frame!.Visible = IsVisible;
|
||||
divider!.Visible = IsVisible && distributor.powerGroups.Last(group => group.frame!.Visible) != this;
|
||||
if (distributor.prevLanguage != GameSettings.CurrentConfig.Language) { GUITextBlock.AutoScaleAndNormalize(powerUnitLabels); }
|
||||
if (distributor.prevLanguage != GameSettings.CurrentConfig.Language)
|
||||
{
|
||||
GUITextBlock.AutoScaleAndNormalize(powerUnitLabels);
|
||||
|
||||
float textAndPaddingWidth = loadDisplayNameLabel!.Font.MeasureString(loadDisplayNameLabel!.Text).X + loadDisplayNameLabel.Padding.X + loadDisplayNameLabel.Padding.Z;
|
||||
float availableWidth = groupContent!.Rect.Width - loadDisplayNameLabel.Parent.Rect.Width + loadDisplayNameLabel.Rect.Width - textAndPaddingWidth;
|
||||
nameGroup!.RectTransform.Resize(new Point((int)availableWidth, nameGroup.Rect.Height));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -716,13 +716,19 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
GetAvailablePower(out float batteryCharge, out float batteryCapacity);
|
||||
|
||||
List<Item> availableAmmo = new List<Item>();
|
||||
List<Item> availableAmmo = [];
|
||||
AddAmmoFromContainer(item.GetComponent<ItemContainer>());
|
||||
foreach (MapEntity e in item.linkedTo)
|
||||
{
|
||||
if (!(e is Item linkedItem)) { continue; }
|
||||
var itemContainer = linkedItem.GetComponent<ItemContainer>();
|
||||
if (itemContainer == null) { continue; }
|
||||
if (e is not Item linkedItem) { continue; }
|
||||
AddAmmoFromContainer(linkedItem.GetComponent<ItemContainer>());
|
||||
}
|
||||
|
||||
void AddAmmoFromContainer(ItemContainer itemContainer)
|
||||
{
|
||||
if (itemContainer == null) { return; }
|
||||
availableAmmo.AddRange(itemContainer.Inventory.AllItems);
|
||||
//add empty slots too
|
||||
for (int i = 0; i < itemContainer.Inventory.Capacity - itemContainer.Inventory.AllItems.Count(); i++)
|
||||
{
|
||||
availableAmmo.Add(null);
|
||||
|
||||
@@ -339,6 +339,19 @@ namespace Barotrauma
|
||||
toolTip += $"‖color:{conditionColorStr}‖ ({(int)item.ConditionPercentage} %)‖color:end‖";
|
||||
}
|
||||
if (!description.IsNullOrEmpty()) { toolTip += '\n' + description; }
|
||||
|
||||
if (item.Prefab.UnlockedRecipeInToolTip.Length > 0 && GameMain.GameSession is { } GameSession)
|
||||
{
|
||||
if (item.Prefab.UnlockedRecipeInToolTip.All(id => GameSession.HasUnlockedRecipe(Character.Controlled, id)))
|
||||
{
|
||||
toolTip += $"\n‖color:{XMLExtensions.ToStringHex(GUIStyle.Green)}‖{TextManager.Get("unlockedrecipe.true")}‖color:end‖";
|
||||
}
|
||||
else
|
||||
{
|
||||
toolTip += $"\n‖color:{XMLExtensions.ToStringHex(GUIStyle.Yellow)}‖{TextManager.Get("unlockedrecipe.false")}‖color:end‖";
|
||||
}
|
||||
}
|
||||
|
||||
if (item.Prefab.ContentPackage != GameMain.VanillaContent && item.Prefab.ContentPackage != null)
|
||||
{
|
||||
colorStr = XMLExtensions.ToStringHex(Color.MediumPurple);
|
||||
@@ -356,19 +369,7 @@ namespace Barotrauma
|
||||
}
|
||||
#if DEBUG
|
||||
toolTip += $" ({item.Prefab.Identifier})";
|
||||
#endif
|
||||
if (!item.Prefab.UnlockedRecipeInToolTip.IsEmpty && GameMain.GameSession is { } GameSession)
|
||||
{
|
||||
if (GameSession.HasUnlockedRecipe(Character.Controlled, item.Prefab.UnlockedRecipeInToolTip))
|
||||
{
|
||||
toolTip += TextManager.Get("unlockedrecipe.true");
|
||||
}
|
||||
else
|
||||
{
|
||||
toolTip += $"\n‖color:{XMLExtensions.ToStringHex(GUIStyle.Yellow)}‖{TextManager.Get("unlockedrecipe.false")}‖color:end‖";
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
if (PlayerInput.KeyDown(InputType.ContextualCommand))
|
||||
{
|
||||
toolTip += $"\n‖color:gui.blue‖{TextManager.ParseInputTypes(TextManager.Get("itemmsgcontextualorders"))}‖color:end‖";
|
||||
@@ -1300,8 +1301,7 @@ namespace Barotrauma
|
||||
SubEditorScreen.StoreCommand(new InventoryPlaceCommand(DraggingItems.First().ParentInventory, new List<Item>(DraggingItems), true));
|
||||
}
|
||||
}
|
||||
|
||||
SoundPlayer.PlayUISound(GUISoundType.DropItem);
|
||||
|
||||
bool removed = false;
|
||||
if (Screen.Selected is SubEditorScreen editor)
|
||||
{
|
||||
|
||||
+6
-6
@@ -75,11 +75,11 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
|
||||
|
||||
|
||||
// ReSharper restore FieldCanBeMadeReadOnly.Local
|
||||
private const string SettingsResetButtonText = "LuaCsForBarotrauma.SettingsMenu.ResetVisibleSettings";
|
||||
private const string SettingsResetPromptTitle = "LuaCsForBarotrauma.SettingsMenu.ResetPrompt.Title";
|
||||
private const string SettingsResetPromptContents = "LuaCsForBarotrauma.SettingsMenu.ResetPrompt.Message";
|
||||
private const string SettingsResetPromptYesText = "LuaCsForBarotrauma.SettingsMenu.ResetPrompt.Yes";
|
||||
private const string SettingsResetPromptNoText = "LuaCsForBarotrauma.SettingsMenu.ResetPrompt.No";
|
||||
private const string SettingsResetButtonText = $"{LuaCsSetup.PackageName}.SettingsMenu.ResetVisibleSettings";
|
||||
private const string SettingsResetPromptTitle = $"{LuaCsSetup.PackageName}.SettingsMenu.ResetPrompt.Title";
|
||||
private const string SettingsResetPromptContents = $"{LuaCsSetup.PackageName}.SettingsMenu.ResetPrompt.Message";
|
||||
private const string SettingsResetPromptYesText = $"{LuaCsSetup.PackageName}.SettingsMenu.ResetPrompt.Yes";
|
||||
private const string SettingsResetPromptNoText = $"{LuaCsSetup.PackageName}.SettingsMenu.ResetPrompt.No";
|
||||
|
||||
|
||||
private event Action OnApplyInstalledModsChanges;
|
||||
@@ -100,7 +100,7 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
|
||||
var menuTitleLayoutGroup = new GUILayoutGroup(
|
||||
new RectTransform(new Vector2(1f, MenuTitleHeight), mainLayoutGroup.RectTransform, Anchor.TopLeft), true, Anchor.TopLeft);
|
||||
GUIUtil.Label(menuTitleLayoutGroup,
|
||||
GetLocalizedString("LuaCsForBarotrauma.SettingsMenu.ModGameplayButton", "Mod Gameplay Settings"),
|
||||
GetLocalizedString($"{LuaCsSetup.PackageName}.SettingsMenu.ModGameplayButton", "Mod Gameplay Settings"),
|
||||
GUIStyle.LargeFont, new Vector2(1f, 1f));
|
||||
|
||||
// page contents
|
||||
|
||||
+3
-3
@@ -46,10 +46,10 @@ public class SettingsMenuSystem : ISettingsMenuSystem
|
||||
var tabControlsIndex = (SettingsMenu.Tab)tabCount+1;
|
||||
|
||||
_gameplayContentFrame = CreateNewContentTab(tabGameplayIndex, __instance,
|
||||
GUIStyle.ComponentStyles.ContainsKey("SettingsMenuTab.LuaCsSettings") ? "SettingsMenuTab.LuaCsSettings" : "SettingsMenuTab.Mods",
|
||||
"LuaCsForBarotrauma.SettingsMenu.ModGameplayButton");
|
||||
GUIStyle.ComponentStyles.ContainsKey("SettingsMenuTab.LuaCsSettings") ? "SettingsMenuTab.LuaCsSettings" : "SettingsMenuTab.Mods",
|
||||
$"{LuaCsSetup.PackageName}.SettingsMenu.ModGameplayButton");
|
||||
/*_controlsContentFrame = CreateNewContentTab(tabControlsIndex, __instance,
|
||||
"SettingsMenuTab.Controls", "LuaCsForBarotrauma.SettingsMenu.ModControlsButton");
|
||||
"SettingsMenuTab.Controls", $"{LuaCsSetup.PackageName}.SettingsMenu.ModControlsButton");
|
||||
*/
|
||||
|
||||
_gameplayMenuInstance = new ModsGameplaySettingsMenu(_gameplayContentFrame, _packageManagementService, _configService, _loggerService, __instance);
|
||||
|
||||
+3
-1
@@ -8,7 +8,7 @@ using System.Xml.Linq;
|
||||
namespace Barotrauma
|
||||
{
|
||||
|
||||
class BackgroundCreature : ISteerable
|
||||
class BackgroundCreature : ISteerable, ILevelRenderableObject
|
||||
{
|
||||
const float MaxDepth = 10000.0f;
|
||||
|
||||
@@ -76,6 +76,8 @@ namespace Barotrauma
|
||||
set;
|
||||
}
|
||||
|
||||
public Vector3 Position => new Vector3(position.X, position.Y, Depth);
|
||||
|
||||
public BackgroundCreature(BackgroundCreaturePrefab prefab, Vector2 position)
|
||||
{
|
||||
this.Prefab = prefab;
|
||||
|
||||
+3
-53
@@ -3,7 +3,6 @@ using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -15,52 +14,11 @@ namespace Barotrauma
|
||||
|
||||
private float checkVisibleTimer;
|
||||
|
||||
private readonly List<BackgroundCreature> creatures = new List<BackgroundCreature>();
|
||||
private readonly List<BackgroundCreature> creatures = [];
|
||||
|
||||
private readonly List<BackgroundCreature> visibleCreatures = new List<BackgroundCreature>();
|
||||
private readonly List<BackgroundCreature> visibleCreatures = [];
|
||||
|
||||
public BackgroundCreatureManager()
|
||||
{
|
||||
/*foreach(var file in files)
|
||||
{
|
||||
LoadConfig(file.Path);
|
||||
}*/
|
||||
}
|
||||
|
||||
/*public BackgroundCreatureManager(string path)
|
||||
{
|
||||
DebugConsole.AddWarning($"Couldn't find any BackgroundCreaturePrefabs files, falling back to {path}");
|
||||
LoadConfig(ContentPath.FromRaw(null, path));
|
||||
}
|
||||
|
||||
private void LoadConfig(ContentPath configPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
XDocument doc = XMLExtensions.TryLoadXml(configPath);
|
||||
if (doc == null) { return; }
|
||||
var mainElement = doc.Root.FromPackage(configPath.ContentPackage);
|
||||
if (mainElement.IsOverride())
|
||||
{
|
||||
mainElement = mainElement.FirstElement();
|
||||
Prefabs.Clear();
|
||||
DebugConsole.NewMessage($"Overriding all background creatures with '{configPath}'", Color.MediumPurple);
|
||||
}
|
||||
else if (Prefabs.Any())
|
||||
{
|
||||
DebugConsole.NewMessage($"Loading additional background creatures from file '{configPath}'");
|
||||
}
|
||||
|
||||
foreach (var element in mainElement.Elements())
|
||||
{
|
||||
Prefabs.Add(new BackgroundCreaturePrefab(element));
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError(String.Format("Failed to load BackgroundCreatures from {0}", configPath), e);
|
||||
}
|
||||
}*/
|
||||
public IEnumerable<BackgroundCreature> VisibleCreatures => visibleCreatures;
|
||||
|
||||
public void SpawnCreatures(Level level, int count, Vector2? position = null)
|
||||
{
|
||||
@@ -161,14 +119,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
foreach (BackgroundCreature creature in visibleCreatures)
|
||||
{
|
||||
creature.Draw(spriteBatch, cam);
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawLights(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
foreach (BackgroundCreature creature in visibleCreatures)
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace Barotrauma
|
||||
|
||||
public void DrawFront(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
renderer?.DrawForeground(spriteBatch, cam, LevelObjectManager);
|
||||
renderer?.DrawForeground(spriteBatch, cam, backgroundCreatureManager, LevelObjectManager);
|
||||
}
|
||||
public void ClientEventRead(IReadMessage msg, float sendingTime)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LevelObject
|
||||
partial class LevelObject : ILevelRenderableObject
|
||||
{
|
||||
public float SwingTimer;
|
||||
public float ScaleOscillateTimer;
|
||||
|
||||
+136
-67
@@ -8,13 +8,20 @@ using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public interface ILevelRenderableObject
|
||||
{
|
||||
public Vector3 Position { get; }
|
||||
|
||||
}
|
||||
|
||||
partial class LevelObjectManager
|
||||
{
|
||||
|
||||
// Pre-initialized to the max size, so that we don't have to resize the lists at runtime. TODO: Could the capacity (of some collections?) be lower?
|
||||
private readonly List<LevelObject> visibleObjectsBack = new List<LevelObject>(MaxVisibleObjects);
|
||||
private readonly List<LevelObject> visibleObjectsMid = new List<LevelObject>(MaxVisibleObjects);
|
||||
private readonly List<LevelObject> visibleObjectsFront = new List<LevelObject>(MaxVisibleObjects);
|
||||
private readonly HashSet<LevelObject> allVisibleObjects = new HashSet<LevelObject>(MaxVisibleObjects);
|
||||
private readonly List<ILevelRenderableObject> visibleObjectsBack = new List<ILevelRenderableObject>(MaxVisibleObjects);
|
||||
private readonly List<ILevelRenderableObject> visibleObjectsMid = new List<ILevelRenderableObject>(MaxVisibleObjects);
|
||||
private readonly List<ILevelRenderableObject> visibleObjectsFront = new List<ILevelRenderableObject>(MaxVisibleObjects);
|
||||
private readonly HashSet<ILevelRenderableObject> allVisibleObjects = new HashSet<ILevelRenderableObject>(MaxVisibleObjects);
|
||||
|
||||
private double NextRefreshTime;
|
||||
|
||||
@@ -35,35 +42,44 @@ namespace Barotrauma
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
||||
{
|
||||
foreach (LevelObject obj in visibleObjectsBack)
|
||||
foreach (ILevelRenderableObject obj in visibleObjectsBack)
|
||||
{
|
||||
obj.Update(deltaTime, cam);
|
||||
if (obj is LevelObject levelObj)
|
||||
{
|
||||
levelObj.Update(deltaTime, cam);
|
||||
}
|
||||
}
|
||||
foreach (LevelObject obj in visibleObjectsMid)
|
||||
foreach (ILevelRenderableObject obj in visibleObjectsMid)
|
||||
{
|
||||
obj.Update(deltaTime, cam);
|
||||
if (obj is LevelObject levelObj)
|
||||
{
|
||||
levelObj.Update(deltaTime, cam);
|
||||
}
|
||||
}
|
||||
foreach (LevelObject obj in visibleObjectsFront)
|
||||
foreach (ILevelRenderableObject obj in visibleObjectsFront)
|
||||
{
|
||||
obj.Update(deltaTime, cam);
|
||||
if (obj is LevelObject levelObj)
|
||||
{
|
||||
levelObj.Update(deltaTime, cam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all visible objects, but not in order, because internally uses a HashSet.
|
||||
/// </summary>
|
||||
public IEnumerable<LevelObject> GetAllVisibleObjects()
|
||||
public IEnumerable<ILevelRenderableObject> GetAllVisibleObjects()
|
||||
{
|
||||
allVisibleObjects.Clear();
|
||||
foreach (LevelObject obj in visibleObjectsBack)
|
||||
foreach (ILevelRenderableObject obj in visibleObjectsBack)
|
||||
{
|
||||
allVisibleObjects.Add(obj);
|
||||
}
|
||||
foreach (LevelObject obj in visibleObjectsMid)
|
||||
foreach (ILevelRenderableObject obj in visibleObjectsMid)
|
||||
{
|
||||
allVisibleObjects.Add(obj);
|
||||
}
|
||||
foreach (LevelObject obj in visibleObjectsFront)
|
||||
foreach (ILevelRenderableObject obj in visibleObjectsFront)
|
||||
{
|
||||
allVisibleObjects.Add(obj);
|
||||
}
|
||||
@@ -73,7 +89,7 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Checks which level objects are in camera view and adds them to the visibleObjects lists
|
||||
/// </summary>
|
||||
private void RefreshVisibleObjects(Rectangle currentIndices, float zoom)
|
||||
private void RefreshVisibleObjects(Rectangle currentIndices, BackgroundCreatureManager backgroundCreatureManager, float zoom)
|
||||
{
|
||||
visibleObjectsBack.Clear();
|
||||
visibleObjectsMid.Clear();
|
||||
@@ -152,6 +168,27 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var backgroundCreature in backgroundCreatureManager.VisibleCreatures)
|
||||
{
|
||||
int drawOrderIndex = 0;
|
||||
for (int i = 0; i < visibleObjectsBack.Count; i++)
|
||||
{
|
||||
if (visibleObjectsBack[i].Position.Z > backgroundCreature.Position.Z)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawOrderIndex = i + 1;
|
||||
if (drawOrderIndex >= MaxVisibleObjects) { break; }
|
||||
}
|
||||
}
|
||||
if (drawOrderIndex >= 0 && drawOrderIndex < MaxVisibleObjects)
|
||||
{
|
||||
visibleObjectsBack.Insert(drawOrderIndex, backgroundCreature);
|
||||
}
|
||||
}
|
||||
|
||||
//object grid is sorted in an ascending order
|
||||
//(so we prefer the objects in the foreground instead of ones in the background if some need to be culled)
|
||||
//rendering needs to be done in a descending order though to get the background objects to be drawn first -> reverse the lists
|
||||
@@ -165,28 +202,28 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Draw the objects behind the level walls
|
||||
/// </summary>
|
||||
public void DrawObjectsBack(SpriteBatch spriteBatch, Camera cam)
|
||||
public void DrawObjectsBack(SpriteBatch spriteBatch, BackgroundCreatureManager backgroundCreatureManager, Camera cam)
|
||||
{
|
||||
DrawObjects(spriteBatch, cam, visibleObjectsBack);
|
||||
DrawObjects(spriteBatch, cam, backgroundCreatureManager, visibleObjectsBack);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw the objects in front of the level walls, but behind characters
|
||||
/// </summary>
|
||||
public void DrawObjectsMid(SpriteBatch spriteBatch, Camera cam)
|
||||
public void DrawObjectsMid(SpriteBatch spriteBatch, BackgroundCreatureManager backgroundCreatureManager, Camera cam)
|
||||
{
|
||||
DrawObjects(spriteBatch, cam, visibleObjectsMid);
|
||||
DrawObjects(spriteBatch, cam, backgroundCreatureManager, visibleObjectsMid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw the objects in front of the level walls and characters
|
||||
/// </summary>
|
||||
public void DrawObjectsFront(SpriteBatch spriteBatch, Camera cam)
|
||||
public void DrawObjectsFront(SpriteBatch spriteBatch, BackgroundCreatureManager backgroundCreatureManager, Camera cam)
|
||||
{
|
||||
DrawObjects(spriteBatch, cam, visibleObjectsFront);
|
||||
DrawObjects(spriteBatch, cam, backgroundCreatureManager, visibleObjectsFront);
|
||||
}
|
||||
|
||||
private void DrawObjects(SpriteBatch spriteBatch, Camera cam, List<LevelObject> objectList)
|
||||
private void DrawObjects(SpriteBatch spriteBatch, Camera cam, BackgroundCreatureManager backgroundCreatureManager, List<ILevelRenderableObject> objectList)
|
||||
{
|
||||
Rectangle indices = Rectangle.Empty;
|
||||
indices.X = (int)Math.Floor(cam.WorldView.X / (float)GridSize);
|
||||
@@ -207,7 +244,7 @@ namespace Barotrauma
|
||||
float z = 0.0f;
|
||||
if (ForceRefreshVisibleObjects || (currentGridIndices != indices && Timing.TotalTime > NextRefreshTime))
|
||||
{
|
||||
RefreshVisibleObjects(indices, cam.Zoom);
|
||||
RefreshVisibleObjects(indices, backgroundCreatureManager, cam.Zoom);
|
||||
ForceRefreshVisibleObjects = false;
|
||||
if (cam.Zoom < 0.1f)
|
||||
{
|
||||
@@ -216,61 +253,93 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
foreach (LevelObject obj in objectList)
|
||||
bool prevObjectHasDeformableSprite = false;
|
||||
foreach (ILevelRenderableObject obj2 in objectList)
|
||||
{
|
||||
Vector2 camDiff = new Vector2(obj.Position.X, obj.Position.Y) - cam.WorldViewCenter;
|
||||
Vector2 camDiff = new Vector2(obj2.Position.X, obj2.Position.Y) - cam.WorldViewCenter;
|
||||
camDiff.Y = -camDiff.Y;
|
||||
|
||||
Sprite activeSprite = obj.Sprite;
|
||||
activeSprite?.Draw(
|
||||
spriteBatch,
|
||||
new Vector2(obj.Position.X, -obj.Position.Y) - camDiff * obj.Position.Z * ParallaxStrength,
|
||||
Color.Lerp(obj.Prefab.SpriteColor, obj.Prefab.SpriteColor.Multiply(Level.Loaded.BackgroundTextureColor), obj.Position.Z / obj.Prefab.FadeOutDepth),
|
||||
activeSprite.Origin,
|
||||
obj.CurrentRotation,
|
||||
obj.CurrentScale,
|
||||
SpriteEffects.None,
|
||||
z);
|
||||
|
||||
if (obj.ActivePrefab.DeformableSprite != null)
|
||||
bool hasDeformableSprite = false;
|
||||
if (obj2 is LevelObject levelObject)
|
||||
{
|
||||
if (obj.CurrentSpriteDeformation != null)
|
||||
hasDeformableSprite = levelObject.ActivePrefab.DeformableSprite != null;
|
||||
if (hasDeformableSprite != prevObjectHasDeformableSprite)
|
||||
{
|
||||
obj.ActivePrefab.DeformableSprite.Deform(obj.CurrentSpriteDeformation);
|
||||
spriteBatch.End();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred,
|
||||
BlendState.NonPremultiplied,
|
||||
SamplerState.LinearWrap, DepthStencilState.DepthRead,
|
||||
transformMatrix: cam.Transform);
|
||||
}
|
||||
else
|
||||
|
||||
Sprite activeSprite = levelObject.Sprite;
|
||||
activeSprite?.Draw(
|
||||
spriteBatch,
|
||||
new Vector2(levelObject.Position.X, -levelObject.Position.Y) - camDiff * levelObject.Position.Z * ParallaxStrength,
|
||||
Color.Lerp(levelObject.Prefab.SpriteColor, levelObject.Prefab.SpriteColor.Multiply(Level.Loaded.BackgroundTextureColor), levelObject.Position.Z / levelObject.Prefab.FadeOutDepth),
|
||||
activeSprite.Origin,
|
||||
levelObject.CurrentRotation,
|
||||
levelObject.CurrentScale,
|
||||
SpriteEffects.None,
|
||||
z);
|
||||
|
||||
if (hasDeformableSprite)
|
||||
{
|
||||
obj.ActivePrefab.DeformableSprite.Reset();
|
||||
}
|
||||
obj.ActivePrefab.DeformableSprite?.Draw(cam,
|
||||
new Vector3(new Vector2(obj.Position.X, obj.Position.Y) - camDiff * obj.Position.Z * ParallaxStrength, z * 10.0f),
|
||||
obj.ActivePrefab.DeformableSprite.Origin,
|
||||
obj.CurrentRotation,
|
||||
obj.CurrentScale,
|
||||
Color.Lerp(obj.Prefab.SpriteColor, obj.Prefab.SpriteColor.Multiply(Level.Loaded.BackgroundTextureColor), obj.Position.Z / 5000.0f));
|
||||
}
|
||||
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Vector2(obj.Position.X, -obj.Position.Y), new Vector2(10.0f, 10.0f), GUIStyle.Red, true);
|
||||
|
||||
if (obj.Triggers == null) { continue; }
|
||||
foreach (LevelTrigger trigger in obj.Triggers)
|
||||
{
|
||||
if (trigger.PhysicsBody == null) continue;
|
||||
GUI.DrawLine(spriteBatch, new Vector2(obj.Position.X, -obj.Position.Y), new Vector2(trigger.WorldPosition.X, -trigger.WorldPosition.Y), Color.Cyan, 0, 3);
|
||||
|
||||
Vector2 flowForce = trigger.GetWaterFlowVelocity();
|
||||
if (flowForce.LengthSquared() > 1)
|
||||
if (levelObject.CurrentSpriteDeformation != null)
|
||||
{
|
||||
flowForce.Y = -flowForce.Y;
|
||||
GUI.DrawLine(spriteBatch, new Vector2(trigger.WorldPosition.X, -trigger.WorldPosition.Y), new Vector2(trigger.WorldPosition.X, -trigger.WorldPosition.Y) + flowForce * 10, GUIStyle.Orange, 0, 5);
|
||||
levelObject.ActivePrefab.DeformableSprite.Deform(levelObject.CurrentSpriteDeformation);
|
||||
}
|
||||
trigger.PhysicsBody.UpdateDrawPosition();
|
||||
trigger.PhysicsBody.DebugDraw(spriteBatch, trigger.IsTriggered ? Color.Cyan : Color.DarkCyan);
|
||||
else
|
||||
{
|
||||
levelObject.ActivePrefab.DeformableSprite.Reset();
|
||||
}
|
||||
levelObject.ActivePrefab.DeformableSprite?.Draw(cam,
|
||||
new Vector3(new Vector2(levelObject.Position.X, levelObject.Position.Y) - camDiff * levelObject.Position.Z * ParallaxStrength, z * 10.0f),
|
||||
levelObject.ActivePrefab.DeformableSprite.Origin,
|
||||
levelObject.CurrentRotation,
|
||||
levelObject.CurrentScale,
|
||||
Color.Lerp(levelObject.Prefab.SpriteColor, levelObject.Prefab.SpriteColor.Multiply(Level.Loaded.BackgroundTextureColor), levelObject.Position.Z / 5000.0f));
|
||||
}
|
||||
prevObjectHasDeformableSprite = hasDeformableSprite;
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Vector2(levelObject.Position.X, -levelObject.Position.Y), new Vector2(10.0f, 10.0f), GUIStyle.Red, true);
|
||||
|
||||
if (levelObject.Triggers == null) { continue; }
|
||||
foreach (LevelTrigger trigger in levelObject.Triggers)
|
||||
{
|
||||
if (trigger.PhysicsBody == null) continue;
|
||||
GUI.DrawLine(spriteBatch, new Vector2(levelObject.Position.X, -levelObject.Position.Y), new Vector2(trigger.WorldPosition.X, -trigger.WorldPosition.Y), Color.Cyan, 0, 3);
|
||||
|
||||
Vector2 flowForce = trigger.GetWaterFlowVelocity();
|
||||
if (flowForce.LengthSquared() > 1)
|
||||
{
|
||||
flowForce.Y = -flowForce.Y;
|
||||
GUI.DrawLine(spriteBatch, new Vector2(trigger.WorldPosition.X, -trigger.WorldPosition.Y), new Vector2(trigger.WorldPosition.X, -trigger.WorldPosition.Y) + flowForce * 10, GUIStyle.Orange, 0, 5);
|
||||
}
|
||||
trigger.PhysicsBody.UpdateDrawPosition();
|
||||
trigger.PhysicsBody.DebugDraw(spriteBatch, trigger.IsTriggered ? Color.Cyan : Color.DarkCyan);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (obj2 is BackgroundCreature backgroundCreature && cam.Zoom > 0.05f)
|
||||
{
|
||||
hasDeformableSprite = backgroundCreature.Prefab.DeformableSprite != null;
|
||||
if (hasDeformableSprite != prevObjectHasDeformableSprite)
|
||||
{
|
||||
spriteBatch.End();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred,
|
||||
BlendState.NonPremultiplied,
|
||||
SamplerState.LinearWrap, DepthStencilState.DepthRead,
|
||||
transformMatrix: cam.Transform);
|
||||
}
|
||||
|
||||
backgroundCreature.Draw(spriteBatch, cam);
|
||||
}
|
||||
prevObjectHasDeformableSprite = hasDeformableSprite;
|
||||
|
||||
|
||||
z += 0.0001f;
|
||||
}
|
||||
|
||||
@@ -214,8 +214,9 @@ namespace Barotrauma
|
||||
//calculate the sum of the forces of nearby level triggers
|
||||
//and use it to move the water texture and water distortion effect
|
||||
Vector2 currentWaterParticleVel = level.GenerationParams.WaterParticleVelocity;
|
||||
foreach (LevelObject levelObject in level.LevelObjectManager.GetAllVisibleObjects())
|
||||
foreach (ILevelRenderableObject obj in level.LevelObjectManager.GetAllVisibleObjects())
|
||||
{
|
||||
if (obj is not LevelObject levelObject) { continue; }
|
||||
if (levelObject.Triggers == null) { continue; }
|
||||
//use the largest water flow velocity of all the triggers
|
||||
Vector2 objectMaxFlow = Vector2.Zero;
|
||||
@@ -274,11 +275,7 @@ namespace Barotrauma
|
||||
SamplerState.LinearWrap, DepthStencilState.DepthRead, null, null,
|
||||
cam.Transform);
|
||||
|
||||
backgroundSpriteManager?.DrawObjectsBack(spriteBatch, cam);
|
||||
if (cam.Zoom > 0.05f)
|
||||
{
|
||||
backgroundCreatureManager?.Draw(spriteBatch, cam);
|
||||
}
|
||||
backgroundSpriteManager?.DrawObjectsBack(spriteBatch, backgroundCreatureManager, cam);
|
||||
|
||||
level.GenerationParams.DrawWaterParticles(spriteBatch, cam, waterParticleOffset);
|
||||
|
||||
@@ -292,17 +289,18 @@ namespace Barotrauma
|
||||
BlendState.NonPremultiplied,
|
||||
SamplerState.LinearClamp, DepthStencilState.DepthRead, null, null,
|
||||
cam.Transform);
|
||||
backgroundSpriteManager?.DrawObjectsMid(spriteBatch, cam);
|
||||
backgroundSpriteManager?.DrawObjectsMid(spriteBatch, backgroundCreatureManager, cam);
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
public void DrawForeground(SpriteBatch spriteBatch, Camera cam, LevelObjectManager backgroundSpriteManager = null)
|
||||
public void DrawForeground(SpriteBatch spriteBatch, Camera cam,
|
||||
BackgroundCreatureManager backgroundCreatureManager, LevelObjectManager backgroundSpriteManager = null)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred,
|
||||
BlendState.NonPremultiplied,
|
||||
SamplerState.LinearClamp, DepthStencilState.DepthRead, null, null,
|
||||
cam.Transform);
|
||||
backgroundSpriteManager?.DrawObjectsFront(spriteBatch, cam);
|
||||
backgroundSpriteManager?.DrawObjectsFront(spriteBatch, backgroundCreatureManager, cam);
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
|
||||
@@ -2547,7 +2547,7 @@ namespace Barotrauma.Networking
|
||||
segmentTable.StartNewSegment(ClientNetSegment.SyncIds);
|
||||
//outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
|
||||
outmsg.WriteUInt16(ChatMessage.LastID);
|
||||
outmsg.WriteUInt16(EntityEventManager.LastReceivedID);
|
||||
outmsg.WriteUInt16(SpoofEntityManagerReceivedId ? (ushort)1 : EntityEventManager.LastReceivedID);
|
||||
outmsg.WriteUInt16(LastClientListUpdateID);
|
||||
|
||||
if (!(GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign) || campaign.LastSaveID == 0)
|
||||
@@ -3370,6 +3370,12 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
get { return votingInterface; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces the client to report the last received event ID as always being 1, making the server believe the client is always behind.
|
||||
/// </summary>
|
||||
public bool SpoofEntityManagerReceivedId { get; set; }
|
||||
|
||||
private VotingInterface votingInterface;
|
||||
|
||||
public bool TypingChatMessage(GUITextBox textBox, string text)
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
byte queueId = msg.ReadByte();
|
||||
float distanceFactor = msg.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
bool isRadio = msg.ReadBoolean();
|
||||
VoipQueue queue = queues.Find(q => q.QueueID == queueId);
|
||||
|
||||
if (queue == null)
|
||||
@@ -117,19 +118,21 @@ namespace Barotrauma.Networking
|
||||
float rangeMultiplier = spectating ? 2.0f : 1.0f;
|
||||
WifiComponent senderRadio = null;
|
||||
|
||||
var messageType =
|
||||
!client.VoipQueue.ForceLocal &&
|
||||
ChatMessage.CanUseRadio(client.Character, out senderRadio) &&
|
||||
(spectating || (ChatMessage.CanUseRadio(Character.Controlled, out var recipientRadio) && senderRadio.CanReceive(recipientRadio)))
|
||||
? ChatMessageType.Radio : ChatMessageType.Default;
|
||||
var messageType = isRadio ? ChatMessageType.Radio : ChatMessageType.Default;
|
||||
|
||||
client.Character.ShowTextlessSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
|
||||
|
||||
client.VoipSound.UseRadioFilter = messageType == ChatMessageType.Radio && !GameSettings.CurrentConfig.Audio.DisableVoiceChatFilters;
|
||||
client.RadioNoise = 0.0f;
|
||||
if (messageType == ChatMessageType.Radio)
|
||||
{
|
||||
//If the client cannot establish a radio, use a headsets default range as a fallback to calculate the radio noise.
|
||||
//This cannot happen in an un-modded setting as CanUseRadio is part of the server side check for isRadio to be true.
|
||||
ChatMessage.CanUseRadio(client.Character, out senderRadio);
|
||||
float senderRadioRange = (senderRadio == null) ? 35000.0f : senderRadio.Range;
|
||||
|
||||
client.VoipSound.UsingRadio = true;
|
||||
client.VoipSound.SetRange(senderRadio.Range * RangeNear * speechImpedimentMultiplier * rangeMultiplier, senderRadio.Range * speechImpedimentMultiplier * rangeMultiplier);
|
||||
client.VoipSound.SetRange(senderRadioRange * RangeNear * speechImpedimentMultiplier * rangeMultiplier, senderRadioRange * speechImpedimentMultiplier * rangeMultiplier);
|
||||
if (distanceFactor > RangeNear && !spectating)
|
||||
{
|
||||
//noise starts increasing exponentially after 40% range
|
||||
|
||||
@@ -533,6 +533,18 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
new GUITickBox(new RectTransform(new Point(300, 30), Frame.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point(40, 280) },
|
||||
"Lenient server startup timeouts")
|
||||
{
|
||||
Selected = NetConfig.UseLenientHandshake,
|
||||
ToolTip = "Start with more lenient Lidgren handshake timeouts. The server is more likely to start even when running multiple instances on the same machine under heavy load.",
|
||||
OnSelected = (tickBox) =>
|
||||
{
|
||||
NetConfig.UseLenientHandshake = tickBox.Selected;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
var minButtonSize = new Point(120, 20);
|
||||
@@ -1126,6 +1138,11 @@ namespace Barotrauma
|
||||
}
|
||||
#endif
|
||||
|
||||
if (NetConfig.UseLenientHandshake)
|
||||
{
|
||||
arguments.Add("-lenienthandshake");
|
||||
}
|
||||
|
||||
var processInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.IO;
|
||||
using Barotrauma.Items.Components;
|
||||
using Barotrauma.Sounds;
|
||||
using Barotrauma.Steam;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Steamworks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.LuaCs.Events;
|
||||
using Barotrauma.Sounds;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -2044,6 +2047,8 @@ namespace Barotrauma
|
||||
|
||||
private bool SaveSubToFile(string name, ContentPackage packageToSaveTo)
|
||||
{
|
||||
bool remoteStorageWasEnabled = Submarine.MainSub.Info.SaveToRemoteStorage;
|
||||
|
||||
Type subFileType = DetermineSubFileType(MainSub?.Info.Type ?? SubmarineType.Player);
|
||||
|
||||
static string getExistingFilePath(ContentPackage package, string fileName)
|
||||
@@ -2272,6 +2277,16 @@ namespace Barotrauma
|
||||
linkedSubBox.AddItem(sub.Name, sub);
|
||||
}
|
||||
subNameLabel.Text = ToolBox.LimitString(MainSub.Info.Name, subNameLabel.Font, subNameLabel.Rect.Width);
|
||||
|
||||
if (remoteStorageWasEnabled)
|
||||
{
|
||||
Submarine.MainSub.Info.SaveToRemoteStorage = true;
|
||||
|
||||
RemoteStorageHelper.TryWrite(
|
||||
localPath: MainSub.Info.FilePath,
|
||||
saveAs: MainSub.Info.FilePath.CleanUpPathCrossPlatform(correctFilenameCase: false),
|
||||
allowOverwrite: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3223,6 +3238,42 @@ namespace Barotrauma
|
||||
|
||||
previewImageButtonHolder.RectTransform.MinSize = new Point(0, previewImageButtonHolder.RectTransform.Children.Max(c => c.MinSize.Y));
|
||||
|
||||
if (SteamManager.IsInitialized)
|
||||
{
|
||||
GUILayoutGroup remoteStorageArea = new(
|
||||
new RectTransform(new Vector2(1f, 0.05f), rightColumn.RectTransform,
|
||||
minSize: new Point(0, minHeight)),
|
||||
isHorizontal: true,
|
||||
childAnchor: Anchor.CenterLeft)
|
||||
{
|
||||
Stretch = true,
|
||||
AbsoluteSpacing = 5
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(Vector2.One, remoteStorageArea.RectTransform),
|
||||
TextManager.Get("RemoteStorageToggle.Title"), textAlignment: Alignment.CenterLeft, wrap: true);
|
||||
|
||||
new GUITickBox(new RectTransform(Vector2.One, remoteStorageArea.RectTransform), label: "")
|
||||
{
|
||||
OnAddedToGUIUpdateList = component =>
|
||||
{
|
||||
// Values may change outside of game.
|
||||
component.Enabled = SteamRemoteStorage.IsCloudEnabledForAccount;
|
||||
component.ToolTip = !SteamRemoteStorage.IsCloudEnabledForAccount ? TextManager.Get("RemoteStorageToggle.Disabled") : "";
|
||||
((GUITickBox)component).SetSelected(SteamRemoteStorage.IsCloudEnabled && MainSub.Info.SaveToRemoteStorage, callOnSelected: false);
|
||||
},
|
||||
OnSelected = tickBox =>
|
||||
{
|
||||
if (tickBox.Selected && !SteamRemoteStorage.IsCloudEnabledForApp)
|
||||
{
|
||||
RemoteStorageHelper.AskToEnable(onAccepted: () => MainSub.Info.SaveToRemoteStorage = true);
|
||||
return false;
|
||||
}
|
||||
return MainSub.Info.SaveToRemoteStorage = tickBox.Selected;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var contentPackageTabber = new GUILayoutGroup(new RectTransform((1.0f, 0.075f), rightColumn.RectTransform), isHorizontal: true);
|
||||
|
||||
GUIButton createTabberBtn(string labelTag)
|
||||
@@ -3746,7 +3797,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
var package = GetLocalPackageThatOwnsSub(subInfo);
|
||||
if (package != null)
|
||||
if (package != null || subInfo.IsFromRemoteStorage)
|
||||
{
|
||||
deleteBtn.Enabled = true;
|
||||
}
|
||||
@@ -3771,13 +3822,29 @@ namespace Barotrauma
|
||||
searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = sender.Text.IsNullOrEmpty(); };
|
||||
searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return true; };
|
||||
|
||||
var sortedSubs = GetLoadableSubs()
|
||||
.OrderBy(s => s.Type)
|
||||
.ThenBy(s => s.Name)
|
||||
.ToList();
|
||||
List<SubmarineInfo> allSubs = [.. SubmarineInfo.SavedSubmarines];
|
||||
foreach (SteamRemoteStorage.RemoteFile remoteFile in SteamRemoteStorage.Files.Where(file => file.Filename.EndsWith(".sub")))
|
||||
{
|
||||
if (!remoteFile.TryRead(out byte[] bytes)) { continue; }
|
||||
|
||||
using System.IO.MemoryStream stream = new(bytes);
|
||||
using GZipStream zipStream = new(stream, CompressionMode.Decompress);
|
||||
if (XMLExtensions.TryLoadXml(zipStream) is not XDocument doc)
|
||||
{
|
||||
DebugConsole.ThrowError($"{RemoteStorageHelper.DebugPrefix} Failed to load submarine \"{remoteFile.Filename}\" from remote storage: file is not a valid XML document.");
|
||||
continue;
|
||||
}
|
||||
|
||||
SubmarineInfo subInfo = new(remoteFile.Filename, element: doc.Root, tryLoad: false) { IsFromRemoteStorage = true };
|
||||
allSubs.Add(subInfo);
|
||||
}
|
||||
|
||||
IOrderedEnumerable<SubmarineInfo> sortedSubs = allSubs
|
||||
.OrderBy(kvp => kvp.Type)
|
||||
.ThenBy(kvp => kvp.Name)
|
||||
.ThenBy(kvp => kvp.IsFromRemoteStorage);
|
||||
|
||||
SubmarineInfo prevSub = null;
|
||||
|
||||
foreach (SubmarineInfo sub in sortedSubs)
|
||||
{
|
||||
if (prevSub == null || prevSub.Type != sub.Type)
|
||||
@@ -3795,35 +3862,44 @@ namespace Barotrauma
|
||||
prevSub = sub;
|
||||
}
|
||||
|
||||
string pathWithoutUserName = Path.GetFullPath(sub.FilePath);
|
||||
string saveFolder = Path.GetFullPath(SaveUtil.DefaultSaveFolder);
|
||||
if (pathWithoutUserName.StartsWith(saveFolder))
|
||||
string displayPath = sub.FilePath;
|
||||
if (sub.IsFromRemoteStorage)
|
||||
{
|
||||
pathWithoutUserName = "..." + pathWithoutUserName[saveFolder.Length..];
|
||||
displayPath += $" {TextManager.Get("RemoteStorage")}";
|
||||
}
|
||||
else
|
||||
{
|
||||
pathWithoutUserName = sub.FilePath;
|
||||
string saveFolder = Path.GetFullPath(SaveUtil.DefaultSaveFolder);
|
||||
string fullPath = Path.GetFullPath(displayPath);
|
||||
if (fullPath.StartsWith(saveFolder))
|
||||
{
|
||||
displayPath = $"...{fullPath[saveFolder.Length..]}";
|
||||
}
|
||||
}
|
||||
|
||||
GUITextBlock textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), subList.Content.RectTransform) { MinSize = new Point(0, 30) },
|
||||
ToolBox.LimitString(sub.Name, GUIStyle.Font, subList.Rect.Width - 80))
|
||||
LocalizedString limitedName = ToolBox.LimitString(sub.Name, GUIStyle.Font, subList.Rect.Width - 80);
|
||||
GUITextBlock textBlock = new(new RectTransform(Vector2.UnitX, subList.Content.RectTransform) { MinSize = new Point(0, 30) }, limitedName)
|
||||
{
|
||||
UserData = sub,
|
||||
ToolTip = pathWithoutUserName
|
||||
ToolTip = displayPath
|
||||
};
|
||||
|
||||
if (!(ContentPackageManager.VanillaCorePackage?.Files.Any(f => f.Path == sub.FilePath) ?? false))
|
||||
if (sub.IsFromRemoteStorage)
|
||||
{
|
||||
// remote storage
|
||||
textBlock.OverrideTextColor(RemoteStorageHelper.SteamColor);
|
||||
}
|
||||
else if (ContentPackageManager.VanillaCorePackage == null || ContentPackageManager.VanillaCorePackage.Files.None(f => f.Path == sub.FilePath))
|
||||
{
|
||||
if (GetLocalPackageThatOwnsSub(sub) == null &&
|
||||
ContentPackageManager.AllPackages.FirstOrDefault(p => p.Files.Any(f => f.Path == sub.FilePath)) is ContentPackage subPackage)
|
||||
{
|
||||
//workshop mod
|
||||
// workshop mod
|
||||
textBlock.OverrideTextColor(Color.MediumPurple);
|
||||
}
|
||||
else
|
||||
{
|
||||
//local mod
|
||||
// local mod
|
||||
textBlock.OverrideTextColor(GUIStyle.TextColorBright);
|
||||
}
|
||||
}
|
||||
@@ -4018,10 +4094,9 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(subList.SelectedComponent?.UserData is SubmarineInfo selectedSubInfo)) { return false; }
|
||||
if (subList.SelectedComponent?.UserData is not SubmarineInfo selectedSubInfo) { return false; }
|
||||
|
||||
var ownerPackage = GetLocalPackageThatOwnsSub(selectedSubInfo);
|
||||
if (ownerPackage is null)
|
||||
if (!selectedSubInfo.IsFromRemoteStorage && GetLocalPackageThatOwnsSub(selectedSubInfo) is null)
|
||||
{
|
||||
if (IsVanillaSub(selectedSubInfo))
|
||||
{
|
||||
@@ -4183,21 +4258,23 @@ namespace Barotrauma
|
||||
{
|
||||
if (sub == null) { return; }
|
||||
|
||||
//If the sub is included in a content package that only defines that one sub,
|
||||
//check that it's a local content package and only allow deletion if it is.
|
||||
//(deleting from the Submarines folder is also currently allowed, but this is temporary)
|
||||
var subPackage = GetLocalPackageThatOwnsSub(sub);
|
||||
if (!ContentPackageManager.LocalPackages.Regular.Contains(subPackage)) { return; }
|
||||
|
||||
var msgBox = new GUIMessageBox(
|
||||
TextManager.Get("DeleteDialogLabel"),
|
||||
TextManager.GetWithVariable("DeleteDialogQuestion", "[file]", sub.Name),
|
||||
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("Cancel") });
|
||||
// If the sub is included in a content package that only defines that one sub,
|
||||
// check that it's a local content package and only allow deletion if it is.
|
||||
// (deleting from the Submarines folder is also currently allowed, but this is temporary)
|
||||
ContentPackage subPackage = GetLocalPackageThatOwnsSub(sub);
|
||||
if (!ContentPackageManager.LocalPackages.Regular.Contains(subPackage)) { subPackage = null; }
|
||||
if (!sub.IsFromRemoteStorage && subPackage == null) { return; }
|
||||
|
||||
GUIMessageBox msgBox = new(TextManager.Get("DeleteDialogLabel"), TextManager.GetWithVariable("DeleteDialogQuestion", "[file]", sub.Name), [TextManager.Get("Yes"), TextManager.Get("Cancel")]);
|
||||
msgBox.Buttons[0].OnClicked += (btn, userData) =>
|
||||
{
|
||||
try
|
||||
if (sub.IsFromRemoteStorage)
|
||||
{
|
||||
if (subPackage != null)
|
||||
RemoteStorageHelper.TryDelete(sub.FilePath);
|
||||
}
|
||||
else if (subPackage != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(sub.FilePath, catchUnauthorizedAccessExceptions: false);
|
||||
ModProject modProject = new ModProject(subPackage);
|
||||
@@ -4208,17 +4285,17 @@ namespace Barotrauma
|
||||
{
|
||||
MainSub.Info.FilePath = null;
|
||||
}
|
||||
}
|
||||
sub.Dispose();
|
||||
CreateLoadScreen();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowErrorLocalized(TextManager.GetWithVariable("DeleteFileError", "[file]", sub.FilePath), e);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowErrorLocalized(TextManager.GetWithVariable("DeleteFileError", "[file]", sub.FilePath), e);
|
||||
}
|
||||
return true;
|
||||
|
||||
sub.Dispose();
|
||||
CreateLoadScreen();
|
||||
return msgBox.Close(btn, userData);
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||
msgBox.Buttons[1].OnClicked += msgBox.Close;
|
||||
}
|
||||
|
||||
|
||||
@@ -445,7 +445,7 @@ namespace Barotrauma
|
||||
{
|
||||
DebugConsole.NewMessage("Missing Localization for property: " + propertyTag);
|
||||
MissingLocalizations.Add($"sp.{propertyTag}.name|{displayName}");
|
||||
MissingLocalizations.Add($"sp.{propertyTag}.description|{property.GetAttribute<Serialize>().Description}");
|
||||
MissingLocalizations.Add($"sp.{propertyTag}.description|{property.GetAttribute<Serialize>()?.Description}");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -467,7 +467,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (toolTip.IsNullOrEmpty())
|
||||
{
|
||||
toolTip = property.GetAttribute<Serialize>().Description;
|
||||
toolTip = property.GetAttribute<Serialize>()?.Description;
|
||||
}
|
||||
|
||||
GUIComponent propertyField = null;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#nullable enable
|
||||
using Steamworks;
|
||||
using System;
|
||||
namespace Barotrauma.Steam;
|
||||
|
||||
internal static partial class RemoteStorageHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Asks the user if they wish to enable remote storage. Accepting enables it automatically.
|
||||
/// </summary>
|
||||
/// <param name="onAccepted">Invoked when the user accepts enabling remote storage.</param>
|
||||
/// <param name="onRejected">Invoked when the user rejects enabling remote storage.</param>
|
||||
/// <remarks>Closes automatically if remote storage was enabled outside of the game, or if remote storage can not be enabled.</remarks>
|
||||
public static void AskToEnable(Action? onAccepted = null, Action? onRejected = null)
|
||||
{
|
||||
GUIMessageBox confirmBox = new GUIMessageBox(
|
||||
TextManager.Get("RemoteStorageEnablePopup.Header"),
|
||||
TextManager.Get("RemoteStorageEnablePopup.Text"),
|
||||
[TextManager.Get("Yes"), TextManager.Get("No")],
|
||||
autoCloseCondition: () => !SteamRemoteStorage.IsCloudEnabledForAccount || SteamRemoteStorage.IsCloudEnabledForApp);
|
||||
|
||||
confirmBox.Buttons[0].OnClicked += (btn, data) =>
|
||||
{
|
||||
SteamRemoteStorage.IsCloudEnabledForApp = true;
|
||||
onAccepted?.Invoke();
|
||||
return confirmBox.Close(btn, data);
|
||||
};
|
||||
confirmBox.Buttons[1].OnClicked += (btn, data) =>
|
||||
{
|
||||
onRejected?.Invoke();
|
||||
return confirmBox.Close(btn, data);
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user