Exemple #1
0
        public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
        {
            if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
            {
                return(false);
            }
            character.AIController.SteeringManager.Reset();
            bool shutDown = objective.Option.Equals("shutdown", StringComparison.OrdinalIgnoreCase);

            IsActive = true;

            if (!shutDown)
            {
                float degreeOfSuccess = DegreeOfSuccess(character);
                float refuelLimit     = 0.3f;
                //characters with insufficient skill levels don't refuel the reactor
                if (degreeOfSuccess > refuelLimit)
                {
                    if (aiUpdateTimer > 0.0f)
                    {
                        aiUpdateTimer -= deltaTime;
                        return(false);
                    }
                    aiUpdateTimer = AIUpdateInterval;
                    // load more fuel if the current maximum output is only 50% of the current load
                    // or if the fuel rod is (almost) deplenished
                    float minCondition = fuelConsumptionRate * MathUtils.Pow2((degreeOfSuccess - refuelLimit) * 2);
                    if (NeedMoreFuel(minimumOutputRatio: 0.5f, minCondition: minCondition))
                    {
                        bool outOfFuel = false;
                        var  container = item.GetComponent <ItemContainer>();
                        if (objective.SubObjectives.None())
                        {
                            var containObjective = AIContainItems <Reactor>(container, character, objective, itemCount: 1, equip: true, removeEmpty: true, spawnItemIfNotFound: character.TeamID == CharacterTeamType.FriendlyNPC, dropItemOnDeselected: true);
                            containObjective.Completed += ReportFuelRodCount;
                            containObjective.Abandoned += ReportFuelRodCount;
                            character.Speak(TextManager.Get("DialogReactorFuel"), null, 0.0f, "reactorfuel", 30.0f);

                            void ReportFuelRodCount()
                            {
                                if (!character.IsOnPlayerTeam)
                                {
                                    return;
                                }
                                if (character.Submarine != Submarine.MainSub)
                                {
                                    return;
                                }
                                int remainingFuelRods = Submarine.MainSub.GetItems(false).Count(i => i.HasTag("reactorfuel") && i.Condition > 1);

                                if (remainingFuelRods == 0)
                                {
                                    character.Speak(TextManager.Get("DialogOutOfFuelRods"), null, 0.0f, "outoffuelrods", 30.0f);
                                    outOfFuel = true;
                                }
                                else if (remainingFuelRods < 3)
                                {
                                    character.Speak(TextManager.Get("DialogLowOnFuelRods"), null, 0.0f, "lowonfuelrods", 30.0f);
                                }
                            }
                        }
                        return(outOfFuel);
                    }
                    else
                    {
                        if (Item.ConditionPercentage <= 0 && AIObjectiveRepairItems.IsValidTarget(Item, character))
                        {
                            if (Item.Repairables.Average(r => r.DegreeOfSuccess(character)) > 0.4f)
                            {
                                objective.AddSubObjective(new AIObjectiveRepairItem(character, Item, objective.objectiveManager, isPriority: true));
                                return(false);
                            }
                            else
                            {
                                character.Speak(TextManager.Get("DialogReactorIsBroken"), identifier: "reactorisbroken", minDurationBetweenSimilar: 30.0f);
                            }
                        }
                        if (TooMuchFuel())
                        {
                            DropFuel(minCondition: 0.1f, maxCondition: 100);
                        }
                        else
                        {
                            DropFuel(minCondition: 0, maxCondition: 0);
                        }
                    }
                }
            }

            if (objective.Override)
            {
                if (lastUser != null && lastUser != character && lastUser != LastAIUser)
                {
                    if (lastUser.SelectedConstruction == item && character.IsOnPlayerTeam)
                    {
                        character.Speak(TextManager.Get("DialogReactorTaken"), null, 0.0f, "reactortaken", 10.0f);
                    }
                }
            }
            else if (LastUserWasPlayer && lastUser != null && lastUser.TeamID == character.TeamID)
            {
                return(true);
            }

            LastUser = LastAIUser = character;

            bool  prevAutoTemp      = autoTemp;
            bool  prevPowerOn       = _powerOn;
            float prevFissionRate   = targetFissionRate;
            float prevTurbineOutput = targetTurbineOutput;

            if (shutDown)
            {
                PowerOn             = false;
                AutoTemp            = false;
                targetFissionRate   = 0.0f;
                targetTurbineOutput = 0.0f;
                unsentChanges       = true;
                return(true);
            }
            else
            {
                PowerOn = true;
                if (objective.Override || !autoTemp)
                {
                    //characters with insufficient skill levels simply set the autotemp on instead of trying to adjust the temperature manually
                    if (degreeOfSuccess < 0.5f)
                    {
                        AutoTemp = true;
                    }
                    else
                    {
                        AutoTemp = false;
                        UpdateAutoTemp(MathHelper.Lerp(0.5f, 2.0f, degreeOfSuccess), 1.0f);
                    }
                }
#if CLIENT
                FissionRateScrollBar.BarScroll   = FissionRate / 100.0f;
                TurbineOutputScrollBar.BarScroll = TurbineOutput / 100.0f;
#endif
                if (autoTemp != prevAutoTemp ||
                    prevPowerOn != _powerOn ||
                    Math.Abs(prevFissionRate - targetFissionRate) > 1.0f ||
                    Math.Abs(prevTurbineOutput - targetTurbineOutput) > 1.0f)
                {
                    unsentChanges = true;
                }
                aiUpdateTimer = AIUpdateInterval;
                return(false);
            }


            void DropFuel(float minCondition, float maxCondition)
            {
                if (item.OwnInventory?.AllItems != null)
                {
                    var container = item.GetComponent <ItemContainer>();
                    foreach (Item item in item.OwnInventory.AllItemsMod)
                    {
                        if (item.ConditionPercentage <= maxCondition && item.ConditionPercentage >= minCondition)
                        {
                            item.Drop(character);
                            break;
                        }
                    }
                }
            }
        }
