(965c31410a) Unstable v0.10.4.0
This commit is contained in:
@@ -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,0‖x" : "255,0,0‖o")}‖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)
|
||||
|
||||
Reference in New Issue
Block a user