Example #1
0
        public override bool IsDuplicate(AIObjective otherObjective)
        {
            AIObjectiveGetItem getItem = otherObjective as AIObjectiveGetItem;

            if (getItem == null)
            {
                return(false);
            }
            if (getItem.equip != equip)
            {
                return(false);
            }
            if (getItem.itemIdentifiers != null && itemIdentifiers != null)
            {
                if (getItem.itemIdentifiers.Length != itemIdentifiers.Length)
                {
                    return(false);
                }
                for (int i = 0; i < getItem.itemIdentifiers.Length; i++)
                {
                    if (getItem.itemIdentifiers[i] != itemIdentifiers[i])
                    {
                        return(false);
                    }
                }
                return(true);
            }
            else if (getItem.itemIdentifiers == null && itemIdentifiers == null)
            {
                return(getItem.targetItem == targetItem);
            }

            return(false);
        }
 public override void Reset()
 {
     base.Reset();
     getItemObjective = null;
     goToObjective    = null;
     containedItems.Clear();
 }
 public override void Reset()
 {
     base.Reset();
     getDivingGear = null;
     getOxygen     = null;
     targetItem    = null;
 }
Example #4
0
        protected override void Act(float deltaTime)
        {
            //get the item that should be contained
            Item itemToContain = null;

            foreach (string identifier in itemIdentifiers)
            {
                itemToContain = character.Inventory.FindItemByIdentifier(identifier) ?? character.Inventory.FindItemByTag(identifier);
                if (itemToContain != null && itemToContain.Condition > 0.0f)
                {
                    break;
                }
            }
            if (itemToContain == null)
            {
                if (getItemObjective != null)
                {
                    if (getItemObjective.IsCompleted())
                    {
                        if (getItemObjective.TargetItem != null)
                        {
                            containedItems.Add(getItemObjective.TargetItem);
                        }
                        else
                        {
                            // Reduce the target item count to prevent getting stuck here, if the target item for some reason is null, which shouldn't happen.
                            targetItemCount--;
                        }
                        getItemObjective = null;
                    }
                    else if (!getItemObjective.CanBeCompleted)
                    {
                        getItemObjective = null;
                        targetItemCount--;
                    }
                }
                TryAddSubObjective(ref getItemObjective, () =>
                                   new AIObjectiveGetItem(character, itemIdentifiers, objectiveManager, checkInventory: checkInventory)
                {
                    GetItemPriority             = GetItemPriority,
                    ignoredContainerIdentifiers = ignoredContainerIdentifiers,
                    ignoredItems = containedItems
                });
                return;
            }
            if (container.Item.ParentInventory == character.Inventory)
            {
                character.Inventory.RemoveItem(itemToContain);
                container.Inventory.TryPutItem(itemToContain, null);
            }
            else
            {
                if (!character.CanInteractWith(container.Item, out _, checkLinked: false))
                {
                    TryAddSubObjective(ref goToObjective, () => new AIObjectiveGoTo(container.Item, character, objectiveManager));
                    return;
                }
                container.Combine(itemToContain);
            }
        }
Example #5
0
 public override void Reset()
 {
     base.Reset();
     getWeldingTool   = null;
     refuelObjective  = null;
     gotoObjective    = null;
     operateObjective = null;
 }
 public override void Reset()
 {
     base.Reset();
     getExtinguisherObjective = null;
     gotoObjective            = null;
     useExtinquisherTimer     = 0;
     sinTime = 0;
 }
Example #7
0
 public override void Reset()
 {
     base.Reset();
     goToObjective          = null;
     getItemObjective       = null;
     replaceOxygenObjective = null;
     safeHull     = null;
     ignoreOxygen = false;
 }
