public override float GetPriority()
 {
     if (!IsAllowed)
     {
         Priority = 0;
         return(Priority);
     }
     // TODO: priority list?
     // Ignore items that are being repaired by someone else.
     if (Item.Repairables.Any(r => r.CurrentFixer != null && r.CurrentFixer != character))
     {
         Priority = 0;
     }
     else
     {
         float distanceFactor = 1;
         if (!isPriority && Item.CurrentHull != character.CurrentHull)
         {
             float yDist = Math.Abs(character.WorldPosition.Y - Item.WorldPosition.Y);
             yDist = yDist > 100 ? yDist * 5 : 0;
             float dist = Math.Abs(character.WorldPosition.X - Item.WorldPosition.X) + yDist;
             distanceFactor = MathHelper.Lerp(1, 0.25f, MathUtils.InverseLerp(0, 5000, dist));
         }
         float severity   = isPriority ? 1 : AIObjectiveRepairItems.GetTargetPriority(Item, character);
         float isSelected = IsRepairing ? 50 : 0;
         float devotion   = (CumulatedDevotion + isSelected) / 100;
         float max        = MathHelper.Min(AIObjectiveManager.OrderPriority - 1, 90);
         Priority = MathHelper.Lerp(0, max, MathHelper.Clamp(devotion + (severity * distanceFactor * PriorityModifier), 0, 1));
     }
     return(Priority);
 }
Example #2
0
        public override void CalculateGlobalIssue()
        {
            itemsNeedingRepair.Clear();

            foreach (Item item in shipCommandManager.CommandedSubmarine.GetItems(true))
            {
                if (!AIObjectiveRepairItems.ViableForRepair(item, shipCommandManager.character, shipCommandManager.character.AIController as HumanAIController))
                {
                    continue;
                }
                if (AIObjectiveRepairItems.NearlyFullCondition(item))
                {
                    continue;
                }
                itemsNeedingRepair.Add(item);
                // merged this logic with AIObjectiveRepairItems
            }

            if (itemsNeedingRepair.Any())
            {
                itemsNeedingRepair.Sort((x, y) => y.ConditionPercentage.CompareTo(x.ConditionPercentage));
                float modifiedPercentage = itemsNeedingRepair.TakeLast(3).Average(x => x.ConditionPercentage) * 0.6f + itemsNeedingRepair.TakeLast(10).Average(x => x.ConditionPercentage) * 0.4f;
                // calculate a modified percentage with the most damaged items, with 60% the weight given to the top 3 damaged and the remaining given to top 10
                GlobalImportance = 100 - modifiedPercentage;
            }
            // this system works reasonably well, though it could give extra importance to repairing critical items like reactors and junction boxes
        }
