Docked subs are forced to correct positions during loading and the docking is "locked" (subs won't get stuck inside each other even if the linked sub is placed incorrectly in the editor)

This commit is contained in:
Regalis
2016-12-13 23:11:13 +02:00
parent 73eb6a2f1b
commit 40c28a11de
2 changed files with 89 additions and 32 deletions

View File

@@ -44,6 +44,12 @@ namespace Barotrauma.Items.Components
private bool docked;
public int DockingDir
{
get { return dockingDir; }
set { dockingDir = value; }
}
[HasDefaultValue("32.0,32.0", false)]
public string DistanceTolerance
{
@@ -177,8 +183,9 @@ namespace Barotrauma.Items.Components
dockingDir = IsHorizontal ?
Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) :
Math.Sign(item.WorldPosition.Y - dockingTarget.item.WorldPosition.Y);
Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y);
dockingTarget.dockingDir = -dockingDir;
foreach (WayPoint wp in WayPoint.WayPointList)
{
@@ -200,12 +207,46 @@ namespace Barotrauma.Items.Components
CreateJoint(false);
}
public void Lock()
{
if (dockingTarget==null)
{
DebugConsole.ThrowError("Error - attempted to lock a docking port that's not connected to anything");
return;
}
else if (joint is WeldJoint)
{
DebugConsole.ThrowError("Error - attempted to lock a docking port that's already locked");
return;
}
dockingDir = IsHorizontal ?
Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) :
Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y);
dockingTarget.dockingDir = -dockingDir;
GameMain.World.RemoveJoint(joint);
PlaySound(ActionType.OnSecondaryUse, item.WorldPosition);
ConnectWireBetweenPorts();
CreateJoint(true);
if (!item.linkedTo.Any(e => e is Hull) && !dockingTarget.item.linkedTo.Any(e => e is Hull))
{
CreateHull();
item.NewComponentEvent(this, false, true);
}
}
private void CreateJoint(bool useWeldJoint)
{
Vector2 offset = (IsHorizontal ?
Vector2.UnitX * Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) :
Vector2.UnitY * Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y));
Vector2.UnitX * dockingDir :
Vector2.UnitY * dockingDir);
offset *= DockedDistance * 0.5f;
Vector2 pos1 = item.WorldPosition + offset;
@@ -500,25 +541,12 @@ namespace Barotrauma.Items.Components
if (joint is DistanceJoint)
{
item.SendSignal(0, "0", "state_out");
dockingState = MathHelper.Lerp(dockingState, 0.5f, deltaTime * 10.0f);
if (Vector2.Distance(joint.WorldAnchorA, joint.WorldAnchorB) < 0.05f)
{
GameMain.World.RemoveJoint(joint);
PlaySound(ActionType.OnSecondaryUse, item.WorldPosition);
ConnectWireBetweenPorts();
CreateJoint(true);
if (!item.linkedTo.Any(e => e is Hull) && !dockingTarget.item.linkedTo.Any(e => e is Hull))
{
CreateHull();
item.NewComponentEvent(this, false, true);
}
Lock();
}
dockingState = MathHelper.Lerp(dockingState, 0.5f, deltaTime * 10.0f);
}
else
{
@@ -612,12 +640,14 @@ namespace Barotrauma.Items.Components
if (!item.linkedTo.Any()) return;
foreach (MapEntity entity in item.linkedTo)
List<MapEntity> linked = new List<MapEntity>(item.linkedTo);
foreach (MapEntity entity in linked)
{
var hull = entity as Hull;
if (hull != null)
{
hull.Remove();
item.linkedTo.Remove(hull);
continue;
}
@@ -625,6 +655,7 @@ namespace Barotrauma.Items.Components
if (gap != null)
{
gap.Remove();
gap.linkedTo.Remove(hull);
continue;
}
@@ -632,10 +663,11 @@ namespace Barotrauma.Items.Components
if (linkedItem == null) continue;
var dockingPort = linkedItem.GetComponent<DockingPort>();
if (dockingPort != null) dockingTarget = dockingPort;
if (dockingPort != null)
{
Dock(dockingPort);
}
}
item.linkedTo.Clear();
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power = 0.0f)

View File

@@ -405,19 +405,29 @@ namespace Barotrauma
}
else
{
sub.SetPosition(WorldPosition - Submarine.WorldPosition);
sub.Submarine = Submarine;
sub.SetPosition(WorldPosition);
}
var linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent<DockingPort>() != null);
if (linkedItem == null) return;
var linkedPort = ((Item)linkedItem).GetComponent<DockingPort>();
DockingPort linkedPort = null;
DockingPort myPort = null;
float closestDistance = 0.0f;
MapEntity linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent<DockingPort>() != null);
if (linkedItem == null)
{
linkedPort = DockingPort.list.Find(dp => dp.DockingTarget != null && dp.DockingTarget.Item.Submarine == sub);
}
else
{
linkedPort = ((Item)linkedItem).GetComponent<DockingPort>();
}
if (linkedPort == null)
{
return;
}
float closestDistance = 0.0f;
foreach (DockingPort port in DockingPort.list)
{
if (port.Item.Submarine != sub || port.IsHorizontal != linkedPort.IsHorizontal) continue;
@@ -432,8 +442,23 @@ namespace Barotrauma
if (myPort != null)
{
myPort.DockingTarget = linkedPort;
}
Vector2 portDiff = myPort.Item.WorldPosition - sub.WorldPosition;
Vector2 offset = (myPort.IsHorizontal ?
Vector2.UnitX * Math.Sign(linkedPort.Item.WorldPosition.X - myPort.Item.WorldPosition.X) :
Vector2.UnitY * Math.Sign(linkedPort.Item.WorldPosition.Y - myPort.Item.WorldPosition.Y));
offset *= myPort.DockedDistance;
sub.SetPosition(
(linkedPort.Item.WorldPosition - portDiff)
- offset);
myPort.Dock(linkedPort);
myPort.Lock();
}
sub.SetPosition(sub.WorldPosition - Submarine.WorldPosition);
sub.Submarine = Submarine;
}
}
}