Unstable v0.1300.0.0 (February 19th 2021)
This commit is contained in:
@@ -13,7 +13,16 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class DockingPort : ItemComponent, IDrawableComponent, IServerSerializable
|
||||
{
|
||||
private static List<DockingPort> list = new List<DockingPort>();
|
||||
public enum DirectionType
|
||||
{
|
||||
None,
|
||||
Top,
|
||||
Bottom,
|
||||
Left,
|
||||
Right
|
||||
}
|
||||
|
||||
private static readonly List<DockingPort> list = new List<DockingPort>();
|
||||
public static IEnumerable<DockingPort> List
|
||||
{
|
||||
get { return list; }
|
||||
@@ -29,15 +38,17 @@ namespace Barotrauma.Items.Components
|
||||
private Fixture outsideBlocker;
|
||||
private Body doorBody;
|
||||
|
||||
private float dockingCooldown;
|
||||
|
||||
private bool docked;
|
||||
private bool obstructedWayPointsDisabled;
|
||||
|
||||
private float forceLockTimer;
|
||||
//if the submarine isn't in the correct position to lock within this time after docking has been activated,
|
||||
//force the sub to the correct position
|
||||
const float ForceLockDelay = 1.0f;
|
||||
const float ForceLockDelay = 1.0f;
|
||||
|
||||
public int DockingDir { get; private set; }
|
||||
public int DockingDir { get; set; }
|
||||
|
||||
[Serialize("32.0,32.0", false, description: "How close the docking port has to be to another port to dock.")]
|
||||
public Vector2 DistanceTolerance { get; set; }
|
||||
@@ -63,6 +74,10 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(DirectionType.None, false, description: "Which direction the port is allowed to dock in. For example, \"Top\" would mean the port can dock to another port above it.\n"+
|
||||
"Normally there's no need to touch this setting, but if you notice the docking position is incorrect (for example due to some unusual docking port configuration without hulls or doors), you can use this to enforce the direction.")]
|
||||
public DirectionType ForceDockingDirection { get; set; }
|
||||
|
||||
public DockingPort DockingTarget { get; private set; }
|
||||
|
||||
public Door Door { get; private set; }
|
||||
@@ -89,6 +104,11 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsLocked
|
||||
{
|
||||
get { return joint is WeldJoint || DockingTarget?.joint is WeldJoint; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Automatically cleared after docking -> no need to unregister
|
||||
/// </summary>
|
||||
@@ -129,20 +149,12 @@ namespace Barotrauma.Items.Components
|
||||
DockingDir = GetDir(DockingTarget);
|
||||
DockingTarget.DockingDir = -DockingDir;
|
||||
}
|
||||
if (joint != null)
|
||||
{
|
||||
CreateJoint(joint is WeldJoint);
|
||||
LinkHullsToGaps();
|
||||
}
|
||||
else if (DockingTarget.joint != null)
|
||||
{
|
||||
if (!GameMain.World.BodyList.Contains(DockingTarget.joint.BodyA) ||
|
||||
!GameMain.World.BodyList.Contains(DockingTarget.joint.BodyB))
|
||||
{
|
||||
DockingTarget.CreateJoint(DockingTarget.joint is WeldJoint);
|
||||
}
|
||||
DockingTarget.LinkHullsToGaps();
|
||||
}
|
||||
|
||||
//undock and redock to recreate the hulls, gaps and physics bodies
|
||||
var prevDockingTarget = DockingTarget;
|
||||
Undock(applyEffects: false);
|
||||
Dock(prevDockingTarget);
|
||||
Lock(true, applyEffects: false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,15 +181,15 @@ namespace Barotrauma.Items.Components
|
||||
private void AttemptDock()
|
||||
{
|
||||
var adjacentPort = FindAdjacentPort();
|
||||
|
||||
if (adjacentPort != null) Dock(adjacentPort);
|
||||
if (adjacentPort != null) { Dock(adjacentPort); }
|
||||
}
|
||||
|
||||
public void Dock(DockingPort target)
|
||||
{
|
||||
if (item.Submarine.DockedTo.Contains(target.item.Submarine)) return;
|
||||
if (item.Submarine.DockedTo.Contains(target.item.Submarine)) { return; }
|
||||
|
||||
forceLockTimer = 0.0f;
|
||||
dockingCooldown = 0.1f;
|
||||
|
||||
if (DockingTarget != null)
|
||||
{
|
||||
@@ -219,7 +231,6 @@ namespace Barotrauma.Items.Components
|
||||
#if SERVER
|
||||
if (GameMain.Server != null && (!item.Submarine?.Loading ?? true))
|
||||
{
|
||||
originalDockingTargetID = DockingTarget.item.ID;
|
||||
item.CreateServerEvent(this);
|
||||
}
|
||||
#endif
|
||||
@@ -229,7 +240,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
|
||||
public void Lock(bool isNetworkMessage, bool forcePosition = false)
|
||||
public void Lock(bool isNetworkMessage, bool forcePosition = false, bool applyEffects = true)
|
||||
{
|
||||
#if CLIENT
|
||||
if (GameMain.Client != null && !isNetworkMessage) { return; }
|
||||
@@ -246,18 +257,24 @@ namespace Barotrauma.Items.Components
|
||||
DockingDir = GetDir(DockingTarget);
|
||||
DockingTarget.DockingDir = -DockingDir;
|
||||
|
||||
ApplyStatusEffects(ActionType.OnUse, 1.0f);
|
||||
|
||||
Vector2 jointDiff = joint.WorldAnchorB - joint.WorldAnchorA;
|
||||
if (item.Submarine.PhysicsBody.Mass < DockingTarget.item.Submarine.PhysicsBody.Mass ||
|
||||
DockingTarget.item.Submarine.Info.IsOutpost)
|
||||
if (applyEffects)
|
||||
{
|
||||
item.Submarine.SubBody.SetPosition(item.Submarine.SubBody.Position + ConvertUnits.ToDisplayUnits(jointDiff));
|
||||
ApplyStatusEffects(ActionType.OnUse, 1.0f);
|
||||
}
|
||||
else if (DockingTarget.item.Submarine.PhysicsBody.Mass < item.Submarine.PhysicsBody.Mass ||
|
||||
item.Submarine.Info.IsOutpost)
|
||||
|
||||
if (forcePosition)
|
||||
{
|
||||
DockingTarget.item.Submarine.SubBody.SetPosition(DockingTarget.item.Submarine.SubBody.Position - ConvertUnits.ToDisplayUnits(jointDiff));
|
||||
Vector2 jointDiff = joint.WorldAnchorB - joint.WorldAnchorA;
|
||||
if (item.Submarine.PhysicsBody.Mass < DockingTarget.item.Submarine.PhysicsBody.Mass ||
|
||||
DockingTarget.item.Submarine.Info.IsOutpost)
|
||||
{
|
||||
item.Submarine.SubBody.SetPosition(item.Submarine.SubBody.Position + ConvertUnits.ToDisplayUnits(jointDiff));
|
||||
}
|
||||
else if (DockingTarget.item.Submarine.PhysicsBody.Mass < item.Submarine.PhysicsBody.Mass ||
|
||||
item.Submarine.Info.IsOutpost)
|
||||
{
|
||||
DockingTarget.item.Submarine.SubBody.SetPosition(DockingTarget.item.Submarine.SubBody.Position - ConvertUnits.ToDisplayUnits(jointDiff));
|
||||
}
|
||||
}
|
||||
|
||||
ConnectWireBetweenPorts();
|
||||
@@ -266,7 +283,6 @@ namespace Barotrauma.Items.Components
|
||||
#if SERVER
|
||||
if (GameMain.Server != null && (!item.Submarine?.Loading ?? true))
|
||||
{
|
||||
originalDockingTargetID = DockingTarget.item.ID;
|
||||
item.CreateServerEvent(this);
|
||||
}
|
||||
#else
|
||||
@@ -311,10 +327,10 @@ namespace Barotrauma.Items.Components
|
||||
joint = null;
|
||||
}
|
||||
|
||||
Vector2 offset = (IsHorizontal ?
|
||||
Vector2 offset = IsHorizontal ?
|
||||
Vector2.UnitX * DockingDir :
|
||||
Vector2.UnitY * DockingDir);
|
||||
offset *= DockedDistance * 0.5f;
|
||||
Vector2.UnitY * DockingDir;
|
||||
offset *= DockedDistance * 0.5f * item.Scale;
|
||||
|
||||
Vector2 pos1 = item.WorldPosition + offset;
|
||||
|
||||
@@ -346,6 +362,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public int GetDir(DockingPort dockingTarget = null)
|
||||
{
|
||||
int forcedDockingDir = GetForcedDockingDir();
|
||||
if (forcedDockingDir != 0) { return forcedDockingDir; }
|
||||
if (dockingTarget != null)
|
||||
{
|
||||
forcedDockingDir = -dockingTarget.GetForcedDockingDir();
|
||||
if (forcedDockingDir != 0) { return forcedDockingDir; }
|
||||
}
|
||||
|
||||
if (DockingDir != 0) { return DockingDir; }
|
||||
|
||||
if (Door != null && Door.LinkedGap.linkedTo.Count > 0)
|
||||
@@ -390,9 +414,10 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
if (dockingTarget != null)
|
||||
{
|
||||
return IsHorizontal ?
|
||||
int dir = IsHorizontal ?
|
||||
Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) :
|
||||
Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y);
|
||||
if (dir != 0) { return dir; }
|
||||
}
|
||||
if (item.Submarine != null)
|
||||
{
|
||||
@@ -404,6 +429,22 @@ namespace Barotrauma.Items.Components
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int GetForcedDockingDir()
|
||||
{
|
||||
switch (ForceDockingDirection)
|
||||
{
|
||||
case DirectionType.Left:
|
||||
return -1;
|
||||
case DirectionType.Right:
|
||||
return 1;
|
||||
case DirectionType.Top:
|
||||
return 1;
|
||||
case DirectionType.Bottom:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void ConnectWireBetweenPorts()
|
||||
{
|
||||
Wire wire = item.GetComponent<Wire>();
|
||||
@@ -491,8 +532,9 @@ namespace Barotrauma.Items.Components
|
||||
subs = new Submarine[] { DockingTarget.item.Submarine, item.Submarine };
|
||||
}
|
||||
|
||||
hullRects[0] = new Rectangle(hullRects[0].Center.X, hullRects[0].Y, ((int)DockedDistance / 2), hullRects[0].Height);
|
||||
hullRects[1] = new Rectangle(hullRects[1].Center.X - ((int)DockedDistance / 2), hullRects[1].Y, ((int)DockedDistance / 2), hullRects[1].Height);
|
||||
int scaledDockedDistance = (int)(DockedDistance / 2 * item.Scale);
|
||||
hullRects[0] = new Rectangle(hullRects[0].Center.X, hullRects[0].Y, scaledDockedDistance, hullRects[0].Height);
|
||||
hullRects[1] = new Rectangle(hullRects[1].Center.X - scaledDockedDistance, hullRects[1].Y, scaledDockedDistance, hullRects[1].Height);
|
||||
|
||||
//expand hulls if needed, so there's no empty space between the sub's hulls and docking port hulls
|
||||
int leftSubRightSide = int.MinValue, rightSubLeftSide = int.MaxValue;
|
||||
@@ -588,8 +630,9 @@ namespace Barotrauma.Items.Components
|
||||
subs = new Submarine[] { DockingTarget.item.Submarine, item.Submarine };
|
||||
}
|
||||
|
||||
hullRects[0] = new Rectangle(hullRects[0].X, hullRects[0].Y + (int)(-hullRects[0].Height + DockedDistance) / 2, hullRects[0].Width, ((int)DockedDistance / 2));
|
||||
hullRects[1] = new Rectangle(hullRects[1].X, hullRects[1].Y - hullRects[1].Height / 2, hullRects[1].Width, ((int)DockedDistance / 2));
|
||||
int scaledDockedDistance = (int)(DockedDistance / 2 * item.Scale);
|
||||
hullRects[0] = new Rectangle(hullRects[0].X, hullRects[0].Y - hullRects[0].Height / 2 + scaledDockedDistance, hullRects[0].Width, scaledDockedDistance);
|
||||
hullRects[1] = new Rectangle(hullRects[1].X, hullRects[1].Y - hullRects[1].Height / 2, hullRects[1].Width, scaledDockedDistance);
|
||||
|
||||
//expand hulls if needed, so there's no empty space between the sub's hulls and docking port hulls
|
||||
int upperSubBottom = int.MaxValue, lowerSubTop = int.MinValue;
|
||||
@@ -801,13 +844,17 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public void Undock()
|
||||
public void Undock(bool applyEffects = true)
|
||||
{
|
||||
if (DockingTarget == null || !docked) return;
|
||||
if (DockingTarget == null || !docked) { return; }
|
||||
|
||||
forceLockTimer = 0.0f;
|
||||
dockingCooldown = 0.1f;
|
||||
|
||||
ApplyStatusEffects(ActionType.OnSecondaryUse, 1.0f);
|
||||
if (applyEffects)
|
||||
{
|
||||
ApplyStatusEffects(ActionType.OnSecondaryUse, 1.0f);
|
||||
}
|
||||
|
||||
DockingTarget.item.Submarine.ConnectedDockingPorts.Remove(item.Submarine);
|
||||
item.Submarine.ConnectedDockingPorts.Remove(DockingTarget.item.Submarine);
|
||||
@@ -879,7 +926,6 @@ namespace Barotrauma.Items.Components
|
||||
#if SERVER
|
||||
if (GameMain.Server != null && (!item.Submarine?.Loading ?? true))
|
||||
{
|
||||
originalDockingTargetID = Entity.NullEntityID;
|
||||
item.CreateServerEvent(this);
|
||||
}
|
||||
#endif
|
||||
@@ -889,6 +935,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
dockingCooldown -= deltaTime;
|
||||
if (DockingTarget == null)
|
||||
{
|
||||
dockingState = MathHelper.Lerp(dockingState, 0.0f, deltaTime * 10.0f);
|
||||
@@ -896,7 +943,6 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
item.SendSignal(0, "0", "state_out", null);
|
||||
item.SendSignal(0, (FindAdjacentPort() != null) ? "1" : "0", "proximity_sensor", null);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -908,7 +954,6 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (joint is DistanceJoint)
|
||||
{
|
||||
item.SendSignal(0, "0", "state_out", null);
|
||||
dockingState = MathHelper.Lerp(dockingState, 0.5f, deltaTime * 10.0f);
|
||||
|
||||
forceLockTimer += deltaTime;
|
||||
@@ -918,9 +963,7 @@ namespace Barotrauma.Items.Components
|
||||
if (jointDiff.LengthSquared() > 0.04f * 0.04f && forceLockTimer < ForceLockDelay)
|
||||
{
|
||||
float totalMass = item.Submarine.PhysicsBody.Mass + DockingTarget.item.Submarine.PhysicsBody.Mass;
|
||||
float massRatio1 = 1.0f;
|
||||
float massRatio2 = 1.0f;
|
||||
|
||||
float massRatio1, massRatio2;
|
||||
if (item.Submarine.PhysicsBody.BodyType != BodyType.Dynamic)
|
||||
{
|
||||
massRatio1 = 0.0f;
|
||||
@@ -954,11 +997,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
doorBody.Enabled = DockingTarget.Door.Body.Enabled;
|
||||
}
|
||||
|
||||
item.SendSignal(0, "1", "state_out", null);
|
||||
|
||||
dockingState = MathHelper.Lerp(dockingState, 1.0f, deltaTime * 10.0f);
|
||||
}
|
||||
|
||||
item.SendSignal(0, IsLocked ? "1" : "0", "state_out", null);
|
||||
}
|
||||
if (!obstructedWayPointsDisabled && dockingState >= 0.99f)
|
||||
{
|
||||
@@ -985,7 +1027,8 @@ namespace Barotrauma.Items.Components
|
||||
if (initialized) { return; }
|
||||
initialized = true;
|
||||
|
||||
float closestDist = 30.0f * 30.0f;
|
||||
float maxXDist = (item.Prefab.sprite.size.X * item.Prefab.Scale) / 2;
|
||||
float closestYDist = (item.Prefab.sprite.size.Y * item.Prefab.Scale) / 2;
|
||||
foreach (Item it in Item.ItemList)
|
||||
{
|
||||
if (it.Submarine != item.Submarine) { continue; }
|
||||
@@ -993,11 +1036,22 @@ namespace Barotrauma.Items.Components
|
||||
var doorComponent = it.GetComponent<Door>();
|
||||
if (doorComponent == null || doorComponent.IsHorizontal == IsHorizontal) { continue; }
|
||||
|
||||
float distSqr = Vector2.DistanceSquared(item.Position, it.Position);
|
||||
if (distSqr < closestDist)
|
||||
float yDist = Math.Abs(it.Position.Y - item.Position.Y);
|
||||
if (item.linkedTo.Contains(it))
|
||||
{
|
||||
// If there's a door linked to the docking port, always treat it close enough.
|
||||
yDist = Math.Min(closestYDist, yDist);
|
||||
}
|
||||
else if (Math.Abs(it.Position.X - item.Position.X) > maxXDist)
|
||||
{
|
||||
// Too far left/right
|
||||
continue;
|
||||
}
|
||||
|
||||
if (yDist <= closestYDist)
|
||||
{
|
||||
Door = doorComponent;
|
||||
closestDist = distSqr;
|
||||
closestYDist = yDist;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1055,6 +1109,8 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
|
||||
if (dockingCooldown > 0.0f) { return; }
|
||||
|
||||
bool wasDocked = docked;
|
||||
DockingPort prevDockingTarget = DockingTarget;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user