Example #1
0
        private void ServerRebuildReactorStats(
            ObjectGeneratorPragmiumReactorPrivateState reactorPrivateState,
            ObjectGeneratorPragmiumReactorPublicState reactorPublicState)
        {
            reactorPrivateState.Stats = this.SharedGetReactorStats(reactorPrivateState);
            reactorPrivateState.ServerItemsContainerLastStateHash = reactorPrivateState.ItemsContainer.StateHash;

            // verify that the reactor has at least a single fuel item, otherwise deactivate it
            var hasAnyFuel = false;

            foreach (var item in reactorPrivateState.ItemsContainer.Items)
            {
                if (item.ProtoItem is ItemReactorFuelRod)
                {
                    hasAnyFuel = true;
                    break;
                }
            }

            if (!hasAnyFuel &&
                (reactorPrivateState.IsEnabled ||
                 reactorPrivateState.ActivationProgressPercents > 0))
            {
                reactorPrivateState.IsEnabled = false;
                reactorPrivateState.ActivationProgressPercents = 0;
                reactorPublicState.ActivationProgressPercents  = 0;
                //Logger.Info("Fuel depleted: " + reactorPrivateState.GameObject);
            }
        }
Example #2
0
        private void ServerApplyItemsDecay(
            ObjectGeneratorPragmiumReactorPrivateState reactorPrivateState,
            double deltaTime)
        {
            var activationProgress = reactorPrivateState.ActivationProgressPercents / 100.0;

            if (activationProgress <= 0)
            {
                reactorPrivateState.ServerAccumulatedDecayDuration = 0;
                return;
            }

            using var tempItemsList = Api.Shared.WrapInTempList(reactorPrivateState.ItemsContainer.Items);
            if (tempItemsList.Count == 0)
            {
                return;
            }

            reactorPrivateState.ServerAccumulatedDecayDuration += deltaTime;
            if (reactorPrivateState.ServerAccumulatedDecayDuration < ItemDecayIntervalDuration)
            {
                return;
            }

            // apply accumulated decay
            reactorPrivateState.ServerAccumulatedDecayDuration -= ItemDecayIntervalDuration;
            var decayMultiplier     = activationProgress * ItemDecayIntervalDuration;
            var fuelDecayMultiplier = 100.0 / reactorPrivateState.Stats.FuelLifetimePercent;

            foreach (var item in tempItemsList.AsList())
            {
                var protoGameObject = item.ProtoGameObject;
                switch (protoGameObject)
                {
                case ItemReactorFuelRod protoFuelRod:
                {
                    var decayAmount = decayMultiplier
                                      * protoFuelRod.DurabilityMax
                                      / protoFuelRod.LifetimeDuration;

                    decayAmount *= fuelDecayMultiplier;

                    ItemDurabilitySystem.ServerModifyDurability(item, -(int)decayAmount);
                    break;
                }

                case ProtoItemReactorModule protoItemModule:
                {
                    var decayAmount = decayMultiplier
                                      * protoItemModule.DurabilityMax
                                      / protoItemModule.LifetimeDuration;

                    ItemDurabilitySystem.ServerModifyDurability(item, -(int)decayAmount);
                    break;
                }
                }
            }
        }
Example #3
0
 /// <summary>
 /// When the reactor completely shut downs, it will destroy all modules
 /// that have remaining durability below 1%.
 /// </summary>
 private static void ServerOnReactorShutdown(ObjectGeneratorPragmiumReactorPrivateState reactorPrivateState)
 {
     foreach (var item in reactorPrivateState.ItemsContainer.Items.ToList())
     {
         if (item.ProtoGameObject is ProtoItemReactorModule &&
             ItemDurabilitySystem.SharedGetDurabilityPercent(item) < 1)
         {
             ItemDurabilitySystem.ServerBreakItem(item);
         }
     }
 }
