Unstable 0.17.3.0

This commit is contained in:
Juan Pablo Arce
2022-03-22 14:44:12 -03:00
parent cefac171f5
commit 4206f6db42
100 changed files with 1380 additions and 655 deletions
@@ -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,17 +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--)
DrawDeformed(firstPass: true);
DrawDeformed(firstPass: false);
void DrawDeformed(bool firstPass)
{
Character c = Character.CharacterList[i];
if (!c.IsVisible || c.AnimController.Limbs.All(l => l.DeformSprite == null)) { continue; }
c.Draw(spriteBatch, Cam);
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) { continue; }
if (c.Params.DrawLast == firstPass) { continue; }
if (c.AnimController.Limbs.All(l => l.DeformSprite == null)) { continue; }
c.Draw(spriteBatch, Cam);
}
spriteBatch.End();
}
spriteBatch.End();
Level.Loaded?.DrawFront(spriteBatch, cam);
@@ -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;
@@ -557,6 +558,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 +814,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 +844,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 +1219,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 +1244,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 +1258,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 +1382,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 +1397,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);
}
}
}
@@ -29,10 +29,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();
@@ -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")
@@ -2225,9 +2223,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);
@@ -2271,6 +2267,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 (var gapPos in Enum.GetValues(typeof(OutpostModuleInfo.GapPosition)))
{
if ((OutpostModuleInfo.GapPosition)gapPos == OutpostModuleInfo.GapPosition.None) { continue; }
canAttachToPrevDropDown.AddItem(TextManager.Capitalize(gapPos.ToString()), gapPos);
if (outpostModuleInfo.CanAttachToPrevious.HasFlag((OutpostModuleInfo.GapPosition)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 +2622,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 +2799,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 +2828,26 @@ 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);
}
UpdateEntityList();
}
@@ -2884,11 +2930,7 @@ 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;
}
return true;
}
@@ -3141,7 +3183,7 @@ namespace Barotrauma
ReconstructLayers();
}
private RegularPackage GetContentPackageIntrinsicallyTiedToSub(SubmarineInfo sub)
private static RegularPackage GetContentPackageIntrinsicallyTiedToSub(SubmarineInfo sub)
{
foreach (RegularPackage regularPackage in ContentPackageManager.RegularPackages)
{
@@ -3171,10 +3213,11 @@ namespace Barotrauma
{
try
{
Directory.Delete(Path.GetDirectoryName(subPackage.Path), true);
Directory.Delete(Path.GetDirectoryName(subPackage.Path), recursive: true);
ContentPackageManager.LocalPackages.Refresh();
ContentPackageManager.EnabledPackages.DisableRemovedMods();
sub.Dispose();
File.Delete(sub.FilePath);
SubmarineInfo.RefreshSavedSubs();
CreateLoadScreen();
}