Human AI improvements, minor UI tweaking

This commit is contained in:
Regalis
2015-11-25 16:04:51 +02:00
parent c456fa3c90
commit 4b5126675c
42 changed files with 687 additions and 321 deletions
@@ -8,14 +8,14 @@ using Barotrauma.Items.Components;
namespace Barotrauma
{
class PathSteeringManager : SteeringManager
class IndoorsSteeringManager : SteeringManager
{
private PathFinder pathFinder;
private SteeringPath currentPath;
private Character character;
private bool canOpenDoors;
private List<Controller> openableButtons;
private Character character;
public SteeringPath CurrentPath
{
@@ -31,15 +31,15 @@ namespace Barotrauma
private float findPathTimer;
public PathSteeringManager(ISteerable host)
public IndoorsSteeringManager(ISteerable host, bool canOpenDoors)
: base(host)
{
pathFinder = new PathFinder(WayPoint.WayPointList.FindAll(wp => wp.SpawnType == SpawnType.Path), true);
pathFinder.GetNodePriority = GetNodePriority;
pathFinder.GetNodePenalty = GetNodePenalty;
this.canOpenDoors = canOpenDoors;
character = (host as AIController).Character;
openableButtons = new List<Controller>();
}
public override void Update(float speed = 1)
@@ -53,37 +53,22 @@ namespace Barotrauma
protected override Vector2 DoSteeringSeek(Vector2 target, float speed = 1)
{
//find a new path if one hasn't been found yet or the target is different from the current target
if (currentPath == null || Vector2.DistanceSquared(target, currentTarget)>10.0f)
if (currentPath == null || Vector2.Distance(target, currentTarget)>1.0f || findPathTimer < -10.0f)
{
if (findPathTimer > 0.0f) return Vector2.Zero;
currentTarget = target;
currentPath = pathFinder.FindPath(host.SimPosition, ConvertUnits.ToSimUnits(target));
currentPath = pathFinder.FindPath(host.SimPosition, target);
findPathTimer = 1.0f;
return DiffToCurrentNode();
}
//if (pathSteering == null || pathSteering.CurrentPath == null || pathSteering.CurrentPath.CurrentNode == null) return;
//if (currentPath.CurrentNode.ConnectedGap != null && currentPath.CurrentNode.ConnectedGap.Open < 0.9f)
//{
foreach (Controller controller in openableButtons)
{
if (Vector2.Distance(controller.Item.SimPosition, character.SimPosition) > controller.Item.PickDistance) continue;
controller.Item.Pick(character, false, true);
}
//}
Vector2 diff = DiffToCurrentNode();
if (diff == Vector2.Zero) return -host.Steering;
return (diff == Vector2.Zero) ? Vector2.Zero : Vector2.Normalize(diff)*speed;
}
@@ -91,61 +76,77 @@ namespace Barotrauma
{
if (currentPath == null) return Vector2.Zero;
currentPath.CheckProgress(host.SimPosition, 0.45f);
if (canOpenDoors) CheckDoorsInPath();
currentPath.CheckProgress(host.SimPosition, character.AnimController.InWater ? 1.0f : 0.6f);
if (currentPath.CurrentNode == null) return Vector2.Zero;
return currentPath.CurrentNode.SimPosition - host.SimPosition;
}
private float GetNodePriority(PathNode node, PathNode nextNode)
private void CheckDoorsInPath()
{
if (character==null) return 0.0f;
if (nextNode.Waypoint.ConnectedGap!=null)
for (int i = 0; i < 2; i++)
{
WayPoint node = i == 0 ? currentPath.CurrentNode : currentPath.PrevNode;
if (node == null || node.ConnectedGap == null || node.ConnectedGap.ConnectedDoor == null) continue;
var door = node.ConnectedGap.ConnectedDoor;
bool open = currentPath.CurrentNode != null &&
Math.Sign(door.Item.SimPosition.X - host.SimPosition.X) == Math.Sign(currentPath.CurrentNode.SimPosition.X - host.SimPosition.X);
//toggle the door if it's the previous node and open, or if it's current node and closed
if (door.IsOpen != open)
{
var buttons = door.GetButtons();
foreach (Controller controller in buttons)
{
if (Vector2.Distance(controller.Item.SimPosition, character.SimPosition) > controller.Item.PickDistance * 2.0f) continue;
controller.Item.Pick(character, false, true);
break;
}
}
}
}
private float? GetNodePenalty(PathNode node, PathNode nextNode)
{
if (character == null) return 0.0f;
if (nextNode.Waypoint.ConnectedGap != null)
{
if (nextNode.Waypoint.ConnectedGap.Open > 0.9f) return 0.0f;
if (nextNode.Waypoint.ConnectedGap.ConnectedDoor == null) return 100.0f;
var doorButtons = GetDoorButtons(nextNode.Waypoint.ConnectedGap.ConnectedDoor);
if (!canOpenDoors) return null;
var doorButtons = nextNode.Waypoint.ConnectedGap.ConnectedDoor.GetButtons();
foreach (Controller button in doorButtons)
{
if (Math.Sign(button.Item.Position.X - nextNode.Waypoint.Position.X) !=
Math.Sign(node.Position.X - nextNode.Position.X)) continue;
if (!button.HasRequiredItems(character, false)) return 1000.0f;
if (!button.HasRequiredItems(character, false)) return null;
}
}
if (node.Waypoint!=null && node.Waypoint.CurrentHull!=null)
{
var hull = node.Waypoint.CurrentHull;
float penalty = hull.FireSources.Any() ? 1000.0f : 0.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;
}
private List<Controller> GetDoorButtons(Door door)
{
if (door == null) return new List<Controller>();
ConnectionPanel connectionPanel = door.Item.GetComponent<ConnectionPanel>();
List<Controller> doorButtons = new List<Controller>();
foreach (Connection c in connectionPanel.Connections)
{
foreach (Wire w in c.Wires)
{
if (w == null) continue;
var otherConnection = w.OtherConnection(c);
if (otherConnection.Item == door.Item || otherConnection == null) continue;
var controller = otherConnection.Item.GetComponent<Controller>();
if (controller != null)
{
doorButtons.Add(controller);
if (!openableButtons.Contains(controller)) openableButtons.Add(controller);
}
}
}
return doorButtons;
}
}
}