protected override void ClientInitialize(ClientInitializeData data)
        {
            base.ClientInitialize(data);

            PowerGridSystem.ClientInitializeConsumerOrProducer(data.GameObject);

            // create sound emitter
            var soundEmitter = Client.Audio.CreateSoundEmitter(
                data.GameObject,
                new SoundResource("Objects/Structures/ObjectFridge/Active"),
                isLooped: true,
                volume: 0.35f,
                radius: 1f);

            soundEmitter.CustomMaxDistance = 3.5f;
            this.ClientSetupSoundEmitter(soundEmitter);

            var publicState = data.PublicState;

            publicState.ClientSubscribe(_ => _.ElectricityConsumerState,
                                        _ => RefreshSoundEmitterState(),
                                        data.ClientState);

            RefreshSoundEmitterState();

            void RefreshSoundEmitterState()
            {
                soundEmitter.IsEnabled = publicState.ElectricityConsumerState
                                         == ElectricityConsumerState.PowerOnActive;
            }
        }
예제 #2
0
        public SprinklerWateringRequestResult SharedCanWaterNow(IStaticWorldObject worldObjectSprinkler)
        {
            var time = IsServer
                           ? Server.Game.FrameTime
                           : Client.CurrentGame.ServerFrameTimeApproximated;

            var privateState = GetPrivateState(worldObjectSprinkler);

            if (privateState.LastWateringTime < double.MaxValue &&
                time - privateState.LastWateringTime < WateringCooldownSeconds)
            {
                return(SprinklerWateringRequestResult.ErrorWateredRecently);
            }

            if (GetPublicState(worldObjectSprinkler).ElectricityConsumerState == ElectricityConsumerState.PowerOff)
            {
                return(SprinklerWateringRequestResult.ErrorPowerOff);
            }

            if (privateState.WaterAmount < this.WaterConsumptionPerWatering)
            {
                return(SprinklerWateringRequestResult.ErrorNotEnoughWater);
            }

            if (IsServer)
            {
                var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(worldObjectSprinkler.Bounds);
                if (!PowerGridSystem.ServerBaseHasCharge(areasGroup, this.ElectricityConsumptionPerWatering))
                {
                    return(SprinklerWateringRequestResult.ErrorNotEnoughElectricity);
                }
            }

            return(SprinklerWateringRequestResult.Success);
        }
        public static void ClientRechargeShield(ILogicObject areasGroup, double targetChargeElectricity)
        {
            Api.Assert(targetChargeElectricity > 0, "Incorrect charge amount");
            var electricityCost = CalculateRequiredElectricityCost(areasGroup,
                                                                   targetChargeElectricity);

            if (electricityCost <= 0)
            {
                return;
            }

            var state = SharedGetShieldPublicStatus(areasGroup);

            if (state == ShieldProtectionStatus.Active)
            {
                throw new Exception("Cannot recharge active shield. It should be disabled.");
            }

            if (!PowerGridSystem.ServerBaseHasCharge(areasGroup, electricityCost))
            {
                var message = PowerGridSystem.SetPowerModeResult.NotEnoughPower.GetDescription();
                NotificationSystem.ClientShowNotification(
                    message,
                    null,
                    color: NotificationColor.Bad);
                return;
            }

            Instance.CallServer(_ => _.ServerRemote_RechargeShield(areasGroup, targetChargeElectricity));
            Logger.Important(
                $"Sent request to charge shield to {targetChargeElectricity:F2} (+{electricityCost:F2} EU)");
        }
예제 #4
0
        public override bool SharedCanFire(ICharacter character, WeaponState weaponState)
        {
            var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(character.TilePosition);

            return(areasGroup is not null &&
                   PowerGridSystem.ServerBaseHasCharge(areasGroup, this.EnergyUsagePerShot));
        }
예제 #5
0
        protected override async void ClientInteractFinish(ClientObjectData data)
        {
            base.ClientInteractFinish(data);

            // toggle power
            await PowerGridSystem.ClientSetPowerMode(
                isOn : data.PublicState.ElectricityConsumerState
                != ElectricityConsumerState.PowerOnActive,
                data.GameObject);
        }
예제 #6
0
        protected override void ClientInitialize(ClientInitializeData data)
        {
            base.ClientInitialize(data);

            var worldObject = data.GameObject;
            var publicState = data.PublicState;
            var renderer    = data.ClientState.Renderer;
            var sceneObject = worldObject.ClientSceneObject;

            PowerGridSystem.ClientInitializeConsumerOrProducer(worldObject);
            var soundEmitter = Client.Audio.CreateSoundEmitter(
                worldObject,
                SoundResourceActive,
                is3D: true,
                volume: 1.0f,
                isLooped: true);

            soundEmitter.CustomMinDistance = 3.0f;
            soundEmitter.CustomMaxDistance = 6.0f;

            // add sprite sheet animation for fan sprite
            var componentAnimator = sceneObject.AddComponent <ClientComponentSpriteSheetAnimator>();

            componentAnimator.Setup(renderer,
                                    ClientComponentSpriteSheetAnimator.CreateAnimationFrames(this.textureAtlasActive)
                                    .Skip(1)
                                    .ToArray(),
                                    isLooped: true,
                                    frameDurationSeconds: 6 / 60.0,
                                    randomizeInitialFrame: true);

            publicState.ClientSubscribe(
                _ => _.ElectricityConsumerState,
                _ => RefreshActiveState(),
                data.ClientState);

            RefreshActiveState();

            void RefreshActiveState()
            {
                var isActive = publicState.ElectricityConsumerState
                               == ElectricityConsumerState.PowerOnActive;

                componentAnimator.IsEnabled = isActive;
                soundEmitter.IsEnabled      = isActive;

                if (!isActive)
                {
                    // reset to default texture
                    renderer.TextureResource = this.DefaultTexture;
                }
            }
        }