Example #4
0
        private void ServerRemote_BuildReactor(IStaticWorldObject worldObjectGenerator, byte reactorIndex)
        {
            this.VerifyGameObject(worldObjectGenerator);
            var character = ServerRemoteContext.Character;

            if (!this.SharedCanInteract(character, worldObjectGenerator, writeToLog: true))
            {
                return;
            }

            if (reactorIndex >= this.ReactorsCountMax)
            {
                throw new ArgumentOutOfRangeException(nameof(reactorIndex));
            }

            var privateState = GetPrivateState(worldObjectGenerator);
            var publicState  = GetPublicState(worldObjectGenerator);

            var reactorPrivateStates = privateState.ReactorStates;
            var reactorPrivateState  = reactorPrivateStates[reactorIndex];

            if (reactorPrivateState is not null)
            {
                throw new Exception($"The reactor is already built: #{reactorIndex} in {worldObjectGenerator}");
            }

            if (!InputItemsHelper.SharedPlayerHasRequiredItems(character,
                                                               this.BuildAdditionalReactorRequiredItems,
                                                               noCheckInCreativeMode: true))
            {
                throw new Exception($"Not enough items to build a reactor: #{reactorIndex} in {worldObjectGenerator}");
            }

            if (!CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                InputItemsHelper.ServerDestroyItems(character, this.BuildAdditionalReactorRequiredItems);
            }

            reactorPrivateState = new ObjectGeneratorPragmiumReactorPrivateState();
            reactorPrivateStates[reactorIndex] = reactorPrivateState;

            this.ServerSetupReactorPrivateState(worldObjectGenerator, reactorPrivateState);

            var reactorPublicStates = publicState.ReactorStates;

            reactorPublicStates[reactorIndex] = new ObjectGeneratorPragmiumReactorPublicState();

            // force refresh over the network and properly binding the state owner object
            privateState.ReactorStates = reactorPrivateStates.ToArray();
            publicState.ReactorStates  = reactorPublicStates.ToArray();
        }
Example #5
0
        private static bool SharedCanActivateReactor(
            IStaticWorldObject worldObjectGenerator,
            ObjectGeneratorPragmiumReactorPrivateState reactorPrivateState,
            bool logErrors)
        {
            if (!reactorPrivateState.ItemsContainer.Items
                .Any(item => item.ProtoItem is ItemReactorFuelRod))
            {
                if (logErrors)
                {
                    Logger.Warning("Cannot activate reactor - no rods: " + worldObjectGenerator);

                    if (IsClient)
                    {
                        NotificationSystem.ClientShowNotification(
                            ErrorCannotStartReactor_Title,
                            message: string.Format(ErrorCannotStartReactor_Description_Format,
                                                   Api.GetProtoEntity <ItemReactorFuelRod>().Name),
                            NotificationColor.Bad,
                            GetProtoEntity <ItemReactorFuelRod>().Icon);
                    }
                }

                return(false);
            }

            var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(worldObjectGenerator);

            if (areasGroup is null)
            {
                // no power grid exists
                if (logErrors)
                {
                    Logger.Warning("Cannot activate reactor - no power grid exists: " + worldObjectGenerator);

                    if (IsClient)
                    {
                        NotificationSystem.ClientShowNotification(
                            ErrorCannotStartReactor_Title,
                            message: PowerGridSystem.SetPowerModeResult.NoPowerGridExist.GetDescription(),
                            NotificationColor.Bad,
                            worldObjectGenerator.ProtoStaticWorldObject.Icon);
                    }
                }

                return(false);
            }

            return(true);
        }
Example #6
0
        protected PragmiumReactorStatsData SharedGetReactorStats(
            ObjectGeneratorPragmiumReactorPrivateState reactorPrivateState)
        {
            double outputValue                = 0,
                   efficiencyPercents         = 100,
                   fuelLifetimePercent        = 100,
                   psiEmissionLevel           = 0,
                   startupShutdownTimePercent = 100;

            foreach (var item in reactorPrivateState.ItemsContainer.Items)
            {
                switch (item.ProtoGameObject)
                {
                case ItemReactorFuelRod protoRod:
                    psiEmissionLevel += protoRod.PsiEmissionLevel;
                    outputValue      += protoRod.OutputElectricityPerSecond;
                    break;

                case ProtoItemReactorModule protoModule:
                    efficiencyPercents         += protoModule.EfficiencyModifierPercents;
                    fuelLifetimePercent        += protoModule.FuelLifetimeModifierPercents;
                    psiEmissionLevel           += protoModule.PsiEmissionModifierValue;
                    startupShutdownTimePercent += protoModule.StartupShutdownTimeModifierPercents;
                    break;
                }
            }

            var generatorRate = RateTimeDependentGeneratorsRate.SharedValue;

            // do not apply it here as the player should not see the change here!
            //fuelLifetimePercent /= generatorRate; // apply generator rate (faster generation but faster fuel decay)
            fuelLifetimePercent = MathHelper.Clamp(fuelLifetimePercent, 1, ushort.MaxValue);

            efficiencyPercents = MathHelper.Clamp(efficiencyPercents, 0, ushort.MaxValue);

            // apply generator rate (faster generation and activation but faster fuel decay)
            startupShutdownTimePercent /= generatorRate;
            startupShutdownTimePercent  = MathHelper.Clamp(startupShutdownTimePercent, 5, ushort.MaxValue);

            psiEmissionLevel = MathHelper.Clamp(psiEmissionLevel, 0, byte.MaxValue);

            outputValue *= efficiencyPercents / 100.0;
            outputValue *= generatorRate; // apply generator rate (faster generation but faster fuel decay)

            return(new PragmiumReactorStatsData((ushort)fuelLifetimePercent,
                                                (ushort)efficiencyPercents,
                                                psiEmissionLevel,
                                                outputValue,
                                                (ushort)startupShutdownTimePercent));
        }
