public override void SelectTarget(AITarget target) { selectedAiTarget = target; selectedTargetMemory = FindTargetMemory(target); targetValue = 100.0f; }
//find the targetMemory that corresponds to some AItarget or create if there isn't one yet private AITargetMemory FindTargetMemory(AITarget target) { AITargetMemory memory = null; if (targetMemories.TryGetValue(target, out memory)) { return(memory); } memory = new AITargetMemory(100.0f); targetMemories.Add(target, memory); return(memory); }
public override void OnAttacked(IDamageable attacker, float amount) { updateTargetsTimer = Math.Min(updateTargetsTimer, 0.1f); coolDownTimer *= 0.1f; if (amount > 0.1f && attackWhenProvoked) { attackHumans = 100.0f; attackRooms = 100.0f; } if (attacker == null || attacker.AiTarget == null) { return; } AITargetMemory targetMemory = FindTargetMemory(attacker.AiTarget); targetMemory.Priority += amount; }
public override void OnAttacked(Character attacker, float amount) { updateTargetsTimer = Math.Min(updateTargetsTimer, 0.1f); coolDownTimer *= 0.1f; if (amount > 0.0f && attackWhenProvoked) { if (!(attacker is AICharacter) || (((AICharacter)attacker).AIController is HumanAIController)) { attackHumans = 100.0f; attackRooms = 100.0f; } } if (attacker == null || attacker.AiTarget == null) { return; } AITargetMemory targetMemory = FindTargetMemory(attacker.AiTarget); targetMemory.Priority += amount / Math.Max(Character.Health, 1.0f); }
//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 //sight/hearing range public void UpdateTargets(Character character) { var prevAiTarget = selectedAiTarget; selectedAiTarget = null; selectedTargetMemory = null; targetValue = 0.0f; UpdateTargetMemories(); foreach (AITarget target in AITarget.List) { if (Level.Loaded != null && target.WorldPosition.Y > Level.Loaded.Size.Y) { continue; } float valueModifier = 0.0f; float dist = 0.0f; Character targetCharacter = target.Entity as Character; //ignore the aitarget if it is the Character itself if (targetCharacter == character) { continue; } if (targetCharacter != null) { if (targetCharacter.IsDead) { if (eatDeadPriority == 0.0f) { continue; } valueModifier = eatDeadPriority; } else if (targetCharacter.SpeciesName == "human") { if (attackHumans == 0.0f) { continue; } valueModifier = attackHumans; } else { EnemyAIController enemy = targetCharacter.AIController as EnemyAIController; if (enemy != null) { if (enemy.combatStrength > combatStrength) { valueModifier = attackStronger; } else if (enemy.combatStrength < combatStrength) { valueModifier = attackWeaker; } else { continue; } } } } 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 a room and the character is already inside a sub if (character.AnimController.CurrentHull != null && target.Entity is Hull) { continue; } valueModifier = attackRooms; } if (valueModifier == 0.0f) { continue; } dist = Vector2.Distance(character.WorldPosition, target.WorldPosition); //if the target has been within range earlier, the character will notice it more easily //(i.e. remember where the target was) if (targetMemories.ContainsKey(target)) { dist *= 0.5f; } //ignore target if it's too far to see or hear if (dist > target.SightRange * sight && dist > target.SoundRange * hearing) { continue; } AITargetMemory targetMemory = FindTargetMemory(target); valueModifier = valueModifier * targetMemory.Priority / dist; if (Math.Abs(valueModifier) > Math.Abs(targetValue)) { Vector2 rayStart = character.AnimController.Limbs[0].SimPosition; Vector2 rayEnd = target.SimPosition; if (target.Entity.Submarine != null && character.Submarine == null) { rayStart -= ConvertUnits.ToSimUnits(target.Entity.Submarine.Position); } Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd); Structure closestStructure = (closestBody == null) ? null : closestBody.UserData as Structure; if (selectedAiTarget == null || Math.Abs(valueModifier) > Math.Abs(targetValue)) { selectedAiTarget = target; selectedTargetMemory = targetMemory; targetValue = valueModifier; } } } if (selectedAiTarget != prevAiTarget) { wallAttackPos = Vector2.Zero; } }