(89fea1963) Refactoring and fixing: - Remove relatively expensive HasAccessToPath calls. - Fix finding diving gear subobjective of goto main objective not checking if we need the gear. - Move the abandon checks from CanBeCompleted property under Act method and use the inherited property. Fixes incorrect results when the goto objective is not the active objective. - Improve the support for concurrent sub objectives.

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:38:02 +03:00
parent 96eb27140e
commit 4695e6f92b
16 changed files with 290 additions and 297 deletions
@@ -80,7 +80,7 @@ namespace Barotrauma
}
else if (needsDivingGear)
{
needsEquipment = !HumanAIController.HasDivingGear(character);
needsEquipment = !HumanAIController.HasDivingMask(character);
}
if (needsEquipment)
{
@@ -601,6 +601,49 @@ namespace Barotrauma
{
character.AIController.SteeringManager.Reset();
}
if (goToObjective != null) { return; }
if (currentHull == null) { return; }
//goto objective doesn't exist (a safe hull not found, or a path to a safe hull not found)
// -> attempt to manually steer away from hazards
Vector2 escapeVel = Vector2.Zero;
foreach (FireSource fireSource in currentHull.FireSources)
{
Vector2 dir = character.Position - fireSource.Position;
float distMultiplier = MathHelper.Clamp(100.0f / Vector2.Distance(fireSource.Position, character.Position), 0.1f, 10.0f);
escapeVel += new Vector2(Math.Sign(dir.X) * distMultiplier, !character.IsClimbing ? 0 : Math.Sign(dir.Y) * distMultiplier);
}
foreach (Character enemy in Character.CharacterList)
{
//don't run from friendly NPCs
if (enemy.TeamID == Character.TeamType.FriendlyNPC) { continue; }
//friendly NPCs don't run away from anything but characters controlled by EnemyAIController (= monsters)
if (character.TeamID == Character.TeamType.FriendlyNPC && !(enemy.AIController is EnemyAIController)) { continue; }
if (enemy.CurrentHull == currentHull && !enemy.IsDead && !enemy.IsUnconscious &&
(enemy.AIController is EnemyAIController || enemy.TeamID != character.TeamID))
{
Vector2 dir = character.Position - enemy.Position;
float distMultiplier = MathHelper.Clamp(100.0f / Vector2.Distance(enemy.Position, character.Position), 0.1f, 10.0f);
escapeVel += new Vector2(Math.Sign(dir.X) * distMultiplier, !character.IsClimbing ? 0 : Math.Sign(dir.Y) * distMultiplier);
}
}
if (escapeVel != Vector2.Zero)
{
//only move if we haven't reached the edge of the room
if ((escapeVel.X < 0 && character.Position.X > currentHull.Rect.X + 50) ||
(escapeVel.X > 0 && character.Position.X < currentHull.Rect.Right - 50))
{
character.AIController.SteeringManager.SteeringManual(deltaTime, escapeVel);
}
else
{
character.AnimController.TargetDir = escapeVel.X < 0.0f ? Direction.Right : Direction.Left;
character.AIController.SteeringManager.Reset();
}
}
else
{
character.AIController.SteeringManager.Reset();
}
}
}
@@ -634,7 +677,6 @@ namespace Barotrauma
unreachable.Add(hull);
continue;
}
if (!PathSteering.HasAccessToPath(path)) { continue; }
int unsafeNodes = path.Nodes.Count(n => n.CurrentHull != character.CurrentHull && HumanAIController.UnsafeHulls.Contains(n.CurrentHull));
hullSafety /= 1 + unsafeNodes;
// If the target is not inside a friendly submarine, considerably reduce the hull safety.