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; } }
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)"); }
public override bool SharedCanFire(ICharacter character, WeaponState weaponState) { var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(character.TilePosition); return(areasGroup is not null && PowerGridSystem.ServerBaseHasCharge(areasGroup, this.EnergyUsagePerShot)); }
protected override async void ClientInteractFinish(ClientObjectData data) { base.ClientInteractFinish(data); // toggle power await PowerGridSystem.ClientSetPowerMode( isOn : data.PublicState.ElectricityConsumerState != ElectricityConsumerState.PowerOnActive, data.GameObject); }
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; } } }
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); }
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); } }
protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); PowerGridSystem.ClientInitializeConsumerOrProducer(data.GameObject); }
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); }
private void ExecuteCommandRestorePower() { PowerGridSystem.ClientRestorePower(this.state); }