Merge https://github.com/Regalis11/Barotrauma into develop
This commit is contained in:
@@ -326,7 +326,9 @@ namespace Barotrauma
|
||||
var lightComponent = item.GetComponent<LightComponent>();
|
||||
if (lightComponent != null)
|
||||
{
|
||||
lightComponent.TemporaryFlickerTimer = Math.Min(EmpStrength * distFactor, 10.0f);
|
||||
//multiply by 10 to make the effect more noticeable
|
||||
//(a strength of 1 is already enough to kill power and shut down the lights, but we want weaker EMPs to make the lights flicker noticeably)
|
||||
lightComponent.TemporaryFlickerTimer = Math.Min(EmpStrength * distFactor * 10.0f, 10.0f);
|
||||
}
|
||||
|
||||
//discharge batteries
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace Barotrauma
|
||||
d.ForceRefreshFadeTimer(Math.Min(d.FadeTimer, d.FadeInTime));
|
||||
}
|
||||
|
||||
UpdateProjSpecific(growModifier);
|
||||
UpdateProjSpecific(growModifier, deltaTime);
|
||||
|
||||
|
||||
if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
|
||||
@@ -273,7 +273,7 @@ namespace Barotrauma
|
||||
position.X -= GrowSpeed * growModifier * 0.5f * deltaTime;
|
||||
}
|
||||
|
||||
partial void UpdateProjSpecific(float growModifier);
|
||||
partial void UpdateProjSpecific(float growModifier, float deltaTime);
|
||||
|
||||
private void OnChangeHull(Vector2 pos, Hull particleHull)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,8 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public bool IsDiagonal { get; }
|
||||
|
||||
public readonly float GlowEffectT;
|
||||
|
||||
//a value between 0.0f-1.0f (0.0 = closed, 1.0f = open)
|
||||
private float open;
|
||||
|
||||
@@ -194,6 +196,8 @@ namespace Barotrauma
|
||||
GapList.Add(this);
|
||||
InsertToList();
|
||||
|
||||
GlowEffectT = Rand.Range(0.0f, 1.0f);
|
||||
|
||||
float blockerSize = ConvertUnits.ToSimUnits(Math.Max(rect.Width, rect.Height)) / 2;
|
||||
outsideCollisionBlocker = GameMain.World.CreateEdge(-Vector2.UnitX * blockerSize, Vector2.UnitX * blockerSize,
|
||||
BodyType.Static,
|
||||
@@ -216,7 +220,7 @@ namespace Barotrauma
|
||||
return new Gap(rect, IsHorizontal, Submarine);
|
||||
}
|
||||
|
||||
public override void Move(Vector2 amount, bool ignoreContacts = false)
|
||||
public override void Move(Vector2 amount, bool ignoreContacts = true)
|
||||
{
|
||||
if (!MathUtils.IsValid(amount))
|
||||
{
|
||||
@@ -224,7 +228,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
base.Move(amount);
|
||||
base.Move(amount, ignoreContacts);
|
||||
|
||||
if (!DisableHullRechecks) { FindHulls(); }
|
||||
}
|
||||
@@ -337,8 +341,28 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private int updateCount;
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
int updateInterval = 4;
|
||||
float flowMagnitude = flowForce.LengthSquared();
|
||||
if (flowMagnitude < 1.0f)
|
||||
{
|
||||
//very sparse updates if there's practically no water moving
|
||||
updateInterval = 8;
|
||||
}
|
||||
else if (linkedTo.Count == 2 && flowMagnitude > 10.0f)
|
||||
{
|
||||
//frequent updates if water is moving between hulls
|
||||
updateInterval = 1;
|
||||
}
|
||||
|
||||
updateCount++;
|
||||
if (updateCount < updateInterval) { return; }
|
||||
deltaTime *= updateCount;
|
||||
updateCount = 0;
|
||||
|
||||
flowForce = Vector2.Zero;
|
||||
outsideColliderRaycastTimer -= deltaTime;
|
||||
|
||||
|
||||
@@ -590,7 +590,7 @@ namespace Barotrauma
|
||||
return index;
|
||||
}
|
||||
|
||||
public override void Move(Vector2 amount, bool ignoreContacts = false)
|
||||
public override void Move(Vector2 amount, bool ignoreContacts = true)
|
||||
{
|
||||
if (!MathUtils.IsValid(amount))
|
||||
{
|
||||
@@ -851,7 +851,21 @@ namespace Barotrauma
|
||||
{
|
||||
decal.Update(deltaTime);
|
||||
}
|
||||
decals.RemoveAll(d => d.FadeTimer >= d.LifeTime || d.BaseAlpha <= 0.001f);
|
||||
//clients don't remove decals unless the server says so
|
||||
if (GameMain.NetworkMember is not { IsClient: true })
|
||||
{
|
||||
for (int i = decals.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var decal = decals[i];
|
||||
if (decal.FadeTimer >= decal.LifeTime || decal.BaseAlpha <= 0.001f)
|
||||
{
|
||||
decals.RemoveAt(i);
|
||||
#if SERVER
|
||||
decalUpdatePending = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aiTarget != null)
|
||||
{
|
||||
@@ -1509,9 +1523,8 @@ namespace Barotrauma
|
||||
public void CleanSection(BackgroundSection section, float cleanVal, bool updateRequired)
|
||||
{
|
||||
bool decalsCleaned = false;
|
||||
for (int i = 0; i < decals.Count; i++)
|
||||
foreach (Decal decal in decals)
|
||||
{
|
||||
Decal decal = decals[i];
|
||||
if (decal.AffectsSection(section))
|
||||
{
|
||||
decal.Clean(cleanVal);
|
||||
@@ -1672,5 +1685,9 @@ namespace Barotrauma
|
||||
return element;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{base.ToString()} ({Name ?? "unnamed"})";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace Barotrauma
|
||||
{
|
||||
me.Move(position);
|
||||
me.Submarine = sub;
|
||||
if (!(me is Item item)) { continue; }
|
||||
if (me is not Item item) { continue; }
|
||||
Wire wire = item.GetComponent<Wire>();
|
||||
//Vector2 subPosition = Submarine == null ? Vector2.Zero : Submarine.HiddenSubPosition;
|
||||
if (wire != null)
|
||||
|
||||
@@ -296,9 +296,9 @@ namespace Barotrauma
|
||||
Vector2 triangleCenter = (edge.Point1 + edge.Point2 + extrudedPoint) / 3;
|
||||
foreach (GraphEdge nearbyEdge in nearbyCell.Edges)
|
||||
{
|
||||
if (!MathUtils.LinesIntersect(nearbyEdge.Point1, triangleCenter, edge.Point1, extrudedPoint) &&
|
||||
!MathUtils.LinesIntersect(nearbyEdge.Point1, triangleCenter, edge.Point2, extrudedPoint) &&
|
||||
!MathUtils.LinesIntersect(nearbyEdge.Point1, triangleCenter, edge.Point1, edge.Point2))
|
||||
if (!MathUtils.LineSegmentsIntersect(nearbyEdge.Point1, triangleCenter, edge.Point1, extrudedPoint) &&
|
||||
!MathUtils.LineSegmentsIntersect(nearbyEdge.Point1, triangleCenter, edge.Point2, extrudedPoint) &&
|
||||
!MathUtils.LineSegmentsIntersect(nearbyEdge.Point1, triangleCenter, edge.Point1, edge.Point2))
|
||||
{
|
||||
isInside = true;
|
||||
break;
|
||||
|
||||
@@ -1454,7 +1454,7 @@ namespace Barotrauma
|
||||
if (node2.X <= pathNodes.Last().X) { continue; }
|
||||
if (MathUtils.NearlyEqual(node1.X, pathNodes.Last().X)) { continue; }
|
||||
if (Math.Abs(node1.Y - nodePos.Y) > tunnel.MinWidth && Math.Abs(node2.Y - nodePos.Y) > tunnel.MinWidth &&
|
||||
!MathUtils.LinesIntersect(node1.ToVector2(), node2.ToVector2(), pathNodes.Last().ToVector2(), nodePos.ToVector2()))
|
||||
!MathUtils.LineSegmentsIntersect(node1.ToVector2(), node2.ToVector2(), pathNodes.Last().ToVector2(), nodePos.ToVector2()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1550,7 +1550,7 @@ namespace Barotrauma
|
||||
foreach (GraphEdge edge in tunnel.Cells[i].Edges)
|
||||
{
|
||||
if (edge.AdjacentCell(tunnel.Cells[i])?.CellType == CellType.Solid &&
|
||||
MathUtils.LinesIntersect(newWaypoint.WorldPosition, prevWayPoint.WorldPosition, edge.Point1, edge.Point2))
|
||||
MathUtils.LineSegmentsIntersect(newWaypoint.WorldPosition, prevWayPoint.WorldPosition, edge.Point1, edge.Point2))
|
||||
{
|
||||
solidCellBetween = true;
|
||||
break;
|
||||
@@ -2801,7 +2801,7 @@ namespace Barotrauma
|
||||
if (Vector2.DistanceSquared(c.EdgeCenter, validLocation.EdgeCenter) > (intervalRange.X * intervalRange.X)) { return true; }
|
||||
// If there is a line from a previous path point to one of its existing cluster locations
|
||||
// which intersects with the line from this path point to the new possible cluster location
|
||||
if (MathUtils.LinesIntersect(anotherPathPoint.Position, c.EdgeCenter, pathPoint.Position, validLocation.EdgeCenter)) { return true; }
|
||||
if (MathUtils.LineSegmentsIntersect(anotherPathPoint.Position, c.EdgeCenter, pathPoint.Position, validLocation.EdgeCenter)) { return true; }
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2975,13 +2975,13 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
/// <param name="rotation">Used by clients to set the rotation for the resources</param>
|
||||
public List<Item> GenerateMissionResources(ItemPrefab prefab, int requiredAmount, PositionType positionType, out float rotation, IEnumerable<Cave> targetCaves = null)
|
||||
public List<Item> GenerateMissionResources(ItemPrefab prefab, int requiredAmount, PositionType positionType, IEnumerable<Cave> targetCaves = null)
|
||||
{
|
||||
var allValidLocations = GetAllValidClusterLocations();
|
||||
var placedResources = new List<Item>();
|
||||
rotation = 0.0f;
|
||||
|
||||
if (allValidLocations.None()) { return placedResources; } // TODO: WHAT?!
|
||||
// if there are no valid locations, don't place anything
|
||||
if (allValidLocations.None()) { return placedResources; }
|
||||
|
||||
// Make sure not to pick a spot that already has other level resources
|
||||
for (int i = allValidLocations.Count - 1; i >= 0; i--)
|
||||
@@ -3077,7 +3077,6 @@ namespace Barotrauma
|
||||
}
|
||||
PlaceResources(prefab, requiredAmount, selectedLocation, out placedResources);
|
||||
Vector2 edgeNormal = selectedLocation.Edge.GetNormal(selectedLocation.Cell);
|
||||
rotation = MathHelper.ToDegrees(-MathUtils.VectorToAngle(edgeNormal) + MathHelper.PiOver2);
|
||||
return placedResources;
|
||||
|
||||
static bool IsOnMainPath(ClusterLocation location) => location.Edge.NextToMainPath;
|
||||
@@ -3182,13 +3181,11 @@ namespace Barotrauma
|
||||
Vector2 edgeNormal = location.Edge.GetNormal(location.Cell);
|
||||
float moveAmount = (item.body == null ? item.Rect.Height / 2 : ConvertUnits.ToDisplayUnits(item.body.GetMaxExtent() * 0.7f));
|
||||
moveAmount += (item.GetComponent<LevelResource>()?.RandomOffsetFromWall ?? 0.0f) * Rand.Range(-0.5f, 0.5f, Rand.RandSync.ServerAndClient);
|
||||
item.Move(edgeNormal * moveAmount, ignoreContacts: true);
|
||||
item.Move(edgeNormal * moveAmount);
|
||||
if (item.GetComponent<Holdable>() is Holdable h)
|
||||
{
|
||||
h.AttachToWall();
|
||||
#if CLIENT
|
||||
item.Rotation = MathHelper.ToDegrees(-MathUtils.VectorToAngle(edgeNormal) + MathHelper.PiOver2);
|
||||
#endif
|
||||
}
|
||||
else if (item.body != null)
|
||||
{
|
||||
@@ -3509,7 +3506,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (GraphEdge e in cell.Edges)
|
||||
{
|
||||
if (!MathUtils.LinesIntersect(closestPathCell.Center, pos.ToVector2(), e.Point1, e.Point2)) { continue; }
|
||||
if (!MathUtils.LineSegmentsIntersect(closestPathCell.Center, pos.ToVector2(), e.Point1, e.Point2)) { continue; }
|
||||
|
||||
cell.CellType = CellType.Removed;
|
||||
for (int x = 0; x < cellGrid.GetLength(0); x++)
|
||||
|
||||
@@ -294,40 +294,37 @@ namespace Barotrauma
|
||||
throw new Exception($"Generating a campaign map failed (no locations created). Width: {Width}, height: {Height}");
|
||||
}
|
||||
|
||||
foreach (Location location in Locations)
|
||||
{
|
||||
if (location.Type.Identifier != "outpost") { continue; }
|
||||
SetStartLocation(location);
|
||||
}
|
||||
FindStartLocation(l => l.Type.Identifier == "outpost");
|
||||
//if no outpost was found (using a mod that replaces the outpost location type?), find any type of outpost
|
||||
if (CurrentLocation == null)
|
||||
{
|
||||
FindStartLocation(l => l.Type.HasOutpost);
|
||||
}
|
||||
|
||||
void FindStartLocation(Func<Location, bool> predicate)
|
||||
{
|
||||
foreach (Location location in Locations)
|
||||
{
|
||||
if (!location.Type.HasOutpost) { continue; }
|
||||
SetStartLocation(location);
|
||||
if (!predicate(location)) { continue; }
|
||||
if (CurrentLocation == null || location.MapPosition.X < CurrentLocation.MapPosition.X)
|
||||
{
|
||||
CurrentLocation = StartLocation = furthestDiscoveredLocation = location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetStartLocation(Location location)
|
||||
|
||||
StartLocation.SecondaryFaction = null;
|
||||
var startOutpostFaction = campaign?.Factions.FirstOrDefault(f => f.Prefab.StartOutpost);
|
||||
if (startOutpostFaction != null)
|
||||
{
|
||||
if (CurrentLocation == null || location.MapPosition.X < CurrentLocation.MapPosition.X)
|
||||
StartLocation.Faction = startOutpostFaction;
|
||||
foreach (var connection in StartLocation.Connections)
|
||||
{
|
||||
CurrentLocation = StartLocation = furthestDiscoveredLocation = location;
|
||||
StartLocation.SecondaryFaction = null;
|
||||
var startOutpostFaction = campaign?.Factions.FirstOrDefault(f => f.Prefab.StartOutpost);
|
||||
if (startOutpostFaction != null)
|
||||
var otherLocation = connection.OtherLocation(StartLocation);
|
||||
if (otherLocation.HasOutpost() && otherLocation.Type.OutpostTeam == CharacterTeamType.FriendlyNPC)
|
||||
{
|
||||
StartLocation.Faction = startOutpostFaction;
|
||||
foreach (var connection in StartLocation.Connections)
|
||||
{
|
||||
var otherLocation = connection.OtherLocation(StartLocation);
|
||||
if (otherLocation.HasOutpost() && otherLocation.Type.OutpostTeam == CharacterTeamType.FriendlyNPC)
|
||||
{
|
||||
otherLocation.Faction = startOutpostFaction;
|
||||
}
|
||||
}
|
||||
}
|
||||
otherLocation.Faction = startOutpostFaction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Barotrauma
|
||||
public List<ushort> unresolvedLinkedToID;
|
||||
|
||||
public static int MapEntityUpdateInterval = 1;
|
||||
public static int GapUpdateInterval = 4;
|
||||
public static int GapUpdateInterval = 1;
|
||||
public static int PoweredUpdateInterval = 1;
|
||||
private static int mapEntityUpdateTick;
|
||||
|
||||
@@ -317,7 +317,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Move(Vector2 amount, bool ignoreContacts = false)
|
||||
public virtual void Move(Vector2 amount, bool ignoreContacts = true)
|
||||
{
|
||||
rect.X += (int)amount.X;
|
||||
rect.Y += (int)amount.Y;
|
||||
@@ -454,7 +454,7 @@ namespace Barotrauma
|
||||
List<Wire> orphanedWires = new List<Wire>();
|
||||
for (int i = 0; i < clones.Count; i++)
|
||||
{
|
||||
if (!(clones[i] is Item cloneItem)) { continue; }
|
||||
if (clones[i] is not Item cloneItem) { continue; }
|
||||
|
||||
var door = cloneItem.GetComponent<Door>();
|
||||
door?.RefreshLinkedGap();
|
||||
@@ -509,10 +509,12 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
(clones[itemIndex] as Item).Connections[connectionIndex].TryAddLink(cloneWire);
|
||||
cloneWire.Connect((clones[itemIndex] as Item).Connections[connectionIndex], false);
|
||||
cloneWire.Connect((clones[itemIndex] as Item).Connections[connectionIndex], n, addNode: false);
|
||||
}
|
||||
|
||||
if ((cloneWire.Connections[0] == null || cloneWire.Connections[1] == null) && cloneItem.GetComponent<DockingPort>() == null)
|
||||
if (originalWire.Connections.Any(c => c != null) &&
|
||||
(cloneWire.Connections[0] == null || cloneWire.Connections[1] == null) &&
|
||||
cloneItem.GetComponent<DockingPort>() == null)
|
||||
{
|
||||
if (!clones.Any(c => (c as Item)?.GetComponent<ConnectionPanel>()?.DisconnectedWires.Contains(cloneWire) ?? false))
|
||||
{
|
||||
|
||||
@@ -786,7 +786,7 @@ namespace Barotrauma
|
||||
//check if the connection overlaps with this module's connection
|
||||
if (selfGapPos1.HasValue && selfGapPos2.HasValue &&
|
||||
!gapPos1.NearlyEquals(gapPos2) && !selfGapPos1.Value.NearlyEquals(selfGapPos2.Value) &&
|
||||
MathUtils.LinesIntersect(gapPos1, gapPos2, selfGapPos1.Value, selfGapPos2.Value))
|
||||
MathUtils.LineSegmentsIntersect(gapPos1, gapPos2, selfGapPos1.Value, selfGapPos2.Value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1105,8 +1105,8 @@ namespace Barotrauma
|
||||
DebugConsole.AddWarning($"Failed to connect junction boxes between outpost modules (not enough free connections in module \"{module.PreviousModule.Info.Name}\")");
|
||||
continue;
|
||||
}
|
||||
wire.Connect(thisJunctionBox.Connections[i], addNode: false);
|
||||
wire.Connect(previousJunctionBox.Connections[i], addNode: false);
|
||||
wire.TryConnect(thisJunctionBox.Connections[i], addNode: false);
|
||||
wire.TryConnect(previousJunctionBox.Connections[i], addNode: false);
|
||||
wire.SetNodes(new List<Vector2>());
|
||||
}
|
||||
}
|
||||
@@ -1374,11 +1374,6 @@ namespace Barotrauma
|
||||
endWaypoint.linkedTo.Add(prevWayPoint);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
startWaypoint.linkedTo.Add(endWaypoint);
|
||||
endWaypoint.linkedTo.Add(startWaypoint);
|
||||
}
|
||||
|
||||
WayPoint closestWaypoint = null;
|
||||
float closestDistSqr = 30.0f * 30.0f;
|
||||
@@ -1595,10 +1590,11 @@ namespace Barotrauma
|
||||
{
|
||||
var startWaypoint = WayPoint.WayPointList.Find(wp => wp.ConnectedGap == bottomGap);
|
||||
var endWaypoint = WayPoint.WayPointList.Find(wp => wp.ConnectedGap == topGap);
|
||||
float margin = 100;
|
||||
if (startWaypoint != null && endWaypoint != null)
|
||||
{
|
||||
WayPoint prevWaypoint = startWaypoint;
|
||||
for (float y = startWaypoint.Position.Y + WayPoint.LadderWaypointInterval; y <= endWaypoint.Position.Y - WayPoint.LadderWaypointInterval; y += WayPoint.LadderWaypointInterval)
|
||||
for (float y = bottomGap.Position.Y + margin; y <= topGap.Position.Y - margin; y += WayPoint.LadderWaypointInterval)
|
||||
{
|
||||
var wayPoint = new WayPoint(new Vector2(startWaypoint.Position.X, y), SpawnType.Path, ladder.Item.Submarine)
|
||||
{
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Barotrauma
|
||||
private static Explosion explosionOnBroken;
|
||||
|
||||
#if DEBUG
|
||||
[Serialize(false, IsPropertySaveable.Yes), Editable]
|
||||
[Serialize(false, IsPropertySaveable.Yes), ConditionallyEditable(ConditionallyEditable.ConditionType.HasBody)]
|
||||
#else
|
||||
[Serialize(false, IsPropertySaveable.Yes)]
|
||||
#endif
|
||||
@@ -104,9 +104,11 @@ namespace Barotrauma
|
||||
|
||||
public List<Body> Bodies { get; private set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.Yes), ConditionallyEditable(ConditionallyEditable.ConditionType.HasBody)]
|
||||
public bool CastShadow
|
||||
{
|
||||
get { return Prefab.CastShadow; }
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool IsHorizontal { get; private set; }
|
||||
@@ -118,7 +120,7 @@ namespace Barotrauma
|
||||
|
||||
private float? maxHealth;
|
||||
|
||||
[Serialize(100.0f, IsPropertySaveable.Yes), Editable(MinValueFloat = 0)]
|
||||
[Serialize(100.0f, IsPropertySaveable.Yes), ConditionallyEditable(ConditionallyEditable.ConditionType.HasBody, MinValueFloat = 0)]
|
||||
public float MaxHealth
|
||||
{
|
||||
get => maxHealth ?? Prefab.Health;
|
||||
@@ -189,14 +191,14 @@ namespace Barotrauma
|
||||
set { spriteColor = value; }
|
||||
}
|
||||
|
||||
[Editable, Serialize(false, IsPropertySaveable.Yes)]
|
||||
[ConditionallyEditable(ConditionallyEditable.ConditionType.HasBody), Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool UseDropShadow
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Editable, Serialize("0,0", IsPropertySaveable.Yes, description: "The position of the drop shadow relative to the structure. If set to zero, the shadow is positioned automatically so that it points towards the sub's center of mass.")]
|
||||
[ConditionallyEditable(ConditionallyEditable.ConditionType.HasBody), Serialize("0,0", IsPropertySaveable.Yes, description: "The position of the drop shadow relative to the structure. If set to zero, the shadow is positioned automatically so that it points towards the sub's center of mass.")]
|
||||
public Vector2 DropShadowOffset
|
||||
{
|
||||
get;
|
||||
@@ -367,7 +369,7 @@ namespace Barotrauma
|
||||
private set;
|
||||
}
|
||||
|
||||
public override void Move(Vector2 amount, bool ignoreContacts = false)
|
||||
public override void Move(Vector2 amount, bool ignoreContacts = true)
|
||||
{
|
||||
if (!MathUtils.IsValid(amount))
|
||||
{
|
||||
@@ -375,7 +377,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
base.Move(amount);
|
||||
base.Move(amount, ignoreContacts);
|
||||
|
||||
for (int i = 0; i < Sections.Length; i++)
|
||||
{
|
||||
@@ -440,13 +442,11 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
float width = BodyWidth > 0.0f ? BodyWidth : rect.Width;
|
||||
float height = BodyHeight > 0.0f ? BodyHeight : rect.Height;
|
||||
if (BodyWidth > 0.0f && BodyHeight > 0.0f)
|
||||
{
|
||||
IsHorizontal = BodyWidth > BodyHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsHorizontal = (rect.Width > rect.Height);
|
||||
IsHorizontal = width > height;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,29 +455,28 @@ namespace Barotrauma
|
||||
|
||||
InitProjSpecific();
|
||||
|
||||
if (!HiddenInGame)
|
||||
SerializableProperties = element != null ? SerializableProperty.DeserializeProperties(this, element) : SerializableProperty.GetProperties(this);
|
||||
if (element?.GetAttribute(nameof(CastShadow)) == null)
|
||||
{
|
||||
if (Prefab.Body)
|
||||
{
|
||||
Bodies = new List<Body>();
|
||||
WallList.Add(this);
|
||||
|
||||
CreateSections();
|
||||
UpdateSections();
|
||||
}
|
||||
else
|
||||
{
|
||||
Sections = new WallSection[1];
|
||||
Sections[0] = new WallSection(rect, this);
|
||||
|
||||
if (StairDirection != Direction.None)
|
||||
{
|
||||
CreateStairBodies();
|
||||
}
|
||||
}
|
||||
CastShadow = Prefab.CastShadow;
|
||||
}
|
||||
|
||||
SerializableProperties = element != null ? SerializableProperty.DeserializeProperties(this, element) : SerializableProperty.GetProperties(this);
|
||||
if (Prefab.Body)
|
||||
{
|
||||
Bodies = new List<Body>();
|
||||
WallList.Add(this);
|
||||
CreateSections();
|
||||
UpdateSections();
|
||||
}
|
||||
else if (StairDirection != Direction.None)
|
||||
{
|
||||
CreateStairBodies();
|
||||
}
|
||||
if (Sections == null)
|
||||
{
|
||||
Sections = new WallSection[1];
|
||||
Sections[0] = new WallSection(rect, this);
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
foreach (var subElement in sp.ConfigElement.Elements())
|
||||
@@ -1546,16 +1545,16 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (element.GetAttributeBool("flippedx", false)) { s.FlipX(false); }
|
||||
if (element.GetAttributeBool("flippedy", false)) { s.FlipY(false); }
|
||||
if (element.GetAttributeBool(nameof(FlippedX), false)) { s.FlipX(false); }
|
||||
if (element.GetAttributeBool(nameof(FlippedY), false)) { s.FlipY(false); }
|
||||
|
||||
//structures with a body drop a shadow by default
|
||||
if (element.GetAttribute("usedropshadow") == null)
|
||||
if (element.GetAttribute(nameof(UseDropShadow)) == null)
|
||||
{
|
||||
s.UseDropShadow = prefab.Body;
|
||||
}
|
||||
|
||||
if (element.GetAttribute("noaitarget") == null)
|
||||
if (element.GetAttribute(nameof(NoAITarget)) == null)
|
||||
{
|
||||
s.NoAITarget = prefab.NoAITarget;
|
||||
}
|
||||
@@ -1604,12 +1603,12 @@ namespace Barotrauma
|
||||
(int)(rect.Y - Submarine.HiddenSubPosition.Y) + "," +
|
||||
width + "," + height));
|
||||
|
||||
if (FlippedX) element.Add(new XAttribute("flippedx", true));
|
||||
if (FlippedY) element.Add(new XAttribute("flippedy", true));
|
||||
if (FlippedX) { element.Add(new XAttribute("flippedx", true)); }
|
||||
if (FlippedY) { element.Add(new XAttribute("flippedy", true)); }
|
||||
|
||||
for (int i = 0; i < Sections.Length; i++)
|
||||
{
|
||||
if (Sections[i].damage == 0.0f) continue;
|
||||
if (Sections[i].damage == 0.0f) { continue; }
|
||||
var sectionElement =
|
||||
new XElement("section",
|
||||
new XAttribute("i", i),
|
||||
@@ -1619,6 +1618,11 @@ namespace Barotrauma
|
||||
|
||||
SerializableProperty.SerializeProperties(this, element);
|
||||
|
||||
if (CastShadow == Prefab.CastShadow)
|
||||
{
|
||||
element.GetAttribute(nameof(CastShadow))?.Remove();
|
||||
}
|
||||
|
||||
foreach (var upgrade in Upgrades)
|
||||
{
|
||||
upgrade.Save(element);
|
||||
|
||||
@@ -7,6 +7,7 @@ using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Voronoi2;
|
||||
@@ -427,17 +428,20 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Returns a rect that contains the borders of this sub and all subs docked to it, excluding outposts
|
||||
/// </summary>
|
||||
public Rectangle GetDockedBorders()
|
||||
public Rectangle GetDockedBorders(bool allowDifferentTeam = true)
|
||||
{
|
||||
checkSubmarineBorders.Clear();
|
||||
return GetDockedBordersRecursive();
|
||||
return GetDockedBordersRecursive(allowDifferentTeam);
|
||||
}
|
||||
|
||||
private Rectangle GetDockedBordersRecursive()
|
||||
private Rectangle GetDockedBordersRecursive(bool allowDifferentTeam)
|
||||
{
|
||||
Rectangle dockedBorders = Borders;
|
||||
checkSubmarineBorders.Add(this);
|
||||
var connectedSubs = DockedTo.Where(s => !checkSubmarineBorders.Contains(s) && !s.Info.IsOutpost);
|
||||
var connectedSubs = DockedTo.Where(s =>
|
||||
!checkSubmarineBorders.Contains(s) &&
|
||||
!s.Info.IsOutpost &&
|
||||
(allowDifferentTeam || s.TeamID == TeamID));
|
||||
foreach (Submarine dockedSub in connectedSubs)
|
||||
{
|
||||
//use docking ports instead of world position to determine
|
||||
@@ -446,7 +450,7 @@ namespace Barotrauma
|
||||
Vector2? expectedLocation = CalculateDockOffset(this, dockedSub);
|
||||
if (expectedLocation == null) { continue; }
|
||||
|
||||
Rectangle dockedSubBorders = dockedSub.GetDockedBordersRecursive();
|
||||
Rectangle dockedSubBorders = dockedSub.GetDockedBordersRecursive(allowDifferentTeam);
|
||||
dockedSubBorders.Location += MathUtils.ToPoint(expectedLocation.Value);
|
||||
|
||||
dockedBorders.Y = -dockedBorders.Y;
|
||||
@@ -458,23 +462,23 @@ namespace Barotrauma
|
||||
return dockedBorders;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Don't use this directly, because the list is updated only when GetConnectedSubs() is called. The method is called so frequently that we don't want to create new list here.
|
||||
/// </summary>
|
||||
private readonly List<Submarine> connectedSubs = new List<Submarine>(2);
|
||||
private readonly HashSet<Submarine> connectedSubs;
|
||||
/// <summary>
|
||||
/// Returns a list of all submarines that are connected to this one via docking ports, including this sub.
|
||||
/// </summary>
|
||||
public List<Submarine> GetConnectedSubs()
|
||||
public IEnumerable<Submarine> GetConnectedSubs()
|
||||
{
|
||||
return connectedSubs;
|
||||
}
|
||||
|
||||
public void RefreshConnectedSubs()
|
||||
{
|
||||
connectedSubs.Clear();
|
||||
connectedSubs.Add(this);
|
||||
GetConnectedSubsRecursive(connectedSubs);
|
||||
|
||||
return connectedSubs;
|
||||
}
|
||||
|
||||
private void GetConnectedSubsRecursive(List<Submarine> subs)
|
||||
private void GetConnectedSubsRecursive(HashSet<Submarine> subs)
|
||||
{
|
||||
foreach (Submarine dockedSub in DockedTo)
|
||||
{
|
||||
@@ -1067,6 +1071,8 @@ namespace Barotrauma
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
RefreshConnectedSubs();
|
||||
|
||||
if (Info.IsWreck)
|
||||
{
|
||||
WreckAI?.Update(deltaTime);
|
||||
@@ -1393,6 +1399,13 @@ namespace Barotrauma
|
||||
|
||||
public Submarine(SubmarineInfo info, bool showErrorMessages = true, Func<Submarine, List<MapEntity>> loadEntities = null, IdRemap linkedRemap = null) : base(null, Entity.NullEntityID)
|
||||
{
|
||||
Stopwatch sw = Stopwatch.StartNew();
|
||||
|
||||
connectedSubs = new HashSet<Submarine>(2)
|
||||
{
|
||||
this
|
||||
};
|
||||
|
||||
upgradeEventIdentifier = new Identifier($"Submarine{ID}");
|
||||
Loading = true;
|
||||
GameMain.World.Enabled = false;
|
||||
@@ -1489,8 +1502,14 @@ namespace Barotrauma
|
||||
if (me.Submarine != this) { continue; }
|
||||
if (me is Item item)
|
||||
{
|
||||
item.SpawnedInCurrentOutpost = info.OutpostGenerationParams != null;
|
||||
item.AllowStealing = info.OutpostGenerationParams?.AllowStealing ?? true;
|
||||
item.AllowStealing = true;
|
||||
if (info.OutpostGenerationParams != null)
|
||||
{
|
||||
item.SpawnedInCurrentOutpost = true;
|
||||
item.AllowStealing =
|
||||
info.OutpostGenerationParams.AllowStealing ||
|
||||
item.RootContainer is { Prefab: { AllowStealingContainedItems: true } };
|
||||
}
|
||||
if (item.GetComponent<Repairable>() != null && indestructible)
|
||||
{
|
||||
item.Indestructible = true;
|
||||
@@ -1569,6 +1588,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
|
||||
@@ -1596,6 +1616,10 @@ namespace Barotrauma
|
||||
Loading = false;
|
||||
GameMain.World.Enabled = true;
|
||||
}
|
||||
sw.Stop();
|
||||
string debugMsg = $"Loading {Info?.Name ?? "unknown"} took {sw.ElapsedMilliseconds} ms.";
|
||||
DebugConsole.Log(debugMsg);
|
||||
System.Diagnostics.Debug.WriteLine(debugMsg);
|
||||
}
|
||||
|
||||
protected override ushort DetermineID(ushort id, Submarine submarine)
|
||||
@@ -1745,8 +1769,7 @@ namespace Barotrauma
|
||||
}
|
||||
#endif
|
||||
if (e.Submarine != this) { continue; }
|
||||
var rootContainer = item.GetRootContainer();
|
||||
if (rootContainer != null && rootContainer.Submarine != this) { continue; }
|
||||
if (item.RootContainer != null && item.RootContainer.Submarine != this) { continue; }
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -777,12 +777,14 @@ namespace Barotrauma
|
||||
characterList ??= GameSession.GetSessionCrewCharacters(CharacterType.Both);
|
||||
|
||||
float price = Price;
|
||||
|
||||
if (location.Faction is { } faction && Faction.GetPlayerAffiliationStatus(faction) is FactionAffiliation.Positive)
|
||||
if (characterList.Any())
|
||||
{
|
||||
price *= 1f - characterList.Max(static c => c.GetStatValue(StatTypes.ShipyardBuyMultiplierAffiliated));
|
||||
if (location.Faction is { } faction && Faction.GetPlayerAffiliationStatus(faction) is FactionAffiliation.Positive)
|
||||
{
|
||||
price *= 1f - characterList.Max(static c => c.GetStatValue(StatTypes.ShipyardBuyMultiplierAffiliated));
|
||||
}
|
||||
price *= 1f - characterList.Max(static c => c.GetStatValue(StatTypes.ShipyardBuyMultiplier));
|
||||
}
|
||||
price *= 1f - characterList.Max(static c => c.GetStatValue(StatTypes.ShipyardBuyMultiplier));
|
||||
|
||||
return (int)price;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Barotrauma
|
||||
|
||||
public static bool ShowWayPoints = true, ShowSpawnPoints = true;
|
||||
|
||||
public const float LadderWaypointInterval = 55.0f;
|
||||
public const float LadderWaypointInterval = 75.0f;
|
||||
|
||||
protected SpawnType spawnType;
|
||||
private string[] idCardTags;
|
||||
|
||||
Reference in New Issue
Block a user