Example #3
0
 public override float GetPriority()
 {
     if (!IsAllowed)
     {
         Priority = 0;
         Abandon  = true;
         return(Priority);
     }
     // TODO: priority list?
     // Ignore items that are being repaired by someone else.
     if (Item.Repairables.Any(r => r.CurrentFixer != null && r.CurrentFixer != character))
     {
         Priority = 0;
     }
     else
     {
         float distanceFactor = 1;
         if (!isPriority && Item.CurrentHull != character.CurrentHull)
         {
             float yDist = Math.Abs(character.WorldPosition.Y - Item.WorldPosition.Y);
             yDist = yDist > 100 ? yDist * 5 : 0;
             float dist = Math.Abs(character.WorldPosition.X - Item.WorldPosition.X) + yDist;
             distanceFactor = MathHelper.Lerp(1, 0.25f, MathUtils.InverseLerp(0, 4000, dist));
         }
         float requiredSuccessFactor = objectiveManager.IsCurrentOrder <AIObjectiveRepairItems>() ? 0 : AIObjectiveRepairItems.RequiredSuccessFactor;
         float severity      = isPriority ? 1 : AIObjectiveRepairItems.GetTargetPriority(Item, character, requiredSuccessFactor) / 100;
         bool  isSelected    = IsRepairing();
         float selectedBonus = isSelected ? 100 - MaxDevotion : 0;
         float devotion      = (CumulatedDevotion + selectedBonus) / 100;
         float reduction     = isPriority ? 1 : isSelected ? 2 : 3;
         float max           = MathHelper.Min(AIObjectiveManager.OrderPriority - reduction, 90);
         Priority = MathHelper.Lerp(0, max, MathHelper.Clamp(devotion + (severity * distanceFactor * PriorityModifier), 0, 1));
     }
     return(Priority);
 }
 protected override float GetPriority()
 {
     if (!IsAllowed || Item.IgnoreByAI(character))
     {
         Priority = 0;
         Abandon  = true;
         if (IsRepairing())
         {
             Item.Repairables.ForEach(r => r.StopRepairing(character));
         }
         return(Priority);
     }
     if (HumanAIController.IsItemRepairedByAnother(Item, out _))
     {
         Priority    = 0;
         IsCompleted = true;
     }
     else
     {
         float distanceFactor = 1;
         if (!isPriority && Item.CurrentHull != character.CurrentHull)
         {
             float yDist = Math.Abs(character.WorldPosition.Y - Item.WorldPosition.Y);
             yDist = yDist > 100 ? yDist * 5 : 0;
             float dist = Math.Abs(character.WorldPosition.X - Item.WorldPosition.X) + yDist;
             distanceFactor = MathHelper.Lerp(1, 0.25f, MathUtils.InverseLerp(0, 4000, dist));
         }
         float requiredSuccessFactor = objectiveManager.HasOrder <AIObjectiveRepairItems>() ? 0 : AIObjectiveRepairItems.RequiredSuccessFactor;
         float severity      = isPriority ? 1 : AIObjectiveRepairItems.GetTargetPriority(Item, character, requiredSuccessFactor) / 100;
         bool  isSelected    = IsRepairing();
         float selectedBonus = isSelected ? 100 - MaxDevotion : 0;
         float devotion      = (CumulatedDevotion + selectedBonus) / 100;
         float reduction     = isPriority ? 1 : isSelected ? 2 : 3;
         float max           = AIObjectiveManager.LowestOrderPriority - reduction;
         float highestWeight = -1;
         foreach (string tag in Item.Prefab.Tags)
         {
             if (JobPrefab.ItemRepairPriorities.TryGetValue(tag, out float weight) && weight > highestWeight)
             {
                 highestWeight = weight;
             }
         }
         if (highestWeight == -1)
         {
             // Predefined weight not found.
             highestWeight = 1;
         }
         Priority = MathHelper.Lerp(0, max, MathHelper.Clamp(devotion + (severity * distanceFactor * highestWeight * PriorityModifier), 0, 1));
     }
     return(Priority);
 }
Example #5
0
        public AIObjective CreateObjective(Order order, string option, Character orderGiver, float priorityModifier = 1)
        {
            if (order == null)
            {
                return(null);
            }
            AIObjective newObjective;

            switch (order.AITag.ToLowerInvariant())
            {
            case "follow":
                if (orderGiver == null)
                {
                    return(null);
                }
                newObjective = new AIObjectiveGoTo(orderGiver, character, this, repeat: true, priorityModifier: priorityModifier)
                {
                    CloseEnough               = 100,
                    AllowGoingOutside         = true,
                    IgnoreIfTargetDead        = true,
                    followControlledCharacter = orderGiver == character,
                    mimic = true
                };
                break;

            case "wait":
                newObjective = new AIObjectiveGoTo(character, character, this, repeat: true, priorityModifier: priorityModifier)
                {
                    AllowGoingOutside = true
                };
                break;

            case "fixleaks":
                newObjective = new AIObjectiveFixLeaks(character, this, priorityModifier);
                break;

            case "chargebatteries":
                newObjective = new AIObjectiveChargeBatteries(character, this, option, priorityModifier);
                break;

            case "rescue":
                newObjective = new AIObjectiveRescueAll(character, this, priorityModifier);
                break;

            case "repairsystems":
                newObjective = new AIObjectiveRepairItems(character, this, priorityModifier)
                {
                    RequireAdequateSkills = option == "jobspecific"
                };
                break;

            case "pumpwater":
                newObjective = new AIObjectivePumpWater(character, this, option, priorityModifier: priorityModifier);
                break;

            case "extinguishfires":
                newObjective = new AIObjectiveExtinguishFires(character, this, priorityModifier);
                break;

            case "fightintruders":
                newObjective = new AIObjectiveFightIntruders(character, this, priorityModifier);
                break;

            case "steer":
                var steering = (order?.TargetEntity as Item)?.GetComponent <Steering>();
                if (steering != null)
                {
                    steering.PosToMaintain = steering.Item.Submarine?.WorldPosition;
                }
                if (order.TargetItemComponent == null)
                {
                    return(null);
                }
                newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, this, option, requireEquip: false, useController: order.UseController, priorityModifier: priorityModifier)
                {
                    IsLoop = true
                };
                break;

            default:
                if (order.TargetItemComponent == null)
                {
                    return(null);
                }
                newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, this, option, requireEquip: false, useController: order.UseController, priorityModifier: priorityModifier)
                {
                    IsLoop = true
                };
                break;
            }
            return(newObjective);
        }
