public override float CalculateDesirability(Agent agent, bool requested) { DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; DataNest dataNest = agent.Memory.Nests.Read().FirstOrDefault(data => data.nest.SpecieID == agent.Creature.SpecieID); if (dataNest == null) { return(0); } float distanceFromNest = Vector3.Distance(agent.transform.position, dataNest.nest.transform.position); if (distanceFromNest > desirabilitiesConfig.ReachNestConsiderationMaxDistance) { distanceFromNest = desirabilitiesConfig.ReachNestConsiderationMaxDistance; } float desirability = desirabilitiesConfig.ReachNestDesirabilityByDistance.Evaluate(distanceFromNest / desirabilitiesConfig.ReachNestConsiderationMaxDistance) * desirabilitiesConfig.ReachNestDesirabilityTwicker; if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalEvade)) { desirability *= desirabilitiesConfig.ReachNestConfirmationBias; } return(desirability); }
public override float CalculateDesirability(Agent agent, bool requested) { if (Player.Instance.IsDie) { return(0); } DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; if (agent.Creature.Traits.Vigilance.Value > desirabilitiesConfig.ObservePlayerConsiderationMaxVigilance) { return(0); } bool playerDetected = agent.Memory.Player.lastSeeTime > Time.time - 1f; if (!playerDetected) { return(0); } if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalEatInPlayerHand)) { return(0); } if (agent.Thinking.ActiveGoal?.GetType() != typeof(GoalObservePlayer) && agent.Memory.Player.lastObserved > Time.time - desirabilitiesConfig.ObservePlayerMinTimeRepeat) { return(0); } float distanceWithPlayer = Vector3.Distance(agent.transform.position, Player.Instance.transform.position); float desirability = desirabilitiesConfig.ObservePlayerDesirabilityByDistance.Evaluate(1 - distanceWithPlayer / desirabilitiesConfig.ObservePlayerConsiderationMaxDistance) * desirabilitiesConfig.ObservePlayerDesirabilityByCuriosiry.Evaluate(agent.Creature.Traits.Curiosity.Value) * desirabilitiesConfig.ObservePlayerDesirabilityByVigilance.Evaluate(agent.Creature.Traits.Vigilance.Value) * desirabilitiesConfig.ObservePlayerDesirabilityTwicker; if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalObservePlayer)) { desirability *= desirabilitiesConfig.ObservePlayerConfirmationBias; } if (GoalEatInPlayerHand_Evaluator.Instance.IsPlayerWantGiveFood()) { desirability *= desirabilitiesConfig.ObservePlayerDesirabilityTwickerWithFoodHolder; } if (agent.Memory.Player.lastTimeFoodGive > Time.time - 10f) { desirability *= desirabilitiesConfig.ObservePlayerDesirabilityTwickerWithGiveFood; } return(desirability); }
public override float CalculateDesirability(Agent agent, bool requested) { DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; IReadOnlyCollection <DataCreature> creatures = agent.Memory.Creatures.Read(); float minDistanceFromHostil = -1; Creature closestHostil = null; foreach (DataCreature data in creatures) { Agent otherAgent = data.creature?.agentCreature; if (!otherAgent || !otherAgent.gameObject.activeSelf || data.RegistrationDate < Time.time - 1f) { continue; } //bool attackSpecies = otherAgent.Steering.Target && otherAgent.Steering.Target.Creature.SpecieID == agent.Creature.SpecieID; //if(!attackSpecies) continue; if (otherAgent.Thinking.ActiveGoal?.GetType() == typeof(GoalTired)) { return(0); } float distance = Vector3.Distance(agent.transform.position, otherAgent.transform.position); bool isHostil = GoalEvade.CreatureIsHostil(agent, otherAgent.Creature); if (!isHostil) { continue; } if (minDistanceFromHostil == -1 || distance < minDistanceFromHostil) { minDistanceFromHostil = distance; closestHostil = otherAgent.Creature; } } if (minDistanceFromHostil == -1) { return(0); } float desirability = desirabilitiesConfig.DefenseDesirabilityByAggressivity.Evaluate(agent.Creature.Traits.Aggressivity.Value) * desirabilitiesConfig.DefenseDesirabilityTwicker * ForceEvaluation.Evaluate(agent, closestHostil); if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalDefense)) { desirability *= desirabilitiesConfig.DefenseConfirmationBias; } return(desirability); }
public override float CalculateDesirability(Agent agent, bool requested) { //TODO TEMP if (agent.Creature.Traits.Carnivorous < 0.5f) { return(0); } if (agent.Steering.Behavior != eSteeringBehavior.Seek && agent.Steering.Behavior != eSteeringBehavior.Wander && agent.Thinking.ActiveGoal?.GetType() != typeof(GoalAvoidPrey)) { return(0); } DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; List <int> preys = new List <int>(agent.Memory.Species.GetByKey(agent.Creature.SpecieID).CarnivorousFoods.Select(food => food.preyID)); IReadOnlyCollection <DataCreature> creatures = agent.Memory.Creatures.Read(); float minDistanceFromPrey = -1; Creature closestPrey = null; foreach (DataCreature data in creatures) { Agent otherAgent = data.creature?.agentCreature; if (!otherAgent || !agent.gameObject.activeSelf || data.RegistrationDate < Time.time - 2f) { continue; } float distance = Vector3.Distance(agent.transform.position, otherAgent.transform.position); bool isPrey = preys.Contains(otherAgent.Creature.SpecieID); if (isPrey && (minDistanceFromPrey == -1 || distance < minDistanceFromPrey)) { minDistanceFromPrey = distance; closestPrey = otherAgent.Creature; } } if (minDistanceFromPrey == -1) { return(0); } float desirability = desirabilitiesConfig.AvoidPreyDesirabilityByDistance.Evaluate(1 - minDistanceFromPrey / desirabilitiesConfig.AvoidPreyConsiderationMaxDistance) * desirabilitiesConfig.AvoidPreyDesirabilityTwicker * (1 / ForceEvaluation.Evaluate(agent, closestPrey)); if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalAvoidPrey)) { desirability *= desirabilitiesConfig.AvoidPreyConfirmationBias; } return(desirability); }
public override void Process() { Goal child = GetActiveGoal(); if (child.IsInactive) { child.Activate(); } DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; float vigilanceConsideration = desirabilitiesConfig.DefensePlayerConsiderationMinVigilance; float vigilance = desirabilitiesConfig.DefensePlayerDesirabilityByAggressivity.Evaluate(owner.Creature.Traits.Vigilance.Value) * (1 / vigilanceConsideration); float distToObserve = Mathf.Lerp(minDistToObserve, maxDistToObserve, 1 - vigilance); bool playerClose = owner.Memory.Player.lastSeeTime > Time.time - 1f && Vector3.Distance(owner.transform.position, Player.Instance.transform.position) < distToObserve; switch (evadeState) { case ObserveState.Pursuit: if (child.IsComplete) { AddSubgoal(new GoalLookAtPlayer(owner)); evadeState = ObserveState.LookAt; } else if (playerClose) { child.Abort(); AddSubgoal(new GoalLookAtPlayer(owner)); evadeState = ObserveState.LookAt; } break; case ObserveState.LookAt: if (!playerClose) { child.Abort(); AddSubgoal(new GoalPursuitPlayer(owner)); evadeState = ObserveState.Pursuit; } break; } if (Time.time - timeStart >= desirabilitiesConfig.ObservePlayerMaxTimeSpend) { status = GoalStatus.Completed; } base.ProcessSubgoals(); }
public override float CalculateDesirability(Agent agent, bool requested) { DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; float desirability = desirabilitiesConfig.HungryDesirabilityByStomack.Evaluate(1 - agent.Creature.Gauges.Hunger.Rate) * desirabilitiesConfig.HungryDesirabilityByGluttony.Evaluate(agent.Creature.Traits.Gluttony.Value) * desirabilitiesConfig.HungryDesirabilityTwicker; if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalHungry)) { desirability *= desirabilitiesConfig.HungryConfirmationBias; } return(desirability); }
public override float CalculateDesirability(Agent agent, bool requested) { //TODO TEMP if (agent.Creature.Traits.Carnivorous >= 0.5f) { return(0); } DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; IReadOnlyCollection <DataCreature> creatures = agent.Memory.Creatures.Read(); float minDistanceFromHostil = -1; Creature closestHostil = null; foreach (DataCreature data in creatures) { Agent otherAgent = data.creature?.agentCreature; if (!otherAgent || !agent.gameObject.activeSelf || data.RegistrationDate < Time.time - 2f) { continue; } float distance = Vector3.Distance(agent.transform.position, otherAgent.transform.position); bool isHostil = GoalEvade.CreatureIsHostil(agent, otherAgent.Creature); if (isHostil && (minDistanceFromHostil == -1 || distance < minDistanceFromHostil)) { minDistanceFromHostil = distance; closestHostil = otherAgent.Creature; } } if (minDistanceFromHostil == -1) { return(0); } float desirability = desirabilitiesConfig.EvadeDesirabilityByDistance.Evaluate(1 - minDistanceFromHostil / desirabilitiesConfig.EvadeConsiderationMaxDistance) * desirabilitiesConfig.EvadeDesirabilityByAggressivity.Evaluate(agent.Creature.Traits.Aggressivity.Value) * desirabilitiesConfig.EvadeDesirabilityTwicker * (1 / ForceEvaluation.Evaluate(agent, closestHostil)); if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalEvade)) { desirability *= desirabilitiesConfig.EvadeConfirmationBias; } return(desirability); }
public override float CalculateDesirability(Agent agent, bool requested) { DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; //float sleepDistance = Mathf.Abs((DayCycleManager.Instance.Cycle + 0.5f) % 1 - agent.Creature.Traits.Nocturnal.Value); float sleep = Mathf.Abs(((DayCycleManager.Instance.Cycle + agent.Creature.Traits.Nocturnal.Value) % 1) * 2 - 1); float desirability = desirabilitiesConfig.SleepDesirabilityByCycleTime.Evaluate(sleep) * desirabilitiesConfig.SleepDesirabilityTwicker; if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalTired)) { desirability *= desirabilitiesConfig.SleepConfirmationBias; } return(desirability); }
public static bool CreatureIsHostil(Agent owner, Creature other) { if (owner.Creature.SpecieID == other.SpecieID) { return(false); } DataSpecies data = owner.Memory.Species.GetByKey(other.SpecieID); if (data == null) { return(false); } if (owner.Debug) { /*Debug.Log("List : " + other.SpecieID); * foreach(int i in data.preyIDs){ * Debug.Log("i"); * }*/ } bool isEatMe = data.IsCarnivorous && data.PreyIDs.Contains(owner.Creature.SpecieID); if (other.agentCreature.IsThinking) { if (!isEatMe) { return(false); } } else { if (!isEatMe && (other.agentCreature.Steering.Target == null || other.agentCreature.Steering.Target.Creature.SpecieID != owner.Creature.SpecieID)) { return(false); } } //if(other.Traits.Carnivorous.Value < 0.5f) return false; DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; return(Vector3.Distance(owner.transform.position, other.transform.position) < desirabilitiesConfig.EvadeConsiderationMaxDistance / 2); }
public override float CalculateDesirability(Agent agent, bool requested) { if (agent.Creature.Age < 0.4f) { return(0); } //TODO temporaire, pour éviter la surpopulation : /*if(SpeciesMetrics.Instance && SpeciesMetrics.Instance.IsReady){ * int nbCreatures = SpeciesMetrics.Instance.NbCreatures[agent.Creature.SpecieID]; * if(nbCreatures >= 18){ * return 0; * } * }*/ int nbCreatures = CreatureFactory.Instance.AliveCreature.Count(c => c.SpecieID == agent.Creature.SpecieID); if (nbCreatures >= 18) { return(0); } DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; float desirability = desirabilitiesConfig.ReproductionDesirabilityByTimer.Evaluate(1 - agent.Creature.Gauges.Reproduction.Rate) * desirabilitiesConfig.ReproductionDesirabilityByLust.Evaluate(agent.Creature.Traits.Lust.Value) * desirabilitiesConfig.ReproductionDesirabilityTwicker; if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalReproduction) || agent.Thinking.ActiveGoal?.GetType() == typeof(GoalReproduce)) { desirability *= desirabilitiesConfig.ReproductionConfirmationBias; } if (requested) { desirability *= desirabilitiesConfig.ReproductionRequestBias; } return(desirability); }
public override float CalculateDesirability(Agent agent, bool requested) { if (Player.Instance.IsDie) { return(0); } DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; if (agent.Creature.Traits.Vigilance.Value < desirabilitiesConfig.EvadePlayerConsiderationMinVigilance) { return(0); } bool playerDetected = agent.Memory.Player.lastSeeTime > Time.time - 2f; if (!playerDetected) { return(0); } float distanceWithPlayer = Vector3.Distance(agent.transform.position, Player.Instance.transform.position); float desirability = desirabilitiesConfig.EvadePlayerDesirabilityByDistance.Evaluate(1 - distanceWithPlayer / desirabilitiesConfig.EvadePlayerConsiderationMaxDistance) * desirabilitiesConfig.EvadePlayerDesirabilityByAggressivity.Evaluate(agent.Creature.Traits.Aggressivity.Value) * desirabilitiesConfig.EvadePlayerDesirabilityByVigilance.Evaluate(agent.Creature.Traits.Vigilance.Value) * desirabilitiesConfig.EvadePlayerDesirabilityTwicker * (1 / ForceEvaluation.EvaluateAgainstPlayer(agent)); if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalEvadePlayer)) { desirability *= desirabilitiesConfig.EvadePlayerConfirmationBias; } if (GoalEatInPlayerHand_Evaluator.Instance.IsPlayerWantGiveFood()) { desirability *= desirabilitiesConfig.EvadePlayerDesirabilityTwickerWithFoodHolder; } return(desirability); }
public override float CalculateDesirability(Agent agent, bool requested) { if (agent.Creature.Traits.Carnivorous > 0.5f) { return(0); } if (Player.Instance.IsDie) { return(0); } if (!IsPlayerWantGiveFood()) { return(0); } DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; bool playerDetected = agent.Memory.Player.lastSeeTime > Time.time - 2f; if (!playerDetected) { return(0); } float distanceWithPlayer = Vector3.Distance(agent.transform.position, Player.Instance.transform.position); float desirability = GoalHungry_Evaluator.Instance.CalculateDesirability(agent, requested) * desirabilitiesConfig.EatInPlayerHandDesirabilityByAggressivity.Evaluate(agent.Creature.Traits.Aggressivity.Value) * desirabilitiesConfig.EatInPlayerHandDesirabilityByVigilance.Evaluate(agent.Creature.Traits.Vigilance.Value) * desirabilitiesConfig.EatInPlayerHandDesirabilityTwicker; if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalEatInPlayerHand)) { desirability *= desirabilitiesConfig.EatInPlayerHandConfirmationBias; } return(desirability); }
public override float CalculateDesirability(Agent agent, bool requested) { if (!agent.Creature.MetabolismActive) { return(0); } DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; float lastComTime = desirabilitiesConfig.CommunicationConsiderationMaxTime; IReadOnlyCollection <DataCommunication> communications = agent.Memory.Communications.Read(); foreach (DataCommunication com in communications) { float time = Time.time - com.RegistrationDate; if (time < lastComTime) { lastComTime = time; } } float desirability = desirabilitiesConfig.CommunicationDesirabilityByTime.Evaluate(lastComTime / desirabilitiesConfig.CommunicationConsiderationMaxTime) * desirabilitiesConfig.CommunicationDesirabilityBySociability.Evaluate(agent.Creature.Traits.Sociability.Value) * desirabilitiesConfig.CommunicationDesirabilityTwicker; if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalCommunication) || agent.Thinking.ActiveGoal?.GetType() == typeof(GoalShare)) { desirability *= desirabilitiesConfig.CommunicationConfirmationBias; } if (requested) { desirability *= desirabilitiesConfig.CommunicationRequestBias; } return(desirability); }
public override void Activate() { base.Activate(); DataNest dataNest = owner.Memory.Nests.Read().FirstOrDefault(data => data.nest.SpecieID == owner.Creature.SpecieID); if (dataNest == null) { status = GoalStatus.Failed; return; } DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; float distWithNest = dataNest != null?Vector3.Distance(owner.transform.position, dataNest.nest.transform.position) : 0; float wantDistWithNest = desirabilitiesConfig.SlepConsiderationMinNestDistance + (desirabilitiesConfig.SlepConsiderationMaxNestDistance - desirabilitiesConfig.SlepConsiderationMinNestDistance) * desirabilitiesConfig.SleepToNestDesirabilityBySociability.Evaluate(owner.Creature.Traits.Sociability.Value); wantDistWithNest = Random.Range(desirabilitiesConfig.SlepConsiderationMinNestDistance, wantDistWithNest); Vector2 randPos = Random.insideUnitCircle; AddSubgoal(new GoalSeek(owner, dataNest.nest.transform.position + new Vector3(randPos.x, 0, randPos.y) * wantDistWithNest)); }
public override float CalculateDesirability(Agent agent, bool requested) { if (Player.Instance.IsDie) { return(0); } DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; if (agent.Creature.Traits.Vigilance.Value > desirabilitiesConfig.ProtectPlayerConsiderationMaxVigilance) { return(0); } bool playerDetected = agent.Memory.Player.lastSeeTime > Time.time - 1f; if (!playerDetected) { return(0); } IReadOnlyCollection <DataCreature> creatures = agent.Memory.Creatures.Read(); float minDistanceFromHostil = -1; Creature closestHostil = null; foreach (DataCreature data in creatures) { Agent otherAgent = data.creature?.agentCreature; if (!otherAgent || !otherAgent.gameObject.activeSelf || data.RegistrationDate < Time.time - 1f) { continue; } if (otherAgent.Creature.SpecieID == agent.Creature.SpecieID) { continue; } if (otherAgent.Thinking.ActiveGoal?.GetType() == typeof(GoalTired)) { continue; } Goal goal = otherAgent.Thinking.ActiveGoal; if (!(goal is GoalDefensePlayer)) { continue; } Goal subGoal = (goal as GoalComposite).GetActiveGoal(); if (subGoal == null || (!(subGoal is GoalPursuitPlayer) && !(subGoal is GoalAttackPlayer))) { continue; } float distance = Vector3.Distance(agent.transform.position, otherAgent.transform.position); if (minDistanceFromHostil == -1 || distance < minDistanceFromHostil) { minDistanceFromHostil = distance; closestHostil = otherAgent.Creature; } } if (minDistanceFromHostil == -1) { return(0); } float desirability = desirabilitiesConfig.ProtectPlayerDesirabilityByAggressivity.Evaluate(agent.Creature.Traits.Aggressivity.Value) * desirabilitiesConfig.ProtectPlayerDesirabilityByVigilance.Evaluate(agent.Creature.Traits.Vigilance.Value) * desirabilitiesConfig.ProtectPlayerDesirabilityTwicker * ForceEvaluation.Evaluate(agent, closestHostil); if (agent.Thinking.ActiveGoal?.GetType() == typeof(GoalProtectPlayer)) { desirability *= desirabilitiesConfig.ProtectPlayerConfirmationBias; } return(desirability); }
public override void Process() { DesirabilitiesConfig desirabilitiesConfig = GameManager.Instance.DesirabilitiesConfig; float vigilanceConsideration = desirabilitiesConfig.DefensePlayerConsiderationMinVigilance; float vigilance = (desirabilitiesConfig.DefensePlayerDesirabilityByAggressivity.Evaluate(owner.Creature.Traits.Vigilance.Value) - vigilanceConsideration) * (1 / (1 - vigilanceConsideration)); vigilance *= (Player.Instance.PlayerController.Velocity.magnitude * desirabilitiesConfig.DefensePlayerPlayerSpeedThreatWeight); float distToAttack = Mathf.Lerp(minDistToAttack, maxDistToAttack, vigilance); float distToPursuit = Mathf.Lerp(minDistToPursuit, maxDistToPursuit, vigilance); Vector3 playerPos = Player.Instance.transform.position; float distanceToPlayer = Vector3.Distance(owner.transform.position, playerPos); Goal child = GetActiveGoal(); if (child != null && child.IsInactive) { child.Activate(); } switch (defenseState) { case DefenseState.LookAt: if (owner.Steering.Behavior != eSteeringBehavior.LookAtPlayer) { AddSubgoal(new GoalLookAtPlayer(owner)); } else if (distanceToPlayer < 2) { if (child != null) { child.Abort(); } AddSubgoal(new GoalAttackPlayer(owner)); defenseState = DefenseState.Attack; timeStart = Time.time; } else if (Time.time - timeStart >= desirabilitiesConfig.DefensePlayerMaxTimeSpend) { status = GoalStatus.Completed; } else { IReadOnlyCollection <DataCreature> friends = owner.Memory.Creatures.Read(); bool friendAggresed = false; Agent friend = null; foreach (DataCreature data in friends) { if (!data.creature) { continue; } Agent agent = data.creature.agentCreature; if (!agent.gameObject.activeSelf || data.RegistrationDate < Time.time - 1f) { continue; } if (Vector3.Distance(agent.transform.position, playerPos) < distToAttack) { friendAggresed = true; friend = agent; break; } } if (!friendAggresed) { friendAggresed = Vector3.Distance(owner.transform.position, playerPos) < distToAttack; friend = owner; } if (friendAggresed) { if (child != null) { child.Abort(); } AddSubgoal(new GoalPursuitPlayer(owner)); defenseState = DefenseState.Pursuit; if (Random.value > 0.5f) { owner.Creature.AudioBox.PlayOneShot(SoundOneShot.CreatureDefense); } timeStart = Time.time; } } break; case DefenseState.Pursuit: if (child.IsComplete) { AddSubgoal(new GoalAttackPlayer(owner)); defenseState = DefenseState.Attack; } else if (child.HasFailed) { defenseState = DefenseState.LookAt; } else if (Vector3.Distance(owner.transform.position, playerPos) > distToPursuit) { child.Abort(); defenseState = DefenseState.LookAt; } break; case DefenseState.Attack: if (child.IsComplete || child.HasFailed) { IReadOnlyCollection <DataCreature> friends = owner.Memory.Creatures.Read(); bool friendAggresed = false; Agent friend = null; foreach (DataCreature data in friends) { if (!data.creature) { continue; } Agent agent = data.creature.agentCreature; if (!agent.gameObject.activeSelf || data.RegistrationDate < Time.time - 1f) { continue; } if (Vector3.Distance(agent.transform.position, playerPos) < distToAttack) { friendAggresed = true; friend = agent; break; } } if (!friendAggresed) { friendAggresed = Vector3.Distance(owner.transform.position, playerPos) < distToAttack; friend = owner; } if (friendAggresed) { if (child != null) { child.Abort(); } AddSubgoal(new GoalPursuitPlayer(owner)); defenseState = DefenseState.Pursuit; } else { AddSubgoal(new GoalLookAtPlayer(owner)); defenseState = DefenseState.LookAt; } } break; } base.ProcessSubgoals(); }