v0.14.6.0
This commit is contained in:
@@ -37,7 +37,14 @@ namespace Barotrauma
|
||||
|
||||
private static bool IsThalamus(MapEntityPrefab entityPrefab, string tag) => entityPrefab.HasSubCategory("thalamus") || entityPrefab.Tags.Contains(tag);
|
||||
|
||||
public WreckAI(Submarine wreck)
|
||||
public static WreckAI Create(Submarine wreck)
|
||||
{
|
||||
var wreckAI = new WreckAI(wreck);
|
||||
if (wreckAI.Config == null) { return null; }
|
||||
return wreckAI;
|
||||
}
|
||||
|
||||
private WreckAI(Submarine wreck)
|
||||
{
|
||||
Wreck = wreck;
|
||||
Config = WreckAIConfig.GetRandom();
|
||||
@@ -55,37 +62,59 @@ namespace Barotrauma
|
||||
}
|
||||
allItems = Wreck.GetItems(false);
|
||||
thalamusItems = allItems.FindAll(i => IsThalamus(i.prefab));
|
||||
var hulls = Wreck.GetHulls(false);
|
||||
hulls.AddRange(Wreck.GetHulls(false));
|
||||
var potentialBrainHulls = new Dictionary<Hull, float>();
|
||||
brain = new Item(brainPrefab, Vector2.Zero, Wreck);
|
||||
thalamusItems.Add(brain);
|
||||
Vector2 negativeMargin = new Vector2(40, 20);
|
||||
Vector2 minSize = brain.Rect.Size.ToVector2() - negativeMargin;
|
||||
Vector2 maxSize = new Vector2(brain.Rect.Width * 3, brain.Rect.Height * 3);
|
||||
// First try to get a room that is not too big and not in the edges of the sub.
|
||||
// Also try not to create the brain in a room that already have carrier items inside.
|
||||
// Ignore hulls that have any linked hulls to keep the calculations simple.
|
||||
Point minSize = brain.Rect.Size.Multiply(brain.Scale);
|
||||
// Bigger hulls are allowed, but not preferred more than what's sufficent.
|
||||
Vector2 sufficentSize = new Vector2(minSize.X * 2, minSize.Y * 1.1f);
|
||||
// Shrink the horizontal axis so that the brain is not placed in the left or right side, where we often have curved walls.
|
||||
// Also ignore hulls that have open gaps, because we'll want the room to be full of water. The room will be filled with water when the brain is inserted in the room.
|
||||
Rectangle shrinkedBounds = ToolBox.GetWorldBounds(Wreck.WorldPosition.ToPoint(), new Point(Wreck.Borders.Width - 500, Wreck.Borders.Height));
|
||||
bool BaseCondition(Hull h) => h.RectWidth > minSize.X && h.RectHeight > minSize.Y && h.GetLinkedEntities<Hull>().None() && h.ConnectedGaps.None(g => g.Open > 0);
|
||||
bool IsNotTooBig(Hull h) => h.RectWidth < maxSize.X && h.RectHeight < maxSize.Y;
|
||||
bool IsNotInFringes(Hull h) => shrinkedBounds.ContainsWorld(h.WorldRect);
|
||||
bool DoesNotContainOtherItems(Hull h) => thalamusItems.None(i => i.CurrentHull == h);
|
||||
Hull brainHull = hulls.GetRandom(h => BaseCondition(h) && IsNotTooBig(h) && IsNotInFringes(h) && DoesNotContainOtherItems(h), Rand.RandSync.Server);
|
||||
if (brainHull == null)
|
||||
foreach (Hull hull in hulls)
|
||||
{
|
||||
brainHull = hulls.GetRandom(h => BaseCondition(h) && IsNotInFringes(h) && DoesNotContainOtherItems(h), Rand.RandSync.Server);
|
||||
}
|
||||
if (brainHull == null)
|
||||
{
|
||||
brainHull = hulls.GetRandom(h => BaseCondition(h) && (IsNotInFringes(h) || DoesNotContainOtherItems(h)), Rand.RandSync.Server);
|
||||
}
|
||||
if (brainHull == null)
|
||||
{
|
||||
brainHull = hulls.GetRandom(BaseCondition, Rand.RandSync.Server);
|
||||
float distanceFromCenter = Vector2.Distance(Wreck.WorldPosition, hull.WorldPosition);
|
||||
float distanceFactor = MathHelper.Lerp(1.0f, 0.5f, MathUtils.InverseLerp(0, Math.Max(shrinkedBounds.Width, shrinkedBounds.Height) / 2, distanceFromCenter));
|
||||
float horizontalSizeFactor = MathHelper.Lerp(0.5f, 1.0f, MathUtils.InverseLerp(minSize.X, sufficentSize.X, hull.Rect.Width));
|
||||
float verticalSizeFactor = MathHelper.Lerp(0.5f, 1.0f, MathUtils.InverseLerp(minSize.Y, sufficentSize.Y, hull.Rect.Height));
|
||||
float weight = verticalSizeFactor * horizontalSizeFactor * distanceFactor;
|
||||
if (hull.GetLinkedEntities<Hull>().Any())
|
||||
{
|
||||
// Ignore hulls that have any linked hulls to keep the calculations simple.
|
||||
continue;
|
||||
}
|
||||
else if (hull.ConnectedGaps.Any(g => g.Open > 0 && (!g.IsRoomToRoom || g.Position.Y < hull.Position.Y)))
|
||||
{
|
||||
// Ignore hulls that have open gaps to outside or below the center point, because we'll want the room to be full of water and not be accessible without breaking the wall.
|
||||
continue;
|
||||
}
|
||||
else if (thalamusItems.Any(i => i.CurrentHull == hull))
|
||||
{
|
||||
// Don't create the brain in a room that already has thalamus items inside it.
|
||||
continue;
|
||||
}
|
||||
else if (hull.Rect.Width < minSize.X || hull.Rect.Height < minSize.Y)
|
||||
{
|
||||
// Don't select too small rooms.
|
||||
continue;
|
||||
}
|
||||
if (weight > 0)
|
||||
{
|
||||
potentialBrainHulls.TryAdd(hull, weight);
|
||||
}
|
||||
}
|
||||
Hull brainHull = ToolBox.SelectWeightedRandom(potentialBrainHulls.Keys.ToList(), potentialBrainHulls.Values.ToList(), Rand.RandSync.Server);
|
||||
var thalamusStructurePrefabs = StructurePrefab.Prefabs.Where(p => IsThalamus(p));
|
||||
if (brainHull == null) { return; }
|
||||
if (brainHull == null)
|
||||
{
|
||||
DebugConsole.AddWarning("Wreck AI: Cannot find a proper room for the brain. Using a random room.");
|
||||
brainHull = hulls.GetRandom(Rand.RandSync.Server);
|
||||
}
|
||||
if (brainHull == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Wreck AI: Cannot find any room for the brain! Failed to create the Thalamus.");
|
||||
return;
|
||||
}
|
||||
brainHull.WaterVolume = brainHull.Volume;
|
||||
brain.SetTransform(brainHull.SimPosition, rotation: 0, findNewHull: false);
|
||||
brain.CurrentHull = brainHull;
|
||||
@@ -158,11 +187,12 @@ namespace Barotrauma
|
||||
if (!spawnOrgans.Contains(item))
|
||||
{
|
||||
spawnOrgans.Add(item);
|
||||
// Try to flood the hull so that the spawner won't die.
|
||||
item.CurrentHull.WaterVolume = item.CurrentHull.Volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
wayPoints.AddRange(Wreck.GetWaypoints(false));
|
||||
hulls.AddRange(Wreck.GetHulls(false));
|
||||
IsAlive = true;
|
||||
thalamusStructures = GetThalamusEntities<Structure>(Wreck, Config.Entity).ToList();
|
||||
}
|
||||
@@ -307,9 +337,16 @@ namespace Barotrauma
|
||||
|
||||
public static void RemoveThalamusItems(Submarine wreck)
|
||||
{
|
||||
List<MapEntity> thalamusItems = new List<MapEntity>();
|
||||
foreach (var wreckAiConfig in WreckAIConfig.List)
|
||||
{
|
||||
GetThalamusEntities(wreck, wreckAiConfig.Entity).ForEachMod(e => e.Remove());
|
||||
thalamusItems.AddRange(GetThalamusEntities(wreck, wreckAiConfig.Entity));
|
||||
}
|
||||
thalamusItems = thalamusItems.Distinct().ToList();
|
||||
foreach (MapEntity thalamusItem in thalamusItems)
|
||||
{
|
||||
thalamusItem.Remove();
|
||||
wreck.PhysicsBody.FarseerBody.FixtureList.Where(f => f.UserData == thalamusItem).ForEachMod(f => wreck.PhysicsBody.FarseerBody.Remove(f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,15 +360,16 @@ namespace Barotrauma
|
||||
private int MaxCellsPerRoom => CalculateCellCount(1, Config.MaxAgentsPerRoom);
|
||||
private int MinCellsOutside => CalculateCellCount(0, Config.MinAgentsOutside);
|
||||
private int MaxCellsOutside => CalculateCellCount(0, Config.MaxAgentsOutside);
|
||||
private int MinCellsInside => CalculateCellCount(2, Config.MinAgentsInside);
|
||||
private int MaxCellsInside => CalculateCellCount(3, Config.MaxAgentsInside);
|
||||
private int MinCellsInside => CalculateCellCount(3, Config.MinAgentsInside);
|
||||
private int MaxCellsInside => CalculateCellCount(5, Config.MaxAgentsInside);
|
||||
private int MaxCellCount => CalculateCellCount(5, Config.MaxAgentCount);
|
||||
private float MinWaterLevel => Config.MinWaterLevel;
|
||||
|
||||
private int CalculateCellCount(int minValue, int maxValue)
|
||||
{
|
||||
if (maxValue == 0) { return 0; }
|
||||
return (int)Math.Round(MathHelper.Lerp(minValue, maxValue, Level.Loaded.Difficulty * 0.01f * Config.AgentSpawnCountDifficultyMultiplier));
|
||||
float t = MathUtils.InverseLerp(0, 100, Level.Loaded.Difficulty * Config.AgentSpawnCountDifficultyMultiplier);
|
||||
return (int)Math.Round(MathHelper.Lerp(minValue, maxValue, t));
|
||||
}
|
||||
|
||||
private float GetSpawnTime()
|
||||
|
||||
Reference in New Issue
Block a user