v0.19.0.0 (unstable)

This commit is contained in:
Regalis11
2022-07-20 18:47:07 +03:00
parent 2e2663a175
commit 6b55adcdd9
170 changed files with 2769 additions and 1634 deletions
@@ -3128,14 +3128,14 @@ namespace Barotrauma
return success;
}
public bool TryGetInterestingPosition(bool useSyncedRand, PositionType positionType, float minDistFromSubs, out Vector2 position, Func<InterestingPosition, bool> filter = null)
public bool TryGetInterestingPosition(bool useSyncedRand, PositionType positionType, float minDistFromSubs, out Vector2 position, Func<InterestingPosition, bool> filter = null, bool suppressWarning = false)
{
bool success = TryGetInterestingPosition(useSyncedRand, positionType, minDistFromSubs, out Point pos, Vector2.Zero, minDistFromPoint: 0, filter);
bool success = TryGetInterestingPosition(useSyncedRand, positionType, minDistFromSubs, out Point pos, Vector2.Zero, minDistFromPoint: 0, filter, suppressWarning);
position = pos.ToVector2();
return success;
}
public bool TryGetInterestingPosition(bool useSyncedRand, PositionType positionType, float minDistFromSubs, out Point position, Vector2 awayPoint, float minDistFromPoint = 0f, Func<InterestingPosition, bool> filter = null)
public bool TryGetInterestingPosition(bool useSyncedRand, PositionType positionType, float minDistFromSubs, out Point position, Vector2 awayPoint, float minDistFromPoint = 0f, Func<InterestingPosition, bool> filter = null, bool suppressWarning = false)
{
if (!PositionsOfInterest.Any())
{
@@ -3155,11 +3155,14 @@ namespace Barotrauma
}
if (!suitablePositions.Any())
{
string errorMsg = "Could not find a suitable position of interest. (PositionType: " + positionType + ", minDistFromSubs: " + minDistFromSubs + ")\n" + Environment.StackTrace.CleanupStackTrace();
GameAnalyticsManager.AddErrorEventOnce("Level.TryGetInterestingPosition:PositionTypeNotFound", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
if (!suppressWarning)
{
string errorMsg = "Could not find a suitable position of interest. (PositionType: " + positionType + ", minDistFromSubs: " + minDistFromSubs + ")\n" + Environment.StackTrace.CleanupStackTrace();
GameAnalyticsManager.AddErrorEventOnce("Level.TryGetInterestingPosition:PositionTypeNotFound", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
#if DEBUG
DebugConsole.ThrowError(errorMsg);
DebugConsole.ThrowError(errorMsg);
#endif
}
position = PositionsOfInterest[Rand.Int(PositionsOfInterest.Count, (useSyncedRand ? Rand.RandSync.ServerAndClient : Rand.RandSync.Unsynced))].Position;
return false;
}
@@ -57,6 +57,8 @@ namespace Barotrauma
public readonly List<EventPrefab> EventHistory = new List<EventPrefab>();
public readonly List<EventPrefab> NonRepeatableEvents = new List<EventPrefab>();
public bool EventsExhausted { get; set; }
public float CrushDepth
{
get
@@ -130,6 +132,8 @@ namespace Barotrauma
string[] nonRepeatablePrefabNames = element.GetAttributeStringArray("nonrepeatableevents", new string[] { });
NonRepeatableEvents.AddRange(EventPrefab.Prefabs.Where(p => nonRepeatablePrefabNames.Any(n => p.Identifier == n)));
EventsExhausted = element.GetAttributeBool(nameof(EventsExhausted).ToLower(), false);
}
@@ -238,7 +242,8 @@ namespace Barotrauma
new XAttribute("difficulty", Difficulty.ToString("G", CultureInfo.InvariantCulture)),
new XAttribute("size", XMLExtensions.PointToString(Size)),
new XAttribute("generationparams", GenerationParams.Identifier),
new XAttribute("initialdepth", InitialDepth));
new XAttribute("initialdepth", InitialDepth),
new XAttribute(nameof(EventsExhausted).ToLower(), EventsExhausted));
if (HasBeaconStation)
{
@@ -944,15 +944,20 @@ namespace Barotrauma
{
foreach (Location location in Locations)
{
location.LevelData.EventsExhausted = false;
if (location.Discovered)
{
if (furthestDiscoveredLocation == null ||
if (furthestDiscoveredLocation == null ||
location.MapPosition.X > furthestDiscoveredLocation.MapPosition.X)
{
furthestDiscoveredLocation = location;
}
}
}
foreach (LocationConnection connection in Connections)
{
connection.LevelData.EventsExhausted = false;
}
foreach (Location location in Locations)
{
@@ -19,7 +19,7 @@ namespace Barotrauma
public NPCSet(ContentXElement element, NPCSetsFile file) : base(file, element.GetAttributeIdentifier("identifier", ""))
{
Humans = element.Elements().Select(npcElement => new HumanPrefab(npcElement, file)).ToImmutableArray();
Humans = element.Elements().Select(npcElement => new HumanPrefab(npcElement, file, Identifier)).ToImmutableArray();
}
public static HumanPrefab? Get(Identifier setIdentifier, Identifier npcidentifier)
@@ -203,7 +203,7 @@ namespace Barotrauma
}
else
{
newCollection.Add(new HumanPrefab(npcElement, file));
newCollection.Add(new HumanPrefab(npcElement, file, npcSetIdentifier: from));
}
}
humanPrefabCollections.Add(newCollection);
@@ -1426,7 +1426,7 @@ namespace Barotrauma
static bool ShouldRemoveLinkedEntity(MapEntity e, bool doorInUse, PlacedModule module)
{
if (e is Item it && it.GetComponent<Ladder>() != null)
if (e is Item it && it.IsLadder)
{
if (module.UsedGapPositions.HasFlag(OutpostModuleInfo.GapPosition.Top) || module.UsedGapPositions.HasFlag(OutpostModuleInfo.GapPosition.Bottom))
{
@@ -1568,7 +1568,7 @@ namespace Barotrauma
foreach (HumanPrefab humanPrefab in humanPrefabs)
{
if (humanPrefab is null) { continue; }
var characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: humanPrefab.GetJobPrefab(Rand.RandSync.ServerAndClient), randSync: Rand.RandSync.ServerAndClient);
var characterInfo = humanPrefab.CreateCharacterInfo(Rand.RandSync.ServerAndClient);
if (location != null && location.KilledCharacterIdentifiers.Contains(characterInfo.GetIdentifier()))
{
killedCharacters.Add(humanPrefab);
@@ -1582,7 +1582,7 @@ namespace Barotrauma
{
for (int tries = 0; tries < 100; tries++)
{
var characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: killedCharacter.GetJobPrefab(Rand.RandSync.ServerAndClient), randSync: Rand.RandSync.ServerAndClient);
var characterInfo = killedCharacter.CreateCharacterInfo(Rand.RandSync.ServerAndClient);
if (!location.KilledCharacterIdentifiers.Contains(characterInfo.GetIdentifier()))
{
selectedCharacters.Add((killedCharacter, characterInfo));
@@ -1,126 +0,0 @@
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
{
class RoundEndCinematic
{
public bool Running
{
get;
private set;
}
public Camera AssignedCamera;
private float duration;
private CoroutineHandle updateCoroutine;
public RoundEndCinematic(Submarine submarine, Camera cam, float duration = 10.0f)
: this(new List<Submarine>() { submarine }, cam, duration)
{
}
public RoundEndCinematic(List<Submarine> submarines, Camera cam, float duration)
{
if (!submarines.Any(s => s != null)) return;
this.duration = duration;
AssignedCamera = cam;
Running = true;
updateCoroutine = CoroutineManager.StartCoroutine(Update(submarines, cam));
}
public void Stop()
{
CoroutineManager.StopCoroutines(updateCoroutine);
Running = false;
#if CLIENT
GUI.ScreenOverlayColor = Color.TransparentBlack;
#endif
}
private IEnumerable<CoroutineStatus> Update(List<Submarine> subs, Camera cam)
{
if (!subs.Any()) yield return CoroutineStatus.Success;
#if CLIENT
Character.Controlled = null;
GameMain.LightManager.LosEnabled = false;
#endif
cam.TargetPos = Vector2.Zero;
Level.Loaded.TopBarrier.Enabled = false;
foreach (Character character in Character.CharacterList)
{
character.AnimController.Frozen = true;
foreach (Limb limb in character.AnimController.Limbs)
{
limb.body.PhysEnabled = false;
}
}
cam.TargetPos = Vector2.Zero;
float timer = 0.0f;
float initialZoom = cam.Zoom;
Vector2 initialCameraPos = cam.Position;
while (timer < duration)
{
if (Screen.Selected != GameMain.GameScreen)
{
yield return new WaitForSeconds(0.1f);
#if CLIENT
GUI.ScreenOverlayColor = Color.TransparentBlack;
#endif
Running = false;
yield return CoroutineStatus.Success;
}
Vector2 minPos = new Vector2(
subs.Min(s => s.WorldPosition.X - s.Borders.Width / 2),
subs.Min(s => s.WorldPosition.Y - s.Borders.Height / 2));
Vector2 maxPos = new Vector2(
subs.Min(s => s.WorldPosition.X + s.Borders.Width / 2),
subs.Min(s => s.WorldPosition.Y + s.Borders.Height / 2));
Vector2 cameraPos = new Vector2(
MathHelper.SmoothStep(minPos.X, maxPos.X, timer / duration),
(minPos.Y + maxPos.Y) / 2.0f);
cam.Translate(cameraPos - cam.Position);
foreach (Submarine sub in subs)
{
sub.PhysicsBody?.ResetDynamics();
}
#if CLIENT
cam.Zoom = MathHelper.SmoothStep(initialZoom, 0.5f, timer / duration);
if (timer / duration > 0.9f)
{
GUI.ScreenOverlayColor = Color.Lerp(Color.TransparentBlack, Color.Black, ((timer / duration) - 0.9f) * 10.0f);
}
#endif
timer += CoroutineManager.UnscaledDeltaTime;
yield return CoroutineStatus.Running;
}
Running = false;
yield return new WaitForSeconds(0.1f);
#if CLIENT
GUI.ScreenOverlayColor = Color.TransparentBlack;
#endif
yield return CoroutineStatus.Success;
}
}
}
@@ -986,14 +986,6 @@ namespace Barotrauma
subBody.Body.ResetDynamics();
subBody.Body.Enabled = false;
foreach (MapEntity e in MapEntity.mapEntityList)
{
if (e.Submarine == this)
{
Spawner.AddEntityToRemoveQueue(e);
}
}
foreach (Character c in Character.CharacterList)
{
if (c.Submarine == this)
@@ -1,8 +1,6 @@
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Barotrauma.Networking;
using FarseerPhysics;
using FarseerPhysics.Collision;
using FarseerPhysics.Common;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
@@ -898,13 +896,15 @@ namespace Barotrauma
}
bool holdingOntoSomething = false;
if (c.SelectedConstruction != null)
if (c.SelectedSecondaryItem != null)
{
holdingOntoSomething =
c.SelectedConstruction.GetComponent<Ladder>() != null ||
(c.SelectedConstruction.GetComponent<Controller>()?.LimbPositions.Any() ?? false);
holdingOntoSomething = c.SelectedSecondaryItem.IsLadder ||
(c.SelectedSecondaryItem.GetComponent<Controller>()?.LimbPositions.Any() ?? false);
}
if (!holdingOntoSomething && c.SelectedItem != null)
{
holdingOntoSomething = c.SelectedItem.GetComponent<Controller>()?.LimbPositions.Any() ?? false;
}
if (!holdingOntoSomething)
{
c.AnimController.Collider.ApplyLinearImpulse(c.AnimController.Collider.Mass * impulse, 10.0f);
@@ -19,7 +19,7 @@ namespace Barotrauma
public static bool ShowWayPoints = true, ShowSpawnPoints = true;
public const float LadderWaypointInterval = 70.0f;
public const float LadderWaypointInterval = 55.0f;
protected SpawnType spawnType;
private string[] idCardTags;
@@ -560,21 +560,22 @@ namespace Barotrauma
stairPoints.ForEach(wp => wp.FindStairs());
}
// Ladders
foreach (Item item in Item.ItemList)
{
var ladders = item.GetComponent<Ladder>();
if (ladders == null) { continue; }
Vector2 bottomPoint = new Vector2(item.Rect.Center.X, item.Rect.Top - item.Rect.Height + 10);
List<WayPoint> ladderPoints = new List<WayPoint>
List<(WayPoint wp, bool connectHullPoints)> ladderPoints = new List<(WayPoint, bool)>
{
new WayPoint(bottomPoint, SpawnType.Path, submarine),
(new WayPoint(bottomPoint, SpawnType.Path, submarine), true)
};
List<Body> ignoredBodies = new List<Body>();
// Lowest point is only meaningful for hanging ladders inside the sub, but it shouldn't matter in other cases either.
// Start point is where the bots normally grasp the ladder when they stand on ground.
WayPoint lowestPoint = ladderPoints[0];
WayPoint lowestPoint = ladderPoints[0].wp;
WayPoint prevPoint = lowestPoint;
Vector2 prevPos = prevPoint.SimPosition;
Body ground = Submarine.PickBody(lowestPoint.SimPosition, lowestPoint.SimPosition - Vector2.UnitY, ignoredBodies,
@@ -589,7 +590,7 @@ namespace Barotrauma
if (lowestPoint == null || Math.Abs(startPoint.Position.Y - startHeight) > 40 && Hull.FindHull(nextPos) != null)
{
startPoint = new WayPoint(nextPos, SpawnType.Path, submarine);
ladderPoints.Add(startPoint);
ladderPoints.Add((startPoint, true));
if (lowestPoint != null)
{
startPoint.ConnectTo(lowestPoint);
@@ -613,18 +614,13 @@ namespace Barotrauma
}
else
{
//no door, check for walls
//no door, check for platforms/walls
pickedBody = Submarine.PickBody(
ConvertUnits.ToSimUnits(new Vector2(startPoint.Position.X, y)), prevPos, ignoredBodies, null, false,
(Fixture f) => f.Body.UserData is Structure);
}
if (pickedBody == null)
{
prevPos = Submarine.LastPickedPosition;
continue;
}
else
if (pickedBody != null)
{
ignoredBodies.Add(pickedBody);
}
@@ -632,19 +628,29 @@ namespace Barotrauma
if (pickedDoor != null)
{
WayPoint newPoint = new WayPoint(pickedDoor.Item.Position, SpawnType.Path, submarine);
ladderPoints.Add(newPoint);
ladderPoints.Add((newPoint, true));
newPoint.ConnectedGap = pickedDoor.LinkedGap;
// TODO: Prevent the waypoint below being too close to the door
newPoint.ConnectTo(prevPoint);
prevPoint = newPoint;
prevPos = new Vector2(prevPos.X, ConvertUnits.ToSimUnits(pickedDoor.Item.Position.Y - pickedDoor.Item.Rect.Height));
// Adjust y to prevent waypoints clamping up together
y = Math.Max(pickedDoor.Item.Position.Y, y);
}
else
{
WayPoint newPoint = new WayPoint(ConvertUnits.ToDisplayUnits(Submarine.LastPickedPosition) + Vector2.UnitY * heightFromFloor, SpawnType.Path, submarine);
ladderPoints.Add(newPoint);
Vector2 pos = pickedBody == null ? new Vector2(startPoint.Position.X, y) :
ConvertUnits.ToDisplayUnits(Submarine.LastPickedPosition) + Vector2.UnitY * heightFromFloor;
WayPoint newPoint = new WayPoint(pos, SpawnType.Path, submarine);
ladderPoints.Add((newPoint, pickedBody != null));
newPoint.ConnectTo(prevPoint);
prevPoint = newPoint;
prevPos = ConvertUnits.ToSimUnits(newPoint.Position);
if (pickedBody != null)
{
// Adjust y to prevent waypoints clamping up together
y = Math.Max(newPoint.Position.Y, y);
}
}
}
@@ -652,33 +658,30 @@ namespace Barotrauma
if (prevPoint.rect.Y < item.Rect.Y - 40)
{
WayPoint wayPoint = new WayPoint(new Vector2(item.Rect.Center.X, item.Rect.Y - 1.0f), SpawnType.Path, submarine);
ladderPoints.Add(wayPoint);
ladderPoints.Add((wayPoint, true));
wayPoint.ConnectTo(prevPoint);
}
// Connect ladder waypoints to hull points at the right and left side
foreach (WayPoint ladderPoint in ladderPoints)
var ladderWaypoints = ladderPoints.Select(lp => lp.wp);
foreach (var ladderPoint in ladderPoints)
{
ladderPoint.Ladders = ladders;
bool isHatch = ladderPoint.ConnectedGap != null && !ladderPoint.ConnectedGap.IsRoomToRoom;
var wp = ladderPoint.wp;
wp.Ladders = ladders;
if (!ladderPoint.connectHullPoints) { continue; }
bool isHatch = wp.ConnectedGap != null && !wp.ConnectedGap.IsRoomToRoom;
for (int dir = -1; dir <= 1; dir += 2)
{
WayPoint closest = null;
if (isHatch)
{
closest = ladderPoint.FindClosest(dir, horizontalSearch: true, new Vector2(500, 1000), ladderPoint.ConnectedGap?.ConnectedDoor?.Body.FarseerBody, filter: wp => wp.CurrentHull == null, ignored: ladderPoints);
}
else
{
closest = ladderPoint.FindClosest(dir, horizontalSearch: true, new Vector2(150, 100), ladderPoint.ConnectedGap?.ConnectedDoor?.Body.FarseerBody, ignored: ladderPoints);
}
WayPoint closest = isHatch ?
wp.FindClosest(dir, horizontalSearch: true, new Vector2(500, 1000), wp.ConnectedGap?.ConnectedDoor?.Body.FarseerBody, filter: wp => wp.CurrentHull == null, ignored: ladderWaypoints) :
wp.FindClosest(dir, horizontalSearch: true, new Vector2(150, 100), wp.ConnectedGap?.ConnectedDoor?.Body.FarseerBody, ignored: ladderWaypoints);
if (closest == null) { continue; }
ladderPoint.ConnectTo(closest);
wp.ConnectTo(closest);
}
}
}
// Another pass: connect cap and bottom points with other ladders when they are vertically adjacent to another (double ladders)
// Another ladder pass: connect cap and bottom points with other ladders when they are vertically adjacent to another (double ladders)
foreach (Item item in Item.ItemList)
{
var ladders = item.GetComponent<Ladder>();
@@ -1035,12 +1038,10 @@ namespace Barotrauma
w.tags = element.GetAttributeIdentifierArray("tags", Array.Empty<Identifier>()).ToHashSet();
string jobIdentifier = element.GetAttributeString("job", "").ToLowerInvariant();
if (!string.IsNullOrWhiteSpace(jobIdentifier))
Identifier jobIdentifier = element.GetAttributeIdentifier("job", Identifier.Empty);
if (!jobIdentifier.IsEmpty)
{
w.AssignedJob =
JobPrefab.Get(jobIdentifier) ??
JobPrefab.Prefabs.Find(jp => jp.Name.Equals(jobIdentifier, StringComparison.OrdinalIgnoreCase));
w.AssignedJob = JobPrefab.Get(jobIdentifier);
}
w.linkedToID = new List<ushort>();