public void UpdateObjectives(float deltaTime) { UpdateOrderObjective(ForcedOrder); if (CurrentOrders.Any()) { foreach (var order in CurrentOrders) { var orderObjective = order.Objective; UpdateOrderObjective(orderObjective); } } void UpdateOrderObjective(AIObjective orderObjective) { if (orderObjective == null) { return; } #if DEBUG // Note: don't automatically remove orders here. Removing orders needs to be done via dismissing. if (!orderObjective.CanBeCompleted) { DebugConsole.NewMessage($"{character.Name}: ORDER {orderObjective.DebugTag}, CANNOT BE COMPLETED.", Color.Red); } #endif orderObjective.Update(deltaTime); } if (WaitTimer > 0) { WaitTimer -= deltaTime; return; } for (int i = 0; i < Objectives.Count; i++) { var objective = Objectives[i]; if (objective.IsCompleted) { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Removing objective {objective.DebugTag}, because it is completed.", Color.LightBlue); #endif Objectives.Remove(objective); } else if (!objective.CanBeCompleted) { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Removing objective {objective.DebugTag}, because it cannot be completed.", Color.Red); #endif Objectives.Remove(objective); FailedAutonomousObjectives = true; } else { objective.Update(deltaTime); } } GetCurrentObjective(); }
public bool HasOrder <T>() where T : AIObjective { return(ForcedOrder is T || CurrentOrders.Any(o => o.Objective is T)); }
public bool HasOrders() { return(ForcedOrder != null || CurrentOrders.Any()); }
public bool IsOrder(AIObjective objective) { return(objective == ForcedOrder || CurrentOrders.Any(o => o.Objective == objective)); }
public void SetOrder(Order order, string option, int priority, Character orderGiver, bool speak) { if (character.IsDead) { #if DEBUG DebugConsole.ThrowError("Attempted to set an order for a dead character"); #else return; #endif } ClearIgnored(); if (order == null || order.Identifier == "dismissed") { if (!string.IsNullOrEmpty(option)) { if (CurrentOrders.Any(o => o.MatchesDismissedOrder(option))) { var dismissedOrderInfo = CurrentOrders.First(o => o.MatchesDismissedOrder(option)); CurrentOrders.Remove(dismissedOrderInfo); } } else { CurrentOrders.Clear(); } } // Make sure the order priorities reflect those set by the player for (int i = CurrentOrders.Count - 1; i >= 0; i--) { var currentOrder = CurrentOrders[i]; if (currentOrder.Objective == null || currentOrder.MatchesOrder(order, option)) { CurrentOrders.RemoveAt(i); continue; } var currentOrderInfo = character.GetCurrentOrder(currentOrder.Order, currentOrder.OrderOption); if (currentOrderInfo.HasValue) { int currentPriority = currentOrderInfo.Value.ManualPriority; if (currentOrder.ManualPriority != currentPriority) { CurrentOrders[i] = new OrderInfo(currentOrder, currentPriority); } } else { CurrentOrders.RemoveAt(i); } } var newCurrentOrder = CreateObjective(order, option, orderGiver, isAutonomous: false); if (newCurrentOrder != null) { CurrentOrders.Add(new OrderInfo(order, option, priority, newCurrentOrder)); } if (!HasOrders()) { // Recreate objectives, because some of them may be removed, if impossible to complete (e.g. due to path finding) CreateAutonomousObjectives(); } else { // This should be redundant, because all the objectives are reset when they are selected as active. newCurrentOrder?.Reset(); if (speak && character.IsOnPlayerTeam) { character.Speak(TextManager.Get("DialogAffirmative"), null, 1.0f); //if (speakRoutine != null) //{ // CoroutineManager.StopCoroutines(speakRoutine); //} //speakRoutine = CoroutineManager.InvokeAfter(() => //{ // if (GameMain.GameSession == null || Level.Loaded == null) { return; } // if (newCurrentOrder != null && character.SpeechImpediment < 100.0f) // { // if (newCurrentOrder is AIObjectiveRepairItems repairItems && repairItems.Targets.None()) // { // character.Speak(TextManager.Get("DialogNoRepairTargets"), null, 3.0f, "norepairtargets"); // } // else if (newCurrentOrder is AIObjectiveChargeBatteries chargeBatteries && chargeBatteries.Targets.None()) // { // character.Speak(TextManager.Get("DialogNoBatteries"), null, 3.0f, "nobatteries"); // } // else if (newCurrentOrder is AIObjectiveExtinguishFires extinguishFires && extinguishFires.Targets.None()) // { // character.Speak(TextManager.Get("DialogNoFire"), null, 3.0f, "nofire"); // } // else if (newCurrentOrder is AIObjectiveFixLeaks fixLeaks && fixLeaks.Targets.None()) // { // character.Speak(TextManager.Get("DialogNoLeaks"), null, 3.0f, "noleaks"); // } // else if (newCurrentOrder is AIObjectiveFightIntruders fightIntruders && fightIntruders.Targets.None()) // { // character.Speak(TextManager.Get("DialogNoEnemies"), null, 3.0f, "noenemies"); // } // else if (newCurrentOrder is AIObjectiveRescueAll rescueAll && rescueAll.Targets.None()) // { // character.Speak(TextManager.Get("DialogNoRescueTargets"), null, 3.0f, "norescuetargets"); // } // else if (newCurrentOrder is AIObjectivePumpWater pumpWater && pumpWater.Targets.None()) // { // character.Speak(TextManager.Get("DialogNoPumps"), null, 3.0f, "nopumps"); // } // } //}, 3); } } }