예제 #7
0
        public override bool SharedOnFire(ICharacter character, WeaponState weaponState)
        {
            var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(character.TilePosition);

            if (areasGroup is null)
            {
                return(false);
            }

            PowerGridSystem.ServerDeductBaseCharge(areasGroup, this.EnergyUsagePerShot);
            return(true);
        }
예제 #8
0
        protected override void ClientInitialize(ClientInitializeData data)
        {
            base.ClientInitialize(data);

            var publicState = data.PublicState;
            var renderer    = data.ClientState.Renderer;

            PowerGridSystem.ClientInitializeConsumerOrProducer(data.GameObject);

            publicState.ClientSubscribe(_ => _.WaterAmountPercent,
                                        _ => RefreshTexture(),
                                        data.ClientState);

            RefreshTexture();

            void RefreshTexture()
            {
                var columnIndex = (1 - publicState.WaterAmountPercent / 100.0)
                                  * (this.textureAtlas.AtlasSize.ColumnsCount - 1);

                renderer.TextureResource = this.textureAtlas.Chunk((byte)Math.Ceiling(columnIndex), 0);
            }
        }
예제 #9
0
 protected override void ClientInitialize(ClientInitializeData data)
 {
     base.ClientInitialize(data);
     PowerGridSystem.ClientInitializeConsumerOrProducer(data.GameObject);
 }
예제 #10
0
        public SprinklerWateringRequestResult ServerTryWaterNow(IStaticWorldObject worldObjectSprinkler)
        {
            var privateState = GetPrivateState(worldObjectSprinkler);
            var publicState  = GetPublicState(worldObjectSprinkler);

            var checkResult = this.SharedCanWaterNow(worldObjectSprinkler);

            if (checkResult != SprinklerWateringRequestResult.Success)
            {
                Logger.Info("Sprinkler cannot water: " + checkResult,
                            characterRelated: ServerRemoteContext.IsRemoteCall
                                                  ? ServerRemoteContext.Character
                                                  : null);

                switch (checkResult)
                {
                case SprinklerWateringRequestResult.ErrorNotEnoughWater:
                    privateState.NextWateringTime = double.MaxValue;
                    break;

                case SprinklerWateringRequestResult.ErrorNotEnoughElectricity:
                    privateState.NextWateringTime = Server.Game.FrameTime + WateringIntervalSeconds;
                    break;
                }

                return(checkResult);
            }

            privateState.LastWateringTime = Server.Game.FrameTime;
            privateState.NextWateringTime = Server.Game.FrameTime + WateringIntervalSeconds;

            var plantObjectsToWater = this.ServerGetPlantObjectsToWater(worldObjectSprinkler);

            if (plantObjectsToWater.Count == 0)
            {
                Logger.Info("No plants to water",
                            characterRelated: ServerRemoteContext.IsRemoteCall
                                                  ? ServerRemoteContext.Character
                                                  : null);
                return(SprinklerWateringRequestResult.Success);
            }

            // consume water
            privateState.SetWaterAmount(privateState.WaterAmount - this.WaterConsumptionPerWatering,
                                        this.WaterCapacity,
                                        publicState);

            // consume electricity
            var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(worldObjectSprinkler.Bounds);

            PowerGridSystem.ServerDeductBaseCharge(areasGroup, this.ElectricityConsumptionPerWatering);

            try
            {
                foreach (var worldObjectPlant in plantObjectsToWater)
                {
                    if (worldObjectPlant.ProtoGameObject is IProtoObjectPlant protoPlant)
                    {
                        protoPlant.ServerOnWatered(worldObjectPlant,
                                                   wateringDuration: WateringIntervalSeconds);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Exception(ex);
            }

            Logger.Info("Watered surroundings now: " + worldObjectSprinkler);

            // reset hashes to ensure the recipe will refresh (it will refill the water bar if there are bottles with water)
            privateState.ManufacturingState.ContainerInputLastStateHash  = null;
            privateState.ManufacturingState.ContainerOutputLastStateHash = null;

            using var observers = Api.Shared.GetTempList <ICharacter>();
            Server.World.GetScopedByPlayers(worldObjectSprinkler, observers);
            this.CallClient(observers.AsList(),
                            _ => _.ClientRemote_OnWatered(worldObjectSprinkler));

            return(SprinklerWateringRequestResult.Success);
        }
예제 #11
0
 private void ExecuteCommandRestorePower()
 {
     PowerGridSystem.ClientRestorePower(this.state);
 }