Example #8
0
        protected override void Act(float deltaTime)
        {
            if (isCompleted)
            {
                return;
            }

            //get the item that should be contained
            Item itemToContain = null;

            foreach (string identifier in itemIdentifiers)
            {
                itemToContain = character.Inventory.FindItemByIdentifier(identifier) ?? character.Inventory.FindItemByTag(identifier);
                if (itemToContain != null && itemToContain.Condition > 0.0f)
                {
                    break;
                }
            }

            if (itemToContain == null)
            {
                getItemObjective = new AIObjectiveGetItem(character, itemIdentifiers)
                {
                    GetItemPriority             = GetItemPriority,
                    ignoredContainerIdentifiers = ignoredContainerIdentifiers
                };
                AddSubObjective(getItemObjective);
                return;
            }

            if (container.Item.ParentInventory == character.Inventory)
            {
                var containedItems = container.Inventory.Items;
                //if there's already something in the mask (empty oxygen tank?), drop it
                var existingItem = containedItems.FirstOrDefault(i => i != null);
                if (existingItem != null)
                {
                    existingItem.Drop(character);
                }

                character.Inventory.RemoveItem(itemToContain);
                container.Inventory.TryPutItem(itemToContain, null);
            }
            else
            {
                if (container.Item.CurrentHull != character.CurrentHull || (Vector2.Distance(character.Position, container.Item.Position) > container.Item.InteractDistance && !container.Item.IsInsideTrigger(character.WorldPosition)))
                {
                    goToObjective = new AIObjectiveGoTo(container.Item, character);
                    AddSubObjective(goToObjective);
                    return;
                }
                container.Combine(itemToContain);
            }

            isCompleted = true;
        }
        public override bool IsDuplicate(AIObjective otherObjective)
        {
            AIObjectiveGetItem getItem = otherObjective as AIObjectiveGetItem;

            if (getItem == null)
            {
                return(false);
            }
            return(getItem.itemName == itemName);
        }
        protected override void Act(float deltaTime)
        {
            if (isCompleted)
            {
                return;
            }

            //get the item that should be contained
            var itemToContain = character.Inventory.FindItem(itemNames);

            if (itemToContain == null)
            {
                getItemObjective = new AIObjectiveGetItem(character, itemNames);
                getItemObjective.GetItemPriority      = GetItemPriority;
                getItemObjective.IgnoreContainedItems = IgnoreAlreadyContainedItems;
                AddSubObjective(getItemObjective);
                return;
            }

            if (container.Item.ParentInventory == character.Inventory)
            {
                var containedItems = container.Inventory.Items;
                //if there's already something in the mask (empty oxygen tank?), drop it
                var existingItem = containedItems.FirstOrDefault(i => i != null);
                if (existingItem != null)
                {
                    existingItem.Drop(character);
                }

                character.Inventory.RemoveItem(itemToContain);
                container.Inventory.TryPutItem(itemToContain, null);
            }
            else
            {
                if (Vector2.Distance(character.Position, container.Item.Position) > container.Item.InteractDistance &&
                    !container.Item.IsInsideTrigger(character.WorldPosition))
                {
                    goToObjective = new AIObjectiveGoTo(container.Item, character);
                    AddSubObjective(goToObjective);
                    return;
                }

                container.Combine(itemToContain);
            }

            isCompleted = true;
        }
