Working towards making monsters eat dead characters (WIP)
This commit is contained in:
@@ -6,15 +6,13 @@ namespace Barotrauma
|
||||
{
|
||||
class AIController : ISteerable
|
||||
{
|
||||
|
||||
public enum AiState { None, Attack, GoTo, Escape }
|
||||
public enum SteeringState { Wander, Seek, Escape }
|
||||
public enum AIState { None, Attack, GoTo, Escape, Eat }
|
||||
|
||||
public bool Enabled;
|
||||
|
||||
public readonly Character Character;
|
||||
|
||||
protected AiState state;
|
||||
protected AIState state;
|
||||
|
||||
protected SteeringManager steeringManager;
|
||||
|
||||
@@ -44,7 +42,7 @@ namespace Barotrauma
|
||||
get { return Character.AnimController.Collider.LinearVelocity; }
|
||||
}
|
||||
|
||||
public AiState State
|
||||
public AIState State
|
||||
{
|
||||
get { return state; }
|
||||
set { state = value; }
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Barotrauma
|
||||
//0.0 = doesn't attack targets of the type
|
||||
//positive values = attacks 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;
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace Barotrauma
|
||||
|
||||
steeringManager = outsideSteering;
|
||||
|
||||
state = AiState.None;
|
||||
state = AIState.None;
|
||||
}
|
||||
|
||||
public override void SelectTarget(AITarget target)
|
||||
@@ -145,11 +145,15 @@ namespace Barotrauma
|
||||
|
||||
if (selectedAiTarget == null)
|
||||
{
|
||||
state = AiState.None;
|
||||
state = AIState.None;
|
||||
}
|
||||
else if ((selectedAiTarget.Entity is Character) && ((Character)selectedAiTarget.Entity).IsDead)
|
||||
{
|
||||
state = AIState.Eat;
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -159,14 +163,17 @@ namespace Barotrauma
|
||||
bool run = false;
|
||||
switch (state)
|
||||
{
|
||||
case AiState.None:
|
||||
case AIState.None:
|
||||
UpdateNone(deltaTime);
|
||||
break;
|
||||
case AiState.Attack:
|
||||
case AIState.Attack:
|
||||
run = coolDownTimer <= 0.0f;
|
||||
UpdateAttack(deltaTime);
|
||||
break;
|
||||
case AiState.Escape:
|
||||
case AIState.Eat:
|
||||
|
||||
break;
|
||||
case AIState.Escape:
|
||||
run = true;
|
||||
UpdateEscape(deltaTime);
|
||||
break;
|
||||
@@ -208,7 +215,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (selectedAiTarget == null || selectedAiTarget.Entity == null || selectedAiTarget.Entity.Removed)
|
||||
{
|
||||
state = AiState.None;
|
||||
state = AIState.None;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -409,6 +416,21 @@ namespace Barotrauma
|
||||
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,
|
||||
//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 dist = 0.0f;
|
||||
|
||||
IDamageable targetDamageable = target.Entity as IDamageable;
|
||||
if (targetDamageable!=null && targetDamageable.Health <= 0.0f) continue;
|
||||
|
||||
Character targetCharacter = target.Entity as Character;
|
||||
|
||||
//ignore the aitarget if it is the Character itself
|
||||
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;
|
||||
valueModifier = attackHumans;
|
||||
@@ -470,6 +495,9 @@ namespace Barotrauma
|
||||
}
|
||||
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
|
||||
if (character.AnimController.CurrentHull != null && character.AnimController.CurrentHull == target.Entity as Hull) continue;
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Barotrauma
|
||||
{
|
||||
switch (aiController.State)
|
||||
{
|
||||
case AIController.AiState.Attack:
|
||||
case AIController.AIState.Attack:
|
||||
PlaySound(CharacterSound.SoundType.Attack);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -1912,13 +1912,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (selectedItems[i] != null) selectedItems[i].Drop(this);
|
||||
}
|
||||
|
||||
if (aiTarget != null)
|
||||
{
|
||||
aiTarget.Remove();
|
||||
aiTarget = null;
|
||||
}
|
||||
|
||||
|
||||
foreach (Limb limb in AnimController.Limbs)
|
||||
{
|
||||
if (limb.pullJoint == null) continue;
|
||||
|
||||
@@ -70,10 +70,12 @@ namespace Barotrauma
|
||||
|
||||
private float damage, burnt;
|
||||
|
||||
private bool isSevered;
|
||||
|
||||
private readonly Vector2 armorSector;
|
||||
private readonly float armorValue;
|
||||
|
||||
Sound hitSound;
|
||||
private Sound hitSound;
|
||||
//a timer for delaying when a hitsound/attacksound can be played again
|
||||
public float soundTimer;
|
||||
public const float SoundInterval = 0.4f;
|
||||
@@ -90,7 +92,18 @@ namespace Barotrauma
|
||||
|
||||
public float AttackTimer;
|
||||
|
||||
public bool IsSevered;
|
||||
public bool IsSevered
|
||||
{
|
||||
get { return isSevered; }
|
||||
set
|
||||
{
|
||||
isSevered = value;
|
||||
if (isSevered)
|
||||
{
|
||||
damage = 100.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool DoesFlip
|
||||
{
|
||||
@@ -429,12 +442,7 @@ namespace Barotrauma
|
||||
// SimPosition, Vector2.Zero);
|
||||
//}
|
||||
}
|
||||
|
||||
public void ActivateDamagedSprite()
|
||||
{
|
||||
damage = 100.0f;
|
||||
}
|
||||
|
||||
|
||||
public void UpdateAttack(float deltaTime, Vector2 attackPosition, IDamageable damageTarget)
|
||||
{
|
||||
float dist = ConvertUnits.ToDisplayUnits(Vector2.Distance(SimPosition, attackPosition));
|
||||
|
||||
@@ -655,7 +655,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user