diff --git a/Barotrauma/Source/Characters/AI/AIController.cs b/Barotrauma/Source/Characters/AI/AIController.cs index a909e4e31..dee7aab5d 100644 --- a/Barotrauma/Source/Characters/AI/AIController.cs +++ b/Barotrauma/Source/Characters/AI/AIController.cs @@ -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; } diff --git a/Barotrauma/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/Source/Characters/AI/EnemyAIController.cs index 047ddf9e1..f414de4f5 100644 --- a/Barotrauma/Source/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/Source/Characters/AI/EnemyAIController.cs @@ -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; diff --git a/Barotrauma/Source/Characters/AICharacter.cs b/Barotrauma/Source/Characters/AICharacter.cs index 7a32bd5b6..7411305f7 100644 --- a/Barotrauma/Source/Characters/AICharacter.cs +++ b/Barotrauma/Source/Characters/AICharacter.cs @@ -51,7 +51,7 @@ namespace Barotrauma { switch (aiController.State) { - case AIController.AiState.Attack: + case AIController.AIState.Attack: PlaySound(CharacterSound.SoundType.Attack); break; default: diff --git a/Barotrauma/Source/Characters/Character.cs b/Barotrauma/Source/Characters/Character.cs index 45ce8787d..cfd474928 100644 --- a/Barotrauma/Source/Characters/Character.cs +++ b/Barotrauma/Source/Characters/Character.cs @@ -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; diff --git a/Barotrauma/Source/Characters/Limb.cs b/Barotrauma/Source/Characters/Limb.cs index 2fb3c553e..5c0aa658d 100644 --- a/Barotrauma/Source/Characters/Limb.cs +++ b/Barotrauma/Source/Characters/Limb.cs @@ -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)); diff --git a/Barotrauma/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs b/Barotrauma/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs index fbd40ca05..0a391d901 100644 --- a/Barotrauma/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs +++ b/Barotrauma/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs @@ -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);