Example #7
0
        public virtual double SharedGetPsiEmissionLevelCurrent(
            ObjectGeneratorPragmiumReactorPrivateState reactorPrivateState)
        {
            if (reactorPrivateState is null)
            {
                return(0);
            }

            var emissionLevel = reactorPrivateState.Stats.PsiEmissionLevel;

            if (emissionLevel <= 0)
            {
                return(0);
            }

            return(emissionLevel
                   * Math.Min(100, 2 * reactorPrivateState.ActivationProgressPercents)
                   / 100.0);
        }
Example #8
0
        protected void ServerSetupReactorPrivateState(
            IStaticWorldObject worldObjectGenerator,
            ObjectGeneratorPragmiumReactorPrivateState reactorPrivateState)
        {
            var itemsContainer  = reactorPrivateState.ItemsContainer;
            var itemsSlotsCount = this.ItemSlotsCountPerReactor;

            if (itemsContainer is not null)
            {
                // container already created - update slots count
                Server.Items.SetSlotsCount(itemsContainer, slotsCount: itemsSlotsCount);
                return;
            }

            itemsContainer = Server.Items.CreateContainer <ItemsContainerGeneratorPragmium>(
                owner: worldObjectGenerator,
                slotsCount: itemsSlotsCount);

            reactorPrivateState.ItemsContainer = itemsContainer;
        }
Example #9
0
        protected PragmiumReactorStatsData SharedGetReactorStats(
            ObjectGeneratorPragmiumReactorPrivateState reactorPrivateState)
        {
            double outputValue                = 0,
                   efficiencyPercents         = 100,
                   fuelLifetimePercent        = 100,
                   psiEmissionLevel           = 0,
                   startupShutdownTimePercent = 100;

            foreach (var item in reactorPrivateState.ItemsContainer.Items)
            {
                switch (item.ProtoGameObject)
                {
                case ItemReactorFuelRod protoRod:
                    psiEmissionLevel += protoRod.PsiEmissionLevel;
                    outputValue      += protoRod.OutputElectricityPerSecond;
                    break;

                case ProtoItemReactorModule protoModule:
                    efficiencyPercents         += protoModule.EfficiencyModifierPercents;
                    fuelLifetimePercent        += protoModule.FuelLifetimeModifierPercents;
                    psiEmissionLevel           += protoModule.PsiEmissionModifierValue;
                    startupShutdownTimePercent += protoModule.StartupShutdownTimeModifierPercents;
                    break;
                }
            }

            fuelLifetimePercent        = MathHelper.Clamp(fuelLifetimePercent, 1, ushort.MaxValue);
            efficiencyPercents         = MathHelper.Clamp(efficiencyPercents, 0, ushort.MaxValue);
            startupShutdownTimePercent = MathHelper.Clamp(startupShutdownTimePercent, 5, ushort.MaxValue);

            psiEmissionLevel = MathHelper.Clamp(psiEmissionLevel, 0, byte.MaxValue);

            outputValue *= efficiencyPercents / 100.0;

            return(new PragmiumReactorStatsData((ushort)fuelLifetimePercent,
                                                (ushort)efficiencyPercents,
                                                psiEmissionLevel,
                                                outputValue,
                                                (ushort)startupShutdownTimePercent));
        }