Example #6
0
        public AIObjective CreateObjective(Order order, string option, Character orderGiver, bool isAutonomous, float priorityModifier = 1)
        {
            if (order == null || order.Identifier == "dismissed")
            {
                return(null);
            }
            AIObjective newObjective;

            switch (order.Identifier.ToLowerInvariant())
            {
            case "follow":
                if (orderGiver == null)
                {
                    return(null);
                }
                newObjective = new AIObjectiveGoTo(orderGiver, character, this, repeat: true, priorityModifier: priorityModifier)
                {
                    CloseEnough                = Rand.Range(90, 100) + Rand.Range(50, 70) * Math.Min(HumanAIController.CountCrew(c => c.ObjectiveManager.CurrentOrder is AIObjectiveGoTo gotoOrder && gotoOrder.Target == orderGiver, onlyBots: true), 4),
                    extraDistanceOutsideSub    = 100,
                    extraDistanceWhileSwimming = 100,
                    AllowGoingOutside          = true,
                    IgnoreIfTargetDead         = true,
                    followControlledCharacter  = true,
                    mimic = true,
                    DialogueIdentifier = "dialogcannotreachplace"
                };
                break;

            case "wait":
                newObjective = new AIObjectiveGoTo(order.TargetSpatialEntity ?? character, character, this, repeat: true, priorityModifier: priorityModifier)
                {
                    AllowGoingOutside = character.Submarine == null || (order.TargetSpatialEntity != null && character.Submarine != order.TargetSpatialEntity.Submarine)
                };
                break;

            case "fixleaks":
                newObjective = new AIObjectiveFixLeaks(character, this, priorityModifier: priorityModifier, prioritizedHull: order.TargetEntity as Hull);
                break;

            case "chargebatteries":
                newObjective = new AIObjectiveChargeBatteries(character, this, option, priorityModifier);
                break;

            case "rescue":
                newObjective = new AIObjectiveRescueAll(character, this, priorityModifier);
                break;

            case "repairsystems":
            case "repairmechanical":
            case "repairelectrical":
                newObjective = new AIObjectiveRepairItems(character, this, priorityModifier: priorityModifier, prioritizedItem: order.TargetEntity as Item)
                {
                    RelevantSkill         = order.AppropriateSkill,
                    RequireAdequateSkills = isAutonomous
                };
                break;

            case "pumpwater":
                if (order.TargetItemComponent is Pump targetPump)
                {
                    if (!order.TargetItemComponent.Item.IsInteractable(character))
                    {
                        return(null);
                    }
                    newObjective = new AIObjectiveOperateItem(targetPump, character, this, option, false, priorityModifier: priorityModifier)
                    {
                        IsLoop   = true,
                        Override = orderGiver != null && orderGiver.IsPlayer
                    };
                    // ItemComponent.AIOperate() returns false by default -> We'd have to set IsLoop = false and implement a custom override of AIOperate for the Pump.cs,
                    // if we want that the bot just switches the pump on/off and continues doing something else.
                    // If we want that the bot does the objective and then forgets about it, I think we could do the same plus dismiss when the bot is done.
                }
                else
                {
                    newObjective = new AIObjectivePumpWater(character, this, option, priorityModifier: priorityModifier);
                }
                break;

            case "extinguishfires":
                newObjective = new AIObjectiveExtinguishFires(character, this, priorityModifier);
                break;

            case "fightintruders":
                newObjective = new AIObjectiveFightIntruders(character, this, priorityModifier);
                break;

            case "steer":
                var steering = (order?.TargetEntity as Item)?.GetComponent <Steering>();
                if (steering != null)
                {
                    steering.PosToMaintain = steering.Item.Submarine?.WorldPosition;
                }
                if (order.TargetItemComponent == null)
                {
                    return(null);
                }
                if (!order.TargetItemComponent.Item.IsInteractable(character))
                {
                    return(null);
                }
                newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, this, option,
                                                          requireEquip: false, useController: order.UseController, controller: order.ConnectedController, priorityModifier: priorityModifier)
                {
                    IsLoop = true,
                    // Don't override unless it's an order by a player
                    Override = orderGiver != null && orderGiver.IsPlayer
                };
                break;

            case "setchargepct":
                newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, this, option, false, priorityModifier: priorityModifier)
                {
                    IsLoop              = false,
                    Override            = !character.IsDismissed,
                    completionCondition = () =>
                    {
                        if (float.TryParse(option, out float pct))
                        {
                            var targetRatio  = Math.Clamp(pct, 0f, 1f);
                            var currentRatio = (order.TargetItemComponent as PowerContainer).RechargeRatio;
                            return(Math.Abs(targetRatio - currentRatio) < 0.05f);
                        }
                        return(true);
                    }
                };
                break;

            case "getitem":
                newObjective = new AIObjectiveGetItem(character, order.TargetEntity as Item ?? order.TargetItemComponent?.Item, this, false, priorityModifier: priorityModifier)
                {
                    MustBeSpecificItem = true
                };
                break;

            case "cleanupitems":
                if (order.TargetEntity is Item targetItem)
                {
                    if (targetItem.HasTag("allowcleanup") && targetItem.ParentInventory == null && targetItem.OwnInventory != null)
                    {
                        // Target all items inside the container
                        newObjective = new AIObjectiveCleanupItems(character, this, targetItem.OwnInventory.AllItems, priorityModifier);
                    }
                    else
                    {
                        newObjective = new AIObjectiveCleanupItems(character, this, targetItem, priorityModifier);
                    }
                }
                else
                {
                    newObjective = new AIObjectiveCleanupItems(character, this, priorityModifier: priorityModifier);
                }
                break;

            default:
                if (order.TargetItemComponent == null)
                {
                    return(null);
                }
                if (!order.TargetItemComponent.Item.IsInteractable(character))
                {
                    return(null);
                }
                newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, this, option,
                                                          requireEquip: false, useController: order.UseController, controller: order.ConnectedController, priorityModifier: priorityModifier)
                {
                    IsLoop = true,
                    // Don't override unless it's an order by a player
                    Override = orderGiver != null && orderGiver.IsPlayer
                };
                if (newObjective.Abandon)
                {
                    return(null);
                }
                break;
            }
            return(newObjective);
        }
        public AIObjective CreateObjective(Order order, string option, Character orderGiver, bool isAutonomous, float priorityModifier = 1)
        {
            if (order == null)
            {
                return(null);
            }
            AIObjective newObjective;

            switch (order.Identifier.ToLowerInvariant())
            {
            case "follow":
                if (orderGiver == null)
                {
                    return(null);
                }
                newObjective = new AIObjectiveGoTo(orderGiver, character, this, repeat: true, priorityModifier: priorityModifier)
                {
                    CloseEnough               = 100,
                    AllowGoingOutside         = true,
                    IgnoreIfTargetDead        = true,
                    followControlledCharacter = orderGiver == character,
                    mimic = true,
                    DialogueIdentifier = "dialogcannotreachplace"
                };
                break;

            case "wait":
                newObjective = new AIObjectiveGoTo(order.TargetEntity ?? character, character, this, repeat: true, priorityModifier: priorityModifier)
                {
                    AllowGoingOutside = character.CurrentHull == null
                };
                break;

            case "fixleaks":
                newObjective = new AIObjectiveFixLeaks(character, this, priorityModifier: priorityModifier, prioritizedHull: order.TargetEntity as Hull);
                break;

            case "chargebatteries":
                newObjective = new AIObjectiveChargeBatteries(character, this, option, priorityModifier);
                break;

            case "rescue":
                newObjective = new AIObjectiveRescueAll(character, this, priorityModifier);
                break;

            case "repairsystems":
            case "repairmechanical":
            case "repairelectrical":
                newObjective = new AIObjectiveRepairItems(character, this, priorityModifier: priorityModifier, prioritizedItem: order.TargetEntity as Item)
                {
                    RelevantSkill         = order.AppropriateSkill,
                    RequireAdequateSkills = isAutonomous
                };
                break;

            case "pumpwater":
                if (order.TargetItemComponent is Pump targetPump)
                {
                    if (order.TargetItemComponent.Item.NonInteractable)
                    {
                        return(null);
                    }
                    newObjective = new AIObjectiveOperateItem(targetPump, character, this, option, false, priorityModifier: priorityModifier)
                    {
                        IsLoop   = true,
                        Override = orderGiver != null && orderGiver.IsPlayer
                    };
                    // ItemComponent.AIOperate() returns false by default -> We'd have to set IsLoop = false and implement a custom override of AIOperate for the Pump.cs,
                    // if we want that the bot just switches the pump on/off and continues doing something else.
                    // If we want that the bot does the objective and then forgets about it, I think we could do the same plus dismiss when the bot is done.
                }
                else
                {
                    newObjective = new AIObjectivePumpWater(character, this, option, priorityModifier: priorityModifier);
                }
                break;

            case "extinguishfires":
                newObjective = new AIObjectiveExtinguishFires(character, this, priorityModifier);
                break;

            case "fightintruders":
                newObjective = new AIObjectiveFightIntruders(character, this, priorityModifier);
                break;

            case "steer":
                var steering = (order?.TargetEntity as Item)?.GetComponent <Steering>();
                if (steering != null)
                {
                    steering.PosToMaintain = steering.Item.Submarine?.WorldPosition;
                }
                if (order.TargetItemComponent == null)
                {
                    return(null);
                }
                if (order.TargetItemComponent.Item.NonInteractable)
                {
                    return(null);
                }
                newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, this, option,
                                                          requireEquip: false, useController: order.UseController, controller: order.ConnectedController, priorityModifier: priorityModifier)
                {
                    IsLoop = true,
                    // Don't override unless it's an order by a player
                    Override = orderGiver != null && orderGiver.IsPlayer
                };
                break;

            default:
                if (order.TargetItemComponent == null)
                {
                    return(null);
                }
                if (order.TargetItemComponent.Item.NonInteractable)
                {
                    return(null);
                }
                newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, this, option,
                                                          requireEquip: false, useController: order.UseController, controller: order.ConnectedController, priorityModifier: priorityModifier)
                {
                    IsLoop = true,
                    // Don't override unless it's an order by a player
                    Override = orderGiver != null && orderGiver.IsPlayer
                };
                if (newObjective.Abandon)
                {
                    return(null);
                }
                break;
            }
            return(newObjective);
        }
