protected void CallAddNewObjective(AIObjective newObjective) { AddNewObjective(newObjective); }
void AddObjective(AIObjective objective) { objective.AddNewObjective += AddObjective; newObjectives.Add(objective); }
protected AIObjectiveContainItem AIContainItems <T>(ItemContainer container, Character character, AIObjective objective, int itemCount, bool equip, bool removeEmpty) where T : ItemComponent { var containObjective = new AIObjectiveContainItem(character, container.GetContainableItemIdentifiers.ToArray(), container, objective.objectiveManager) { targetItemCount = itemCount, Equip = equip, RemoveEmpty = removeEmpty, GetItemPriority = i => { if (i.ParentInventory?.Owner is Item) { //don't take items from other items of the same type if (((Item)i.ParentInventory.Owner).GetComponent <T>() != null) { return(0.0f); } } return(1.0f); } }; // TODO: are we sure that we want to abandon the objective here? containObjective.Abandoned += () => objective.Abandon = true; objective.AddSubObjective(containObjective); return(containObjective); }
protected AIObjectiveContainItem AIContainItems <T>(ItemContainer container, Character character, AIObjective currentObjective, int itemCount, bool equip, bool removeEmpty, bool spawnItemIfNotFound = false, bool dropItemOnDeselected = false) where T : ItemComponent { AIObjectiveContainItem containObjective = null; if (character.AIController is HumanAIController aiController) { containObjective = new AIObjectiveContainItem(character, container.GetContainableItemIdentifiers.ToArray(), container, currentObjective.objectiveManager, spawnItemIfNotFound: spawnItemIfNotFound) { targetItemCount = itemCount, Equip = equip, RemoveEmpty = removeEmpty, GetItemPriority = i => { if (i.ParentInventory?.Owner is Item) { //don't take items from other items of the same type if (((Item)i.ParentInventory.Owner).GetComponent <T>() != null) { return(0.0f); } } return(1.0f); } }; containObjective.Abandoned += () => aiController.IgnoredItems.Add(container.Item); if (dropItemOnDeselected) { currentObjective.Deselected += () => { if (containObjective == null) { return; } if (containObjective.IsCompleted) { return; } Item item = containObjective.ItemToContain; if (item != null && character.CanInteractWith(item, checkLinked: false)) { item.Drop(character); } }; } currentObjective.AddSubObjective(containObjective); } return(containObjective); }
/// <summary> /// To find the best cover point, we will compute a cost for every unoccupied cover point within our /// cover point sensor. Then choose the cover point with the lowest cost. We normally prefer cover points /// that are close to the enemy, but also close to our AI. For example, we prefer points that are very near /// the enemy, but then also prefer points that are between us and the enemy (not on the other side of them). /// </summary> /// <param name="ai">The AI executing the action</param> private void FindBestCoverPoint(AI ai) { if (!CoverVariable.IsValid || !CoverVariable.IsVariable) return; //We don't actually have to have an enemy. We can choose cover points that are simply near ourselves. Vector3 tEnemyPosition = ai.Kinematic.Position; if (EnemyVariable.IsValid && EnemyVariable.IsVariable) { //using a MoveLookTarget lets us automatically convert between gameObject, Vector3, etc., when getting //a position from AI memory MoveLookTarget tTarget = MoveLookTarget.GetTargetFromVariable(ai.WorkingMemory, EnemyVariable.VariableName, ai.Motor.CloseEnoughDistance); if (tTarget.IsValid) tEnemyPosition = tTarget.Position; } //Cover points should be marked with the "cover" tactical aspect _coverSensor.Sense("cover", RAINSensor.MatchType.ALL); //Default cover point is our own position float bestCost = float.MaxValue; Vector3 tCoverPosition = ai.Kinematic.Position; for (int i = 0; i < _coverSensor.Matches.Count; i++) { TacticalAspect tCandidateAspect = _coverSensor.Matches[i] as TacticalAspect; if (tCandidateAspect == null) continue; //Cover points are AIObjectives, which are objects that allow AI to "occupy" them AIObjective tObjective = tCandidateAspect.Entity.Form.GetComponent<AIObjective>(); //Skip occupied cover points if ((tObjective == null) || (tObjective.IsOccupied)) continue; //Our cost function gives 50% more weight to points near the enemy //But then also adds in the AI distance to the point float tCost = 1.5f * Vector3.Distance(tEnemyPosition, tCandidateAspect.Position) + Vector3.Distance(ai.Kinematic.Position, tCandidateAspect.Position); if (tCost < bestCost) { _currentCoverPoint = tObjective; tCoverPosition = tCandidateAspect.Position; bestCost = tCost; } } //If we found a cover point, then occupy it if (_currentCoverPoint != null) _currentCoverPoint.Occupy(ai.Body); //Set the cover position in AI memory ai.WorkingMemory.SetItem<Vector3>(CoverVariable.VariableName, tCoverPosition); }
/// <summary> /// If we have a cover point, vacate it and set our cover point to null /// </summary> /// <param name="ai">The AI executing the action</param> private void Vacate(AI ai) { if (_currentCoverPoint != null) _currentCoverPoint.Vacate(ai.Body); _currentCoverPoint = null; }
protected AIObjectiveContainItem AIContainItems <T>(ItemContainer container, Character character, AIObjective objective, int itemCount, bool equip, bool removeEmpty) where T : ItemComponent { AIObjectiveContainItem containObjective = null; if (character.AIController is HumanAIController aiController) { containObjective = new AIObjectiveContainItem(character, container.GetContainableItemIdentifiers.ToArray(), container, objective.objectiveManager) { targetItemCount = itemCount, Equip = equip, RemoveEmpty = removeEmpty, GetItemPriority = i => { if (i.ParentInventory?.Owner is Item) { //don't take items from other items of the same type if (((Item)i.ParentInventory.Owner).GetComponent <T>() != null) { return(0.0f); } } return(1.0f); } }; containObjective.Abandoned += () => { aiController.IgnoredItems.Add(container.Item); }; objective.AddSubObjective(containObjective); } return(containObjective); }