Unstable v0.19.5.0

This commit is contained in:
Juan Pablo Arce
2022-09-14 12:47:17 -03:00
parent 3f2c843247
commit 1fd2a51bbb
158 changed files with 5702 additions and 4813 deletions
@@ -67,6 +67,8 @@ namespace Barotrauma
public static readonly Queue<ulong> WorkshopItemsToUpdate = new Queue<ulong>();
private readonly GUIListBox tutorialList;
#region Creation
public MainMenuScreen(GameMain game)
{
@@ -429,26 +431,19 @@ namespace Barotrauma
menuTabs[Tab.Tutorials] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing });
//PLACEHOLDER
var tutorialList = new GUIListBox(
tutorialList = new GUIListBox(
new RectTransform(new Vector2(0.95f, 0.85f), menuTabs[Tab.Tutorials].RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.1f) })
{
PlaySoundOnSelect = true,
};
foreach (var tutorialPrefab in TutorialPrefab.Prefabs.OrderBy(p => p.Order))
{
var tutorial = new Tutorial(tutorialPrefab);
var tutorialText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), tutorialList.Content.RectTransform), tutorial.DisplayName, textAlignment: Alignment.Center, font: GUIStyle.LargeFont)
{
TextColor = GUIStyle.Green,
UserData = tutorial
};
}
tutorialList.OnSelected += (component, obj) =>
{
(obj as Tutorial)?.Start();
return true;
};
CreateTutorialButtons();
this.game = game;
menuTabs[Tab.Credits] = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null)
@@ -463,7 +458,28 @@ namespace Barotrauma
var creditsContainer = new GUIFrame(new RectTransform(new Vector2(0.75f, 1.5f), menuTabs[Tab.Credits].RectTransform, Anchor.CenterRight), style: "OuterGlow", color: Color.Black * 0.8f);
creditsPlayer = new CreditsPlayer(new RectTransform(Vector2.One, creditsContainer.RectTransform), "Content/Texts/Credits.xml");
}
#endregion
private void CreateTutorialButtons()
{
foreach (var tutorialPrefab in TutorialPrefab.Prefabs.OrderBy(p => p.Order))
{
var tutorial = new Tutorial(tutorialPrefab);
var tutorialText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), tutorialList.Content.RectTransform), tutorial.DisplayName, textAlignment: Alignment.Center, font: GUIStyle.LargeFont)
{
TextColor = GUIStyle.Green,
UserData = tutorial
};
}
}
public static void UpdateInstanceTutorialButtons()
{
if (GameMain.MainMenuScreen is not MainMenuScreen menuScreen) { return; }
menuScreen.tutorialList.ClearChildren();
menuScreen.CreateTutorialButtons();
}
#endregion
#region Selection
public override void Select()
@@ -1117,7 +1133,7 @@ namespace Barotrauma
var playstyleContainer = new GUIFrame(new RectTransform(new Vector2(1.35f, 0.1f), parent.RectTransform), style: null, color: Color.Black);
playstyleBanner = new GUIImage(new RectTransform(new Vector2(1.0f, 0.1f), playstyleContainer.RectTransform),
ServerListScreen.PlayStyleBanners[0], scaleToFit: true)
GUIStyle.GetComponentStyle($"PlayStyleBanner.{PlayStyle.Serious}").GetSprite(GUIComponent.ComponentState.None), scaleToFit: true)
{
UserData = PlayStyle.Serious
};
@@ -1336,12 +1352,15 @@ namespace Barotrauma
private void SetServerPlayStyle(PlayStyle playStyle)
{
playstyleBanner.Sprite = ServerListScreen.PlayStyleBanners[(int)playStyle];
playstyleBanner.Sprite = GUIStyle
.GetComponentStyle($"PlayStyleBanner.{playStyle}")
.GetSprite(GUIComponent.ComponentState.None);
playstyleBanner.UserData = playStyle;
var nameText = playstyleBanner.GetChild<GUITextBlock>();
nameText.Text = TextManager.AddPunctuation(':', TextManager.Get("serverplaystyle"), TextManager.Get("servertag." + playStyle));
nameText.Color = ServerListScreen.PlayStyleColors[(int)playStyle];
nameText.Color = playstyleBanner.Sprite
.SourceElement.GetAttributeColor("BannerColor") ?? Color.White;
nameText.RectTransform.NonScaledSize = (nameText.Font.MeasureString(nameText.Text) + new Vector2(25, 10) * GUI.Scale).ToPoint();
playstyleDescription.Text = TextManager.Get("servertagdescription." + playStyle);
@@ -92,7 +92,7 @@ namespace Barotrauma
var missingPackages = GameMain.Client.ClientPeer.ServerContentPackages
.Where(sp => sp.ContentPackage is null).ToArray();
if (!missingPackages.Any())
if (!missingPackages.Any(p => p.IsMandatory))
{
if (!GameMain.Client.IsServerOwner)
{
@@ -106,7 +106,7 @@ namespace Barotrauma
.Select(p => p.RegularPackage)
.OfType<RegularPackage>().ToList();
//keep enabled client-side-only mods enabled
regularPackages.AddRange(ContentPackageManager.EnabledPackages.Regular.Where(p => !p.HasMultiplayerSyncedContent));
regularPackages.AddRange(ContentPackageManager.EnabledPackages.Regular.Where(p => !p.HasMultiplayerSyncedContent && !regularPackages.Contains(p)));
ContentPackageManager.EnabledPackages.SetRegular(regularPackages);
}
GameMain.NetLobbyScreen.Select();
@@ -177,11 +177,11 @@ namespace Barotrauma
});
buttonContainerSpacing(0.1f);
var missingIds = missingPackages.Where(
mp => mp.WorkshopId != 0
&& ContentPackageManager.WorkshopPackages.All(wp
=> wp.SteamWorkshopId != mp.WorkshopId))
.Select(mp => mp.WorkshopId)
var missingIds = missingPackages
.Where(p => p.IsMandatory)
.Select(mp => ContentPackageId.Parse(mp.UgcId))
.NotNone()
.Where(id => ContentPackageManager.WorkshopPackages.All(wp => !wp.UgcId.Equals(id)))
.ToArray();
if (missingIds.Any() && SteamManager.IsInitialized)
{
@@ -191,7 +191,7 @@ namespace Barotrauma
{
if (GameMain.Client != null)
{
BulkDownloader.SubscribeToServerMods(missingIds,
BulkDownloader.SubscribeToServerMods(missingIds.OfType<SteamWorkshopId>().Select(id => id.Value),
new ConnectCommand(
serverName: GameMain.Client.ServerName,
endpoint: GameMain.Client.ClientPeer.ServerEndpoint));
@@ -202,7 +202,7 @@ namespace Barotrauma
buttonContainerSpacing(0.15f);
}
foreach (var p in missingPackages)
foreach (var p in missingPackages.Where(p => p.IsMandatory))
{
pendingDownloads.Enqueue(p);
@@ -294,26 +294,50 @@ namespace Barotrauma
?? serverPackages.FirstOrDefault(p => p.CorePackage != null)
?.CorePackage
?? throw new Exception($"Failed to find core package to enable");
List<RegularPackage> regularPackages
= serverPackages.Where(p => p.CorePackage is null)
.Select(p =>
p.RegularPackage
?? downloadedPackages.FirstOrDefault(d => d is RegularPackage && d.Hash.Equals(p.Hash))
?? throw new Exception($"Could not find regular package \"{p.Name}\""))
.Cast<RegularPackage>()
.ToList();
List<RegularPackage> regularPackages = new List<RegularPackage>();
foreach (var p in serverPackages)
{
if (p.CorePackage != null) { continue; }
RegularPackage? matchingPackage =
p.RegularPackage ?? downloadedPackages.FirstOrDefault(d => d is RegularPackage && d.Hash.Equals(p.Hash)) as RegularPackage;
if (matchingPackage is null)
{
if (!p.IsMandatory)
{
//we don't need to care about missing non-mandatory (= submarine) mods
continue;
}
else
{
throw new Exception($"Could not find regular package \"{p.Name}\"");
}
}
regularPackages.Add(matchingPackage);
}
foreach (var regularPackage in regularPackages)
{
DebugConsole.NewMessage($"Enabling \"{regularPackage.Name}\" ({regularPackage.Dir})", Color.Lime);
}
//keep enabled client-side-only mods enabled
regularPackages.AddRange(ContentPackageManager.EnabledPackages.Regular.Where(p => !p.HasMultiplayerSyncedContent));
regularPackages.AddRange(ContentPackageManager.EnabledPackages.Regular.Where(p => !p.HasMultiplayerSyncedContent && !regularPackages.Contains(p)));
ContentPackageManager.EnabledPackages.BackUp();
ContentPackageManager.EnabledPackages.SetCore(corePackage);
ContentPackageManager.EnabledPackages.SetRegular(regularPackages);
//see if any of the packages we enabled contain subs that we were missing previously, and update their paths
foreach (var serverSub in GameMain.Client.ServerSubmarines)
{
if (File.Exists(serverSub.FilePath)) { continue; }
var matchingSub = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == serverSub.Name && s.MD5Hash == serverSub.MD5Hash);
if (matchingSub != null)
{
serverSub.FilePath = matchingSub.FilePath;
}
}
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.SubList, GameMain.Client.ServerSubmarines);
GameMain.NetLobbyScreen.Select();
}
}
@@ -666,7 +666,7 @@ namespace Barotrauma
OnSelected = (tickbox) =>
{
if (GameMain.Client == null) { return true; }
ServerInfo info = GameMain.Client.ServerSettings.GetServerListInfo();
ServerInfo info = GameMain.Client.CreateServerInfoFromSettings();
if (tickbox.Selected)
{
GameMain.ServerListScreen.AddToFavoriteServers(info);
@@ -1432,10 +1432,6 @@ namespace Barotrauma
bool nameChangePending = isGameRunning && GameMain.Client.PendingName != string.Empty && GameMain.Client?.Character?.Name != GameMain.Client.PendingName;
changesPendingText = null;
if (isGameRunning)
{
infoContainer.RectTransform.AbsoluteOffset = new Point(0, (int)(parent.Rect.Height * 0.025f));
}
if (TabMenu.PendingChanges)
{
@@ -1454,7 +1450,6 @@ namespace Barotrauma
{
if (GameMain.Client == null) { return; }
string newName = Client.SanitizeName(tb.Text);
newName = newName.Replace(":", "").Replace(";", "");
if (newName == GameMain.Client.Name) return;
if (string.IsNullOrWhiteSpace(newName))
{
@@ -1782,6 +1777,10 @@ namespace Barotrauma
// Hide spectate tickbox if spectating is not allowed
spectateBox.Visible = allowSpectating;
if (infoContainer != null)
{
infoContainer.RectTransform.RelativeSize = new Vector2(infoContainer.RectTransform.RelativeSize.X, spectateBox.Visible ? 0.92f : 0.97f);
}
}
public void SetAutoRestart(bool enabled, float timer = 0.0f)
@@ -2753,25 +2752,24 @@ namespace Barotrauma
if (GameMain.NetworkMember?.ServerSettings == null) { return; }
PlayStyle playStyle = GameMain.NetworkMember.ServerSettings.PlayStyle;
if ((int)playStyle < 0 ||
(int)playStyle >= ServerListScreen.PlayStyleBanners.Length)
{
return;
}
Sprite sprite = ServerListScreen.PlayStyleBanners[(int)playStyle];
Sprite sprite = GUIStyle
.GetComponentStyle($"PlayStyleBanner.{playStyle}")?
.GetSprite(GUIComponent.ComponentState.None);
if (sprite is null) { return; }
float scale = component.Rect.Width / sprite.size.X;
sprite.Draw(spriteBatch, component.Center, scale: scale);
if (!prevPlayStyle.HasValue || playStyle != prevPlayStyle.Value)
{
var nameText = component.GetChild<GUITextBlock>();
nameText.Text = TextManager.Get("servertag." + playStyle);
nameText.Color = ServerListScreen.PlayStyleColors[(int)playStyle];
nameText.Text = TextManager.Get($"ServerTag.{playStyle}");
nameText.Color = sprite.SourceElement.GetAttributeColor("BannerColor") ?? Color.White;
nameText.RectTransform.NonScaledSize = (nameText.Font.MeasureString(nameText.Text) + new Vector2(25, 10) * GUI.Scale).ToPoint();
prevPlayStyle = playStyle;
component.ToolTip = TextManager.Get("servertagdescription." + playStyle);
component.ToolTip = TextManager.Get($"ServerTagDescription.{playStyle}");
}
publicOrPrivate.RectTransform.NonScaledSize = (publicOrPrivate.Font.MeasureString(publicOrPrivate.Text) + new Vector2(25, 8) * GUI.Scale).ToPoint();
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,112 @@
using System;
using Barotrauma.Extensions;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Barotrauma
{
public class PanelAnimator
{
private readonly GUIScissorComponent container;
private readonly GUIFrame leftFrame;
private readonly GUIComponent middleFrame;
private readonly GUIFrame rightFrame;
private readonly GUIButton leftButton;
private readonly GUIButton rightButton;
private float leftAnimState = 1.0f;
private float rightAnimState = 0.0f;
public bool LeftEnabled
{
get => leftButton.Enabled;
set => leftButton.Enabled = value;
}
public bool RightEnabled
{
get => rightButton.Enabled;
set => rightButton.Enabled = value;
}
public bool LeftVisible = true;
public bool RightVisible = false;
public PanelAnimator(RectTransform rectTransform, GUIFrame leftFrame, GUIComponent middleFrame, GUIFrame rightFrame)
{
container = new GUIScissorComponent(rectTransform);
this.leftFrame = leftFrame;
this.middleFrame = middleFrame;
this.rightFrame = rightFrame;
void own(GUIComponent component)
{
component.RectTransform.Parent = container.Content.RectTransform;
component.RectTransform.Anchor = Anchor.TopLeft;
component.RectTransform.Pivot = Pivot.TopLeft;
component.GetAllChildren<GUIDropDown>().ForEach(dd => dd.RefreshListBoxParent());
}
GUIButton makeButton(Action action)
=> new GUIButton(new RectTransform(new Vector2(0.01f, 1.0f), container.Content.RectTransform)
{ MinSize = new Point(20, 0), MaxSize = new Point(int.MaxValue, (int)(150 * GUI.Scale)) },
style: "UIToggleButton")
{
OnClicked = (_, __) =>
{
action();
return false;
}
};
own(leftFrame);
this.leftButton = makeButton(() => LeftVisible = !LeftVisible);
own(middleFrame);
this.rightButton = makeButton(() => RightVisible = !RightVisible);
own(rightFrame);
}
public void Update()
{
if (!LeftEnabled) { LeftVisible = false; }
if (!RightEnabled) { RightVisible = false; }
static void updateState(ref float state, bool visible)
=> state = MathHelper.Lerp(state, visible ? 0.0f : 1.0f, 0.5f);
updateState(ref leftAnimState, LeftVisible);
updateState(ref rightAnimState, RightVisible);
static int width(GUIComponent c)
=> c.RectTransform.NonScaledSize.X;
int height = container.RectTransform.NonScaledSize.Y;
int buttonY = height/2 - leftButton.RectTransform.NonScaledSize.Y/2;
leftFrame.RectTransform.AbsoluteOffset = new Point((int)(-width(leftFrame) * leftAnimState), 0);
leftButton.RectTransform.AbsoluteOffset = leftFrame.RectTransform.AbsoluteOffset
+ new Point(width(leftFrame), buttonY);
leftButton.Children.ForEach(c => c.SpriteEffects = LeftVisible
? SpriteEffects.FlipHorizontally
: SpriteEffects.None);
rightFrame.RectTransform.AbsoluteOffset = new Point((int)(width(container) + width(rightFrame) * (rightAnimState-1f)), 0);
rightButton.RectTransform.AbsoluteOffset = rightFrame.RectTransform.AbsoluteOffset
+ new Point(-width(rightButton), buttonY);
rightButton.Children.ForEach(c => c.SpriteEffects = RightVisible
? SpriteEffects.None
: SpriteEffects.FlipHorizontally);
middleFrame.RectTransform.AbsoluteOffset = new Point(
leftButton.RectTransform.AbsoluteOffset.X + width(leftButton),
0);
middleFrame.RectTransform.NonScaledSize = new Point(
rightButton.RectTransform.AbsoluteOffset.X - middleFrame.RectTransform.AbsoluteOffset.X,
height);
}
}
}
@@ -1547,6 +1547,8 @@ namespace Barotrauma
GUI.ForceMouseOn(null);
if (ImageManager.EditorMode) { GameSettings.SaveCurrentConfig(); }
MapEntityPrefab.Selected = null;
saveFrame = null;
@@ -1797,25 +1799,14 @@ namespace Barotrauma
{
Type subFileType = DetermineSubFileType(MainSub?.Info.Type ?? SubmarineType.Player);
void addSubAndSaveModProject(ModProject modProject, string filePath, string packagePath)
static string getExistingFilePath(ContentPackage package, string fileName)
{
filePath = filePath.CleanUpPath();
packagePath = packagePath.CleanUpPath();
string packageDir = Path.GetDirectoryName(packagePath).CleanUpPathCrossPlatform(correctFilenameCase: false);
if (filePath.StartsWith(packageDir))
if (Submarine.MainSub?.Info == null) { return null; }
if (package.Files.Any(f => f.Path == MainSub.Info.FilePath && Path.GetFileName(f.Path.Value) == fileName))
{
filePath = $"{ContentPath.ModDirStr}/{filePath[packageDir.Length..]}";
return MainSub.Info.FilePath;
}
if (!modProject.Files.Any(f => f.Type == subFileType &&
f.Path == filePath))
{
var newFile = ModProject.File.FromPath(filePath, subFileType);
modProject.AddFile(newFile);
}
using var _ = Validation.SkipInDebugBuilds();
modProject.DiscardHashAndInstallTime();
modProject.Save(packagePath);
return null;
}
if (!GameMain.DebugDraw)
@@ -1861,101 +1852,139 @@ namespace Barotrauma
#if !DEBUG
throw new InvalidOperationException("Cannot save to Vanilla package");
#endif
savePath = string.Format((MainSub?.Info.Type ?? SubmarineType.Player) switch
{
SubmarineType.Player => "Content/Submarines/{0}",
SubmarineType.Outpost => "Content/Map/Outposts/{0}",
SubmarineType.Ruin => "Content/Submarines/{0}", //we don't seem to use this anymore...
SubmarineType.Wreck => "Content/Map/Wrecks/{0}",
SubmarineType.BeaconStation => "Content/Map/BeaconStations/{0}",
SubmarineType.EnemySubmarine => "Content/Map/EnemySubmarines/{0}",
SubmarineType.OutpostModule => "Content/Map/Outposts/{0}",
_ => throw new InvalidOperationException()
}, savePath);
savePath =
getExistingFilePath(packageToSaveTo, savePath) ??
string.Format((MainSub?.Info.Type ?? SubmarineType.Player) switch
{
SubmarineType.Player => "Content/Submarines/{0}",
SubmarineType.Outpost => "Content/Map/Outposts/{0}",
SubmarineType.Ruin => "Content/Submarines/{0}", //we don't seem to use this anymore...
SubmarineType.Wreck => "Content/Map/Wrecks/{0}",
SubmarineType.BeaconStation => "Content/Map/BeaconStations/{0}",
SubmarineType.EnemySubmarine => "Content/Map/EnemySubmarines/{0}",
SubmarineType.OutpostModule => "Content/Map/Outposts/{0}",
_ => throw new InvalidOperationException()
}, savePath);
modProject.ModVersion = "";
}
else
{
savePath = Path.Combine(packageToSaveTo.Dir, savePath);
string existingFilePath = getExistingFilePath(packageToSaveTo, savePath);
//if we're trying to save a sub that's already included in the package with the same name as before, save directly in the same path
if (existingFilePath != null)
{
savePath = existingFilePath;
}
//otherwise make sure we're not trying to overwrite another sub in the same package
else
{
savePath = Path.Combine(packageToSaveTo.Dir, savePath);
if (File.Exists(savePath))
{
var verification = new GUIMessageBox(TextManager.Get("warning"), TextManager.Get("subeditor.duplicatesubinpackage"),
new LocalizedString[] { TextManager.Get("yes"), TextManager.Get("no") });
verification.Buttons[0].OnClicked = (_, _) =>
{
addSubAndSave(modProject, savePath, fileListPath);
verification.Close();
return true;
};
verification.Buttons[1].OnClicked = verification.Close;
return false;
}
}
}
addSubAndSaveModProject(modProject, savePath, fileListPath);
}
else if (MainSub?.Info?.FilePath != null
&& MainSub.Info.Name != null
&& MainSub.Info.FilePath.StartsWith(ContentPackage.LocalModsDir)
&& MainSub.Info.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
{
prevSavePath = MainSub.Info.FilePath.CleanUpPath();
ContentPackage contentPackage = GetLocalPackageThatOwnsSub(MainSub.Info);
if (contentPackage == null)
{
throw new InvalidOperationException($"Tried to overwrite a submarine ({name}) that's not in a local package!");
}
ModProject modProject = new ModProject(contentPackage);
packageToSaveTo = contentPackage;
savePath = prevSavePath;
addSubAndSaveModProject(modProject, savePath, contentPackage.Path);
addSubAndSave(modProject, savePath, fileListPath);
}
else
{
savePath = Path.Combine(newLocalModDir, savePath);
ModProject modProject = new ModProject { Name = name };
addSubAndSaveModProject(modProject, savePath, Path.Combine(Path.GetDirectoryName(savePath), ContentPackage.FileListFileName));
}
savePath = savePath.CleanUpPathCrossPlatform(correctFilenameCase: false);
if (MainSub != null)
{
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
if (previewImage?.Sprite?.Texture != null && !previewImage.Sprite.Texture.IsDisposed && MainSub.Info.Type != SubmarineType.OutpostModule)
if (File.Exists(savePath))
{
bool savePreviewImage = true;
using System.IO.MemoryStream imgStream = new System.IO.MemoryStream();
try
{
previewImage.Sprite.Texture.SaveAsPng(imgStream, previewImage.Sprite.Texture.Width, previewImage.Sprite.Texture.Height);
}
catch (Exception e)
{
DebugConsole.ThrowError($"Saving the preview image of the submarine \"{MainSub.Info.Name}\" failed.", e);
savePreviewImage = false;
}
MainSub.TrySaveAs(savePath, savePreviewImage ? imgStream : null);
new GUIMessageBox(TextManager.Get("warning"), TextManager.GetWithVariable("subeditor.packagealreadyexists", "[name]", name));
return false;
}
else
{
MainSub.TrySaveAs(savePath);
ModProject modProject = new ModProject { Name = name };
addSubAndSave(modProject, savePath, Path.Combine(Path.GetDirectoryName(savePath), ContentPackage.FileListFileName));
}
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
}
MainSub.CheckForErrors();
GUI.AddMessage(TextManager.GetWithVariable("SubSavedNotification", "[filepath]", savePath), GUIStyle.Green);
if (savePath.StartsWith(newLocalModDir))
void addSubAndSave(ModProject modProject, string filePath, string packagePath)
{
filePath = filePath.CleanUpPath();
packagePath = packagePath.CleanUpPath();
string packageDir = Path.GetDirectoryName(packagePath).CleanUpPathCrossPlatform(correctFilenameCase: false);
if (filePath.StartsWith(packageDir))
{
ContentPackageManager.LocalPackages.Refresh();
var newPackage = ContentPackageManager.LocalPackages.FirstOrDefault(p => p.Path.StartsWith(newLocalModDir));
if (newPackage is RegularPackage regular)
filePath = $"{ContentPath.ModDirStr}/{filePath[packageDir.Length..]}";
}
if (!modProject.Files.Any(f => f.Type == subFileType &&
f.Path == filePath))
{
var newFile = ModProject.File.FromPath(filePath, subFileType);
modProject.AddFile(newFile);
}
using var _ = Validation.SkipInDebugBuilds();
modProject.DiscardHashAndInstallTime();
modProject.Save(packagePath);
savePath = savePath.CleanUpPathCrossPlatform(correctFilenameCase: false);
if (MainSub != null)
{
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
if (previewImage?.Sprite?.Texture != null && !previewImage.Sprite.Texture.IsDisposed && MainSub.Info.Type != SubmarineType.OutpostModule)
{
ContentPackageManager.EnabledPackages.EnableRegular(regular);
GameSettings.SaveCurrentConfig();
bool savePreviewImage = true;
using System.IO.MemoryStream imgStream = new System.IO.MemoryStream();
try
{
previewImage.Sprite.Texture.SaveAsPng(imgStream, previewImage.Sprite.Texture.Width, previewImage.Sprite.Texture.Height);
}
catch (Exception e)
{
DebugConsole.ThrowError($"Saving the preview image of the submarine \"{MainSub.Info.Name}\" failed.", e);
savePreviewImage = false;
}
MainSub.TrySaveAs(savePath, savePreviewImage ? imgStream : null);
}
}
if (packageToSaveTo != null) { ReloadModifiedPackage(packageToSaveTo); }
SubmarineInfo.RefreshSavedSub(savePath);
if (prevSavePath != null && prevSavePath != savePath) { SubmarineInfo.RefreshSavedSub(prevSavePath); }
MainSub.Info.PreviewImage = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.FilePath == savePath)?.PreviewImage;
else
{
MainSub.TrySaveAs(savePath);
}
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
string downloadFolder = Path.GetFullPath(SaveUtil.SubmarineDownloadFolder);
linkedSubBox.ClearChildren();
foreach (SubmarineInfo sub in SubmarineInfo.SavedSubmarines)
{
if (sub.Type != SubmarineType.Player) { continue; }
if (Path.GetDirectoryName(Path.GetFullPath(sub.FilePath)) == downloadFolder) { continue; }
linkedSubBox.AddItem(sub.Name, sub);
MainSub.CheckForErrors();
GUI.AddMessage(TextManager.GetWithVariable("SubSavedNotification", "[filepath]", savePath), GUIStyle.Green);
if (savePath.StartsWith(newLocalModDir))
{
ContentPackageManager.LocalPackages.Refresh();
var newPackage = ContentPackageManager.LocalPackages.FirstOrDefault(p => p.Path.StartsWith(newLocalModDir));
if (newPackage is RegularPackage regular)
{
ContentPackageManager.EnabledPackages.EnableRegular(regular);
GameSettings.SaveCurrentConfig();
}
}
if (packageToSaveTo != null) { ReloadModifiedPackage(packageToSaveTo); }
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();
foreach (SubmarineInfo sub in SubmarineInfo.SavedSubmarines)
{
if (sub.Type != SubmarineType.Player) { continue; }
if (Path.GetDirectoryName(Path.GetFullPath(sub.FilePath)) == downloadFolder) { continue; }
linkedSubBox.AddItem(sub.Name, sub);
}
subNameLabel.Text = ToolBox.LimitString(MainSub.Info.Name, subNameLabel.Font, subNameLabel.Rect.Width);
}
subNameLabel.Text = ToolBox.LimitString(MainSub.Info.Name, subNameLabel.Font, subNameLabel.Rect.Width);
}
return false;
@@ -2735,40 +2764,31 @@ namespace Barotrauma
new GUICustomComponent(new RectTransform(Vector2.Zero, saveInPackageLayout.RectTransform),
onUpdate: (f, component) =>
{
bool canCreateNewPackage = true;
foreach (GUIComponent contentChild in packageToSaveInList.Content.Children)
{
contentChild.Visible = !(contentChild.UserData is ContentPackage p)
|| !string.Equals(p.Name, nameBox.Text, StringComparison.OrdinalIgnoreCase);
canCreateNewPackage &= contentChild.Visible;
contentChild.Visible &= !(contentChild.GetChild<GUILayoutGroup>()?.GetChild<GUITextBlock>() is GUITextBlock tb &&
!tb.Text.Contains(packToSaveInFilter.Text, StringComparison.OrdinalIgnoreCase));
}
if (newPackageListIcon.Style.Identifier != "NewContentPackageIcon" && canCreateNewPackage)
{
GUIStyle.Apply(newPackageListIcon, "NewContentPackageIcon");
newPackageListText.Text = TextManager.Get("CreateNewLocalPackage");
}
if (newPackageListIcon.Style.Identifier != "WorkshopMenu.EditButton" && !canCreateNewPackage)
{
GUIStyle.Apply(newPackageListIcon, "WorkshopMenu.EditButton");
newPackageListText.Text = TextManager.GetWithVariable("UpdateExistingLocalPackage", "[mod]", nameBox.Text);
}
});
packageToSaveInList.Select(0);
ContentPackage ownerPkg = null;
if (MainSub?.Info != null) { ownerPkg = GetLocalPackageThatOwnsSub(MainSub.Info); }
foreach (var p in ContentPackageManager.LocalPackages)
{
addItemToPackageToSaveList(p.Name, p);
var packageListItem = addItemToPackageToSaveList(p.Name, p);
if (p == ownerPkg)
{
var packageListIcon = packageListItem.GetChild<GUIFrame>();
var packageListText = packageListItem.GetChild<GUITextBlock>();
GUIStyle.Apply(packageListIcon, "WorkshopMenu.EditButton");
packageListText.Text = TextManager.GetWithVariable("UpdateExistingLocalPackage", "[mod]", p.Name);
}
}
if (ownerPkg != null && !string.Equals(ownerPkg.Name, nameBox.Text, StringComparison.OrdinalIgnoreCase))
if (ownerPkg != null)
{
packageToSaveInList.Select(ownerPkg);
packageToSaveInList.ScrollToElement(packageToSaveInList.SelectedComponent);
var element = packageToSaveInList.Content.FindChild(ownerPkg);
element?.RectTransform.SetAsFirstChild();
}
packageToSaveInList.Select(0);
var requiredContentPackagesLayout = new GUILayoutGroup(new RectTransform(Vector2.One,
horizontalArea.RectTransform, Anchor.BottomRight))
@@ -3424,7 +3444,8 @@ namespace Barotrauma
{
if (GetWorkshopPackageThatOwnsSub(selectedSubInfo) is ContentPackage workshopPackage)
{
if (publishedWorkshopItemIds.Contains(workshopPackage.SteamWorkshopId))
if (workshopPackage.TryExtractSteamWorkshopId(out var workshopId)
&& publishedWorkshopItemIds.Contains(workshopId.Value))
{
AskLoadPublishedSub(selectedSubInfo, workshopPackage);
}