Beispiel #1
0
        public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
        {
            if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
            {
                return(false);
            }

            IsActive = true;

            float degreeOfSuccess = DegreeOfSuccess(character);

            //characters with insufficient skill levels don't refuel the reactor
            if (degreeOfSuccess > 0.2f)
            {
                if (objective.SubObjectives.None())
                {
                    var containedItems = item.ContainedItems;
                    foreach (Item fuelRod in containedItems)
                    {
                        if (fuelRod != null && fuelRod.Condition <= 0.0f)
                        {
                            if (!FindSuitableContainer(character,
                                                       i =>
                            {
                                var container = i.GetComponent <ItemContainer>();
                                if (container == null)
                                {
                                    return(0);
                                }
                                if (container.Inventory.IsFull())
                                {
                                    return(0);
                                }
                                if (container.ShouldBeContained(fuelRod, out bool isRestrictionsDefined))
                                {
                                    if (isRestrictionsDefined)
                                    {
                                        return(3);
                                    }
                                    else
                                    {
                                        if (fuelRod.Prefab.IsContainerPreferred(container, out bool isPreferencesDefined))
                                        {
                                            return(isPreferencesDefined ? 2 : 1);
                                        }
                                        else
                                        {
                                            return(isPreferencesDefined ? 0 : 1);
                                        }
                                    }
                                }
                                else
                                {
                                    return(0);
                                }
                            }, out Item targetContainer))
                            {
                                return(false);
                            }
                            var decontainObjective = new AIObjectiveDecontainItem(character, fuelRod, item.GetComponent <ItemContainer>(), objective.objectiveManager, targetContainer?.GetComponent <ItemContainer>());
                            decontainObjective.Abandoned += () =>
                            {
                                itemIndex = 0;
                                if (targetContainer != null)
                                {
                                    ignoredContainers.Add(targetContainer);
                                }
                            };
                            objective.AddSubObjectiveInQueue(decontainObjective);
                        }
                    }
                }

                if (aiUpdateTimer > 0.0f)
                {
                    aiUpdateTimer -= deltaTime;
                    return(false);
                }

                //load more fuel if the current maximum output is only 50% of the current load
                if (NeedMoreFuel(minimumOutputRatio: 0.5f))
                {
                    aiUpdateTimer = AIUpdateInterval;
                    if (objective.SubObjectives.None())
                    {
                        var containFuelObjective = new AIObjectiveContainItem(character, fuelTags, item.GetComponent <ItemContainer>(), objective.objectiveManager)
                        {
                            targetItemCount = item.ContainedItems.Count(i => i != null && fuelTags.Any(t => i.Prefab.Identifier == t || i.HasTag(t))) + 1,
                            GetItemPriority = (Item fuelItem) =>
                            {
                                if (fuelItem.ParentInventory?.Owner is Item)
                                {
                                    //don't take fuel from other reactors
                                    if (((Item)fuelItem.ParentInventory.Owner).GetComponent <Reactor>() != null)
                                    {
                                        return(0.0f);
                                    }
                                }
                                return(1.0f);
                            }
                        };
                        containFuelObjective.Abandoned += () => objective.Abandon = true;
                        objective.AddSubObjective(containFuelObjective);
                        character?.Speak(TextManager.Get("DialogReactorFuel"), null, 0.0f, "reactorfuel", 30.0f);
                    }
                    return(false);
                }
                else if (TooMuchFuel())
                {
                    foreach (Item item in item.ContainedItems)
                    {
                        if (item != null && fuelTags.Any(t => item.Prefab.Identifier == t || item.HasTag(t)))
                        {
                            if (!character.Inventory.TryPutItem(item, character, allowedSlots: item.AllowedSlots))
                            {
                                item.Drop(character);
                            }
                            break;
                        }
                    }
                }
            }

            if (lastUser != character && lastUser != null && lastUser.SelectedConstruction == item)
            {
                character.Speak(TextManager.Get("DialogReactorTaken"), null, 0.0f, "reactortaken", 10.0f);
            }

            LastUser = lastAIUser = character;

            bool  prevAutoTemp      = autoTemp;
            bool  prevShutDown      = shutDown;
            float prevFissionRate   = targetFissionRate;
            float prevTurbineOutput = targetTurbineOutput;

            switch (objective.Option.ToLowerInvariant())
            {
            case "powerup":
                shutDown = false;
                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
                onOffSwitch.BarScroll            = 0.0f;
                fissionRateScrollBar.BarScroll   = FissionRate / 100.0f;
                turbineOutputScrollBar.BarScroll = TurbineOutput / 100.0f;
#endif
                break;

            case "shutdown":
#if CLIENT
                onOffSwitch.BarScroll = 1.0f;
#endif
                AutoTemp            = false;
                shutDown            = true;
                targetFissionRate   = 0.0f;
                targetTurbineOutput = 0.0f;
                break;
            }

            if (autoTemp != prevAutoTemp ||
                prevShutDown != shutDown ||
                Math.Abs(prevFissionRate - targetFissionRate) > 1.0f ||
                Math.Abs(prevTurbineOutput - targetTurbineOutput) > 1.0f)
            {
                unsentChanges = true;
            }

            aiUpdateTimer = AIUpdateInterval;

            return(false);
        }