Crawlers and mantises can attach to ice walls when idling

This commit is contained in:
Joonas Rikkonen
2017-06-22 20:05:19 +03:00
parent 397e6a5a97
commit 03670d735d
3 changed files with 106 additions and 56 deletions
@@ -16,6 +16,7 @@
sight="0.5" sight="0.5"
hearing="1.0" hearing="1.0"
fleehealththreshold="10" fleehealththreshold="10"
attachtowalls="true"
attackcooldown="3.0"/> attackcooldown="3.0"/>
<ragdoll headposition="50" headangle="-70" <ragdoll headposition="50" headangle="-70"
@@ -18,6 +18,7 @@
attackcooldown="1.0" attackcooldown="1.0"
sight="0.5" sight="0.5"
hearing="1.0" hearing="1.0"
attachtowalls="true"
fleehealththreshold="20"/> fleehealththreshold="20"/>
<ragdoll headposition="120" headangle="-90" <ragdoll headposition="120" headangle="-90"
@@ -23,6 +23,7 @@ namespace Barotrauma
//negative values = escapes targets of this type //negative values = escapes targets of this type
private float attackRooms, attackHumans, attackWeaker, attackStronger, eatDeadPriority; private float attackRooms, attackHumans, attackWeaker, attackStronger, eatDeadPriority;
//determines which characters are considered weaker/stronger
private float combatStrength; private float combatStrength;
private SteeringManager outsideSteering, insideSteering; private SteeringManager outsideSteering, insideSteering;
@@ -30,14 +31,12 @@ namespace Barotrauma
private float updateTargetsTimer; private float updateTargetsTimer;
private float raycastTimer; private float raycastTimer;
//a timer for attacks such as biting that last for a specific amount of time
//the duration is determined by the attackDuration of the attacking limb
private float attackTimer;
//a "cooldown time" after an attack during which the Character doesn't try to attack again //a "cooldown time" after an attack during which the Character doesn't try to attack again
private float attackCoolDown; private float attackCoolDown;
private float coolDownTimer; private float coolDownTimer;
private bool attachToWalls;
//a point in a wall which the Character is currently targeting //a point in a wall which the Character is currently targeting
private Vector2 wallAttackPos; private Vector2 wallAttackPos;
@@ -95,6 +94,8 @@ namespace Barotrauma
fleeHealthThreshold = ToolBox.GetAttributeFloat(aiElement, "fleehealththreshold", 0.0f); fleeHealthThreshold = ToolBox.GetAttributeFloat(aiElement, "fleehealththreshold", 0.0f);
attachToWalls = ToolBox.GetAttributeBool(aiElement, "attachtowalls", false);
outsideSteering = new SteeringManager(this); outsideSteering = new SteeringManager(this);
insideSteering = new IndoorsSteeringManager(this, false); insideSteering = new IndoorsSteeringManager(this, false);
@@ -199,25 +200,84 @@ namespace Barotrauma
} }
} }
#region Idle
private void UpdateNone(float deltaTime) private void UpdateNone(float deltaTime)
{ {
//wander around randomly attackingLimb = null;
if (Character.Submarine==null && SimPosition.Y < ConvertUnits.ToSimUnits(SubmarineBody.DamageDepth*0.5f)) coolDownTimer -= deltaTime;
if (Character.Submarine == null && SimPosition.Y < ConvertUnits.ToSimUnits(SubmarineBody.DamageDepth * 0.5f))
{ {
//steer straight up if very deep
steeringManager.SteeringManual(deltaTime, Vector2.UnitY); steeringManager.SteeringManual(deltaTime, Vector2.UnitY);
return;
}
if (attachToWalls && Character.Submarine == null)
{
raycastTimer -= deltaTime;
//check if there are any walls nearby the character could attach to
if (raycastTimer < 1.0f)
{
wallAttackPos = Vector2.Zero;
var cells = Level.Loaded.GetCells(WorldPosition, 1);
if (cells.Count > 0)
{
Body closestBody = Submarine.CheckVisibility(Character.SimPosition, ConvertUnits.ToSimUnits(cells[0].Center));
if (closestBody != null && closestBody.UserData is Voronoi2.VoronoiCell)
{
wallAttackPos = Submarine.LastPickedPosition;
}
}
raycastTimer = RaycastInterval;
}
} }
else else
{ {
steeringManager.SteeringAvoid(deltaTime, 0.1f); wallAttackPos = Vector2.Zero;
steeringManager.SteeringWander(0.5f);
} }
attackingLimb = null; if (wallAttackPos == Vector2.Zero)
attackTimer = 0.0f; {
//wander around randomly
steeringManager.SteeringAvoid(deltaTime, 0.1f);
steeringManager.SteeringWander(0.5f);
return;
}
coolDownTimer -= deltaTime; float dist = Vector2.Distance(SimPosition, wallAttackPos);
if (dist < Math.Max(Math.Max(Character.AnimController.Collider.radius, Character.AnimController.Collider.width), Character.AnimController.Collider.height) * 1.2f)
{
//close enough to a wall -> attach
Character.AnimController.Collider.MoveToPos(wallAttackPos, 1.0f);
steeringManager.Reset();
}
else
{
//move closer to the wall
steeringManager.SteeringAvoid(deltaTime, 0.1f);
steeringManager.SteeringSeek(wallAttackPos);
}
} }
#endregion
#region Escape
private void UpdateEscape(float deltaTime)
{
SteeringManager.SteeringManual(deltaTime, Vector2.Normalize(SimPosition - selectedAiTarget.SimPosition) * 5);
SteeringManager.SteeringWander(1.0f);
SteeringManager.SteeringAvoid(deltaTime, 2f);
}
#endregion
#region Attack
private void UpdateAttack(float deltaTime) private void UpdateAttack(float deltaTime)
{ {
if (selectedAiTarget == null || selectedAiTarget.Entity == null || selectedAiTarget.Entity.Removed) if (selectedAiTarget == null || selectedAiTarget.Entity == null || selectedAiTarget.Entity.Removed)
@@ -250,7 +310,7 @@ namespace Barotrauma
} }
} }
} }
if (Math.Abs(Character.AnimController.movement.X) > 0.1f && !Character.AnimController.InWater) if (Math.Abs(Character.AnimController.movement.X) > 0.1f && !Character.AnimController.InWater)
{ {
Character.AnimController.TargetDir = Character.SimPosition.X < attackSimPosition.X ? Direction.Right : Direction.Left; Character.AnimController.TargetDir = Character.SimPosition.X < attackSimPosition.X ? Direction.Right : Direction.Left;
@@ -281,13 +341,13 @@ namespace Barotrauma
{ {
foreach (Limb limb in Character.AnimController.Limbs) foreach (Limb limb in Character.AnimController.Limbs)
{ {
if (limb.attack==null) continue; if (limb.attack == null) continue;
attackLimb = limb; attackLimb = limb;
if (ConvertUnits.ToDisplayUnits(Vector2.Distance(limb.SimPosition, attackSimPosition)) > limb.attack.Range) continue; if (ConvertUnits.ToDisplayUnits(Vector2.Distance(limb.SimPosition, attackSimPosition)) > limb.attack.Range) continue;
attackingLimb = limb; attackingLimb = limb;
break; break;
} }
if (Character.IsRemotePlayer) if (Character.IsRemotePlayer)
@@ -302,37 +362,14 @@ namespace Barotrauma
if (steeringManager is IndoorsSteeringManager) if (steeringManager is IndoorsSteeringManager)
{ {
var indoorsSteering = (IndoorsSteeringManager)steeringManager; var indoorsSteering = (IndoorsSteeringManager)steeringManager;
if (indoorsSteering.CurrentPath!=null && (indoorsSteering.CurrentPath.Finished || indoorsSteering.CurrentPath.Unreachable)) if (indoorsSteering.CurrentPath != null && (indoorsSteering.CurrentPath.Finished || indoorsSteering.CurrentPath.Unreachable))
{ {
steeringManager.SteeringManual(deltaTime, attackSimPosition - attackLimb.SimPosition); steeringManager.SteeringManual(deltaTime, attackSimPosition - attackLimb.SimPosition);
} }
} }
if (attackingLimb != null) UpdateLimbAttack(deltaTime, attackingLimb, attackSimPosition); if (attackingLimb != null) UpdateLimbAttack(deltaTime, attackingLimb, attackSimPosition);
}
}
private void UpdateEscape(float deltaTime)
{
SteeringManager.SteeringManual(deltaTime, Vector2.Normalize(SimPosition - selectedAiTarget.SimPosition) * 5);
SteeringManager.SteeringWander(1.0f);
SteeringManager.SteeringAvoid(deltaTime, 2f);
}
private void UpdateCoolDown(Vector2 attackPosition, float deltaTime)
{
coolDownTimer -= deltaTime;
attackingLimb = null;
float dist = Vector2.Distance(attackPosition, Character.SimPosition);
if (dist < ConvertUnits.ToSimUnits(500.0f))
{
steeringManager.SteeringSeek(attackPosition, -0.8f);
steeringManager.SteeringManual(deltaTime, Vector2.Normalize(Character.SimPosition - attackPosition) * (1.0f - (dist / 500.0f)));
} }
steeringManager.SteeringAvoid(deltaTime, 1.0f);
} }
private void GetTargetEntity() private void GetTargetEntity()
@@ -424,6 +461,26 @@ namespace Barotrauma
} }
} }
private void UpdateCoolDown(Vector2 attackPosition, float deltaTime)
{
coolDownTimer -= deltaTime;
attackingLimb = null;
float dist = Vector2.Distance(attackPosition, Character.SimPosition);
if (dist < ConvertUnits.ToSimUnits(500.0f))
{
steeringManager.SteeringSeek(attackPosition, -0.8f);
steeringManager.SteeringManual(deltaTime, Vector2.Normalize(Character.SimPosition - attackPosition) * (1.0f - (dist / 500.0f)));
}
steeringManager.SteeringAvoid(deltaTime, 1.0f);
}
#endregion
#region Eat
private void UpdateEating(float deltaTime) private void UpdateEating(float deltaTime)
{ {
if (selectedAiTarget == null || selectedAiTarget.Entity == null || selectedAiTarget.Entity.Removed) if (selectedAiTarget == null || selectedAiTarget.Entity == null || selectedAiTarget.Entity.Removed)
@@ -505,6 +562,10 @@ namespace Barotrauma
} }
} }
#endregion
#region Targeting
//goes through all the AItargets, evaluates how preferable it is to attack the target, //goes through all the AItargets, evaluates how preferable it is to attack the target,
//whether the Character can see/hear the target and chooses the most preferable target within //whether the Character can see/hear the target and chooses the most preferable target within
//sight/hearing range //sight/hearing range
@@ -603,21 +664,6 @@ namespace Barotrauma
Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd); Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd);
Structure closestStructure = (closestBody == null) ? null : closestBody.UserData as Structure; Structure closestStructure = (closestBody == null) ? null : closestBody.UserData as Structure;
/* float targetStrength = 0.0f;
if (targetDamageable != null)
{
targetStrength = targetDamageable.Health;
}
else if (closestStructure!=null)
{
targetStrength = ((IDamageable)closestStructure).Health;
}
else
{
targetStrength = 1000.0f;
}*/
;
if (selectedAiTarget == null || Math.Abs(valueModifier) > Math.Abs(targetValue)) if (selectedAiTarget == null || Math.Abs(valueModifier) > Math.Abs(targetValue))
{ {
@@ -669,6 +715,8 @@ namespace Barotrauma
} }
} }
#endregion
public override void DebugDraw(SpriteBatch spriteBatch) public override void DebugDraw(SpriteBatch spriteBatch)
{ {
if (Character.IsDead) return; if (Character.IsDead) return;