(965c31410a) Unstable v0.10.4.0

This commit is contained in:
Juan Pablo Arce
2020-07-21 08:57:50 -03:00
parent 4f8bd39789
commit 33d3a41104
546 changed files with 45952 additions and 25762 deletions
@@ -656,10 +656,11 @@ namespace Barotrauma
public static List<Vector2[]> GenerateJaggedLine(Vector2 start, Vector2 end, int iterations, float offsetAmount)
{
List<Vector2[]> segments = new List<Vector2[]>();
List<Vector2[]> segments = new List<Vector2[]>
{
new Vector2[] { start, end }
};
segments.Add(new Vector2[] { start, end });
for (int n = 0; n < iterations; n++)
{
for (int i = 0; i < segments.Count; i++)
@@ -830,6 +831,31 @@ namespace Barotrauma
return (float)Math.Pow(f, p);
}
/// <summary>
/// Converts the alignment to a vector where -1,-1 is the top-left corner, 0,0 the center and 1,1 bottom-right
/// </summary>
public static Vector2 ToVector2(this Alignment alignment)
{
Vector2 vector = new Vector2(0.0f,0.0f);
if (alignment.HasFlag(Alignment.Left))
{
vector.X = -1.0f;
}
else if (alignment.HasFlag(Alignment.Right))
{
vector.X = 1.0f;
}
if (alignment.HasFlag(Alignment.Top))
{
vector.Y = -1.0f;
}
else if (alignment.HasFlag(Alignment.Bottom))
{
vector.Y = 1.0f;
}
return vector;
}
/// <summary>
/// Rotates a point in 2d space around another point.
/// Modified from:
@@ -33,24 +33,40 @@ namespace Barotrauma
syncedRandom[(int)RandSync.Server] = new MTRandom(seed);
syncedRandom[(int)RandSync.ClientOnly] = new MTRandom(seed);
}
public static int ThreadId = 0;
private static void CheckRandThreadSafety(RandSync sync)
{
if (ThreadId != 0 && sync == RandSync.Server)
{
if (System.Threading.Thread.CurrentThread.ManagedThreadId != ThreadId)
{
throw new Exception("Unauthorized multithreaded access to RandSync.Server");
}
}
}
public static float Range(float minimum, float maximum, RandSync sync=RandSync.Unsynced)
{
CheckRandThreadSafety(sync);
return (float)(sync == RandSync.Unsynced ? localRandom : (syncedRandom[(int)sync])).NextDouble() * (maximum - minimum) + minimum;
}
public static double Range(double minimum, double maximum, RandSync sync = RandSync.Unsynced)
{
CheckRandThreadSafety(sync);
return (sync == RandSync.Unsynced ? localRandom : (syncedRandom[(int)sync])).NextDouble() * (maximum - minimum) + minimum;
}
public static int Range(int minimum, int maximum, RandSync sync = RandSync.Unsynced)
{
CheckRandThreadSafety(sync);
return (sync == RandSync.Unsynced ? localRandom : (syncedRandom[(int)sync])).Next(maximum - minimum) + minimum;
}
public static int Int(int max, RandSync sync = RandSync.Unsynced)
{
CheckRandThreadSafety(sync);
return (sync == RandSync.Unsynced ? localRandom : (syncedRandom[(int)sync])).Next(max);
}
@@ -69,10 +69,38 @@ namespace Barotrauma
try
{
GameMain.GameSession.Save(Path.Combine(TempPath, "gamesession.xml"));
}
catch (Exception e)
{
DebugConsole.ThrowError("Error saving gamesession", e);
}
try
{
string mainSubPath = null;
if (GameMain.GameSession.SubmarineInfo != null)
{
string subPath = Path.Combine(TempPath, GameMain.GameSession.SubmarineInfo.Name + ".sub");
GameMain.GameSession.SubmarineInfo.SaveAs(subPath);
mainSubPath = Path.Combine(TempPath, GameMain.GameSession.SubmarineInfo.Name + ".sub");
GameMain.GameSession.SubmarineInfo.SaveAs(mainSubPath);
for (int i = 0; i < GameMain.GameSession.OwnedSubmarines.Count; i++)
{
if (GameMain.GameSession.OwnedSubmarines[i].Name == GameMain.GameSession.SubmarineInfo.Name)
{
GameMain.GameSession.OwnedSubmarines[i] = GameMain.GameSession.SubmarineInfo;
}
}
}
if (GameMain.GameSession.OwnedSubmarines != null)
{
for (int i = 0; i < GameMain.GameSession.OwnedSubmarines.Count; i++)
{
SubmarineInfo storedInfo = GameMain.GameSession.OwnedSubmarines[i];
string subPath = Path.Combine(TempPath, storedInfo.Name + ".sub");
if (mainSubPath == subPath) { continue; }
storedInfo.SaveAs(subPath);
}
}
}
catch (Exception e)
@@ -80,21 +108,10 @@ namespace Barotrauma
DebugConsole.ThrowError("Error saving submarine", e);
}
try
{
GameMain.GameSession.Save(Path.Combine(TempPath, "gamesession.xml"));
}
catch (Exception e)
{
DebugConsole.ThrowError("Error saving gamesession", e);
}
try
{
CompressDirectory(TempPath, filePath, null);
}
catch (Exception e)
{
DebugConsole.ThrowError("Error compressing save file", e);
@@ -109,19 +126,43 @@ namespace Barotrauma
XDocument doc = XMLExtensions.TryLoadXml(Path.Combine(TempPath, "gamesession.xml"));
if (doc == null) { return; }
string subPath = Path.Combine(TempPath, doc.Root.GetAttributeString("submarine", "")) + ".sub";
SubmarineInfo selectedSub = new SubmarineInfo(subPath, "");
GameMain.GameSession = new GameSession(selectedSub, filePath, doc);
if (!IsSaveFileCompatible(doc))
{
throw new Exception($"The save file \"{filePath}\" is not compatible with this version of Barotrauma.");
}
var ownedSubmarines = LoadOwnedSubmarines(doc, out SubmarineInfo selectedSub);
GameMain.GameSession = new GameSession(selectedSub, ownedSubmarines, doc, filePath);
}
public static void LoadGame(string filePath, GameSession gameSession)
public static List<SubmarineInfo> LoadOwnedSubmarines(XDocument saveDoc, out SubmarineInfo selectedSub)
{
string subPath = Path.Combine(TempPath, saveDoc.Root.GetAttributeString("submarine", "")) + ".sub";
selectedSub = new SubmarineInfo(subPath);
List<SubmarineInfo> ownedSubmarines = null;
var ownedSubsElement = saveDoc.Root.Element("ownedsubmarines");
if (ownedSubsElement != null)
{
ownedSubmarines = new List<SubmarineInfo>();
foreach (XElement subElement in ownedSubsElement.Elements())
{
string subName = subElement.GetAttributeString("name", "");
string ownedSubPath = Path.Combine(TempPath, subName + ".sub");
ownedSubmarines.Add(new SubmarineInfo(ownedSubPath));
}
}
return ownedSubmarines;
}
/*public static void LoadMultiplayerCampaignState(string filePath, MultiPlayerCampaign multiplayerCampaign)
{
DebugConsole.Log("Loading save file for an existing game session (" + filePath + ")");
DecompressToDirectory(filePath, TempPath, null);
XDocument doc = XMLExtensions.TryLoadXml(Path.Combine(TempPath, "gamesession.xml"));
if (doc == null) { return; }
gameSession.Load(doc.Root);
}
}*/
public static XDocument LoadGameSessionDoc(string filePath)
{
@@ -139,6 +180,12 @@ namespace Barotrauma
return XMLExtensions.TryLoadXml(Path.Combine(TempPath, "gamesession.xml"));
}
public static bool IsSaveFileCompatible(XDocument saveDoc)
{
if (saveDoc?.Root?.Attribute("version") == null) { return false; }
return true;
}
public static void DeleteSave(string filePath)
{
try
@@ -175,7 +222,7 @@ namespace Barotrauma
return Path.Combine(folder, saveName);
}
public static IEnumerable<string> GetSaveFiles(SaveType saveType)
public static IEnumerable<string> GetSaveFiles(SaveType saveType, bool includeInCompatible = true)
{
string folder = saveType == SaveType.Singleplayer ? SaveFolder : MultiplayerSaveFolder;
if (!Directory.Exists(folder))
@@ -191,13 +238,24 @@ namespace Barotrauma
}
}
List<string> files = Directory.GetFiles(folder, "*.save").ToList();
List<string> files = Directory.GetFiles(folder, "*.save", System.IO.SearchOption.TopDirectoryOnly).ToList();
string legacyFolder = saveType == SaveType.Singleplayer ? LegacySaveFolder : LegacyMultiplayerSaveFolder;
if (Directory.Exists(legacyFolder))
{
files.AddRange(Directory.GetFiles(legacyFolder, "*.save"));
files.AddRange(Directory.GetFiles(legacyFolder, "*.save", System.IO.SearchOption.TopDirectoryOnly));
}
if (!includeInCompatible)
{
for (int i = files.Count - 1; i >= 0; i--)
{
XDocument doc = LoadGameSessionDoc(files[i]);
if (!IsSaveFileCompatible(doc))
{
files.RemoveAt(i);
}
}
}
return files;
}
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -7,8 +8,11 @@ namespace Barotrauma
{
public static class TaskPool
{
const int MaxTasks = 5000;
private struct TaskAction
{
public string Name;
public Task Task;
public Action<Task, object> OnCompletion;
public object UserData;
@@ -16,32 +20,41 @@ namespace Barotrauma
private static List<TaskAction> taskActions = new List<TaskAction>();
private static void AddInternal(Task task, Action<Task, object> onCompletion, object userdata)
public static void ListTasks(string[] args)
{
lock (taskActions)
{
taskActions.Add(new TaskAction() { Task = task, OnCompletion = onCompletion, UserData = userdata });
DebugConsole.NewMessage($"Task count: {taskActions.Count}");
for (int i=0;i<taskActions.Count;i++)
{
DebugConsole.NewMessage($" -{i}: {taskActions[i].Name}, {taskActions[i].Task.Status}");
}
}
}
public static void Add(Task task, Action<Task> onCompletion)
private static void AddInternal(string name, Task task, Action<Task, object> onCompletion, object userdata)
{
AddInternal(task, (Task t, object obj) => { onCompletion?.Invoke(t); }, null);
lock (taskActions)
{
if (taskActions.Count >= MaxTasks)
{
throw new Exception(
"Too many tasks in the TaskPool:\n" + string.Join('\n', taskActions.Select(ta => ta.Name))
);
}
taskActions.Add(new TaskAction() { Name = name, Task = task, OnCompletion = onCompletion, UserData = userdata });
DebugConsole.Log($"New task: {name} ({taskActions.Count}/{MaxTasks})");
}
}
public static void Add<U>(Task task, U userdata, Action<Task, U> onCompletion) where U : class
public static void Add(string name, Task task, Action<Task> onCompletion)
{
AddInternal(task, (Task t, object obj) => { onCompletion?.Invoke(t, (U)obj); }, userdata);
AddInternal(name, task, (Task t, object obj) => { onCompletion?.Invoke(t); }, null);
}
public static void Add<T>(Task<T> task, Action<Task<T>> onCompletion)
public static void Add<U>(string name, Task task, U userdata, Action<Task, U> onCompletion) where U : class
{
AddInternal(task, (Task t, object obj) => { onCompletion?.Invoke((Task<T>)t); }, null);
}
public static void Add<T,U>(Task<T> task, U userdata, Action<Task<T>, U> onCompletion) where U : class
{
AddInternal(task, (Task t, object obj) => { onCompletion?.Invoke((Task<T>)t, (U)obj); }, userdata);
AddInternal(name, task, (Task t, object obj) => { onCompletion?.Invoke(t, (U)obj); }, userdata);
}
public static void Update()
@@ -53,6 +66,7 @@ namespace Barotrauma
if (taskActions[i].Task.IsCompleted)
{
taskActions[i].OnCompletion?.Invoke(taskActions[i].Task, taskActions[i].UserData);
DebugConsole.Log($"Task {taskActions[i].Name} completed ({taskActions.Count-1}/{MaxTasks})");
taskActions.RemoveAt(i);
i--;
}
@@ -212,6 +212,39 @@ namespace Barotrauma
return inputType;
}
/// <summary>
/// Returns either a green [x] or a red [o]
/// </summary>
/// <param name="isFinished"></param>
/// <returns></returns>
public static string GetDebugSymbol(bool isFinished)
{
return $"[‖color:{(isFinished ? "0,255,0x" : "255,0,0o")}‖color:end‖]";
}
/// <summary>
/// Turn the object into a string and give it rich color based on the object type
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string ColorizeObject(this object obj)
{
string color = obj switch
{
bool b => b ? "80,250,123" : "255,85,85",
string _ => "241,250,140",
int _ => "189,147,249",
float _ => "189,147,249",
double _ => "189,147,249",
null => "255,85,85",
_ => "139,233,253"
};
return obj is string
? $"‖color:{color}‖\"{obj}\"‖color:end‖"
: $"‖color:{color}‖{obj ?? "null"}‖color:end‖";
}
// Convert an RGB value into an HLS value.
public static Vector3 RgbToHLS(Vector3 color)