Example #8
0
        protected void ReportProblems()
        {
            Order newOrder = null;

            if (Character.CurrentHull != null)
            {
                foreach (var hull in VisibleHulls)
                {
                    foreach (Character c in Character.CharacterList)
                    {
                        if (c.CurrentHull != hull)
                        {
                            continue;
                        }
                        if (AIObjectiveFightIntruders.IsValidTarget(c, Character))
                        {
                            AddTargets <AIObjectiveFightIntruders, Character>(Character, c);
                            if (newOrder == null)
                            {
                                var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportintruders");
                                newOrder = new Order(orderPrefab, c.CurrentHull, null, orderGiver: Character);
                            }
                        }
                    }
                    if (AIObjectiveExtinguishFires.IsValidTarget(hull, Character))
                    {
                        AddTargets <AIObjectiveExtinguishFires, Hull>(Character, hull);
                        if (newOrder == null)
                        {
                            var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportfire");
                            newOrder = new Order(orderPrefab, hull, null, orderGiver: Character);
                        }
                    }
                    foreach (Character c in Character.CharacterList)
                    {
                        if (c.CurrentHull != hull)
                        {
                            continue;
                        }
                        if (AIObjectiveRescueAll.IsValidTarget(c, Character))
                        {
                            if (AddTargets <AIObjectiveRescueAll, Character>(c, Character))
                            {
                                if (newOrder == null)
                                {
                                    var orderPrefab = Order.PrefabList.Find(o => o.AITag == "requestfirstaid");
                                    newOrder = new Order(orderPrefab, c.CurrentHull, null, orderGiver: Character);
                                }
                            }
                        }
                    }
                    foreach (var gap in hull.ConnectedGaps)
                    {
                        if (AIObjectiveFixLeaks.IsValidTarget(gap, Character))
                        {
                            AddTargets <AIObjectiveFixLeaks, Gap>(Character, gap);
                            if (newOrder == null && !gap.IsRoomToRoom)
                            {
                                var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportbreach");
                                newOrder = new Order(orderPrefab, hull, null, orderGiver: Character);
                            }
                        }
                    }
                    foreach (Item item in Item.ItemList)
                    {
                        if (item.CurrentHull != hull)
                        {
                            continue;
                        }
                        if (AIObjectiveRepairItems.IsValidTarget(item, Character))
                        {
                            if (item.Repairables.All(r => item.Condition > r.ShowRepairUIThreshold))
                            {
                                continue;
                            }
                            AddTargets <AIObjectiveRepairItems, Item>(Character, item);
                            if (newOrder == null)
                            {
                                var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportbrokendevices");
                                newOrder = new Order(orderPrefab, item.CurrentHull, item.Repairables?.FirstOrDefault(), orderGiver: Character);
                            }
                        }
                    }
                }
            }
            if (newOrder != null)
            {
                if (GameMain.GameSession?.CrewManager != null && GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime))
                {
                    Character.Speak(newOrder.GetChatMessage("", Character.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order);
#if SERVER
                    GameMain.Server.SendOrderChatMessage(new OrderChatMessage(newOrder, "", Character.CurrentHull, null, Character));
#endif
                }
            }
        }
