Unstable 0.15.15.0 (and the one before it I forgor)

This commit is contained in:
Markus Isberg
2021-11-18 21:34:30 +09:00
parent 10e5fd5f3e
commit 80f39cd2a3
257 changed files with 4916 additions and 2582 deletions
@@ -1,4 +1,5 @@
using Microsoft.Xna.Framework;
#nullable enable
using Barotrauma.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -12,13 +13,13 @@ namespace Barotrauma
private int maxId;
private readonly List<Range<int>> srcRanges;
private readonly List<Range<int>>? srcRanges;
private readonly int destOffset;
public IdRemap(XElement parentElement, int offset)
public IdRemap(XElement? parentElement, int offset)
{
destOffset = offset;
if (parentElement != null && parentElement.HasElements)
if (parentElement is { HasElements: true })
{
srcRanges = new List<Range<int>>();
foreach (XElement subElement in parentElement.Elements())
@@ -26,56 +27,60 @@ namespace Barotrauma
int id = subElement.GetAttributeInt("ID", -1);
if (id > 0) { InsertId(id); }
}
maxId = GetOffsetId(srcRanges.Last().End) + 1;
maxId = GetOffsetId(srcRanges.Last().End);
}
else
{
maxId = offset + 1;
maxId = offset;
}
}
public ushort AssignMaxId()
public void AssignMaxId(out ushort result)
{
maxId++;
return (ushort)maxId;
result = (ushort)maxId;
}
private void InsertId(int id)
{
for (int i = 0; i < srcRanges.Count; i++)
if (srcRanges is null) { throw new NullReferenceException("Called InsertId when srcRanges is null"); }
void tryMergeRangeWithNext(int indexA)
{
if (srcRanges[i].Start > id)
int indexB = indexA + 1;
if (indexA < 0 /* Index A out of bounds */
|| indexB >= srcRanges.Count /* Index B out of bounds */)
{
if (srcRanges[i].Start == (id + 1))
{
srcRanges[i] = new Range<int>(id, srcRanges[i].End);
if (i > 0 && srcRanges[i].Start == srcRanges[i - 1].End)
{
srcRanges[i - 1] = new Range<int>(srcRanges[i - 1].Start, srcRanges[i].End);
srcRanges.RemoveAt(i);
}
}
else
{
srcRanges.Insert(i, new Range<int>(id, id));
}
return;
}
else if (srcRanges[i].End < id)
Range<int> rangeA = srcRanges[indexA];
Range<int> rangeB = srcRanges[indexB];
if ((rangeA.End+1) >= rangeB.Start) //The end of range A is right before the start of range B, this should be one range
{
if (srcRanges[i].End == (id - 1))
{
srcRanges[i] = new Range<int>(srcRanges[i].Start, id);
if (i < (srcRanges.Count - 1) && srcRanges[i].End == srcRanges[i + 1].Start)
{
srcRanges[i] = new Range<int>(srcRanges[i].Start, srcRanges[i + 1].End);
srcRanges.RemoveAt(i + 1);
}
return;
}
srcRanges[indexA] = new Range<int>(rangeA.Start, rangeB.End);
srcRanges.RemoveAt(indexB);
}
}
srcRanges.Add(new Range<int>(id, id));
int insertIndex = srcRanges.Count;
for (int i = 0; i < srcRanges.Count; i++)
{
if (srcRanges[i].Contains(id)) //We already have a range that contains this ID, duplicates are invalid input!
{
throw new InvalidOperationException($"Duplicate ID: {id}");
}
if (srcRanges[i].Start > id) //ID is between srcRanges[i-1] and srcRanges[i], insert at i
{
insertIndex = i;
break;
}
}
srcRanges.Insert(insertIndex, new Range<int>(id, id)); //Insert new range consisting of solely the new ID
tryMergeRangeWithNext(insertIndex); //Try merging new range with the one that comes after it
tryMergeRangeWithNext(insertIndex - 1); //Try merging new range with the one that comes before it
}
public ushort GetOffsetId(XElement element)
@@ -85,31 +90,47 @@ namespace Barotrauma
public ushort GetOffsetId(int id)
{
if (id <= 0) { return 0; }
if (destOffset < 0) { return 0; }
if (srcRanges == null) { return (ushort)(id + destOffset); }
if (id <= 0) //Input cannot be remapped because it's negative
{
return 0;
}
if (destOffset < 0) //Remapper has been defined to discard all input
{
return 0;
}
if (srcRanges is null) //Remapper defines no source ranges so it just adds an offset
{
return (ushort)(id + destOffset);
}
int rangeSize(in Range<int> r)
=> r.End - r.Start + 1;
int currOffset = destOffset;
for (int i = 0; i < srcRanges.Count; i++)
{
if (id >= srcRanges[i].Start && id <= srcRanges[i].End)
if (srcRanges[i].Contains(id))
{
return (ushort)(id - srcRanges[i].Start + 1 + currOffset);
//The source range for this ID has been found!
//The return value is such that all IDs that
//are returned by this remapper are contiguous,
//even if they weren't originally
return (ushort)(id - srcRanges[i].Start + currOffset);
}
currOffset += srcRanges[i].End - srcRanges[i].Start + 1;
currOffset += rangeSize(srcRanges[i]);
}
return 0;
}
public static ushort DetermineNewOffset()
{
ushort idOffset = 0;
int largestEntityId = 0;
foreach (Entity e in Entity.GetEntities())
{
if (e.ID > Entity.ReservedIDStart || e is Submarine) { continue; }
idOffset = Math.Max(idOffset, e.ID);
largestEntityId = Math.Max(largestEntityId, e.ID);
}
return idOffset;
return (ushort)(largestEntityId+1);
}
}
}
@@ -1,8 +1,12 @@
#nullable enable
using System;
namespace Barotrauma
{
public struct Range<T> where T : IComparable
/// <summary>
/// An inclusive range, i.e. [Start, End] where Start <= End
/// </summary>
public struct Range<T> where T : notnull, IComparable<T>
{
private T start; private T end;
public T Start
@@ -25,6 +29,9 @@ namespace Barotrauma
}
}
public bool Contains(in T v)
=> start.CompareTo(v) <= 0 && end.CompareTo(v) >= 0;
private void VerifyStartLessThanEnd()
{
if (start.CompareTo(end) > 0) { throw new InvalidOperationException($"Range<{typeof(T).Name}>.Start set to a value greater than End ({start} > {end})"); }
@@ -425,7 +425,7 @@ namespace Barotrauma
return buffer;
}
public static T SelectWeightedRandom<T>(IList<T> objects, IList<float> weights, Rand.RandSync randSync)
public static T SelectWeightedRandom<T>(IList<T> objects, IList<float> weights, Rand.RandSync randSync = Rand.RandSync.Unsynced)
{
return SelectWeightedRandom(objects, weights, Rand.GetRNG(randSync));
}