(5c32d30a9) Adjust and fix the steering behavior: Only the characters in the idle state and outside the sub are considered active members of the group.

This commit is contained in:
Joonas Rikkonen
2019-04-29 21:09:18 +03:00
parent e583f570ff
commit 250368078f
3 changed files with 42 additions and 11 deletions
@@ -373,6 +373,12 @@ namespace Barotrauma
LatchOntoAI?.Update(this, deltaTime); LatchOntoAI?.Update(this, deltaTime);
IsSteeringThroughGap = false; IsSteeringThroughGap = false;
if (SwarmBehavior != null)
{
SwarmBehavior.IsActive = State == AIState.Idle && Character.CurrentHull == null;
SwarmBehavior.Refresh();
SwarmBehavior.UpdateSteering(deltaTime);
}
steeringManager.Update(Character.AnimController.GetCurrentSpeed(run)); steeringManager.Update(Character.AnimController.GetCurrentSpeed(run));
} }
@@ -793,6 +799,7 @@ namespace Barotrauma
{ {
UpdateLimbAttack(deltaTime, AttackingLimb, attackSimPos, distance); UpdateLimbAttack(deltaTime, AttackingLimb, attackSimPos, distance);
} }
return false;
} }
public bool IsSteeringThroughGap { get; private set; } public bool IsSteeringThroughGap { get; private set; }
@@ -14,11 +14,16 @@ namespace Barotrauma
private float maxDistFromCenter; private float maxDistFromCenter;
private float cohesion; private float cohesion;
private List<AICharacter> members = new List<AICharacter>(); public List<AICharacter> Members { get; private set; } = new List<AICharacter>();
public HashSet<AICharacter> ActiveMembers { get; private set; } = new HashSet<AICharacter>();
private AIController ai; private EnemyAIController ai;
public SwarmBehavior(XElement element, AIController ai) public bool IsActive { get; set; }
public bool IsEnoughMembers => ActiveMembers.Count > 1;
public SwarmBehavior(XElement element, EnemyAIController ai)
{ {
this.ai = ai; this.ai = ai;
minDistFromClosest = ConvertUnits.ToSimUnits(element.GetAttributeFloat("mindistfromclosest", 10.0f)); minDistFromClosest = ConvertUnits.ToSimUnits(element.GetAttributeFloat("mindistfromclosest", 10.0f));
@@ -32,21 +37,36 @@ namespace Barotrauma
{ {
if (character.AIController is EnemyAIController enemyAI && enemyAI.SwarmBehavior != null) if (character.AIController is EnemyAIController enemyAI && enemyAI.SwarmBehavior != null)
{ {
enemyAI.SwarmBehavior.members = swarm.ToList(); enemyAI.SwarmBehavior.Members = swarm.ToList();
} }
} }
} }
public void Update(float deltaTime) public void Refresh()
{ {
members.RemoveAll(m => m.IsDead || m.Removed); Members.RemoveAll(m => m.IsDead || m.Removed);
if (members.Count < 2) { return; } foreach (var member in Members)
{
if (!member.AIController.Enabled && member.IsRemotePlayer || Character.Controlled == member || !((EnemyAIController)member.AIController).SwarmBehavior.IsActive)
{
ActiveMembers.Remove(member);
}
else
{
ActiveMembers.Add(member);
}
}
}
public void UpdateSteering(float deltaTime)
{
if (!IsActive) { return; }
if (!IsEnoughMembers) { return; }
//calculate the "center of mass" of the swarm and the distance to the closest character in the swarm //calculate the "center of mass" of the swarm and the distance to the closest character in the swarm
float closestDistSqr = float.MaxValue; float closestDistSqr = float.MaxValue;
Vector2 center = Vector2.Zero; Vector2 center = Vector2.Zero;
AICharacter closest = null; AICharacter closest = null;
foreach (AICharacter member in members) foreach (AICharacter member in Members)
{ {
center += member.SimPosition; center += member.SimPosition;
if (member == ai.Character) { continue; } if (member == ai.Character) { continue; }
@@ -57,7 +77,7 @@ namespace Barotrauma
closest = member; closest = member;
} }
} }
center /= members.Count; center /= Members.Count;
if (closest == null) { return; } if (closest == null) { return; }
@@ -83,11 +103,11 @@ namespace Barotrauma
if (cohesion > 0.0f) if (cohesion > 0.0f)
{ {
Vector2 avgVel = Vector2.Zero; Vector2 avgVel = Vector2.Zero;
foreach (AICharacter member in members) foreach (AICharacter member in Members)
{ {
avgVel += member.AnimController.TargetMovement; avgVel += member.AnimController.TargetMovement;
} }
avgVel /= members.Count; avgVel /= Members.Count;
ai.SteeringManager.SteeringManual(deltaTime, avgVel * cohesion); ai.SteeringManager.SteeringManual(deltaTime, avgVel * cohesion);
} }
} }
@@ -2563,6 +2563,10 @@ namespace Barotrauma
GameMain.GameSession?.CrewManager?.RemoveCharacter(this); GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif #endif
#if CLIENT
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif
#if CLIENT #if CLIENT
GameMain.GameSession?.CrewManager?.RemoveCharacter(this); GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif #endif