Build 1.1.4.0
This commit is contained in:
@@ -213,9 +213,21 @@ namespace Barotrauma
|
||||
get
|
||||
{
|
||||
if (Level.Loaded == null) { return false; }
|
||||
if (Level.Loaded.EndOutpost != null && DockedTo.Contains(Level.Loaded.EndOutpost))
|
||||
if (Level.Loaded.EndOutpost != null)
|
||||
{
|
||||
return true;
|
||||
if (DockedTo.Contains(Level.Loaded.EndOutpost))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (Level.Loaded.EndOutpost.exitPoints.Any())
|
||||
{
|
||||
return IsAtOutpostExit(Level.Loaded.EndOutpost);
|
||||
}
|
||||
}
|
||||
else if (Level.Loaded.Type == LevelData.LevelType.Outpost && Level.Loaded.StartOutpost != null)
|
||||
{
|
||||
//in outpost levels, the outpost is always the start outpost: check it if has an exit
|
||||
return IsAtOutpostExit(Level.Loaded.StartOutpost);
|
||||
}
|
||||
return (Vector2.DistanceSquared(Position + HiddenSubPosition, Level.Loaded.EndExitPosition) < Level.ExitDistance * Level.ExitDistance);
|
||||
}
|
||||
@@ -226,14 +238,44 @@ namespace Barotrauma
|
||||
get
|
||||
{
|
||||
if (Level.Loaded == null) { return false; }
|
||||
if (Level.Loaded.StartOutpost != null && DockedTo.Contains(Level.Loaded.StartOutpost))
|
||||
if (Level.Loaded.StartOutpost != null)
|
||||
{
|
||||
return true;
|
||||
if (DockedTo.Contains(Level.Loaded.StartOutpost))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (Level.Loaded.StartOutpost.exitPoints.Any())
|
||||
{
|
||||
return IsAtOutpostExit(Level.Loaded.StartOutpost);
|
||||
}
|
||||
}
|
||||
return (Vector2.DistanceSquared(Position + HiddenSubPosition, Level.Loaded.StartExitPosition) < Level.ExitDistance * Level.ExitDistance);
|
||||
}
|
||||
}
|
||||
|
||||
public bool AtEitherExit => AtStartExit || AtEndExit;
|
||||
|
||||
private bool IsAtOutpostExit(Submarine outpost)
|
||||
{
|
||||
if (outpost.exitPoints.Any())
|
||||
{
|
||||
Rectangle worldBorders = Borders;
|
||||
worldBorders.Location += WorldPosition.ToPoint();
|
||||
foreach (var exitPoint in outpost.exitPoints)
|
||||
{
|
||||
if (exitPoint.ExitPointSize != Point.Zero)
|
||||
{
|
||||
if (RectsOverlap(worldBorders, exitPoint.ExitPointWorldRect)) { return true; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RectContains(worldBorders, exitPoint.WorldPosition)) { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public new Vector2 DrawPosition
|
||||
{
|
||||
@@ -284,6 +326,9 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<WayPoint> exitPoints = new List<WayPoint>();
|
||||
public IReadOnlyList<WayPoint> ExitPoints { get { return exitPoints; } }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Barotrauma.Submarine (" + (Info?.Name ?? "[NULL INFO]") + ", " + IdOffset + ")";
|
||||
@@ -350,12 +395,23 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
public WreckAI WreckAI { get; private set; }
|
||||
public SubmarineTurretAI TurretAI { get; private set; }
|
||||
|
||||
public bool CreateWreckAI()
|
||||
{
|
||||
WreckAI = WreckAI.Create(this);
|
||||
return WreckAI != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an AI that operates all the turrets on a sub, same as Thalamus but only operates the turrets.
|
||||
/// </summary>
|
||||
public bool CreateTurretAI()
|
||||
{
|
||||
TurretAI = new SubmarineTurretAI(this);
|
||||
return TurretAI != null;
|
||||
}
|
||||
|
||||
public void DisableWreckAI()
|
||||
{
|
||||
if (WreckAI == null)
|
||||
@@ -991,6 +1047,7 @@ namespace Barotrauma
|
||||
{
|
||||
WreckAI?.Update(deltaTime);
|
||||
}
|
||||
TurretAI?.Update(deltaTime);
|
||||
|
||||
if (subBody?.Body == null) { return; }
|
||||
|
||||
@@ -1038,7 +1095,7 @@ namespace Barotrauma
|
||||
|
||||
public void ApplyForce(Vector2 force)
|
||||
{
|
||||
if (subBody != null) subBody.ApplyForce(force);
|
||||
if (subBody != null) { subBody.ApplyForce(force); }
|
||||
}
|
||||
|
||||
public void EnableMaintainPosition()
|
||||
@@ -1271,22 +1328,38 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the sub whose borders contain the position
|
||||
/// Finds the sub whose borders contain the position. Note that this method uses the "actual" position of the sub outside the level:
|
||||
/// only use this if the position is in a submarine's local coordinate space!
|
||||
/// </summary>
|
||||
public static Submarine FindContaining(Vector2 position)
|
||||
public static Submarine FindContainingInLocalCoordinates(Vector2 position, float inflate = 500.0f)
|
||||
{
|
||||
foreach (Submarine sub in Loaded)
|
||||
{
|
||||
Rectangle subBorders = sub.Borders;
|
||||
subBorders.Location += MathUtils.ToPoint(sub.HiddenSubPosition) - new Microsoft.Xna.Framework.Point(0, sub.Borders.Height);
|
||||
|
||||
subBorders.Inflate(500.0f, 500.0f);
|
||||
|
||||
if (subBorders.Contains(position)) return sub;
|
||||
subBorders.Location += MathUtils.ToPoint(sub.HiddenSubPosition) - new Point(0, sub.Borders.Height);
|
||||
subBorders.Inflate(inflate, inflate);
|
||||
if (subBorders.Contains(position)) { return sub; }
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the sub whose world borders contain the position.
|
||||
/// </summary>
|
||||
public static Submarine FindContaining(Vector2 worldPosition, float inflate = 500.0f)
|
||||
{
|
||||
foreach (Submarine sub in Loaded)
|
||||
{
|
||||
Rectangle worldBorders = sub.Borders;
|
||||
worldBorders.Location += sub.WorldPosition.ToPoint();
|
||||
worldBorders.Inflate(inflate, inflate);
|
||||
if (RectContains(worldBorders, worldPosition)) { return sub; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Rectangle GetBorders(XElement submarineElement)
|
||||
{
|
||||
Vector4 bounds = Vector4.Zero;
|
||||
@@ -1325,14 +1398,19 @@ namespace Barotrauma
|
||||
|
||||
//place the sub above the top of the level
|
||||
HiddenSubPosition = HiddenSubStartPosition;
|
||||
if (GameMain.GameSession != null && GameMain.GameSession.LevelData != null)
|
||||
if (GameMain.GameSession?.LevelData != null)
|
||||
{
|
||||
HiddenSubPosition += Vector2.UnitY * GameMain.GameSession.LevelData.Size.Y;
|
||||
}
|
||||
|
||||
foreach (Submarine sub in loaded)
|
||||
for (int i = 0; i < loaded.Count; i++)
|
||||
{
|
||||
HiddenSubPosition += Vector2.UnitY * (sub.Borders.Height + 5000.0f);
|
||||
Submarine sub = loaded[i];
|
||||
HiddenSubPosition =
|
||||
new Vector2(
|
||||
//1st sub on the left side, 2nd on the right, etc
|
||||
HiddenSubPosition.X * (i % 2 == 0 ? 1 : -1),
|
||||
HiddenSubPosition.Y + sub.Borders.Height + 5000.0f);
|
||||
}
|
||||
|
||||
IdOffset = IdRemap.DetermineNewOffset();
|
||||
@@ -1460,10 +1538,15 @@ namespace Barotrauma
|
||||
MapEntity.MapLoaded(newEntities, true);
|
||||
foreach (MapEntity me in MapEntity.mapEntityList)
|
||||
{
|
||||
if (me is LinkedSubmarine linkedSub && linkedSub.Submarine == this)
|
||||
if (me.Submarine != this) { continue; }
|
||||
if (me is LinkedSubmarine linkedSub)
|
||||
{
|
||||
linkedSub.LinkDummyToMainSubmarine();
|
||||
}
|
||||
else if (me is WayPoint wayPoint && wayPoint.SpawnType.HasFlag(SpawnType.ExitPoint))
|
||||
{
|
||||
exitPoints.Add(wayPoint);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Hull hull in matchingHulls)
|
||||
@@ -1478,6 +1561,7 @@ namespace Barotrauma
|
||||
|
||||
#if CLIENT
|
||||
GameMain.LightManager.OnMapLoaded();
|
||||
Lights.ConvexHull.RecalculateAll(this);
|
||||
#endif
|
||||
//if the sub was made using an older version,
|
||||
//halve the brightness of the lights to make them look (almost) right on the new lighting formula
|
||||
@@ -1683,57 +1767,66 @@ namespace Barotrauma
|
||||
|
||||
public static void Unload()
|
||||
{
|
||||
if (Unloading)
|
||||
{
|
||||
DebugConsole.AddWarning($"Called {nameof(Submarine.Unload)} when already unloading.");
|
||||
return;
|
||||
}
|
||||
|
||||
Unloading = true;
|
||||
try
|
||||
{
|
||||
|
||||
#if CLIENT
|
||||
RoundSound.RemoveAllRoundSounds();
|
||||
GameMain.LightManager?.ClearLights();
|
||||
RoundSound.RemoveAllRoundSounds();
|
||||
GameMain.LightManager?.ClearLights();
|
||||
#endif
|
||||
|
||||
var _loaded = new List<Submarine>(loaded);
|
||||
foreach (Submarine sub in _loaded)
|
||||
{
|
||||
sub.Remove();
|
||||
}
|
||||
|
||||
loaded.Clear();
|
||||
|
||||
visibleEntities = null;
|
||||
|
||||
if (GameMain.GameScreen.Cam != null) { GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; }
|
||||
|
||||
RemoveAll();
|
||||
|
||||
if (Item.ItemList.Count > 0)
|
||||
{
|
||||
List<Item> items = new List<Item>(Item.ItemList);
|
||||
foreach (Item item in items)
|
||||
var _loaded = new List<Submarine>(loaded);
|
||||
foreach (Submarine sub in _loaded)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while unloading submarines - item \"" + item.Name + "\" (ID:" + item.ID + ") not removed");
|
||||
try
|
||||
{
|
||||
item.Remove();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while removing \"" + item.Name + "\"!", e);
|
||||
}
|
||||
sub.Remove();
|
||||
}
|
||||
Item.ItemList.Clear();
|
||||
|
||||
loaded.Clear();
|
||||
|
||||
visibleEntities = null;
|
||||
|
||||
if (GameMain.GameScreen.Cam != null) { GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; }
|
||||
|
||||
RemoveAll();
|
||||
|
||||
if (Item.ItemList.Count > 0)
|
||||
{
|
||||
List<Item> items = new List<Item>(Item.ItemList);
|
||||
foreach (Item item in items)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while unloading submarines - item \"" + item.Name + "\" (ID:" + item.ID + ") not removed");
|
||||
try
|
||||
{
|
||||
item.Remove();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while removing \"" + item.Name + "\"!", e);
|
||||
}
|
||||
}
|
||||
Item.ItemList.Clear();
|
||||
}
|
||||
|
||||
Ragdoll.RemoveAll();
|
||||
PhysicsBody.RemoveAll();
|
||||
GameMain.World = null;
|
||||
|
||||
Powered.Grids.Clear();
|
||||
|
||||
GC.Collect();
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
Unloading = false;
|
||||
}
|
||||
|
||||
Ragdoll.RemoveAll();
|
||||
|
||||
PhysicsBody.RemoveAll();
|
||||
|
||||
GameMain.World?.Clear();
|
||||
GameMain.World = null;
|
||||
|
||||
Powered.Grids.Clear();
|
||||
|
||||
GC.Collect();
|
||||
|
||||
Unloading = false;
|
||||
}
|
||||
|
||||
public override void Remove()
|
||||
@@ -1800,18 +1893,18 @@ namespace Barotrauma
|
||||
{
|
||||
if (node == null || node.Waypoint == null) { continue; }
|
||||
var wp = node.Waypoint;
|
||||
if (wp.isObstructed) { continue; }
|
||||
if (wp.IsObstructed) { continue; }
|
||||
foreach (var connection in node.connections)
|
||||
{
|
||||
var connectedWp = connection.Waypoint;
|
||||
if (connectedWp.isObstructed) { continue; }
|
||||
if (connectedWp.IsObstructed) { continue; }
|
||||
Vector2 start = ConvertUnits.ToSimUnits(wp.WorldPosition);
|
||||
Vector2 end = ConvertUnits.ToSimUnits(connectedWp.WorldPosition);
|
||||
var body = PickBody(start, end, null, Physics.CollisionLevel, allowInsideFixture: false);
|
||||
if (body != null)
|
||||
{
|
||||
connectedWp.isObstructed = true;
|
||||
wp.isObstructed = true;
|
||||
connectedWp.IsObstructed = true;
|
||||
wp.IsObstructed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1830,11 +1923,11 @@ namespace Barotrauma
|
||||
{
|
||||
if (node == null || node.Waypoint == null) { continue; }
|
||||
var wp = node.Waypoint;
|
||||
if (wp.isObstructed) { continue; }
|
||||
if (wp.IsObstructed) { continue; }
|
||||
foreach (var connection in node.connections)
|
||||
{
|
||||
var connectedWp = connection.Waypoint;
|
||||
if (connectedWp.isObstructed || connectedWp.Ladders != null) { continue; }
|
||||
if (connectedWp.IsObstructed || connectedWp.Ladders != null) { continue; }
|
||||
Vector2 start = ConvertUnits.ToSimUnits(wp.WorldPosition) - otherSub.SimPosition;
|
||||
Vector2 end = ConvertUnits.ToSimUnits(connectedWp.WorldPosition) - otherSub.SimPosition;
|
||||
var body = PickBody(start, end, null, Physics.CollisionWall, allowInsideFixture: true);
|
||||
@@ -1842,8 +1935,8 @@ namespace Barotrauma
|
||||
{
|
||||
if (body.UserData is Structure wall && !wall.IsPlatform || body.UserData is Item && body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall))
|
||||
{
|
||||
connectedWp.isObstructed = true;
|
||||
wp.isObstructed = true;
|
||||
connectedWp.IsObstructed = true;
|
||||
wp.IsObstructed = true;
|
||||
if (!obstructedNodes.TryGetValue(otherSub, out HashSet<PathNode> nodes))
|
||||
{
|
||||
nodes = new HashSet<PathNode>();
|
||||
@@ -1865,7 +1958,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (obstructedNodes.TryGetValue(otherSub, out HashSet<PathNode> nodes))
|
||||
{
|
||||
nodes.ForEach(n => n.Waypoint.isObstructed = false);
|
||||
nodes.ForEach(n => n.Waypoint.IsObstructed = false);
|
||||
nodes.Clear();
|
||||
obstructedNodes.Remove(otherSub);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user