From 93940ff5a83e7dd9b080cf60a123b01023a444a6 Mon Sep 17 00:00:00 2001 From: Regalis Date: Sat, 20 May 2017 17:11:33 +0300 Subject: [PATCH] - AI crew can avoid firesources in nearby hulls, not just the one they're currently inside - fixed fires, oxygen and water level not being taken into account in path cost calculations - particle collision fix --- .../Characters/AI/IndoorsSteeringManager.cs | 25 ++++++++----- .../AI/Objectives/AIObjectiveFindSafety.cs | 35 +++++++++++++++++-- Subsurface/Source/Map/FireSource.cs | 16 ++++----- Subsurface/Source/Map/Hull.cs | 31 ++++++++++++++-- Subsurface/Source/Particles/Particle.cs | 1 + 5 files changed, 86 insertions(+), 22 deletions(-) diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs index 462a7e617..b446539ad 100644 --- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs +++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs @@ -192,8 +192,6 @@ namespace Barotrauma { for (int i = 0; i < 2; i++) { - - WayPoint node = null; WayPoint nextNode = null; @@ -268,11 +266,16 @@ namespace Barotrauma private float? GetNodePenalty(PathNode node, PathNode nextNode) { if (character == null) return 0.0f; - if (nextNode.Waypoint.ConnectedGap != null) + + float penalty = 0.0f; + if (nextNode.Waypoint.ConnectedGap != null && nextNode.Waypoint.ConnectedGap.Open < 0.9f) { - if (nextNode.Waypoint.ConnectedGap.Open > 0.9f) return 0.0f; - if (nextNode.Waypoint.ConnectedGap.ConnectedDoor == null) return 100.0f; + if (nextNode.Waypoint.ConnectedGap.ConnectedDoor == null) + { + penalty = 100.0f; + } + //door closed and the character can't open doors -> node can't be traversed if (!canOpenDoors || character.LockHands) return null; var doorButtons = nextNode.Waypoint.ConnectedGap.ConnectedDoor.Item.GetConnectedComponents(); @@ -291,16 +294,20 @@ namespace Barotrauma { var hull = node.Waypoint.CurrentHull; - float penalty = hull.FireSources.Any() ? 1000.0f : 0.0f; + if (hull.FireSources.Count > 0) + { + foreach (FireSource fs in hull.FireSources) + { + penalty += fs.Size.X * 10.0f; + } + } if (character.NeedsAir && hull.Volume / hull.Rect.Width > 100.0f) penalty += 500.0f; if (character.PressureProtection < 10.0f && hull.Volume > hull.FullVolume) penalty += 1000.0f; } - return 0.0f; + return penalty; } - - } } diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs index ec5e0d3d5..5c845dd78 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs @@ -155,6 +155,23 @@ namespace Barotrauma currenthullSafety = GetHullSafety(character.AnimController.CurrentHull, character); priority = 100.0f - currenthullSafety; + var nearbyHulls = character.AnimController.CurrentHull.GetConnectedHulls(3); + + foreach (Hull hull in nearbyHulls) + { + foreach (FireSource fireSource in hull.FireSources) + { + //increase priority if almost within damage range of a fire + if (character.Position.X > fireSource.Position.X - fireSource.DamageRange * 2 && + character.Position.X < fireSource.Position.X + fireSource.Size.X + fireSource.DamageRange * 2 && + character.Position.Y > hull.Rect.Y - hull.Rect.Height && + character.Position.Y < hull.Rect.Y) + { + priority += Math.Max(fireSource.Size.X, 50.0f); + } + } + } + if (NeedsDivingGear()) { @@ -164,16 +181,28 @@ namespace Barotrauma return priority; } - public static float GetHullSafety(Hull hull, Character character) + private static float GetHullSafety(Hull hull, Character character) { if (hull == null) return 0.0f; float waterPercentage = (hull.Volume / hull.FullVolume) * 100.0f; float fireAmount = 0.0f; - foreach (FireSource fireSource in hull.FireSources) + var nearbyHulls = character.AnimController.CurrentHull.GetConnectedHulls(3); + + foreach (Hull hull2 in nearbyHulls) { - fireAmount += Math.Max(fireSource.Size.X, 50.0f); + foreach (FireSource fireSource in hull2.FireSources) + { + //increase priority if almost within damage range of a fire + if (character.Position.X > fireSource.Position.X - fireSource.DamageRange * 2 && + character.Position.X < fireSource.Position.X + fireSource.Size.X + fireSource.DamageRange * 2 && + character.Position.Y > hull2.Rect.Y - hull2.Rect.Height && + character.Position.Y < hull2.Rect.Y) + { + fireAmount += Math.Max(fireSource.Size.X, 50.0f); + } + } } float safety = 100.0f - fireAmount; diff --git a/Subsurface/Source/Map/FireSource.cs b/Subsurface/Source/Map/FireSource.cs index 2401d8493..c0a67531d 100644 --- a/Subsurface/Source/Map/FireSource.cs +++ b/Subsurface/Source/Map/FireSource.cs @@ -56,6 +56,11 @@ namespace Barotrauma } } + public float DamageRange + { + get { return (float)Math.Sqrt(size.X) * 20.0f; } + } + public Hull Hull { get { return hull; } @@ -125,12 +130,7 @@ namespace Barotrauma } } } - - public bool Contains(Vector2 pos) - { - return pos.X > position.X && pos.X fireSource.position.X + fireSource.size.X || @@ -251,7 +251,7 @@ namespace Barotrauma Character c = Character.CharacterList[i]; if (c.AnimController.CurrentHull == null || c.IsDead) continue; - float range = (float)Math.Sqrt(size.X) * 20.0f; + float range = DamageRange; if (c.Position.X < position.X - range || c.Position.X > position.X + size.X + range) continue; if (c.Position.Y < position.Y - size.Y || c.Position.Y > hull.Rect.Y) continue; @@ -260,7 +260,7 @@ namespace Barotrauma { if (limb.WearingItems.Find(w => w != null && w.WearableComponent.Item.FireProof) != null) continue; limb.Burnt += dmg * 10.0f; - c.AddDamage(limb.SimPosition, DamageType.None, dmg, 0, 0, false); + c.AddDamage(limb.SimPosition, DamageType.Burn, dmg, 0, 0, false); } } } diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index 94cbdec9b..d2e30446a 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -348,6 +348,7 @@ namespace Barotrauma { fireSource.Remove(); } + fireSources.Clear(); if (soundIndex > -1) { @@ -399,7 +400,7 @@ namespace Barotrauma { if (PlayerInput.LeftButtonClicked()) { - new FireSource(position); + new FireSource(position, this); } } } @@ -560,7 +561,6 @@ namespace Barotrauma //pos.Normalize(); item.body.ApplyForce((gap.LerpedFlowForce/distance) * deltaTime); } - } public void Extinquish(float deltaTime, float amount, Vector2 position) @@ -578,6 +578,33 @@ namespace Barotrauma if (GameMain.Server != null) GameMain.Server.CreateEntityEvent(this); } + public List GetConnectedHulls(int? searchDepth) + { + return GetAdjacentHulls(new List(), 0, searchDepth); + + } + + private List GetAdjacentHulls(List connectedHulls, int steps, int? searchDepth) + { + connectedHulls.Add(this); + + if (searchDepth != null && steps >= searchDepth.Value) return connectedHulls; + + foreach (Gap g in ConnectedGaps) + { + for (int i = 0; i < 2 && i < g.linkedTo.Count; i++) + { + Hull hull = g.linkedTo[i] as Hull; + if (hull != null && !connectedHulls.Contains(hull)) + { + hull.GetAdjacentHulls(connectedHulls, steps++, searchDepth); + } + } + } + + return connectedHulls; + } + public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) { //if (back) return; diff --git a/Subsurface/Source/Particles/Particle.cs b/Subsurface/Source/Particles/Particle.cs index 4102288cf..61374da06 100644 --- a/Subsurface/Source/Particles/Particle.cs +++ b/Subsurface/Source/Particles/Particle.cs @@ -252,6 +252,7 @@ namespace Barotrauma.Particles Hull newHull = Hull.FindHull(position); if (newHull != currentHull) { + currentHull = newHull; hullGaps = currentHull == null ? new List() : currentHull.ConnectedGaps; OnChangeHull?.Invoke(position, currentHull); }