private void UnequipUnnecessaryItems() { if (ObjectiveManager.HasActiveObjective <AIObjectiveDecontainItem>()) { return; } if (findItemState == FindItemState.None || findItemState == FindItemState.Extinguisher) { if (!ObjectiveManager.IsCurrentObjective <AIObjectiveExtinguishFires>() && !objectiveManager.HasActiveObjective <AIObjectiveExtinguishFire>()) { var extinguisher = Character.Inventory.FindItemByTag("extinguisher"); if (extinguisher != null && Character.HasEquippedItem(extinguisher)) { if (ObjectiveManager.GetCurrentPriority() >= AIObjectiveManager.RunPriority) { extinguisher.Drop(Character); } else { findItemState = FindItemState.Extinguisher; if (FindSuitableContainer(Character, extinguisher, out Item targetContainer)) { findItemState = FindItemState.None; itemIndex = 0; if (targetContainer != null) { var decontainObjective = new AIObjectiveDecontainItem(Character, extinguisher, targetContainer.GetComponent <ItemContainer>(), ObjectiveManager, targetContainer.GetComponent <ItemContainer>()); decontainObjective.Abandoned += () => ignoredContainers.Add(targetContainer); ObjectiveManager.CurrentObjective.AddSubObjective(decontainObjective, addFirst: true); return; } else { extinguisher.Drop(Character); } } } } } } if (findItemState == FindItemState.None || findItemState == FindItemState.DivingSuit || findItemState == FindItemState.DivingMask) { if (!NeedsDivingGear(Character, Character.CurrentHull, out _)) { bool oxygenLow = Character.OxygenAvailable < CharacterHealth.LowOxygenThreshold; bool shouldKeepTheGearOn = Character.AnimController.HeadInWater || Character.CurrentHull.WaterPercentage > 50 || ObjectiveManager.IsCurrentObjective <AIObjectiveFindSafety>() || ObjectiveManager.CurrentObjective.GetSubObjectivesRecursive(true).Any(o => o.KeepDivingGearOn); bool removeDivingSuit = !Character.AnimController.HeadInWater && oxygenLow; AIObjectiveGoTo gotoObjective = ObjectiveManager.CurrentOrder as AIObjectiveGoTo; if (!removeDivingSuit) { bool targetHasNoSuit = gotoObjective != null && gotoObjective.mimic && !HasDivingSuit(gotoObjective.Target as Character); removeDivingSuit = !shouldKeepTheGearOn && (gotoObjective == null || targetHasNoSuit); } bool takeMaskOff = !Character.AnimController.HeadInWater && oxygenLow; if (!takeMaskOff && Character.CurrentHull.WaterPercentage < 40) { bool targetHasNoMask = gotoObjective != null && gotoObjective.mimic && !HasDivingMask(gotoObjective.Target as Character); takeMaskOff = !shouldKeepTheGearOn && (gotoObjective == null || targetHasNoMask); } if (gotoObjective != null) { if (gotoObjective.Target is Hull h) { if (NeedsDivingGear(Character, h, out _)) { removeDivingSuit = false; takeMaskOff = false; } } else if (gotoObjective.Target is Character c) { if (NeedsDivingGear(Character, c.CurrentHull, out _)) { removeDivingSuit = false; takeMaskOff = false; } } else if (gotoObjective.Target is Item i) { if (NeedsDivingGear(Character, i.CurrentHull, out _)) { removeDivingSuit = false; takeMaskOff = false; } } } if (findItemState == FindItemState.None || findItemState == FindItemState.DivingSuit) { if (removeDivingSuit) { var divingSuit = Character.Inventory.FindItemByTag("divingsuit"); if (divingSuit != null) { if (oxygenLow || ObjectiveManager.GetCurrentPriority() >= AIObjectiveManager.RunPriority) { divingSuit.Drop(Character); } else { findItemState = FindItemState.DivingSuit; if (FindSuitableContainer(Character, divingSuit, out Item targetContainer)) { findItemState = FindItemState.None; itemIndex = 0; if (targetContainer != null) { var decontainObjective = new AIObjectiveDecontainItem(Character, divingSuit, targetContainer.GetComponent <ItemContainer>(), ObjectiveManager, targetContainer.GetComponent <ItemContainer>()); decontainObjective.Abandoned += () => ignoredContainers.Add(targetContainer); ObjectiveManager.CurrentObjective.AddSubObjective(decontainObjective, addFirst: true); return; } else { divingSuit.Drop(Character); } } } } } } if (findItemState == FindItemState.None || findItemState == FindItemState.DivingMask) { if (takeMaskOff) { var mask = Character.Inventory.FindItemByTag("divingmask"); if (mask != null && Character.Inventory.IsInLimbSlot(mask, InvSlotType.Head)) { if (!mask.AllowedSlots.Contains(InvSlotType.Any) || !Character.Inventory.TryPutItem(mask, Character, new List <InvSlotType>() { InvSlotType.Any })) { if (oxygenLow || ObjectiveManager.GetCurrentPriority() >= AIObjectiveManager.RunPriority) { mask.Drop(Character); } else { findItemState = FindItemState.DivingMask; if (FindSuitableContainer(Character, mask, out Item targetContainer)) { findItemState = FindItemState.None; itemIndex = 0; if (targetContainer != null) { var decontainObjective = new AIObjectiveDecontainItem(Character, mask, targetContainer.GetComponent <ItemContainer>(), ObjectiveManager, targetContainer.GetComponent <ItemContainer>()); decontainObjective.Abandoned += () => ignoredContainers.Add(targetContainer); ObjectiveManager.CurrentObjective.AddSubObjective(decontainObjective, addFirst: true); return; } else { mask.Drop(Character); } } } } } } } } } if (findItemState == FindItemState.None || findItemState == FindItemState.OtherItem) { if (ObjectiveManager.IsCurrentObjective <AIObjectiveIdle>() || ObjectiveManager.IsCurrentObjective <AIObjectiveOperateItem>() || ObjectiveManager.IsCurrentObjective <AIObjectivePumpWater>() || ObjectiveManager.IsCurrentObjective <AIObjectiveChargeBatteries>()) { foreach (var item in Character.Inventory.Items) { if (item == null) { continue; } if (Character.HasEquippedItem(item) && (Character.Inventory.IsInLimbSlot(item, InvSlotType.RightHand) || Character.Inventory.IsInLimbSlot(item, InvSlotType.LeftHand) || Character.Inventory.IsInLimbSlot(item, InvSlotType.RightHand | InvSlotType.LeftHand))) { if (!item.AllowedSlots.Contains(InvSlotType.Any) || !Character.Inventory.TryPutItem(item, Character, new List <InvSlotType>() { InvSlotType.Any })) { if (FindSuitableContainer(Character, item, out Item targetContainer)) { findItemState = FindItemState.None; itemIndex = 0; if (targetContainer != null) { var decontainObjective = new AIObjectiveDecontainItem(Character, item, targetContainer.GetComponent <ItemContainer>(), ObjectiveManager, targetContainer.GetComponent <ItemContainer>()); decontainObjective.Abandoned += () => ignoredContainers.Add(targetContainer); ObjectiveManager.CurrentObjective.AddSubObjective(decontainObjective, addFirst: true); return; } else { item.Drop(Character); } } else { findItemState = FindItemState.OtherItem; } } } } } } }
protected void ReportProblems() { Order newOrder = null; Hull targetHull = null; if (Character.CurrentHull != null) { foreach (var hull in VisibleHulls) { foreach (Character c in Character.CharacterList) { if (c.CurrentHull != hull || !c.Enabled) { continue; } if (AIObjectiveFightIntruders.IsValidTarget(c, Character)) { if (AddTargets <AIObjectiveFightIntruders, Character>(Character, c) && newOrder == null) { var orderPrefab = Order.GetPrefab("reportintruders"); newOrder = new Order(orderPrefab, hull, null, orderGiver: Character); targetHull = hull; } } } if (AIObjectiveExtinguishFires.IsValidTarget(hull, Character)) { if (AddTargets <AIObjectiveExtinguishFires, Hull>(Character, hull) && newOrder == null) { var orderPrefab = Order.GetPrefab("reportfire"); newOrder = new Order(orderPrefab, hull, null, orderGiver: Character); targetHull = hull; } } foreach (Character c in Character.CharacterList) { if (c.CurrentHull != hull) { continue; } if (AIObjectiveRescueAll.IsValidTarget(c, Character)) { if (AddTargets <AIObjectiveRescueAll, Character>(c, Character) && newOrder == null && !ObjectiveManager.HasActiveObjective <AIObjectiveRescue>()) { var orderPrefab = Order.GetPrefab("requestfirstaid"); newOrder = new Order(orderPrefab, hull, null, orderGiver: Character); targetHull = hull; } } } foreach (var gap in hull.ConnectedGaps) { if (AIObjectiveFixLeaks.IsValidTarget(gap, Character)) { if (AddTargets <AIObjectiveFixLeaks, Gap>(Character, gap) && newOrder == null && !gap.IsRoomToRoom) { var orderPrefab = Order.GetPrefab("reportbreach"); newOrder = new Order(orderPrefab, hull, null, orderGiver: Character); targetHull = hull; } } } foreach (Item item in Item.ItemList) { if (item.CurrentHull != hull) { continue; } if (AIObjectiveRepairItems.IsValidTarget(item, Character)) { if (item.Repairables.All(r => item.ConditionPercentage > r.ShowRepairUIThreshold)) { continue; } if (AddTargets <AIObjectiveRepairItems, Item>(Character, item) && newOrder == null && !ObjectiveManager.HasActiveObjective <AIObjectiveRepairItem>()) { var orderPrefab = Order.GetPrefab("reportbrokendevices"); newOrder = new Order(orderPrefab, hull, item.Repairables?.FirstOrDefault(), orderGiver: Character); targetHull = hull; } } } } } if (newOrder != null) { if (GameMain.GameSession?.CrewManager != null && GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime)) { Character.Speak(newOrder.GetChatMessage("", targetHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order); #if SERVER GameMain.Server.SendOrderChatMessage(new OrderChatMessage(newOrder, "", targetHull, null, Character)); #endif } } }