Unstable 0.17.4.0

This commit is contained in:
Markus Isberg
2022-03-30 00:08:09 +09:00
parent 2968e23ae8
commit c1b8e5a341
177 changed files with 3388 additions and 1977 deletions
@@ -680,7 +680,7 @@ namespace Barotrauma
//locationInfoPanel?.UpdateAuto(1.0f);
}
public void SelectTab(CampaignMode.InteractionType tab)
public void SelectTab(CampaignMode.InteractionType tab, Identifier storeIdentifier = default)
{
if (Campaign.ShowCampaignUI || (Campaign.ForceMapUI && tab == CampaignMode.InteractionType.Map))
{
@@ -724,8 +724,7 @@ namespace Barotrauma
}
break;
case CampaignMode.InteractionType.Store:
Store.RefreshItemsToSell();
Store.Refresh();
Store.SelectStore(storeIdentifier);
break;
case CampaignMode.InteractionType.Crew:
CrewManagement.UpdateCrew();
@@ -2805,7 +2805,8 @@ namespace Barotrauma.CharacterEditor
return false;
}
#endif
if (!character.IsHuman && !string.IsNullOrEmpty(RagdollParams.Texture) && !File.Exists(RagdollParams.Texture))
ContentPath texturePath = ContentPath.FromRaw(character.Prefab.ContentPackage, RagdollParams.Texture);
if (!character.IsHuman && (texturePath.IsNullOrWhiteSpace() || !File.Exists(texturePath.Value)))
{
DebugConsole.ThrowError($"Invalid texture path: {RagdollParams.Texture}");
return false;
@@ -248,18 +248,24 @@ namespace Barotrauma
}
spriteBatch.End();
//draw characters with deformable limbs last, because they can't be batched into SpriteBatch
//pretty hacky way of preventing draw order issues between normal and deformable sprites
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, null, DepthStencilState.None, null, null, cam.Transform);
//backwards order to render the most recently spawned characters in front (characters spawned later have a larger sprite depth)
for (int i = Character.CharacterList.Count - 1; i >= 0; i--)
{
Character c = Character.CharacterList[i];
if (!c.IsVisible || c.AnimController.Limbs.All(l => l.DeformSprite == null)) { continue; }
c.Draw(spriteBatch, Cam);
}
DrawDeformed(firstPass: true);
DrawDeformed(firstPass: false);
spriteBatch.End();
void DrawDeformed(bool firstPass)
{
//backwards order to render the most recently spawned characters in front (characters spawned later have a larger sprite depth)
for (int i = Character.CharacterList.Count - 1; i >= 0; i--)
{
Character c = Character.CharacterList[i];
if (!c.IsVisible) { continue; }
if (c.Params.DrawLast == firstPass) { continue; }
if (c.AnimController.Limbs.All(l => l.DeformSprite == null)) { continue; }
c.Draw(spriteBatch, Cam);
}
}
Level.Loaded?.DrawFront(spriteBatch, cam);
//draw the rendertarget and particles that are only supposed to be drawn in water into renderTargetWater
@@ -32,7 +32,7 @@ namespace Barotrauma
private readonly GUITextBox seedBox;
private readonly GUITickBox lightingEnabled, cursorLightEnabled, mirrorLevel;
private readonly GUITickBox lightingEnabled, cursorLightEnabled, allowInvalidOutpost, mirrorLevel;
private Sprite editingSprite;
@@ -126,6 +126,7 @@ namespace Barotrauma
OnClicked = (btn, obj) =>
{
SerializeAll();
GUI.AddMessage(TextManager.Get("leveleditor.allsaved"), GUIStyle.Green);
return true;
}
};
@@ -169,6 +170,12 @@ namespace Barotrauma
mirrorLevel = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.02f), paddedRightPanel.RectTransform), TextManager.Get("mirrorentityx"));
allowInvalidOutpost = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.025f), paddedRightPanel.RectTransform),
TextManager.Get("leveleditor.allowinvalidoutpost"))
{
ToolTip = TextManager.Get("leveleditor.allowinvalidoutpost.tooltip")
};
new GUIButton(new RectTransform(new Vector2(1.0f, 0.05f), paddedRightPanel.RectTransform),
TextManager.Get("leveleditor.generate"))
{
@@ -179,6 +186,7 @@ namespace Barotrauma
GameMain.LightManager.ClearLights();
LevelData levelData = LevelData.CreateRandom(seedBox.Text, generationParams: selectedParams);
levelData.ForceOutpostGenerationParams = outpostParamsList.SelectedData as OutpostGenerationParams;
levelData.AllowInvalidOutpost = allowInvalidOutpost.Selected;
Level.Generate(levelData, mirror: mirrorLevel.Selected);
GameMain.LightManager.AddLight(pointerLightSource);
if (!wasLevelLoaded || Cam.Position.X < 0 || Cam.Position.Y < 0 || Cam.Position.Y > Level.Loaded.Size.X || Cam.Position.Y > Level.Loaded.Size.Y)
@@ -46,6 +46,7 @@ namespace Barotrauma
private GUITextBox serverNameBox, passwordBox, maxPlayersBox;
private GUITickBox isPublicBox, wrongPasswordBanBox, karmaBox;
private GUIDropDown serverExecutableDropdown;
private readonly GUIButton joinServerButton, hostServerButton, steamWorkshopButton;
private readonly GameMain game;
@@ -418,7 +419,14 @@ namespace Barotrauma
//PLACEHOLDER
var tutorialList = new GUIListBox(
new RectTransform(new Vector2(0.95f, 0.85f), menuTabs[Tab.Tutorials].RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.1f) });
var tutorialTypes = ReflectionUtils.GetDerivedNonAbstract<Tutorial>();
var tutorialTypes = new List<Type>()
{
typeof(MechanicTutorial),
typeof(EngineerTutorial),
typeof(DoctorTutorial),
typeof(OfficerTutorial),
typeof(CaptainTutorial),
};
foreach (Type tutorialType in tutorialTypes)
{
Tutorial tutorial = (Tutorial)Activator.CreateInstance(tutorialType);
@@ -557,6 +565,35 @@ namespace Barotrauma
GameMain.Instance.ShowCampaignDisclaimer(() => { SelectTab(null, Tab.HostServer); });
return true;
}
serverExecutableDropdown.ListBox.Content.Children.ToArray()
.Where(c => c.UserData is ServerExecutableFile f && !ContentPackageManager.EnabledPackages.All.Contains(f.ContentPackage))
.ForEach(serverExecutableDropdown.ListBox.RemoveChild);
var newServerExes
= ContentPackageManager.EnabledPackages.All.SelectMany(p => p.GetFiles<ServerExecutableFile>())
.Where(f => serverExecutableDropdown.ListBox.Content.Children.None(c => c.UserData == f))
.ToArray();
foreach (var newServerExe in newServerExes)
{
serverExecutableDropdown.AddItem($"{newServerExe.ContentPackage.Name} - {Path.GetFileNameWithoutExtension(newServerExe.Path.Value)}", userData: newServerExe);
}
serverExecutableDropdown.ListBox.Content.Children.ForEach(c =>
{
c.RectTransform.RelativeSize = (1.0f, c.RectTransform.RelativeSize.Y);
c.ForceLayoutRecalculation();
});
bool serverExePickable = serverExecutableDropdown.ListBox.Content.CountChildren > 1;
serverExecutableDropdown.Parent.Visible
= serverExePickable;
serverExecutableDropdown.Parent.RectTransform.RelativeSize
= (1.0f, serverExePickable ? 0.1f : 0.0f);
serverExecutableDropdown.Parent.ForceLayoutRecalculation();
(serverExecutableDropdown.Parent.Parent as GUILayoutGroup)?.Recalculate();
if (serverExecutableDropdown.SelectedComponent is null)
{
serverExecutableDropdown.Select(0);
}
break;
case Tab.Tutorials:
if (!GameSettings.CurrentConfig.CampaignDisclaimerShown)
@@ -784,7 +821,7 @@ namespace Barotrauma
GameMain.ResetNetLobbyScreen();
try
{
string exeName = "DedicatedServer.exe";
string exeName = serverExecutableDropdown.SelectedComponent?.UserData is ServerExecutableFile f ? f.Path.Value : "DedicatedServer";
string arguments = "-name \"" + ToolBox.EscapeCharacters(name) + "\"" +
" -public " + isPublicBox.Selected.ToString() +
@@ -814,15 +851,20 @@ namespace Barotrauma
arguments += " -ownerkey " + ownerKey;
}
string filename = exeName;
#if LINUX || OSX
filename = "./" + Path.GetFileNameWithoutExtension(exeName);
//arguments = ToolBox.EscapeCharacters(arguments);
string filename = Path.Combine(
Path.GetDirectoryName(exeName),
Path.GetFileNameWithoutExtension(exeName));
#if WINDOWS
filename += ".exe";
#else
filename = "./" + exeName;
#endif
var processInfo = new ProcessStartInfo
{
FileName = filename,
Arguments = arguments,
WorkingDirectory = Directory.GetCurrentDirectory(),
#if !DEBUG
CreateNoWindow = true,
UseShellExecute = false,
@@ -1184,12 +1226,12 @@ namespace Barotrauma
label.RectTransform.MaxSize = serverNameBox.RectTransform.MaxSize;
var maxPlayersLabel = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("MaxPlayers"), textAlignment: textAlignment);
var buttonContainer = new GUILayoutGroup(new RectTransform(textFieldSize, maxPlayersLabel.RectTransform, Anchor.CenterRight), isHorizontal: true)
var buttonContainer = new GUILayoutGroup(new RectTransform(textFieldSize, maxPlayersLabel.RectTransform, Anchor.CenterRight), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
Stretch = true,
RelativeSpacing = 0.1f
};
new GUIButton(new RectTransform(new Vector2(0.2f, 1.0f), buttonContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIMinusButton", textAlignment: Alignment.Center)
new GUIButton(new RectTransform(Vector2.One, buttonContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIMinusButton", textAlignment: Alignment.Center)
{
UserData = -1,
OnClicked = ChangeMaxPlayers
@@ -1209,7 +1251,7 @@ namespace Barotrauma
currMaxPlayers = (int)MathHelper.Clamp(currMaxPlayers, 1, NetConfig.MaxPlayers);
maxPlayersBox.Text = currMaxPlayers.ToString();
};
new GUIButton(new RectTransform(new Vector2(0.2f, 1.0f), buttonContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIPlusButton", textAlignment: Alignment.Center)
new GUIButton(new RectTransform(Vector2.One, buttonContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIPlusButton", textAlignment: Alignment.Center)
{
UserData = 1,
OnClicked = ChangeMaxPlayers
@@ -1223,6 +1265,41 @@ namespace Barotrauma
};
label.RectTransform.MaxSize = passwordBox.RectTransform.MaxSize;
var serverExecutableLabel = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform),
TextManager.Get("ServerExecutable"), textAlignment: textAlignment);
const string vanillaServerOption = "Vanilla";
serverExecutableDropdown
= new GUIDropDown(new RectTransform(textFieldSize, serverExecutableLabel.RectTransform, Anchor.CenterRight),
vanillaServerOption);
var listBoxSize = serverExecutableDropdown.ListBox.RectTransform.RelativeSize;
serverExecutableDropdown.ListBox.RectTransform.RelativeSize = new Vector2(listBoxSize.X * 1.5f, listBoxSize.Y);
serverExecutableDropdown.AddItem(vanillaServerOption, userData: null);
serverExecutableDropdown.OnSelected = (selected, userData) =>
{
if (userData != null)
{
var warningBox = new GUIMessageBox(headerText: TextManager.Get("Warning"),
text: TextManager.GetWithVariable("ModServerExesAtYourOwnRisk", "[exename]", serverExecutableDropdown.Text),
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
warningBox.Buttons[0].OnClicked = (_, __) =>
{
warningBox.Close();
return false;
};
warningBox.Buttons[1].OnClicked = (_, __) =>
{
serverExecutableDropdown.Select(0);
warningBox.Close();
return false;
};
}
serverExecutableDropdown.Text = ToolBox.LimitString(serverExecutableDropdown.Text,
serverExecutableDropdown.Font, serverExecutableDropdown.Rect.Width * 8 / 10);
return true;
};
// tickbox upper ---------------
var tickboxAreaUpper = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, tickBoxSize.Y), parent.RectTransform), isHorizontal: true);
@@ -1312,8 +1389,8 @@ namespace Barotrauma
{
var client = new RestClient(RemoteContentUrl);
var request = new RestRequest("MenuContent.xml", Method.GET);
client.ExecuteAsync(request, RemoteContentReceived);
CoroutineManager.StartCoroutine(WairForRemoteContentReceived());
TaskPool.Add("RequestMainMenuRemoteContent", client.ExecuteAsync(request),
RemoteContentReceived);
}
catch (Exception e)
@@ -1327,58 +1404,31 @@ namespace Barotrauma
}
}
private IEnumerable<CoroutineStatus> WairForRemoteContentReceived()
private void RemoteContentReceived(Task t)
{
while (true)
try
{
lock (remoteContentLock)
if (!t.TryGetResult(out IRestResponse remoteContentResponse)) { throw new Exception("Task did not return a valid result"); }
string xml = remoteContentResponse.Content;
int index = xml.IndexOf('<');
if (index > 0) { xml = xml.Substring(index, xml.Length - index); }
if (!string.IsNullOrWhiteSpace(xml))
{
if (remoteContentResponse != null) { break; }
}
yield return new WaitForSeconds(0.1f);
}
lock (remoteContentLock)
{
if (remoteContentResponse.ResponseStatus != ResponseStatus.Completed || remoteContentResponse.StatusCode != HttpStatusCode.OK)
{
yield return CoroutineStatus.Success;
}
try
{
string xml = remoteContentResponse.Content;
int index = xml.IndexOf('<');
if (index > 0) { xml = xml.Substring(index, xml.Length - index); }
if (!string.IsNullOrWhiteSpace(xml))
remoteContentDoc = XDocument.Parse(xml);
foreach (var subElement in remoteContentDoc?.Root.Elements())
{
remoteContentDoc = XDocument.Parse(xml);
foreach (var subElement in remoteContentDoc?.Root.Elements())
{
GUIComponent.FromXML(subElement.FromPackage(null), remoteContentContainer.RectTransform);
}
GUIComponent.FromXML(subElement.FromPackage(null), remoteContentContainer.RectTransform);
}
}
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("Reading received remote main menu content failed.", e);
#endif
GameAnalyticsManager.AddErrorEventOnce("MainMenuScreen.WairForRemoteContentReceived:Exception", GameAnalyticsManager.ErrorSeverity.Error,
"Reading received remote main menu content failed. " + e.Message);
}
}
yield return CoroutineStatus.Success;
}
private readonly object remoteContentLock = new object();
private IRestResponse remoteContentResponse;
private void RemoteContentReceived(IRestResponse response, RestRequestAsyncHandle handle)
{
lock (remoteContentLock)
catch (Exception e)
{
remoteContentResponse = response;
#if DEBUG
DebugConsole.ThrowError("Reading received remote main menu content failed.", e);
#endif
GameAnalyticsManager.AddErrorEventOnce("MainMenuScreen.RemoteContentReceived:Exception", GameAnalyticsManager.ErrorSeverity.Error,
"Reading received remote main menu content failed. " + e.Message);
}
}
}
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Barotrauma.Extensions;
using Barotrauma.IO;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
@@ -29,10 +30,19 @@ namespace Barotrauma
currentDownload = null;
confirmDownload = false;
}
private void DeletePrevDownloads()
{
if (Directory.Exists(ModReceiver.DownloadFolder))
{
Directory.Delete(ModReceiver.DownloadFolder, recursive: true);
}
}
public override void Select()
{
base.Select();
DeletePrevDownloads();
Reset();
Frame.ClearChildren();
@@ -67,6 +77,18 @@ namespace Barotrauma
.Where(sp => sp.ContentPackage is null).ToArray();
if (!missingPackages.Any())
{
if (!GameMain.Client.IsServerOwner)
{
ContentPackageManager.EnabledPackages.BackUp();
ContentPackageManager.EnabledPackages.SetCore(
GameMain.Client.ClientPeer.ServerContentPackages
.Select(p => p.CorePackage)
.First(p => p != null));
ContentPackageManager.EnabledPackages.SetRegular(
GameMain.Client.ClientPeer.ServerContentPackages
.Select(p => p.RegularPackage)
.Where(p => p != null).ToArray());
}
GameMain.NetLobbyScreen.Select();
return;
}
@@ -201,7 +223,7 @@ namespace Barotrauma
if (!pendingDownloads.Contains(p))
{
downloadProgress.ClearChildren();
downloadProgress.GetAllChildren<GUITextBlock>().ToArray().ForEach(c => downloadProgress.RemoveChild(c));
return 1.0f;
}
@@ -3786,7 +3786,7 @@ namespace Barotrauma
RelativeSpacing = 0.02f
};
var dragIndicator = new GUIButton(new RectTransform(new Vector2(0.1f, 0.5f), frameContent.RectTransform, scaleBasis: ScaleBasis.BothHeight),
var dragIndicator = new GUIButton(new RectTransform(new Vector2(0.5f, 0.5f), frameContent.RectTransform, scaleBasis: ScaleBasis.BothHeight),
style: "GUIDragIndicator")
{
CanBeFocused = false
@@ -380,7 +380,7 @@ namespace Barotrauma
string spriteFolder = "";
ContentPath texturePath = null;
if (element.Attribute("texture") != null)
if (element.GetAttribute("texture") != null)
{
texturePath = element.GetAttributeContentPath("texture");
}
@@ -9,11 +9,7 @@ using System.Linq;
using System.Threading;
using System.Xml.Linq;
using Microsoft.Xna.Framework.Input;
#if DEBUG
using System.IO;
#else
using Barotrauma.IO;
#endif
namespace Barotrauma
{
@@ -1262,7 +1258,9 @@ namespace Barotrauma
}
textBlock.Text = ToolBox.LimitString(textBlock.Text, textBlock.Font, textBlock.Rect.Width);
if (ep.Category == MapEntityCategory.ItemAssembly)
if (ep.Category == MapEntityCategory.ItemAssembly
&& ep.ContentPackage?.Files.Length == 1
&& ContentPackageManager.LocalPackages.Contains(ep.ContentPackage))
{
var deleteButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.2f), paddedFrame.RectTransform, Anchor.BottomCenter) { MinSize = new Point(0, 20) },
TextManager.Get("Delete"), style: "GUIButtonSmall")
@@ -1978,6 +1976,7 @@ namespace Barotrauma
if (newPackage is RegularPackage regular)
{
ContentPackageManager.EnabledPackages.EnableRegular(regular);
GameSettings.SaveCurrentConfig();
}
}
SubmarineInfo.RefreshSavedSub(savePath);
@@ -2164,12 +2163,12 @@ namespace Barotrauma
var allowAttachDropDown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1f), allowAttachGroup.RectTransform),
text: LocalizedString.Join(", ", MainSub?.Info?.OutpostModuleInfo?.AllowAttachToModules.Select(s => TextManager.Capitalize(s.Value)) ?? ((LocalizedString)"Any").ToEnumerable()), selectMultiple: true);
allowAttachDropDown.AddItem(TextManager.Capitalize("any"), "any");
allowAttachDropDown.AddItem(TextManager.Capitalize("any"), "any".ToIdentifier());
if (MainSub.Info.OutpostModuleInfo == null ||
!MainSub.Info.OutpostModuleInfo.AllowAttachToModules.Any() ||
MainSub.Info.OutpostModuleInfo.AllowAttachToModules.All(s => s == "any"))
{
allowAttachDropDown.SelectItem("any");
allowAttachDropDown.SelectItem("any".ToIdentifier());
}
foreach (Identifier flag in availableFlags)
{
@@ -2211,7 +2210,7 @@ namespace Barotrauma
locationTypeDropDown.SelectItem(locationType);
}
}
if (!MainSub.Info?.OutpostModuleInfo?.AllowedLocationTypes?.Any() ?? true) { locationTypeDropDown.SelectItem("any"); }
if (!MainSub.Info?.OutpostModuleInfo?.AllowedLocationTypes?.Any() ?? true) { locationTypeDropDown.SelectItem("any".ToIdentifier()); }
locationTypeDropDown.OnSelected += (_, __) =>
{
@@ -2225,9 +2224,7 @@ namespace Barotrauma
// gap positions ---------------------
var gapPositionGroup = new GUILayoutGroup(new RectTransform(new Vector2(.975f, 0.1f), outpostSettingsContainer.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), gapPositionGroup.RectTransform), TextManager.Get("outpostmodulegappositions"), textAlignment: Alignment.CenterLeft);
var gapPositionDropDown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1f), gapPositionGroup.RectTransform),
text: "", selectMultiple: true);
@@ -2238,11 +2235,11 @@ namespace Barotrauma
{
outpostModuleInfo.DetermineGapPositions(MainSub);
}
foreach (var gapPos in Enum.GetValues(typeof(OutpostModuleInfo.GapPosition)))
foreach (OutpostModuleInfo.GapPosition gapPos in Enum.GetValues(typeof(OutpostModuleInfo.GapPosition)))
{
if ((OutpostModuleInfo.GapPosition)gapPos == OutpostModuleInfo.GapPosition.None) { continue; }
if (gapPos == OutpostModuleInfo.GapPosition.None) { continue; }
gapPositionDropDown.AddItem(TextManager.Capitalize(gapPos.ToString()), gapPos);
if (outpostModuleInfo.GapPositions.HasFlag((OutpostModuleInfo.GapPosition)gapPos))
if (outpostModuleInfo.GapPositions.HasFlag(gapPos))
{
gapPositionDropDown.SelectItem(gapPos);
}
@@ -2271,6 +2268,49 @@ namespace Barotrauma
};
gapPositionGroup.RectTransform.MinSize = new Point(0, gapPositionGroup.RectTransform.Children.Max(c => c.MinSize.Y));
var canAttachToPrevGroup = new GUILayoutGroup(new RectTransform(new Vector2(.975f, 0.1f), outpostSettingsContainer.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), canAttachToPrevGroup.RectTransform), TextManager.Get("canattachtoprevious"), textAlignment: Alignment.CenterLeft)
{
ToolTip = TextManager.Get("canattachtoprevious.tooltip")
};
var canAttachToPrevDropDown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1f), canAttachToPrevGroup.RectTransform),
text: "", selectMultiple: true);
if (outpostModuleInfo != null)
{
foreach (OutpostModuleInfo.GapPosition gapPos in Enum.GetValues(typeof(OutpostModuleInfo.GapPosition)))
{
if (gapPos == OutpostModuleInfo.GapPosition.None) { continue; }
canAttachToPrevDropDown.AddItem(TextManager.Capitalize(gapPos.ToString()), gapPos);
if (outpostModuleInfo.CanAttachToPrevious.HasFlag(gapPos))
{
canAttachToPrevDropDown.SelectItem(gapPos);
}
}
}
canAttachToPrevDropDown.OnSelected += (_, __) =>
{
if (Submarine.MainSub.Info?.OutpostModuleInfo == null) { return false; }
Submarine.MainSub.Info.OutpostModuleInfo.CanAttachToPrevious = OutpostModuleInfo.GapPosition.None;
if (canAttachToPrevDropDown.SelectedDataMultiple.Any())
{
List<string> gapPosTexts = new List<string>();
foreach (OutpostModuleInfo.GapPosition gapPos in canAttachToPrevDropDown.SelectedDataMultiple)
{
Submarine.MainSub.Info.OutpostModuleInfo.CanAttachToPrevious |= gapPos;
gapPosTexts.Add(TextManager.Capitalize(gapPos.ToString()).Value);
}
canAttachToPrevDropDown.Text = ToolBox.LimitString(string.Join(", ", gapPosTexts), canAttachToPrevDropDown.Font, canAttachToPrevDropDown.Rect.Width);
}
else
{
canAttachToPrevDropDown.Text = ToolBox.LimitString("None", canAttachToPrevDropDown.Font, canAttachToPrevDropDown.Rect.Width);
}
return true;
};
canAttachToPrevGroup.RectTransform.MinSize = new Point(0, gapPositionGroup.RectTransform.Children.Max(c => c.MinSize.Y));
// -------------------
var maxModuleCountGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), outpostSettingsContainer.RectTransform), isHorizontal: true)
@@ -2583,7 +2623,18 @@ namespace Barotrauma
//don't show content packages that only define submarine files
//(it doesn't make sense to require another sub to be installed to install this one)
if (contentPack.Files.All(f => f is SubmarineFile)) { continue; }
if (!contentPacks.Contains(contentPack.Name)) { contentPacks.Add(contentPack.Name); }
if (!contentPacks.Contains(contentPack.Name))
{
string altName = contentPack.AltNames.FirstOrDefault(n => contentPacks.Contains(n));
if (!string.IsNullOrEmpty(altName))
{
MainSub.Info.RequiredContentPackages.Remove(altName);
MainSub.Info.RequiredContentPackages.Add(contentPack.Name);
contentPacks.Remove(altName);
}
contentPacks.Add(contentPack.Name);
}
}
foreach (string contentPackageName in contentPacks)
@@ -2749,11 +2800,7 @@ namespace Barotrauma
}
bool hideInMenus = nameBox.Parent.GetChildByUserData("hideinmenus") is GUITickBox hideInMenusTickBox && hideInMenusTickBox.Selected;
#if DEBUG
string saveFolder = ItemAssemblyPrefab.VanillaSaveFolder;
#else
string saveFolder = Path.Combine(ContentPackage.LocalModsDir, nameBox.Text);
#endif
string filePath = Path.Combine(saveFolder, $"{nameBox.Text}.xml").CleanUpPathCrossPlatform();
if (File.Exists(filePath))
{
@@ -2782,26 +2829,27 @@ namespace Barotrauma
void Save()
{
XDocument doc = new XDocument(ItemAssemblyPrefab.Save(MapEntity.SelectedList.ToList(), nameBox.Text, descriptionBox.Text, hideInMenus));
#if DEBUG
doc.Save(filePath);
#else
doc.SaveSafe(filePath);
#endif
ContentPackage existingContentPackage = ContentPackageManager.LocalPackages.FirstOrDefault(p => p.Files.Any(f => f.Path == filePath));
ContentPackage existingContentPackage = ContentPackageManager.LocalPackages.Regular.FirstOrDefault(p => p.Files.Any(f => f.Path == filePath));
if (existingContentPackage == null)
{
//content package doesn't exist, create one
ModProject modProject = new ModProject() { Name = nameBox.Text };
var newFile = ModProject.File.FromPath<ItemAssemblyFile>(filePath);
var newFile = ModProject.File.FromPath<ItemAssemblyFile>(Path.Combine(ContentPath.ModDirStr, $"{nameBox.Text}.xml"));
modProject.AddFile(newFile);
ContentPackageManager.LocalPackages.SaveAndEnableRegularMod(modProject);
}
else
{
EnqueueForReload(existingContentPackage);
string newPackagePath = ContentPackageManager.LocalPackages.SaveRegularMod(modProject);
existingContentPackage = ContentPackageManager.LocalPackages.GetRegularModByPath(newPackagePath);
}
XDocument doc = new XDocument(ItemAssemblyPrefab.Save(MapEntity.SelectedList.ToList(), nameBox.Text, descriptionBox.Text, hideInMenus));
doc.SaveSafe(filePath);
var resultPackage = ContentPackageManager.ReloadContentPackage(existingContentPackage) as RegularPackage;
if (!ContentPackageManager.EnabledPackages.Regular.Contains(resultPackage))
{
ContentPackageManager.EnabledPackages.EnableRegular(resultPackage);
GameSettings.SaveCurrentConfig();
}
UpdateEntityList();
}
@@ -2884,11 +2932,8 @@ namespace Barotrauma
{
if (deleteButtonHolder.FindChild("delete") is GUIButton deleteBtn)
{
#if DEBUG
deleteBtn.Enabled = true;
#else
deleteBtn.Enabled = userData is SubmarineInfo subInfo && !subInfo.IsVanillaSubmarine();
#endif
deleteBtn.Enabled = userData is SubmarineInfo subInfo
&& (GetContentPackageIntrinsicallyTiedToSub(subInfo) != null || Path.GetDirectoryName(subInfo.FilePath) == SubmarineInfo.SavePath);
}
return true;
}
@@ -3141,18 +3186,10 @@ namespace Barotrauma
ReconstructLayers();
}
private RegularPackage GetContentPackageIntrinsicallyTiedToSub(SubmarineInfo sub)
{
foreach (RegularPackage regularPackage in ContentPackageManager.RegularPackages)
{
if (regularPackage.Files.Length == 1 && regularPackage.Files[0].Path == sub.FilePath)
{
return regularPackage;
}
}
return null;
}
private static RegularPackage GetContentPackageIntrinsicallyTiedToSub(SubmarineInfo sub)
=> ContentPackageManager.LocalPackages.Regular
.Where(p => p.Files.Length == 1)
.FirstOrDefault(regularPackage => regularPackage.Files[0].Path == sub.FilePath);
private void TryDeleteSub(SubmarineInfo sub)
{
@@ -3160,8 +3197,10 @@ namespace Barotrauma
//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 = GetContentPackageIntrinsicallyTiedToSub(sub);
if (!ContentPackageManager.LocalPackages.Regular.Contains(subPackage)) { return; }
bool isInOldSavePath = Path.GetDirectoryName(sub.FilePath) == SubmarineInfo.SavePath;
if (!ContentPackageManager.LocalPackages.Regular.Contains(subPackage) && !isInOldSavePath) { return; }
var msgBox = new GUIMessageBox(
TextManager.Get("DeleteDialogLabel"),
@@ -3171,10 +3210,18 @@ namespace Barotrauma
{
try
{
Directory.Delete(Path.GetDirectoryName(subPackage.Path), true);
if (subPackage != null)
{
Directory.Delete(Path.GetDirectoryName(subPackage.Path), recursive: true);
ContentPackageManager.LocalPackages.Refresh();
ContentPackageManager.EnabledPackages.DisableRemovedMods();
}
else if (isInOldSavePath && File.Exists(sub.FilePath))
{
File.Delete(sub.FilePath);
}
sub.Dispose();
File.Delete(sub.FilePath);
SubmarineInfo.RefreshSavedSubs();
CreateLoadScreen();
}