Example #11
0
        protected override void Act(float deltaTime)
        {
            // Only continue when the get item sub objectives have been completed.
            if (subObjectives.Any())
            {
                return;
            }
            foreach (Repairable repairable in Item.Repairables)
            {
                if (!repairable.HasRequiredItems(character, false))
                {
                    //make sure we have all the items required to fix the target item
                    foreach (var kvp in repairable.requiredItems)
                    {
                        foreach (RelatedItem requiredItem in kvp.Value)
                        {
                            var getItemObjective = new AIObjectiveGetItem(character, requiredItem.Identifiers, objectiveManager, true);
                            if (objectiveManager.IsCurrentOrder <AIObjectiveRepairItems>())
                            {
                                if (character.IsOnPlayerTeam)
                                {
                                    getItemObjective.Abandoned += () => character.Speak(TextManager.Get("dialogcannotfindrequireditemtorepair"), null, 0.0f, "dialogcannotfindrequireditemtorepair", 10.0f);
                                }
                            }
                            subObjectives.Add(getItemObjective);
                        }
                    }
                    return;
                }
            }
            if (repairTool == null)
            {
                FindRepairTool();
            }
            if (repairTool != null)
            {
                if (repairTool.Item.OwnInventory == null)
                {
#if DEBUG
                    DebugConsole.ThrowError($"{character.Name}: AIObjectiveRepairItem failed - the item \"" + repairTool + "\" has no proper inventory");
#endif
                    Abandon = true;
                    return;
                }
                HumanAIController.UnequipContainedItems(repairTool.Item, it => !it.HasTag("weldingfuel"));
                HumanAIController.UnequipEmptyItems(repairTool.Item);
                RelatedItem item = null;
                Item        fuel = null;
                foreach (RelatedItem requiredItem in repairTool.requiredItems[RelatedItem.RelationType.Contained])
                {
                    item = requiredItem;
                    fuel = repairTool.Item.OwnInventory.AllItems.FirstOrDefault(it => it.Condition > 0.0f && requiredItem.MatchesItem(it));
                    if (fuel != null)
                    {
                        break;
                    }
                }
                if (fuel == null)
                {
                    RemoveSubObjective(ref goToObjective);
                    TryAddSubObjective(ref refuelObjective, () => new AIObjectiveContainItem(character, item.Identifiers, repairTool.Item.GetComponent <ItemContainer>(), objectiveManager, spawnItemIfNotFound: character.TeamID == CharacterTeamType.FriendlyNPC),
                                       onCompleted: () => RemoveSubObjective(ref refuelObjective),
                                       onAbandon: () => Abandon = true);
                    return;
                }
            }
            if (!character.IsClimbing && character.CanInteractWith(Item, out _, checkLinked: false))
            {
                HumanAIController.FaceTarget(Item);
                if (repairTool != null)
                {
                    OperateRepairTool(deltaTime);
                }
                foreach (Repairable repairable in Item.Repairables)
                {
                    if (repairable.CurrentFixer != null && repairable.CurrentFixer != character)
                    {
                        // Someone else is repairing the target. Abandon the objective if the other is better at this than us.
                        Abandon = repairable.CurrentFixer.IsPlayer || repairable.DegreeOfSuccess(character) < repairable.DegreeOfSuccess(repairable.CurrentFixer);
                    }
                    if (!Abandon)
                    {
                        if (character.SelectedConstruction != Item)
                        {
                            if (!Item.TryInteract(character, ignoreRequiredItems: true, forceSelectKey: true) &&
                                !Item.TryInteract(character, ignoreRequiredItems: true, forceActionKey: true))
                            {
                                Abandon = true;
                            }
                        }
                        if (previousCondition == -1)
                        {
                            previousCondition = Item.Condition;
                        }
                        else if (Item.Condition < previousCondition)
                        {
                            // If the current condition is less than the previous condition, we can't complete the task, so let's abandon it. The item is probably deteriorating at a greater speed than we can repair it.
                            Abandon = true;
                        }
                    }
                    if (Abandon)
                    {
                        if (character.IsOnPlayerTeam && IsRepairing())
                        {
                            character.Speak(TextManager.GetWithVariable("DialogCannotRepair", "[itemname]", Item.Name, true), null, 0.0f, "cannotrepair", 10.0f);
                        }
                        repairable.StopRepairing(character);
                    }
                    else if (repairable.CurrentFixer != character)
                    {
                        repairable.StartRepairing(character, Repairable.FixActions.Repair);
                    }
                    break;
                }
            }
            else
            {
                RemoveSubObjective(ref refuelObjective);
                // If cannot reach the item, approach it.
                TryAddSubObjective(ref goToObjective,
                                   constructor: () =>
                {
                    previousCondition = -1;
                    var objective     = new AIObjectiveGoTo(Item, character, objectiveManager)
                    {
                        // Don't stop in ladders, because we can't interact with other items while holding the ladders.
                        endNodeFilter = node => node.Waypoint.Ladders == null
                    };
                    if (repairTool != null)
                    {
                        objective.CloseEnough = repairTool.Range * 0.75f;
                    }
                    return(objective);
                },
                                   onAbandon: () =>
                {
                    Abandon = true;
                    if (character.IsOnPlayerTeam && IsRepairing())
                    {
                        character.Speak(TextManager.GetWithVariable("DialogCannotRepair", "[itemname]", Item.Name, true), null, 0.0f, "cannotrepair", 10.0f);
                    }
                });
            }
        }