Example #9
0
        public void SetOrder(Order order, string option, Character orderGiver)
        {
            CurrentOrder = null;
            if (order == null)
            {
                return;
            }

            switch (order.AITag.ToLowerInvariant())
            {
            case "follow":
                CurrentOrder = new AIObjectiveGoTo(orderGiver, character, true)
                {
                    CloseEnough               = 1.5f,
                    AllowGoingOutside         = true,
                    IgnoreIfTargetDead        = true,
                    FollowControlledCharacter = orderGiver == character
                };
                break;

            case "wait":
                CurrentOrder = new AIObjectiveGoTo(character, character, true)
                {
                    AllowGoingOutside = true
                };
                break;

            case "fixleaks":
                CurrentOrder = new AIObjectiveFixLeaks(character);
                break;

            case "chargebatteries":
                CurrentOrder = new AIObjectiveChargeBatteries(character, option);
                break;

            case "rescue":
                CurrentOrder = new AIObjectiveRescueAll(character);
                break;

            case "repairsystems":
                CurrentOrder = new AIObjectiveRepairItems(character)
                {
                    RequireAdequateSkills = option != "all"
                };
                break;

            case "pumpwater":
                CurrentOrder = new AIObjectivePumpWater(character, option);
                break;

            case "extinguishfires":
                CurrentOrder = new AIObjectiveExtinguishFires(character);
                break;

            case "steer":
                var steering = (order?.TargetEntity as Item)?.GetComponent <Steering>();
                if (steering != null)
                {
                    steering.PosToMaintain = steering.Item.Submarine?.WorldPosition;
                }
                if (order.TargetItemComponent == null)
                {
                    return;
                }
                CurrentOrder = new AIObjectiveOperateItem(order.TargetItemComponent, character, option, false, null, order.UseController);
                break;

            default:
                if (order.TargetItemComponent == null)
                {
                    return;
                }
                CurrentOrder = new AIObjectiveOperateItem(order.TargetItemComponent, character, option, false, null, order.UseController);
                break;
            }
        }