Exemple #2
0
        public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
        {
            character.AIController.SteeringManager.Reset();
            if (objective.Override)
            {
                if (user != character && user != null && user.SelectedConstruction == item && character.IsOnPlayerTeam)
                {
                    character.Speak(TextManager.Get("DialogSteeringTaken"), null, 0.0f, "steeringtaken", 10.0f);
                }
            }
            user = character;

            if (Item.ConditionPercentage <= 0 && AIObjectiveRepairItems.IsValidTarget(Item, character))
            {
                if (Item.Repairables.Average(r => r.DegreeOfSuccess(character)) > 0.4f)
                {
                    objective.AddSubObjective(new AIObjectiveRepairItem(character, Item, objective.objectiveManager, isPriority: true));
                    return(false);
                }
                else
                {
                    character.Speak(TextManager.Get("DialogNavTerminalIsBroken"), identifier: "navterminalisbroken", minDurationBetweenSimilar: 30.0f);
                }
            }

            if (!AutoPilot)
            {
                unsentChanges = true;
                AutoPilot     = true;
            }
            IncreaseSkillLevel(user, deltaTime);
            switch (objective.Option.ToLowerInvariant())
            {
            case "maintainposition":
                if (objective.Override)
                {
                    SetMaintainPosition();
                }
                break;

            case "navigateback":
                if (Level.IsLoadedOutpost)
                {
                    break;
                }
                if (DockingSources.Any(d => d.Docked))
                {
                    item.SendSignal("1", "toggle_docking");
                }
                if (objective.Override)
                {
                    if (MaintainPos || LevelEndSelected || !LevelStartSelected || navigateTactically)
                    {
                        unsentChanges = true;
                    }
                    SetDestinationLevelStart();
                }
                break;

            case "navigatetodestination":
                if (Level.IsLoadedOutpost)
                {
                    break;
                }
                if (DockingSources.Any(d => d.Docked))
                {
                    item.SendSignal("1", "toggle_docking");
                }
                if (objective.Override)
                {
                    if (MaintainPos || !LevelEndSelected || LevelStartSelected || navigateTactically)
                    {
                        unsentChanges = true;
                    }
                    SetDestinationLevelEnd();
                }
                break;

            case "navigatetactical":
                if (Level.IsLoadedOutpost)
                {
                    break;
                }
                if (DockingSources.Any(d => d.Docked))
                {
                    item.SendSignal("1", "toggle_docking");
                }
                if (objective.Override)
                {
                    if (MaintainPos || LevelEndSelected || LevelStartSelected || !navigateTactically)
                    {
                        unsentChanges = true;
                    }
                    SetDestinationTactical();
                }
                break;
            }
            sonar?.AIOperate(deltaTime, character, objective);
            if (!MaintainPos && showIceSpireWarning && character.IsOnPlayerTeam)
            {
                character.Speak(TextManager.Get("dialogicespirespottedsonar"), null, 0.0f, "icespirespottedsonar", 60.0f);
            }
            return(false);
        }