Example #12
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 override void Reset()
 {
     base.Reset();
     goToObjective    = null;
     getItemObjective = null;
 }
        protected override void Act(float deltaTime)
        {
            var extinguisherItem = character.Inventory.FindItemByTag("fireextinguisher");

            if (extinguisherItem == null || extinguisherItem.Condition <= 0.0f || !character.HasEquippedItem(extinguisherItem))
            {
                TryAddSubObjective(ref getExtinguisherObjective, () =>
                {
                    if (character.IsOnPlayerTeam && !character.HasEquippedItem("fireextinguisher", allowBroken: false))
                    {
                        character.Speak(TextManager.Get("DialogFindExtinguisher"), null, 2.0f, "findextinguisher", 30.0f);
                    }
                    var getItemObjective = new AIObjectiveGetItem(character, "fireextinguisher", objectiveManager, equip: true)
                    {
                        AllowStealing = true,
                        // If the item is inside an unsafe hull, decrease the priority
                        GetItemPriority = i => HumanAIController.UnsafeHulls.Contains(i.CurrentHull) ? 0.1f : 1
                    };
                    if (objectiveManager.HasOrder <AIObjectiveExtinguishFires>())
                    {
                        getItemObjective.Abandoned += () => character.Speak(TextManager.Get("dialogcannotfindfireextinguisher"), null, 0.0f, "dialogcannotfindfireextinguisher", 10.0f);
                    }
                    ;
                    return(getItemObjective);
                });
            }
            else
            {
                var extinguisher = extinguisherItem.GetComponent <RepairTool>();
                if (extinguisher == null)
                {
#if DEBUG
                    DebugConsole.ThrowError($"{character.Name}: AIObjectiveExtinguishFire failed - the item \"" + extinguisherItem + "\" has no RepairTool component but is tagged as an extinguisher");
#endif
                    Abandon = true;
                    return;
                }
                foreach (FireSource fs in targetHull.FireSources)
                {
                    float xDist   = Math.Abs(character.WorldPosition.X - fs.WorldPosition.X) - fs.DamageRange;
                    float yDist   = Math.Abs(character.WorldPosition.Y - fs.WorldPosition.Y);
                    bool  inRange = xDist + yDist < extinguisher.Range;
                    // Use the hull position, because the fire x pos is sometimes inside a wall -> the bot can't ever see it and continues running towards the wall.
                    ISpatialEntity lookTarget = character.CurrentHull == targetHull || character.CurrentHull.linkedTo.Contains(targetHull) ? targetHull : fs as ISpatialEntity;
                    bool           move       = !inRange || !character.CanSeeTarget(lookTarget);
                    if ((inRange && character.CanSeeTarget(lookTarget)) || useExtinquisherTimer > 0)
                    {
                        useExtinquisherTimer += deltaTime;
                        if (useExtinquisherTimer > 2.0f)
                        {
                            useExtinquisherTimer = 0.0f;
                        }
                        // Aim
                        character.CursorPosition = fs.Position;
                        Vector2 fromCharacterToFireSource = fs.WorldPosition - character.WorldPosition;
                        float   dist = fromCharacterToFireSource.Length();
                        character.CursorPosition += VectorExtensions.Forward(extinguisherItem.body.TransformedRotation + (float)Math.Sin(sinTime) / 2, dist / 2);
                        if (extinguisherItem.RequireAimToUse)
                        {
                            character.SetInput(InputType.Aim, false, true);
                            sinTime += deltaTime * 10;
                        }
                        character.SetInput(extinguisherItem.IsShootable ? InputType.Shoot : InputType.Use, false, true);
                        extinguisher.Use(deltaTime, character);
                        if (!targetHull.FireSources.Contains(fs))
                        {
                            character.Speak(TextManager.GetWithVariable("DialogPutOutFire", "[roomname]", targetHull.DisplayName, true), null, 0, "putoutfire", 10.0f);
                        }
                    }
                    if (move)
                    {
                        //go to the first firesource
                        if (TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(fs, character, objectiveManager, closeEnough: Math.Max(fs.DamageRange, extinguisher.Range * 0.7f))
                        {
                            DialogueIdentifier = "dialogcannotreachfire",
                            TargetName = fs.Hull.DisplayName
                        },
                                               onAbandon: () => Abandon = true,
                                               onCompleted: () => RemoveSubObjective(ref gotoObjective)))
                        {
                            gotoObjective.requiredCondition = () => targetHull == null || character.CanSeeTarget(targetHull);
                        }
                    }
                    else
                    {
                        character.AIController.SteeringManager.Reset();
                    }
                    break;
                }
            }
        }
 public override void Reset()
 {
     base.Reset();
     getItemObjective = null;
     containObjective = null;
 }
        protected override void Act(float deltaTime)
        {
            var extinguisherItem = character.Inventory.FindItemByIdentifier("extinguisher") ?? character.Inventory.FindItemByTag("extinguisher");

            if (extinguisherItem == null || extinguisherItem.Condition <= 0.0f || !character.HasEquippedItem(extinguisherItem))
            {
                if (getExtinguisherObjective == null)
                {
                    character.Speak(TextManager.Get("DialogFindExtinguisher"), null, 2.0f, "findextinguisher", 30.0f);
                    getExtinguisherObjective = new AIObjectiveGetItem(character, "extinguisher", true);
                }
                else
                {
                    getExtinguisherObjective.TryComplete(deltaTime);
                }

                return;
            }

            var extinguisher = extinguisherItem.GetComponent <RepairTool>();

            if (extinguisher == null)
            {
                DebugConsole.ThrowError("AIObjectiveExtinguishFire failed - the item \"" + extinguisherItem + "\" has no RepairTool component but is tagged as an extinguisher");
                return;
            }

            foreach (FireSource fs in targetHull.FireSources)
            {
                bool inRange = fs.IsInDamageRange(character, MathHelper.Clamp(fs.DamageRange * 1.5f, extinguisher.Range * 0.5f, extinguisher.Range));
                if (targetHull == character.CurrentHull && (inRange || useExtinquisherTimer > 0.0f))
                {
                    useExtinquisherTimer += deltaTime;
                    if (useExtinquisherTimer > 2.0f)
                    {
                        useExtinquisherTimer = 0.0f;
                    }

                    character.CursorPosition = fs.Position;
                    character.SetInput(InputType.Aim, false, true);
                    if (!character.IsClimbing)
                    {
                        character.AIController.SteeringManager.Reset();
                    }
                    extinguisher.Use(deltaTime, character);

                    if (!targetHull.FireSources.Contains(fs))
                    {
                        character.Speak(TextManager.Get("DialogPutOutFire").Replace("[roomname]", targetHull.Name), null, 0, "putoutfire", 10.0f);
                    }
                    return;
                }
                else
                {
                    //go to the first firesource
                    if (gotoObjective == null || !gotoObjective.CanBeCompleted || gotoObjective.IsCompleted())
                    {
                        gotoObjective = new AIObjectiveGoTo(ConvertUnits.ToSimUnits(fs.Position), character);
                    }
                    else
                    {
                        gotoObjective.TryComplete(deltaTime);
                    }
                    break;
                }
            }
        }