Example #10
0
        protected override void ServerInitialize(ServerInitializeData data)
        {
            base.ServerInitialize(data);

            var worldObjectGenerator = data.GameObject;
            var publicState          = data.PublicState;
            var privateState         = data.PrivateState;

            var reactorPrivateStates = privateState.ReactorStates;

            if (reactorPrivateStates?.Length != this.ReactorsCountMax)
            {
                privateState.ReactorStates = null;
                publicState.ReactorStates  = null;
                reactorPrivateStates       = new ObjectGeneratorPragmiumReactorPrivateState[this.ReactorsCountMax];
            }

            var reactorPublicStates = publicState.ReactorStates
                                      ?? new ObjectGeneratorPragmiumReactorPublicState[this.ReactorsCountMax];

            for (var index = 0; index < reactorPrivateStates.Length; index++)
            {
                var reactorPrivateState = reactorPrivateStates[index];
                if (reactorPrivateState is null &&
                    index < this.ReactorsCountInitial)
                {
                    reactorPrivateState         = new ObjectGeneratorPragmiumReactorPrivateState();
                    reactorPrivateStates[index] = reactorPrivateState;
                }

                if (reactorPrivateState is not null)
                {
                    this.ServerSetupReactorPrivateState(worldObjectGenerator, reactorPrivateState);
                    reactorPublicStates[index] = new ObjectGeneratorPragmiumReactorPublicState();
                }
            }

            // force refresh over the network and properly binding the state owner object
            privateState.ReactorStates = reactorPrivateStates.ToArray();
            publicState.ReactorStates  = reactorPublicStates.ToArray();
        }
Example #11
0
        private static void ServerApplyItemsDecay(
            ObjectGeneratorPragmiumReactorPrivateState reactorPrivateState,
            double deltaTime)
        {
            var activationProgress = reactorPrivateState.ActivationProgressPercents / 100.0;

            if (activationProgress <= 0)
            {
                reactorPrivateState.ServerAccumulatedDecayDuration = 0;
                return;
            }

            using var tempItemsList = Api.Shared.WrapInTempList(reactorPrivateState.ItemsContainer.Items);
            if (tempItemsList.Count == 0)
            {
                return;
            }

            reactorPrivateState.ServerAccumulatedDecayDuration += deltaTime;
            if (reactorPrivateState.ServerAccumulatedDecayDuration < ItemDecayIntervalDuration)
            {
                return;
            }

            // let's apply accumulated decay
            reactorPrivateState.ServerAccumulatedDecayDuration -= ItemDecayIntervalDuration;
            var decayMultiplier = activationProgress * ItemDecayIntervalDuration;

            // apply generator rate (faster generation but faster fuel decay)
            decayMultiplier *= RateTimeDependentGeneratorsRate.SharedValue;

            var fuelDecayMultiplier = 100.0 / reactorPrivateState.Stats.FuelLifetimePercent;

            foreach (var item in tempItemsList.AsList())
            {
                var protoGameObject = item.ProtoGameObject;
                switch (protoGameObject)
                {
                case ItemReactorFuelRod protoFuelRod:
                {
                    var decayAmount = decayMultiplier
                                      * protoFuelRod.DurabilityMax
                                      / protoFuelRod.LifetimeDuration;

                    decayAmount *= fuelDecayMultiplier;

                    ItemDurabilitySystem.ServerModifyDurability(item, -(int)decayAmount);
                    break;
                }

                case ProtoItemReactorModule protoItemModule:
                {
                    var decayAmount = decayMultiplier
                                      * protoItemModule.DurabilityMax
                                      / protoItemModule.LifetimeDuration;

                    // Don't allow for modules to decay completely.
                    // When the reactor completely shut downs, it will destroy all modules
                    // that have remaining durability below 1% (see ServerOnReactorShutdown).
                    var privateState = item.GetPrivateState <IItemWithDurabilityPrivateState>();
                    decayAmount = Math.Min(decayAmount, privateState.DurabilityCurrent - 1);

                    if (decayAmount > 0)
                    {
                        ItemDurabilitySystem.ServerModifyDurability(item, -(int)decayAmount);
                    }

                    break;
                }
                }
            }
        }