Unstable 1.1.14.0

This commit is contained in:
Markus Isberg
2023-10-02 16:43:54 +03:00
parent 94f5a93a0c
commit cf8f0de659
606 changed files with 21906 additions and 11456 deletions
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using FarseerPhysics;
namespace Barotrauma
{
@@ -13,6 +14,7 @@ namespace Barotrauma
public readonly int MinAmount, MaxAmount;
private readonly List<Character> monsters = new List<Character>();
public readonly float SpawnDistance;
private readonly float scatter;
private readonly float offset;
private readonly float delayBetweenSpawns;
@@ -56,7 +58,7 @@ namespace Barotrauma
}
public MonsterEvent(EventPrefab prefab)
: base (prefab)
: base(prefab)
{
string speciesFile = prefab.ConfigElement.GetAttributeString("characterfile", "");
CharacterPrefab characterPrefab = CharacterPrefab.FindByFilePath(speciesFile);
@@ -94,7 +96,7 @@ namespace Barotrauma
}
spawnPointTag = prefab.ConfigElement.GetAttributeString("spawnpointtag", string.Empty);
SpawnDistance = prefab.ConfigElement.GetAttributeFloat("spawndistance", 0);
offset = prefab.ConfigElement.GetAttributeFloat("offset", 0);
scatter = Math.Clamp(prefab.ConfigElement.GetAttributeFloat("scatter", 500), 0, 3000);
delayBetweenSpawns = prefab.ConfigElement.GetAttributeFloat("delaybetweenspawns", 0.1f);
@@ -174,6 +176,15 @@ namespace Barotrauma
}
}
public override string GetDebugInfo()
{
return
$"Finished: {IsFinished.ColorizeObject()}\n" +
$"Amount: {MinAmount.ColorizeObject()} - {MaxAmount.ColorizeObject()}\n" +
$"Spawn pending: {SpawnPending.ColorizeObject()}\n" +
$"Spawn position: {SpawnPos.ColorizeObject()}";
}
private List<Level.InterestingPosition> GetAvailableSpawnPositions()
{
var availablePositions = Level.Loaded.PositionsOfInterest.FindAll(p => SpawnPosType.HasFlag(p.PositionType));
@@ -214,13 +225,14 @@ namespace Barotrauma
return availablePositions;
}
private Level.InterestingPosition chosenPosition;
private void FindSpawnPosition(bool affectSubImmediately)
{
if (disallowed) { return; }
spawnPos = Vector2.Zero;
var availablePositions = GetAvailableSpawnPositions();
var chosenPosition = new Level.InterestingPosition(Point.Zero, Level.PositionType.MainPath, isValid: false);
chosenPosition = new Level.InterestingPosition(Point.Zero, Level.PositionType.MainPath, isValid: false);
bool isRuinOrWreck = SpawnPosType.HasFlag(Level.PositionType.Ruin) || SpawnPosType.HasFlag(Level.PositionType.Wreck);
if (affectSubImmediately && !isRuinOrWreck && !SpawnPosType.HasFlag(Level.PositionType.Abyss))
{
@@ -454,52 +466,109 @@ namespace Barotrauma
{
if (submarine.Info.Type != SubmarineType.Player) { continue; }
float minDist = GetMinDistanceToSub(submarine);
if (Vector2.DistanceSquared(submarine.WorldPosition, spawnPos.Value) < minDist * minDist) { return; }
if (Vector2.DistanceSquared(submarine.WorldPosition, spawnPos.Value) < minDist * minDist)
{
// Too close to a player sub.
return;
}
}
}
float minDistance = Prefab.SpawnDistance;
if (minDistance <= 0)
float spawnDistance = SpawnDistance;
if (spawnDistance <= 0)
{
if (SpawnPosType.HasFlag(Level.PositionType.Cave))
{
minDistance = 8000;
spawnDistance = 8000;
}
else if (SpawnPosType.HasFlag(Level.PositionType.Ruin))
{
minDistance = 5000;
spawnDistance = 5000;
}
else if (SpawnPosType.HasFlag(Level.PositionType.Wreck) || SpawnPosType.HasFlag(Level.PositionType.BeaconStation))
{
minDistance = 3000;
spawnDistance = 3000;
}
}
if (minDistance > 0)
if (spawnDistance > 0)
{
bool someoneNearby = false;
foreach (Submarine submarine in Submarine.Loaded)
{
if (submarine.Info.Type != SubmarineType.Player) { continue; }
if (Vector2.DistanceSquared(submarine.WorldPosition, spawnPos.Value) < MathUtils.Pow2(minDistance))
float distanceSquared = Vector2.DistanceSquared(submarine.WorldPosition, spawnPos.Value);
if (distanceSquared < MathUtils.Pow2(spawnDistance))
{
someoneNearby = true;
break;
if (chosenPosition.Submarine != null)
{
Vector2 from = Submarine.GetRelativeSimPositionFromWorldPosition(spawnPos.Value, chosenPosition.Submarine, chosenPosition.Submarine);
Vector2 to = Submarine.GetRelativeSimPositionFromWorldPosition(submarine.WorldPosition, chosenPosition.Submarine, submarine);
if (CheckLineOfSight(from, to, chosenPosition.Submarine))
{
// Line of sight to a player sub -> don't spawn yet.
return;
}
}
else
{
break;
}
}
}
foreach (Character c in Character.CharacterList)
{
if (c == Character.Controlled || c.IsRemotePlayer)
{
if (Vector2.DistanceSquared(c.WorldPosition, spawnPos.Value) < MathUtils.Pow2(minDistance))
float distanceSquared = Vector2.DistanceSquared(c.WorldPosition, spawnPos.Value);
if (distanceSquared < MathUtils.Pow2(spawnDistance))
{
someoneNearby = true;
break;
if (chosenPosition.Submarine != null)
{
Vector2 from = Submarine.GetRelativeSimPositionFromWorldPosition(spawnPos.Value, chosenPosition.Submarine, chosenPosition.Submarine);
Vector2 to = Submarine.GetRelativeSimPositionFromWorldPosition(c.WorldPosition, chosenPosition.Submarine, c.Submarine);
if (CheckLineOfSight(from, to, chosenPosition.Submarine))
{
// Line of sight to a player character -> don't spawn. Disable the event to prevent monsters "magically" spawning here.
Finish();
return;
}
}
else
{
break;
}
}
}
}
if (!someoneNearby) { return; }
static bool CheckLineOfSight(Vector2 from, Vector2 to, Submarine targetSub)
{
var bodies = Submarine.PickBodies(from, to, ignoredBodies: null, Physics.CollisionWall);
foreach (var b in bodies)
{
if (b.UserData is ISpatialEntity spatialEntity && spatialEntity.Submarine != targetSub)
{
// Different sub -> ignore
continue;
}
if (b.UserData is Structure s && !s.IsPlatform && s.CastShadow)
{
return false;
}
if (b.UserData is Item item && item.GetComponent<Door>() is Door door)
{
if (!door.IsBroken && !door.IsOpen)
{
return false;
}
}
}
return true;
}
}
if (SpawnPosType.HasFlag(Level.PositionType.Abyss) || SpawnPosType.HasFlag(Level.PositionType.AbyssCave))
{
bool anyInAbyss = false;