@@ -942,6 +942,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
|
||||
Anger += 0.01f;
|
||||
|
||||
bool wasRemoved = branch.Removed;
|
||||
Branches.Remove(branch);
|
||||
branch.Removed = true;
|
||||
|
||||
@@ -986,9 +987,11 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
Kill();
|
||||
return;
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
SendNetworkMessage(this, NetworkHeader.BranchRemove, branch);
|
||||
if (!wasRemoved)
|
||||
{
|
||||
SendNetworkMessage(this, NetworkHeader.BranchRemove, branch);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Barotrauma
|
||||
|
||||
public Explosion(float range, float force, float damage, float structureDamage, float itemDamage, float empStrength = 0.0f, float ballastFloraStrength = 0.0f)
|
||||
{
|
||||
Attack = new Attack(damage, 0.0f, 0.0f, structureDamage, itemDamage, range)
|
||||
Attack = new Attack(damage, 0.0f, 0.0f, structureDamage, itemDamage, Math.Min(range, 1000000))
|
||||
{
|
||||
SeverLimbsProbability = 1.0f
|
||||
};
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace Barotrauma
|
||||
get { return open; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value)) { return; }
|
||||
if (value > open) { openedTimer = 1.0f; }
|
||||
open = MathHelper.Clamp(value, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
@@ -525,7 +525,13 @@ namespace Barotrauma
|
||||
|
||||
public override MapEntity Clone()
|
||||
{
|
||||
return new Hull(MapEntityPrefab.Find(null, "hull"), rect, Submarine);
|
||||
var clone = new Hull(MapEntityPrefab.Find(null, "hull"), rect, Submarine);
|
||||
foreach (KeyValuePair<string, SerializableProperty> property in SerializableProperties)
|
||||
{
|
||||
if (!property.Value.Attributes.OfType<Editable>().Any()) { continue; }
|
||||
clone.SerializableProperties[property.Key].TrySetValue(clone, property.Value.GetValue(this));
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public static EntityGrid GenerateEntityGrid(Rectangle worldRect)
|
||||
|
||||
@@ -1837,7 +1837,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (RuinShape ruinShape in ruin.RuinShapes)
|
||||
{
|
||||
var tooClose = GetTooCloseCells(ruinShape.Rect.Center.ToVector2(), Math.Max(ruinShape.Rect.Width, ruinShape.Rect.Height));
|
||||
var tooClose = GetTooCloseCells(ruinShape.Rect.Center.ToVector2(), Math.Max(ruinShape.Rect.Width, ruinShape.Rect.Height) * 4);
|
||||
|
||||
foreach (VoronoiCell cell in tooClose)
|
||||
{
|
||||
@@ -1984,7 +1984,7 @@ namespace Barotrauma
|
||||
private DestructibleLevelWall CreateIceSpire(List<GraphEdge> usedSpireEdges)
|
||||
{
|
||||
const float maxLength = 15000.0f;
|
||||
|
||||
float minEdgeLength = 100.0f;
|
||||
var mainPathPos = PositionsOfInterest.Where(pos => pos.PositionType == PositionType.MainPath).GetRandom(Rand.RandSync.Server);
|
||||
double closestDistSqr = double.PositiveInfinity;
|
||||
GraphEdge closestEdge = null;
|
||||
@@ -1999,8 +1999,9 @@ namespace Barotrauma
|
||||
if (edge.Center.Y > Size.Y / 2 && (edge.Center.X < Size.X * 0.3f || edge.Center.X > Size.X * 0.7f)) { continue; }
|
||||
if (Vector2.DistanceSquared(edge.Center, StartPosition) < maxLength * maxLength) { continue; }
|
||||
if (Vector2.DistanceSquared(edge.Center, EndPosition) < maxLength * maxLength) { continue; }
|
||||
//don't spawn on very long edges
|
||||
if (Vector2.DistanceSquared(edge.Point1, edge.Point2) > 1000.0f * 1000.0f) { continue; }
|
||||
//don't spawn on very long or very short edges
|
||||
float edgeLengthSqr = Vector2.DistanceSquared(edge.Point1, edge.Point2);
|
||||
if (edgeLengthSqr > 1000.0f * 1000.0f || edgeLengthSqr < minEdgeLength * minEdgeLength) { continue; }
|
||||
//don't spawn on edges facing away from the main path
|
||||
if (Vector2.Dot(Vector2.Normalize(mainPathPos.Position.ToVector2()) - edge.Center, edge.GetNormal(cell)) < 0.5f) { continue; }
|
||||
double distSqr = MathUtils.DistanceSquared(edge.Center.X, edge.Center.Y, mainPathPos.Position.X, mainPathPos.Position.Y);
|
||||
@@ -2723,7 +2724,7 @@ namespace Barotrauma
|
||||
|
||||
if (tries == 10)
|
||||
{
|
||||
position = EndPosition - Vector2.UnitY * 300.0f;
|
||||
position = startPos;
|
||||
}
|
||||
|
||||
} while (tries < 10);
|
||||
@@ -3048,8 +3049,10 @@ namespace Barotrauma
|
||||
var waypoints = WayPoint.WayPointList.Where(wp =>
|
||||
wp.Submarine == null &&
|
||||
wp.SpawnType == SpawnType.Path &&
|
||||
wp.WorldPosition.X < EndExitPosition.X &&
|
||||
!IsCloseToStart(wp.WorldPosition, minDistance) &&
|
||||
!IsCloseToEnd(wp.WorldPosition, minDistance)).ToList();
|
||||
!IsCloseToEnd(wp.WorldPosition, minDistance)
|
||||
).ToList();
|
||||
|
||||
var subDoc = SubmarineInfo.OpenFile(contentFile.Path);
|
||||
Rectangle subBorders = Submarine.GetBorders(subDoc.Root);
|
||||
@@ -3134,7 +3137,7 @@ namespace Barotrauma
|
||||
}
|
||||
tempSW.Stop();
|
||||
Debug.WriteLine($"Sub {sub.Info.Name} loaded in { tempSW.ElapsedMilliseconds} (ms)");
|
||||
sub.SetPosition(spawnPoint);
|
||||
sub.SetPosition(spawnPoint, forceUndockFromStaticSubmarines: false);
|
||||
wreckPositions.Add(sub, positions);
|
||||
blockedRects.Add(sub, rects);
|
||||
return sub;
|
||||
|
||||
@@ -75,6 +75,10 @@ namespace Barotrauma
|
||||
}
|
||||
Cells = new List<VoronoiCell>() { wallCell };
|
||||
Body = CaveGenerator.GeneratePolygons(Cells, level, out triangles);
|
||||
if (triangles.Count == 0)
|
||||
{
|
||||
throw new ArgumentException("Failed to generate a wall (not enough triangles). Original vertices: " + string.Join(", ", originalVertices.Select(v => v.ToString())));
|
||||
}
|
||||
#if CLIENT
|
||||
GenerateVertices();
|
||||
#endif
|
||||
|
||||
@@ -192,6 +192,7 @@ namespace Barotrauma
|
||||
if (!SelectedMissions.Contains(mission) && mission != null)
|
||||
{
|
||||
selectedMissions.Add(mission);
|
||||
selectedMissions.Sort((m1, m2) => availableMissions.IndexOf(m1).CompareTo(availableMissions.IndexOf(m2)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,6 +462,18 @@ namespace Barotrauma
|
||||
CreateStore(force: true);
|
||||
}
|
||||
|
||||
public void UnlockInitialMissions()
|
||||
{
|
||||
if (Type.MissionIdentifiers.Any())
|
||||
{
|
||||
UnlockMissionByIdentifier(Type.MissionIdentifiers.GetRandom(Rand.RandSync.Server));
|
||||
}
|
||||
if (Type.MissionTags.Any())
|
||||
{
|
||||
UnlockMissionByTag(Type.MissionTags.GetRandom(Rand.RandSync.Server));
|
||||
}
|
||||
}
|
||||
|
||||
public void UnlockMission(MissionPrefab missionPrefab, LocationConnection connection)
|
||||
{
|
||||
if (AvailableMissions.Any(m => m.Prefab == missionPrefab)) { return; }
|
||||
|
||||
@@ -484,14 +484,7 @@ namespace Barotrauma
|
||||
{
|
||||
Difficulty = MathHelper.Clamp(location.MapPosition.X / Width * 100, 0.0f, 100.0f)
|
||||
};
|
||||
if (location.Type.MissionIdentifiers.Any())
|
||||
{
|
||||
location.UnlockMissionByIdentifier(location.Type.MissionIdentifiers.GetRandom());
|
||||
}
|
||||
if (location.Type.MissionTags.Any())
|
||||
{
|
||||
location.UnlockMissionByTag(location.Type.MissionTags.GetRandom());
|
||||
}
|
||||
location.UnlockInitialMissions();
|
||||
}
|
||||
foreach (LocationConnection connection in Connections)
|
||||
{
|
||||
|
||||
@@ -1078,7 +1078,7 @@ namespace Barotrauma
|
||||
#endif
|
||||
}
|
||||
|
||||
float gapOpen = (damage / MaxHealth - LeakThreshold) * (1.0f / (1.0f - LeakThreshold));
|
||||
float gapOpen = MaxHealth <= 0.0f ? 0.0f : (damage / MaxHealth - LeakThreshold) * (1.0f / (1.0f - LeakThreshold));
|
||||
Sections[sectionIndex].gap.Open = gapOpen;
|
||||
}
|
||||
|
||||
@@ -1095,7 +1095,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (damageDiff < 0.0f)
|
||||
{
|
||||
attacker.Info.IncreaseSkillLevel("mechanical",
|
||||
attacker.Info?.IncreaseSkillLevel("mechanical",
|
||||
-damageDiff * SkillSettings.Current.SkillIncreasePerRepairedStructureDamage / Math.Max(attacker.GetSkillLevel("mechanical"), 1.0f),
|
||||
SectionPosition(sectionIndex));
|
||||
}
|
||||
|
||||
@@ -282,9 +282,11 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
private float ballastFloraTimer;
|
||||
public bool ImmuneToBallastFlora { get; set; }
|
||||
public void AttemptBallastFloraInfection(string identifier, float deltaTime, float probability)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (ImmuneToBallastFlora) { return; }
|
||||
|
||||
if (ballastFloraTimer < 1f)
|
||||
{
|
||||
@@ -1264,7 +1266,7 @@ namespace Barotrauma
|
||||
{
|
||||
List<(ItemContainer container, int freeSlots)> containers = new List<(ItemContainer container, int freeSlots)>();
|
||||
var connectedSubs = GetConnectedSubs();
|
||||
foreach (Item item in Item.ItemList)
|
||||
foreach (Item item in Item.ItemList.ToList())
|
||||
{
|
||||
if (!connectedSubs.Contains(item.Submarine)) { continue; }
|
||||
if (!item.HasTag("cargocontainer")) { continue; }
|
||||
|
||||
@@ -671,17 +671,20 @@ namespace Barotrauma
|
||||
|
||||
Body.LinearVelocity -= velChange;
|
||||
|
||||
float damageAmount = contactDot * Body.Mass / limb.character.Mass;
|
||||
limb.character.LastDamageSource = submarine;
|
||||
limb.character.DamageLimb(ConvertUnits.ToDisplayUnits(collision.ImpactPos), limb,
|
||||
AfflictionPrefab.ImpactDamage.Instantiate(damageAmount).ToEnumerable(), 0.0f, true, 0.0f);
|
||||
|
||||
if (limb.character.IsDead)
|
||||
if (contactDot > 0.1f)
|
||||
{
|
||||
foreach (LimbJoint limbJoint in limb.character.AnimController.LimbJoints)
|
||||
float damageAmount = contactDot * Body.Mass / limb.character.Mass;
|
||||
limb.character.LastDamageSource = submarine;
|
||||
limb.character.DamageLimb(ConvertUnits.ToDisplayUnits(collision.ImpactPos), limb,
|
||||
AfflictionPrefab.ImpactDamage.Instantiate(damageAmount).ToEnumerable(), 0.0f, true, 0.0f);
|
||||
|
||||
if (limb.character.IsDead)
|
||||
{
|
||||
if (limbJoint.IsSevered || (limbJoint.LimbA != limb && limbJoint.LimbB != limb)) continue;
|
||||
limb.character.AnimController.SeverLimbJoint(limbJoint);
|
||||
foreach (LimbJoint limbJoint in limb.character.AnimController.LimbJoints)
|
||||
{
|
||||
if (limbJoint.IsSevered || (limbJoint.LimbA != limb && limbJoint.LimbB != limb)) continue;
|
||||
limb.character.AnimController.SeverLimbJoint(limbJoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,6 +404,8 @@ namespace Barotrauma
|
||||
{
|
||||
var vanillaSubs = vanilla.GetFilesOfType(ContentType.Submarine)
|
||||
.Concat(vanilla.GetFilesOfType(ContentType.Wreck))
|
||||
.Concat(vanilla.GetFilesOfType(ContentType.BeaconStation))
|
||||
.Concat(vanilla.GetFilesOfType(ContentType.EnemySubmarine))
|
||||
.Concat(vanilla.GetFilesOfType(ContentType.Outpost))
|
||||
.Concat(vanilla.GetFilesOfType(ContentType.OutpostModule));
|
||||
string pathToCompare = FilePath.Replace(@"\", @"/").ToLowerInvariant();
|
||||
|
||||
@@ -779,6 +779,7 @@ namespace Barotrauma
|
||||
public static WayPoint[] SelectCrewSpawnPoints(List<CharacterInfo> crew, Submarine submarine)
|
||||
{
|
||||
List<WayPoint> subWayPoints = WayPointList.FindAll(wp => wp.Submarine == submarine);
|
||||
subWayPoints.Shuffle();
|
||||
|
||||
List<WayPoint> unassignedWayPoints = subWayPoints.FindAll(wp => wp.spawnType == SpawnType.Human);
|
||||
|
||||
@@ -789,7 +790,7 @@ namespace Barotrauma
|
||||
//try to give the crew member a spawnpoint that hasn't been assigned to anyone and matches their job
|
||||
for (int n = 0; n < unassignedWayPoints.Count; n++)
|
||||
{
|
||||
if (crew[i].Job.Prefab != unassignedWayPoints[n].AssignedJob) continue;
|
||||
if (crew[i].Job.Prefab != unassignedWayPoints[n].AssignedJob) { continue; }
|
||||
assignedWayPoints[i] = unassignedWayPoints[n];
|
||||
unassignedWayPoints.RemoveAt(n);
|
||||
|
||||
@@ -800,17 +801,17 @@ namespace Barotrauma
|
||||
//go through the crewmembers that don't have a spawnpoint yet (if any)
|
||||
for (int i = 0; i < crew.Count; i++)
|
||||
{
|
||||
if (assignedWayPoints[i] != null) continue;
|
||||
if (assignedWayPoints[i] != null) { continue; }
|
||||
|
||||
//try to assign a spawnpoint that matches the job, even if the spawnpoint is already assigned to someone else
|
||||
foreach (WayPoint wp in subWayPoints)
|
||||
{
|
||||
if (wp.spawnType != SpawnType.Human || wp.AssignedJob != crew[i].Job.Prefab) continue;
|
||||
if (wp.spawnType != SpawnType.Human || wp.AssignedJob != crew[i].Job.Prefab) { continue; }
|
||||
|
||||
assignedWayPoints[i] = wp;
|
||||
break;
|
||||
}
|
||||
if (assignedWayPoints[i] != null) continue;
|
||||
if (assignedWayPoints[i] != null) { continue; }
|
||||
|
||||
//try to assign a spawnpoint that isn't meant for any specific job
|
||||
var nonJobSpecificPoints = subWayPoints.FindAll(wp => wp.spawnType == SpawnType.Human && wp.AssignedJob == null);
|
||||
@@ -819,7 +820,7 @@ namespace Barotrauma
|
||||
assignedWayPoints[i] = nonJobSpecificPoints[Rand.Int(nonJobSpecificPoints.Count, Rand.RandSync.Server)];
|
||||
}
|
||||
|
||||
if (assignedWayPoints[i] != null) continue;
|
||||
if (assignedWayPoints[i] != null) { continue; }
|
||||
|
||||
//everything else failed -> just give a random spawnpoint inside the sub
|
||||
assignedWayPoints[i] = GetRandom(SpawnType.Human, null, submarine, useSyncedRand: true);
|
||||
|
||||
Reference in New Issue
Block a user