Working towards making monsters eat dead characters (WIP)

This commit is contained in:
Joonas Rikkonen
2017-06-19 19:24:59 +03:00
parent 06e23ffe6d
commit aa541695fc
6 changed files with 63 additions and 35 deletions
@@ -6,15 +6,13 @@ namespace Barotrauma
{ {
class AIController : ISteerable class AIController : ISteerable
{ {
public enum AIState { None, Attack, GoTo, Escape, Eat }
public enum AiState { None, Attack, GoTo, Escape }
public enum SteeringState { Wander, Seek, Escape }
public bool Enabled; public bool Enabled;
public readonly Character Character; public readonly Character Character;
protected AiState state; protected AIState state;
protected SteeringManager steeringManager; protected SteeringManager steeringManager;
@@ -44,7 +42,7 @@ namespace Barotrauma
get { return Character.AnimController.Collider.LinearVelocity; } get { return Character.AnimController.Collider.LinearVelocity; }
} }
public AiState State public AIState State
{ {
get { return state; } get { return state; }
set { state = value; } set { state = value; }
@@ -21,7 +21,7 @@ namespace Barotrauma
//0.0 = doesn't attack targets of the type //0.0 = doesn't attack targets of the type
//positive values = attacks targets of this type //positive values = attacks targets of this type
//negative values = escapes targets of this type //negative values = escapes targets of this type
private float attackRooms, attackHumans, attackWeaker, attackStronger; private float attackRooms, attackHumans, attackWeaker, attackStronger, eatDeadPriority;
private float combatStrength; private float combatStrength;
@@ -97,7 +97,7 @@ namespace Barotrauma
steeringManager = outsideSteering; steeringManager = outsideSteering;
state = AiState.None; state = AIState.None;
} }
public override void SelectTarget(AITarget target) public override void SelectTarget(AITarget target)
@@ -145,11 +145,15 @@ namespace Barotrauma
if (selectedAiTarget == null) if (selectedAiTarget == null)
{ {
state = AiState.None; state = AIState.None;
}
else if ((selectedAiTarget.Entity is Character) && ((Character)selectedAiTarget.Entity).IsDead)
{
state = AIState.Eat;
} }
else else
{ {
state = (targetValue < 0.0f || Character.Health < fleeHealthThreshold) ? AiState.Escape : AiState.Attack; state = (targetValue < 0.0f || Character.Health < fleeHealthThreshold) ? AIState.Escape : AIState.Attack;
} }
//if (coolDownTimer >= 0.0f) return; //if (coolDownTimer >= 0.0f) return;
} }
@@ -159,14 +163,17 @@ namespace Barotrauma
bool run = false; bool run = false;
switch (state) switch (state)
{ {
case AiState.None: case AIState.None:
UpdateNone(deltaTime); UpdateNone(deltaTime);
break; break;
case AiState.Attack: case AIState.Attack:
run = coolDownTimer <= 0.0f; run = coolDownTimer <= 0.0f;
UpdateAttack(deltaTime); UpdateAttack(deltaTime);
break; break;
case AiState.Escape: case AIState.Eat:
break;
case AIState.Escape:
run = true; run = true;
UpdateEscape(deltaTime); UpdateEscape(deltaTime);
break; break;
@@ -208,7 +215,7 @@ namespace Barotrauma
{ {
if (selectedAiTarget == null || selectedAiTarget.Entity == null || selectedAiTarget.Entity.Removed) if (selectedAiTarget == null || selectedAiTarget.Entity == null || selectedAiTarget.Entity.Removed)
{ {
state = AiState.None; state = AIState.None;
return; return;
} }
@@ -409,6 +416,21 @@ namespace Barotrauma
coolDownTimer = attackCoolDown; coolDownTimer = attackCoolDown;
} }
} }
private void UpdateEat(float deltaTime)
{
if (selectedAiTarget == null)
{
state = AIState.None;
return;
}
var head = Character.AnimController.GetLimb(LimbType.Head);
if (head == null) head = Character.AnimController.MainLimb;
Vector2 attackSimPosition = Character.Submarine == null ? ConvertUnits.ToSimUnits(selectedAiTarget.WorldPosition) : selectedAiTarget.SimPosition;
steeringManager.SteeringSeek(attackSimPosition - (head.SimPosition - SimPosition), 3);
}
//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
@@ -433,17 +455,20 @@ namespace Barotrauma
float valueModifier = 0.0f; float valueModifier = 0.0f;
float dist = 0.0f; float dist = 0.0f;
IDamageable targetDamageable = target.Entity as IDamageable;
if (targetDamageable!=null && targetDamageable.Health <= 0.0f) continue;
Character targetCharacter = target.Entity as Character; Character targetCharacter = target.Entity as Character;
//ignore the aitarget if it is the Character itself //ignore the aitarget if it is the Character itself
if (targetCharacter == character) continue; if (targetCharacter == character) continue;
if (targetCharacter!=null) if (targetCharacter != null)
{ {
if (targetCharacter.SpeciesName == "human") if (targetCharacter.IsDead)
{
if (eatDeadPriority == 0.0f) continue;
valueModifier = eatDeadPriority;
}
else if (targetCharacter.SpeciesName == "human")
{ {
if (attackHumans == 0.0f) continue; if (attackHumans == 0.0f) continue;
valueModifier = attackHumans; valueModifier = attackHumans;
@@ -470,6 +495,9 @@ namespace Barotrauma
} }
else if (target.Entity!=null && attackRooms != 0.0f) else if (target.Entity!=null && attackRooms != 0.0f)
{ {
IDamageable targetDamageable = target.Entity as IDamageable;
if (targetDamageable != null && targetDamageable.Health <= 0.0f) continue;
//skip the target if it's the room the Character is inside of //skip the target if it's the room the Character is inside of
if (character.AnimController.CurrentHull != null && character.AnimController.CurrentHull == target.Entity as Hull) continue; if (character.AnimController.CurrentHull != null && character.AnimController.CurrentHull == target.Entity as Hull) continue;
+1 -1
View File
@@ -51,7 +51,7 @@ namespace Barotrauma
{ {
switch (aiController.State) switch (aiController.State)
{ {
case AIController.AiState.Attack: case AIController.AIState.Attack:
PlaySound(CharacterSound.SoundType.Attack); PlaySound(CharacterSound.SoundType.Attack);
break; break;
default: default:
+1 -7
View File
@@ -1912,13 +1912,7 @@ namespace Barotrauma
{ {
if (selectedItems[i] != null) selectedItems[i].Drop(this); if (selectedItems[i] != null) selectedItems[i].Drop(this);
} }
if (aiTarget != null)
{
aiTarget.Remove();
aiTarget = null;
}
foreach (Limb limb in AnimController.Limbs) foreach (Limb limb in AnimController.Limbs)
{ {
if (limb.pullJoint == null) continue; if (limb.pullJoint == null) continue;
+16 -8
View File
@@ -70,10 +70,12 @@ namespace Barotrauma
private float damage, burnt; private float damage, burnt;
private bool isSevered;
private readonly Vector2 armorSector; private readonly Vector2 armorSector;
private readonly float armorValue; private readonly float armorValue;
Sound hitSound; private Sound hitSound;
//a timer for delaying when a hitsound/attacksound can be played again //a timer for delaying when a hitsound/attacksound can be played again
public float soundTimer; public float soundTimer;
public const float SoundInterval = 0.4f; public const float SoundInterval = 0.4f;
@@ -90,7 +92,18 @@ namespace Barotrauma
public float AttackTimer; public float AttackTimer;
public bool IsSevered; public bool IsSevered
{
get { return isSevered; }
set
{
isSevered = value;
if (isSevered)
{
damage = 100.0f;
}
}
}
public bool DoesFlip public bool DoesFlip
{ {
@@ -429,12 +442,7 @@ namespace Barotrauma
// SimPosition, Vector2.Zero); // SimPosition, Vector2.Zero);
//} //}
} }
public void ActivateDamagedSprite()
{
damage = 100.0f;
}
public void UpdateAttack(float deltaTime, Vector2 attackPosition, IDamageable damageTarget) public void UpdateAttack(float deltaTime, Vector2 attackPosition, IDamageable damageTarget)
{ {
float dist = ConvertUnits.ToDisplayUnits(Vector2.Distance(SimPosition, attackPosition)); float dist = ConvertUnits.ToDisplayUnits(Vector2.Distance(SimPosition, attackPosition));
@@ -655,7 +655,7 @@ namespace Barotrauma.Tutorials
enemy.Health = 50.0f; enemy.Health = 50.0f;
enemy.AIController.State = AIController.AiState.None; enemy.AIController.State = AIController.AIState.None;
Vector2 targetPos = Character.Controlled.WorldPosition + new Vector2(0.0f, 3000.0f); Vector2 targetPos = Character.Controlled.WorldPosition + new Vector2(0.0f, 3000.0f);