(14f26adfa) Take the position of a sub's docking port into account when determining where to place outposts. Humpback's docking port for example is 600 units to the right from the sub's centerpoint, which prevented it from docking in some levels because the left side of the sub hit the wall at the left side of the outpost. Closes #1028
This commit is contained in:
@@ -21,6 +21,7 @@ namespace Barotrauma
|
|||||||
if (wallTarget != null)
|
if (wallTarget != null)
|
||||||
{
|
{
|
||||||
Vector2 wallTargetPos = wallTarget.Position;
|
Vector2 wallTargetPos = wallTarget.Position;
|
||||||
|
if (wallTarget.Structure.Submarine != null) wallTargetPos += wallTarget.Structure.Submarine.Position;
|
||||||
wallTargetPos.Y = -wallTargetPos.Y;
|
wallTargetPos.Y = -wallTargetPos.Y;
|
||||||
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Red, false);
|
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Red, false);
|
||||||
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
|
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using Barotrauma.Particles;
|
using Barotrauma.Particles;
|
||||||
using Barotrauma.Sounds;
|
using Barotrauma.Sounds;
|
||||||
|
using Lidgren.Network;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Xna.Framework.Input;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Lidgren.Network;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -19,6 +18,8 @@ namespace Barotrauma
|
|||||||
private List<Decal> decals = new List<Decal>();
|
private List<Decal> decals = new List<Decal>();
|
||||||
|
|
||||||
private float serverUpdateDelay;
|
private float serverUpdateDelay;
|
||||||
|
private float remoteWaterVolume, remoteOxygenPercentage;
|
||||||
|
private List<Vector3> remoteFireSources;
|
||||||
|
|
||||||
private bool networkUpdatePending;
|
private bool networkUpdatePending;
|
||||||
private float networkUpdateTimer;
|
private float networkUpdateTimer;
|
||||||
@@ -139,6 +140,10 @@ namespace Barotrauma
|
|||||||
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
serverUpdateDelay -= deltaTime;
|
serverUpdateDelay -= deltaTime;
|
||||||
|
if (serverUpdateDelay <= 0.0f)
|
||||||
|
{
|
||||||
|
ApplyRemoteState();
|
||||||
|
}
|
||||||
|
|
||||||
if (networkUpdatePending)
|
if (networkUpdatePending)
|
||||||
{
|
{
|
||||||
@@ -547,18 +552,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void ClientRead(ServerNetObject type, NetBuffer message, float sendingTime)
|
public void ClientRead(ServerNetObject type, NetBuffer message, float sendingTime)
|
||||||
{
|
{
|
||||||
float newWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
|
remoteWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
|
||||||
float newOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
remoteOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||||
|
|
||||||
bool hasFireSources = message.ReadBoolean();
|
bool hasFireSources = message.ReadBoolean();
|
||||||
int fireSourceCount = 0;
|
int fireSourceCount = 0;
|
||||||
List<Vector3> newFireSources = new List<Vector3>();
|
remoteFireSources = new List<Vector3>();
|
||||||
if (hasFireSources)
|
if (hasFireSources)
|
||||||
{
|
{
|
||||||
fireSourceCount = message.ReadRangedInteger(0, 16);
|
fireSourceCount = message.ReadRangedInteger(0, 16);
|
||||||
for (int i = 0; i < fireSourceCount; i++)
|
for (int i = 0; i < fireSourceCount; i++)
|
||||||
{
|
{
|
||||||
newFireSources.Add(new Vector3(
|
remoteFireSources.Add(new Vector3(
|
||||||
MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
|
MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
|
||||||
MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
|
MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
|
||||||
message.ReadRangedSingle(0.0f, 1.0f, 8)));
|
message.ReadRangedSingle(0.0f, 1.0f, 8)));
|
||||||
@@ -567,41 +572,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (serverUpdateDelay > 0.0f) { return; }
|
if (serverUpdateDelay > 0.0f) { return; }
|
||||||
|
|
||||||
WaterVolume = newWaterVolume;
|
|
||||||
OxygenPercentage = newOxygenPercentage;
|
|
||||||
|
|
||||||
for (int i = 0; i < fireSourceCount; i++)
|
|
||||||
{
|
|
||||||
Vector2 pos = new Vector2(
|
|
||||||
rect.X + rect.Width * newFireSources[i].X,
|
|
||||||
rect.Y - rect.Height + (rect.Height * newFireSources[i].Y));
|
|
||||||
float size = newFireSources[i].Z * rect.Width;
|
|
||||||
|
|
||||||
var newFire = i < FireSources.Count ?
|
|
||||||
FireSources[i] :
|
|
||||||
new FireSource(Submarine == null ? pos : pos + Submarine.Position, null, true);
|
|
||||||
newFire.Position = pos;
|
|
||||||
newFire.Size = new Vector2(size, newFire.Size.Y);
|
|
||||||
|
|
||||||
//ignore if the fire wasn't added to this room (invalid position)?
|
|
||||||
if (!FireSources.Contains(newFire))
|
|
||||||
{
|
|
||||||
newFire.Remove();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = FireSources.Count - 1; i >= fireSourceCount; i--)
|
|
||||||
{
|
|
||||||
FireSources[i].Remove();
|
|
||||||
if (i < FireSources.Count)
|
|
||||||
{
|
|
||||||
FireSources.RemoveAt(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serverUpdateDelay > 0.0f) { return; }
|
|
||||||
|
|
||||||
ApplyRemoteState();
|
ApplyRemoteState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,16 @@ namespace Barotrauma
|
|||||||
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
if (IdFreed) { return; }
|
if (IdFreed) { return; }
|
||||||
|
|
||||||
|
//don't create updates if all clients are very far from the hull
|
||||||
|
float hullUpdateDistanceSqr = NetConfig.HullUpdateDistance * NetConfig.HullUpdateDistance;
|
||||||
|
if (!GameMain.Server.ConnectedClients.Any(c =>
|
||||||
|
c.Character != null &&
|
||||||
|
Vector2.DistanceSquared(c.Character.WorldPosition, WorldPosition) < hullUpdateDistanceSqr))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//update client hulls if the amount of water has changed by >10%
|
//update client hulls if the amount of water has changed by >10%
|
||||||
//or if oxygen percentage has changed by 5%
|
//or if oxygen percentage has changed by 5%
|
||||||
if (Math.Abs(lastSentVolume - waterVolume) > Volume * 0.1f ||
|
if (Math.Abs(lastSentVolume - waterVolume) > Volume * 0.1f ||
|
||||||
@@ -31,7 +41,7 @@ namespace Barotrauma
|
|||||||
GameMain.NetworkMember.CreateEntityEvent(this);
|
GameMain.NetworkMember.CreateEntityEvent(this);
|
||||||
lastSentVolume = waterVolume;
|
lastSentVolume = waterVolume;
|
||||||
lastSentOxygen = OxygenPercentage;
|
lastSentOxygen = OxygenPercentage;
|
||||||
sendUpdateTimer = NetworkUpdateInterval;
|
sendUpdateTimer = NetConfig.HullUpdateInterval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -346,6 +346,12 @@ namespace Barotrauma.Networking
|
|||||||
Write(msg, eventsToSync, out sentEvents, client);
|
Write(msg, eventsToSync, out sentEvents, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (NetEntityEvent entityEvent in sentEvents)
|
||||||
|
{
|
||||||
|
(entityEvent as ServerEntityEvent).Sent = true;
|
||||||
|
client.EntityEventLastSent[entityEvent.ID] = NetTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (NetEntityEvent entityEvent in sentEvents)
|
foreach (NetEntityEvent entityEvent in sentEvents)
|
||||||
{
|
{
|
||||||
(entityEvent as ServerEntityEvent).Sent = true;
|
(entityEvent as ServerEntityEvent).Sent = true;
|
||||||
|
|||||||
@@ -447,6 +447,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
attackWorldPos = wallTarget.Position;
|
attackWorldPos = wallTarget.Position;
|
||||||
attackSimPos = ConvertUnits.ToSimUnits(attackWorldPos);
|
attackSimPos = ConvertUnits.ToSimUnits(attackWorldPos);
|
||||||
|
if (Character.Submarine == null && wallTarget.Structure.Submarine != null)
|
||||||
|
{
|
||||||
|
attackWorldPos += wallTarget.Structure.Submarine.Position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (SelectedAiTarget.Entity is Character c)
|
else if (SelectedAiTarget.Entity is Character c)
|
||||||
{
|
{
|
||||||
@@ -467,6 +471,15 @@ namespace Barotrauma
|
|||||||
|
|
||||||
// Take the sub position into account in the sim pos
|
// Take the sub position into account in the sim pos
|
||||||
if (Character.Submarine == null && SelectedAiTarget.Entity.Submarine != null)
|
if (Character.Submarine == null && SelectedAiTarget.Entity.Submarine != null)
|
||||||
|
{
|
||||||
|
attackSimPos += SelectedAiTarget.Entity.Submarine.SimPosition;
|
||||||
|
}
|
||||||
|
else if (Character.Submarine != null && SelectedAiTarget.Entity.Submarine == null)
|
||||||
|
{
|
||||||
|
attackSimPos -= Character.Submarine.SimPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Math.Abs(Character.AnimController.movement.X) > 0.1f && !Character.AnimController.InWater)
|
||||||
{
|
{
|
||||||
Character.AnimController.TargetDir = Character.WorldPosition.X < attackWorldPos.X ? Direction.Right : Direction.Left;
|
Character.AnimController.TargetDir = Character.WorldPosition.X < attackWorldPos.X ? Direction.Right : Direction.Left;
|
||||||
}
|
}
|
||||||
@@ -477,24 +490,30 @@ namespace Barotrauma
|
|||||||
if (wallTarget != null && wallTarget.SectionIndex > -1 && CanPassThroughHole(wallTarget.Structure, wallTarget.SectionIndex))
|
if (wallTarget != null && wallTarget.SectionIndex > -1 && CanPassThroughHole(wallTarget.Structure, wallTarget.SectionIndex))
|
||||||
{
|
{
|
||||||
WallSection section = wallTarget.Structure.GetSection(wallTarget.SectionIndex);
|
WallSection section = wallTarget.Structure.GetSection(wallTarget.SectionIndex);
|
||||||
Vector2 targetPos = wallTarget.Structure.SectionPosition(wallTarget.SectionIndex, true);
|
Hull targetHull = section.gap?.FlowTargetHull;
|
||||||
if (section?.gap != null && section.gap.IsRoomToRoom && SteerThroughGap(wallTarget.Structure, section, targetPos, deltaTime))
|
if (targetHull != null && !section.gap.IsRoomToRoom)
|
||||||
{
|
{
|
||||||
return;
|
Vector2 targetPos = wallTarget.Structure.SectionPosition(wallTarget.SectionIndex, true);
|
||||||
}
|
if (wallTarget.Structure.IsHorizontal)
|
||||||
}
|
|
||||||
else if (SelectedAiTarget.Entity is Structure wall)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < wall.Sections.Length; i++)
|
|
||||||
{
|
|
||||||
WallSection section = wall.Sections[i];
|
|
||||||
if (CanPassThroughHole(wall, i) && section?.gap != null)
|
|
||||||
{
|
{
|
||||||
if (SteerThroughGap(wall, section, section.gap.WorldPosition, deltaTime))
|
targetPos.Y = targetHull.WorldRect.Y - targetHull.Rect.Height / 2;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetPos.X = targetHull.WorldRect.Center.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
latchOntoAI?.DeattachFromBody();
|
||||||
|
Character.AnimController.ReleaseStuckLimbs();
|
||||||
|
if (steeringManager is IndoorsSteeringManager)
|
||||||
|
{
|
||||||
|
steeringManager.SteeringManual(deltaTime, Vector2.Normalize(targetPos - Character.WorldPosition));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
steeringManager.SteeringSeek(ConvertUnits.ToSimUnits(targetPos));
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (SelectedAiTarget.Entity is Item i)
|
else if (SelectedAiTarget.Entity is Item i)
|
||||||
@@ -509,8 +528,6 @@ namespace Barotrauma
|
|||||||
if (Character.WorldPosition.Y < door.Item.WorldRect.Y && Character.WorldPosition.Y > door.Item.WorldRect.Y - door.Item.Rect.Height)
|
if (Character.WorldPosition.Y < door.Item.WorldRect.Y && Character.WorldPosition.Y > door.Item.WorldRect.Y - door.Item.Rect.Height)
|
||||||
{
|
{
|
||||||
velocity.Y = 0;
|
velocity.Y = 0;
|
||||||
latchOntoAI?.DeattachFromBody();
|
|
||||||
Character.AnimController.ReleaseStuckLimbs();
|
|
||||||
steeringManager.SteeringManual(deltaTime, velocity);
|
steeringManager.SteeringManual(deltaTime, velocity);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -520,8 +537,6 @@ namespace Barotrauma
|
|||||||
if (Character.WorldPosition.X < door.Item.WorldRect.X && Character.WorldPosition.X > door.Item.WorldRect.Right)
|
if (Character.WorldPosition.X < door.Item.WorldRect.X && Character.WorldPosition.X > door.Item.WorldRect.Right)
|
||||||
{
|
{
|
||||||
velocity.X = 0;
|
velocity.X = 0;
|
||||||
latchOntoAI?.DeattachFromBody();
|
|
||||||
Character.AnimController.ReleaseStuckLimbs();
|
|
||||||
steeringManager.SteeringManual(deltaTime, velocity);
|
steeringManager.SteeringManual(deltaTime, velocity);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -687,34 +702,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SteerThroughGap(Structure wall, WallSection section, Vector2 targetWorldPos, float deltaTime)
|
|
||||||
{
|
|
||||||
Hull targetHull = section.gap?.FlowTargetHull;
|
|
||||||
if (targetHull != null) // && !section.gap.IsRoomToRoom
|
|
||||||
{
|
|
||||||
if (wall.IsHorizontal)
|
|
||||||
{
|
|
||||||
targetWorldPos.Y = targetHull.WorldRect.Y - targetHull.Rect.Height / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
targetWorldPos.X = targetHull.WorldRect.Center.X;
|
|
||||||
}
|
|
||||||
latchOntoAI?.DeattachFromBody();
|
|
||||||
Character.AnimController.ReleaseStuckLimbs();
|
|
||||||
if (steeringManager is IndoorsSteeringManager)
|
|
||||||
{
|
|
||||||
steeringManager.SteeringManual(deltaTime, Vector2.Normalize(targetWorldPos - Character.WorldPosition));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
steeringManager.SteeringSeek(ConvertUnits.ToSimUnits(targetWorldPos));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Limb GetAttackLimb(Vector2 attackWorldPos, Limb ignoredLimb = null)
|
private Limb GetAttackLimb(Vector2 attackWorldPos, Limb ignoredLimb = null)
|
||||||
{
|
{
|
||||||
AttackContext currentContext = Character.GetAttackContext();
|
AttackContext currentContext = Character.GetAttackContext();
|
||||||
@@ -738,6 +725,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
wallTarget = null;
|
wallTarget = null;
|
||||||
|
|
||||||
|
if (Character.AnimController.CurrentHull != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//check if there's a wall between the target and the Character
|
//check if there's a wall between the target and the Character
|
||||||
Vector2 rayStart = SimPosition;
|
Vector2 rayStart = SimPosition;
|
||||||
Vector2 rayEnd = SelectedAiTarget.SimPosition;
|
Vector2 rayEnd = SelectedAiTarget.SimPosition;
|
||||||
@@ -745,7 +737,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (offset)
|
if (offset)
|
||||||
{
|
{
|
||||||
rayStart -= SelectedAiTarget.Entity.Submarine.SimPosition;
|
rayStart -= ConvertUnits.ToSimUnits(SelectedAiTarget.Entity.Submarine.Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd, ignoreSubs: true);
|
Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd, ignoreSubs: true);
|
||||||
@@ -793,12 +785,8 @@ namespace Barotrauma
|
|||||||
sectionPos.X += (wall.BodyWidth <= 0.0f ? wall.Rect.Width : wall.BodyWidth) / 2 * attachTargetNormal.X;
|
sectionPos.X += (wall.BodyWidth <= 0.0f ? wall.Rect.Width : wall.BodyWidth) / 2 * attachTargetNormal.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
latchOntoAI?.SetAttachTarget(wall.Submarine.PhysicsBody.FarseerBody, wall.Submarine, sectionPos, attachTargetNormal);
|
|
||||||
if (wall.Submarine != null)
|
|
||||||
{
|
|
||||||
sectionPos += wall.Submarine.Position;
|
|
||||||
}
|
|
||||||
wallTarget = new WallTarget(sectionPos, wall, sectionIndex);
|
wallTarget = new WallTarget(sectionPos, wall, sectionIndex);
|
||||||
|
latchOntoAI?.SetAttachTarget(wall.Submarine.PhysicsBody.FarseerBody, wall.Submarine, ConvertUnits.ToSimUnits(sectionPos), attachTargetNormal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1014,27 +1002,14 @@ namespace Barotrauma
|
|||||||
else if (target.Entity is Structure s)
|
else if (target.Entity is Structure s)
|
||||||
{
|
{
|
||||||
targetingTag = "wall";
|
targetingTag = "wall";
|
||||||
if (aggressiveBoarding)
|
if (character.CurrentHull == null && aggressiveBoarding)
|
||||||
{
|
{
|
||||||
// Ignore walls when inside.
|
valueModifier = s.HasBody ? 2 : 0;
|
||||||
valueModifier = character.CurrentHull == null ? 2 : 0;
|
foreach (var section in s.Sections)
|
||||||
if (valueModifier > 0)
|
|
||||||
{
|
{
|
||||||
// Ignore structures that doesn't have a body (not walls)
|
if (section.gap != null)
|
||||||
valueModifier *= s.HasBody ? 1 : 0;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < s.Sections.Length; i++)
|
|
||||||
{
|
|
||||||
var section = s.Sections[i];
|
|
||||||
if (CanPassThroughHole(s, i))
|
|
||||||
{
|
{
|
||||||
// Ignore walls that can be passed through
|
// up to 100% more priority for every gap in the wall
|
||||||
valueModifier = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (section.gap != null)
|
|
||||||
{
|
|
||||||
// up to 100% priority increase for every gap in the wall
|
|
||||||
valueModifier *= 1 + section.gap.Open;
|
valueModifier *= 1 + section.gap.Open;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -520,10 +520,9 @@ namespace Barotrauma
|
|||||||
// Ignore blocking on items, because it causes cases where a Mudraptor cannot hit the hatch, for example.
|
// Ignore blocking on items, because it causes cases where a Mudraptor cannot hit the hatch, for example.
|
||||||
wasHit = true;
|
wasHit = true;
|
||||||
}
|
}
|
||||||
else if (damageTarget is Structure wall && structureBody != null &&
|
else if (damageTarget is Structure && structureBody?.UserData is Structure)
|
||||||
(structureBody.UserData is Structure || (structureBody.UserData is Submarine sub && sub == wall.Submarine)))
|
|
||||||
{
|
{
|
||||||
// If the attack is aimed to a structure (wall) and hits a structure or the sub, it's successful
|
// If the attack is aimed to a structure and hits a structure, it's successful
|
||||||
wasHit = true;
|
wasHit = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ namespace Barotrauma
|
|||||||
DockingPort myPort = null, outPostPort = null;
|
DockingPort myPort = null, outPostPort = null;
|
||||||
foreach (DockingPort port in DockingPort.List)
|
foreach (DockingPort port in DockingPort.List)
|
||||||
{
|
{
|
||||||
if (port.IsHorizontal) { continue; }
|
if (port.IsHorizontal || port.Docked) { continue; }
|
||||||
if (port.Item.Submarine == level.StartOutpost)
|
if (port.Item.Submarine == level.StartOutpost)
|
||||||
{
|
{
|
||||||
outPostPort = port;
|
outPostPort = port;
|
||||||
|
|||||||
@@ -176,11 +176,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
UpdateProjSpecific(growModifier);
|
UpdateProjSpecific(growModifier);
|
||||||
|
|
||||||
#if CLIENT
|
if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
|
||||||
if (GameMain.Client != null) return;
|
{
|
||||||
#endif
|
Remove();
|
||||||
|
}
|
||||||
if (size.X < 1.0f) Remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void UpdateProjSpecific(float growModifier);
|
partial void UpdateProjSpecific(float growModifier);
|
||||||
@@ -293,10 +292,6 @@ namespace Barotrauma
|
|||||||
//evaporate some of the water
|
//evaporate some of the water
|
||||||
hull.WaterVolume -= extinguishAmount;
|
hull.WaterVolume -= extinguishAmount;
|
||||||
|
|
||||||
#if CLIENT
|
|
||||||
if (GameMain.Client != null) return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
|
if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
|
||||||
{
|
{
|
||||||
Remove();
|
Remove();
|
||||||
@@ -326,11 +321,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
hull.WaterVolume -= extinguishAmount;
|
hull.WaterVolume -= extinguishAmount;
|
||||||
|
|
||||||
#if CLIENT
|
if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
|
||||||
if (GameMain.Client != null) return;
|
{
|
||||||
#endif
|
Remove();
|
||||||
|
}
|
||||||
if (size.X < 1.0f) Remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Extinguish(float deltaTime, float amount, Vector2 worldPosition)
|
public void Extinguish(float deltaTime, float amount, Vector2 worldPosition)
|
||||||
|
|||||||
@@ -1522,14 +1522,40 @@ namespace Barotrauma
|
|||||||
outpost.MakeOutpost();
|
outpost.MakeOutpost();
|
||||||
|
|
||||||
Point? minSize = null;
|
Point? minSize = null;
|
||||||
|
DockingPort subPort = null;
|
||||||
if (Submarine.MainSub != null)
|
if (Submarine.MainSub != null)
|
||||||
{
|
{
|
||||||
Point subSize = Submarine.MainSub.GetDockedBorders().Size;
|
Point subSize = Submarine.MainSub.GetDockedBorders().Size;
|
||||||
Point outpostSize = outpost.GetDockedBorders().Size;
|
Point outpostSize = outpost.GetDockedBorders().Size;
|
||||||
minSize = new Point(Math.Max(subSize.X, outpostSize.X), subSize.Y + outpostSize.Y);
|
minSize = new Point(Math.Max(subSize.X, outpostSize.X), subSize.Y + outpostSize.Y);
|
||||||
|
|
||||||
|
float closestDistance = float.MaxValue;
|
||||||
|
foreach (DockingPort port in DockingPort.List)
|
||||||
|
{
|
||||||
|
if (port.IsHorizontal || port.Docked) { continue; }
|
||||||
|
if (port.Item.Submarine != Submarine.MainSub) { continue; }
|
||||||
|
//the submarine port has to be at the top of the sub
|
||||||
|
if (port.Item.WorldPosition.Y < Submarine.MainSub.WorldPosition.Y) { continue; }
|
||||||
|
float dist = Math.Abs(port.Item.WorldPosition.X - Submarine.MainSub.WorldPosition.X);
|
||||||
|
if (dist < closestDistance)
|
||||||
|
{
|
||||||
|
subPort = port;
|
||||||
|
closestDistance = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outpost.SetPosition(outpost.FindSpawnPos(i == 0 ? StartPosition : EndPosition, minSize));
|
float subDockingPortOffset = subPort == null ? 0.0f : subPort.Item.WorldPosition.X - Submarine.MainSub.WorldPosition.X;
|
||||||
|
//don't try to compensate if the port is very far from the sub's center of mass
|
||||||
|
if (Math.Abs(subDockingPortOffset) > 2000.0f)
|
||||||
|
{
|
||||||
|
subDockingPortOffset = MathHelper.Clamp(subDockingPortOffset, -2000.0f, 2000.0f);
|
||||||
|
string warningMsg = "Docking port very far from the sub's center of mass (submarine: " + Submarine.MainSub.Name + ", dist: " + subDockingPortOffset + "). The level generator may not be able to place the outpost so that docking is possible.";
|
||||||
|
DebugConsole.NewMessage(warningMsg, Color.Orange);
|
||||||
|
GameAnalyticsManager.AddErrorEventOnce("Lever.CreateOutposts:DockingPortVeryFar" + Submarine.MainSub.Name, GameAnalyticsSDK.Net.EGAErrorSeverity.Warning, warningMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
outpost.SetPosition(outpost.FindSpawnPos(i == 0 ? StartPosition : EndPosition, minSize, subDockingPortOffset));
|
||||||
if ((i == 0) == !Mirrored)
|
if ((i == 0) == !Mirrored)
|
||||||
{
|
{
|
||||||
StartOutpost = outpost;
|
StartOutpost = outpost;
|
||||||
|
|||||||
@@ -432,12 +432,16 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (ForceFluctuationStrength > 0.0f)
|
if (ForceFluctuationStrength > 0.0f)
|
||||||
{
|
{
|
||||||
forceFluctuationTimer += deltaTime;
|
//no need for force fluctuation (or network updates) if the trigger limits velocity and there are no triggerers
|
||||||
if (forceFluctuationTimer > ForceFluctuationInterval)
|
if (forceMode != TriggerForceMode.LimitVelocity || triggerers.Any())
|
||||||
{
|
{
|
||||||
NeedsNetworkSyncing = true;
|
forceFluctuationTimer += deltaTime;
|
||||||
currentForceFluctuation = Rand.Range(1.0f - ForceFluctuationStrength, 1.0f);
|
if (forceFluctuationTimer > ForceFluctuationInterval)
|
||||||
forceFluctuationTimer = 0.0f;
|
{
|
||||||
|
NeedsNetworkSyncing = true;
|
||||||
|
currentForceFluctuation = Rand.Range(1.0f - ForceFluctuationStrength, 1.0f);
|
||||||
|
forceFluctuationTimer = 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -494,7 +494,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 FindSpawnPos(Vector2 spawnPos, Point? submarineSize = null)
|
public Vector2 FindSpawnPos(Vector2 spawnPos, Point? submarineSize = null, float subDockingPortOffset = 0.0f)
|
||||||
{
|
{
|
||||||
Rectangle dockedBorders = GetDockedBorders();
|
Rectangle dockedBorders = GetDockedBorders();
|
||||||
Vector2 diffFromDockedBorders =
|
Vector2 diffFromDockedBorders =
|
||||||
@@ -542,17 +542,17 @@ namespace Barotrauma
|
|||||||
else if (minX < 0)
|
else if (minX < 0)
|
||||||
{
|
{
|
||||||
//no wall found at the left side, spawn to the left from the right-side wall
|
//no wall found at the left side, spawn to the left from the right-side wall
|
||||||
spawnPos.X = maxX - minWidth - 100.0f;
|
spawnPos.X = maxX - minWidth - 100.0f + subDockingPortOffset;
|
||||||
}
|
}
|
||||||
else if (maxX > Level.Loaded.Size.X)
|
else if (maxX > Level.Loaded.Size.X)
|
||||||
{
|
{
|
||||||
//no wall found at right side, spawn to the right from the left-side wall
|
//no wall found at right side, spawn to the right from the left-side wall
|
||||||
spawnPos.X = minX + minWidth + 100.0f;
|
spawnPos.X = minX + minWidth + 100.0f + subDockingPortOffset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//walls found at both sides, use their midpoint
|
//walls found at both sides, use their midpoint
|
||||||
spawnPos.X = (minX + maxX) / 2;
|
spawnPos.X = (minX + maxX) / 2 + subDockingPortOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnPos.Y = Math.Min(spawnPos.Y, Level.Loaded.Size.Y - dockedBorders.Height / 2 - 10);
|
spawnPos.Y = Math.Min(spawnPos.Y, Level.Loaded.Size.Y - dockedBorders.Height / 2 - 10);
|
||||||
|
|||||||
@@ -35,8 +35,9 @@ namespace Barotrauma.Networking
|
|||||||
public const float DeleteDisconnectedTime = 20.0f;
|
public const float DeleteDisconnectedTime = 20.0f;
|
||||||
|
|
||||||
public const float ItemConditionUpdateInterval = 0.15f;
|
public const float ItemConditionUpdateInterval = 0.15f;
|
||||||
|
|
||||||
public const float LevelObjectUpdateInterval = 0.5f;
|
public const float LevelObjectUpdateInterval = 0.5f;
|
||||||
|
public const float HullUpdateInterval = 0.5f;
|
||||||
|
public const float HullUpdateDistance = 20000.0f;
|
||||||
|
|
||||||
public const int MaxEventPacketsPerUpdate = 4;
|
public const int MaxEventPacketsPerUpdate = 4;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user