Example #10
0
        public AIObjective CreateObjective(Order order, string option, Character orderGiver, float priorityModifier = 1)
        {
            if (order == null)
            {
                return(null);
            }
            AIObjective newObjective;

            switch (order.Identifier.ToLowerInvariant())
            {
            case "follow":
                if (orderGiver == null)
                {
                    return(null);
                }
                newObjective = new AIObjectiveGoTo(orderGiver, character, this, repeat: true, priorityModifier: priorityModifier)
                {
                    CloseEnough               = 100,
                    AllowGoingOutside         = true,
                    IgnoreIfTargetDead        = true,
                    followControlledCharacter = orderGiver == character,
                    mimic = true,
                    DialogueIdentifier = "dialogcannotreachplace"
                };
                break;

            case "wait":
                newObjective = new AIObjectiveGoTo(order.TargetEntity ?? character, character, this, repeat: true, priorityModifier: priorityModifier)
                {
                    AllowGoingOutside = character.CurrentHull == null
                };
                break;

            case "fixleaks":
                newObjective = new AIObjectiveFixLeaks(character, this, priorityModifier: priorityModifier, prioritizedHull: order.TargetEntity as Hull);
                break;

            case "chargebatteries":
                newObjective = new AIObjectiveChargeBatteries(character, this, option, priorityModifier);
                break;

            case "rescue":
                newObjective = new AIObjectiveRescueAll(character, this, priorityModifier);
                break;

            case "repairsystems":
            case "repairmechanical":
            case "repairelectrical":
                newObjective = new AIObjectiveRepairItems(character, this, priorityModifier: priorityModifier, prioritizedItem: order.TargetEntity as Item)
                {
                    RelevantSkill         = order.AppropriateSkill,
                    RequireAdequateSkills = option == "jobspecific"
                };
                break;

            case "pumpwater":
                if (order.TargetItemComponent is Pump targetPump)
                {
                    newObjective = new AIObjectiveOperateItem(targetPump, character, this, option, false, priorityModifier: priorityModifier);
                    // newObjective.Completed += DismissSelf;
                }
                else
                {
                    newObjective = new AIObjectivePumpWater(character, this, option, priorityModifier: priorityModifier);
                }
                break;

            case "extinguishfires":
                newObjective = new AIObjectiveExtinguishFires(character, this, priorityModifier);
                break;

            case "fightintruders":
                newObjective = new AIObjectiveFightIntruders(character, this, priorityModifier);
                break;

            case "steer":
                var steering = (order?.TargetEntity as Item)?.GetComponent <Steering>();
                if (steering != null)
                {
                    steering.PosToMaintain = steering.Item.Submarine?.WorldPosition;
                }
                if (order.TargetItemComponent == null)
                {
                    return(null);
                }
                newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, this, option, requireEquip: false, useController: order.UseController, priorityModifier: priorityModifier)
                {
                    IsLoop = true,
                    // Don't override unless it's an order by a player
                    Override = orderGiver != null && orderGiver.IsPlayer
                };
                break;

            default:
                if (order.TargetItemComponent == null)
                {
                    return(null);
                }
                newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, this, option, requireEquip: false, useController: order.UseController, priorityModifier: priorityModifier)
                {
                    IsLoop = true,
                    // Don't override unless it's an order by a player
                    Override = orderGiver != null && orderGiver.IsPlayer
                };
                break;
            }
            return(newObjective);
        }