public static void UpdateWithManufacturing( IStaticWorldObject worldObject, LiquidContainerState liquidContainerState, LiquidContainerConfig liquidContainerConfig, ManufacturingState manufacturingState, ManufacturingConfig manufacturingConfig, double deltaTime, bool isProduceLiquid, bool forceUpdateRecipe = false) { ManufacturingMechanic.UpdateRecipeOnly( worldObject, manufacturingState, manufacturingConfig, force: forceUpdateRecipe); var isUseRequested = manufacturingState.HasActiveRecipe; UpdateWithoutManufacturing( liquidContainerState, liquidContainerConfig, deltaTime, isProduceLiquid, isUseRequested, out var wasUsed); if (wasUsed) { ManufacturingMechanic.UpdateCraftingQueueOnly( manufacturingState, deltaTime); } }
protected override void ServerUpdate(ServerUpdateData data) { var privateState = data.PrivateState; var manufacturingState = privateState.ManufacturingState; var worldObject = data.GameObject; // update active recipe ManufacturingMechanic.UpdateRecipeOnly( worldObject, manufacturingState, this.ManufacturingConfig); var hasActiveRecipe = manufacturingState.HasActiveRecipe; bool isActive; var fuelBurningState = privateState.FuelBurningState; if (fuelBurningState == null) { // no fuel burning state - always active isActive = true; } else { // progress fuel burning FuelBurningMechanic.Update( worldObject, fuelBurningState, privateState.FuelBurningByproductsQueue, this.ManufacturingConfig, data.DeltaTime, isNeedFuelNow: hasActiveRecipe && !manufacturingState.CraftingQueue.IsContainerOutputFull); // active only when fuel is burning isActive = fuelBurningState.FuelUseTimeRemainsSeconds > 0; } data.PublicState.IsManufacturingActive = isActive; if (isActive && hasActiveRecipe) { // progress crafting ManufacturingMechanic.UpdateCraftingQueueOnly( manufacturingState, data.DeltaTime); // it's important to synchronize this property here // (because rollback might happen due to unable to spawn output items and container hash will be changed) // TODO: this is hack and we need a better way to track whether the container was actually changed or a better way to update the last state hash. manufacturingState.ContainerOutputLastStateHash = manufacturingState.CraftingQueue.ContainerOutputLastStateHash; } }
public static void UpdateWithManufacturing( IStaticWorldObject worldObject, LiquidContainerState liquidContainerState, LiquidContainerConfig liquidContainerConfig, ManufacturingState manufacturingState, ManufacturingConfig manufacturingConfig, double deltaTime, bool isProduceLiquid, bool forceUpdateRecipe = false) { ManufacturingMechanic.UpdateRecipeOnly( worldObject, manufacturingState, manufacturingConfig, force: forceUpdateRecipe); var isUseRequested = manufacturingState.HasActiveRecipe; var wasFull = liquidContainerState.Amount >= liquidContainerConfig.Capacity; UpdateWithoutManufacturing( liquidContainerState, liquidContainerConfig, deltaTime, isProduceLiquid, isUseRequested, out var wasUsed); if (!wasFull && liquidContainerState.Amount >= liquidContainerConfig.Capacity) { /* Note: This is a special workaround for oil pump. * The problem with it is that it becomes inactive (IsActive set to false) for single server update * once the full capacity is reached. With this workaround we're forcing it to refresh the recipe * that will in turn update the crafting queue and produce the output without interruption. */ // became full, update the recipe ManufacturingMechanic.UpdateRecipeOnly( worldObject, manufacturingState, manufacturingConfig, force: forceUpdateRecipe); // force crafting system update wasUsed = true; } if (wasUsed) { ManufacturingMechanic.UpdateCraftingQueueOnly( manufacturingState, deltaTime); } }
protected override void ServerUpdate(ServerUpdateData data) { var privateState = data.PrivateState; var publicState = data.PublicState; var liquidContainerState = privateState.LiquidState; var isFull = liquidContainerState.Amount >= this.LiquidContainerConfig.Capacity; ManufacturingMechanic.UpdateRecipeOnly( data.GameObject, privateState.ManufacturingState, this.ManufacturingConfig, force: !isFull); ManufacturingMechanic.UpdateCraftingQueueOnly( privateState.ManufacturingState, deltaTime: data.DeltaTime); // refill liquid LiquidContainerSystem.UpdateWithoutManufacturing( liquidContainerState, this.LiquidContainerConfig, data.DeltaTime, isProduceLiquid: false, wasUsed: out _, isUseRequested: publicState.IsActive, resetAmountToZeroWhenNotEnoughToUse: true); var isActive = publicState.ElectricityProducerState == ElectricityProducerState.PowerOnActive && privateState.LiquidState.Amount > 0; var fuelBurningState = privateState.FuelBurningState; if (fuelBurningState is not null) { // progress fuel burning FuelBurningMechanic.Update( data.GameObject, fuelBurningState, privateState.FuelBurningByproductsQueue, this.ManufacturingConfig, data.DeltaTime, byproductsQueueRate: 1, isNeedFuelNow: publicState.ElectricityProducerState == ElectricityProducerState.PowerOnActive && privateState.LiquidState.Amount > 0); // active only when fuel is burning isActive = fuelBurningState.FuelUseTimeRemainsSeconds > 0; } publicState.IsActive = isActive; }
protected override void ServerUpdate(ServerUpdateData data) { var privateState = data.PrivateState; var manufacturingState = privateState.ManufacturingState; var worldObject = data.GameObject; // update active recipe ManufacturingMechanic.UpdateRecipeOnly( worldObject, manufacturingState, this.ManufacturingConfig); var hasActiveRecipe = manufacturingState.HasActiveRecipe; var isActive = false; var fuelBurningState = privateState.FuelBurningState; if (fuelBurningState is null) { // no fuel burning state if (this.ElectricityConsumptionPerSecondWhenActive <= 0) { // no fuel burning and no electricity consumption - always active isActive = true; } else { // Consuming electricity. // Active only if electricity state is on and has active recipe. var publicState = data.PublicState; if (publicState.ElectricityConsumerState == ElectricityConsumerState.PowerOnActive) { isActive = hasActiveRecipe && !manufacturingState.CraftingQueue.IsContainerOutputFull; } } } else { // progress fuel burning FuelBurningMechanic.Update( worldObject, fuelBurningState, privateState.FuelBurningByproductsQueue, this.ManufacturingConfig, deltaTime: data.DeltaTime, byproductsQueueRate: StructureConstants.ManufacturingSpeedMultiplier, isNeedFuelNow: hasActiveRecipe && !manufacturingState.CraftingQueue.IsContainerOutputFull); // active only when fuel is burning isActive = fuelBurningState.FuelUseTimeRemainsSeconds > 0; } data.PublicState.IsActive = isActive; if (isActive && hasActiveRecipe) { // progress crafting ManufacturingMechanic.UpdateCraftingQueueOnly( manufacturingState, deltaTime: data.DeltaTime * StructureConstants.ManufacturingSpeedMultiplier * this.ManufacturingSpeedMultiplier); // it's important to synchronize this property here // (because rollback might happen due to unable to spawn output items and container hash will be changed) // TODO: this is hack and we need a better way to track whether the container was actually changed or a better way to update the last state hash. manufacturingState.ContainerOutputLastStateHash = manufacturingState.CraftingQueue.ContainerOutputLastStateHash; } }
protected override void ServerUpdate(ServerUpdateData data) { var worldObject = data.GameObject; var deltaTime = data.DeltaTime; var privateState = data.PrivateState; var manufacturingStateRawPetroleum = data.PrivateState.ManufacturingState; var manufacturingStateGasoline = data.PrivateState.ManufacturingStateGasoline; var manufacturingStateMineralOil = data.PrivateState.ManufacturingStateMineralOil; var liquidStateRawPetroleum = privateState.LiquidStateRawPetroleum; var liquidStateGasoline = privateState.LiquidStateGasoline; var liquidStateMineralOil = privateState.LiquidStateMineralOil; // Force update all recipes: // it will auto-detect and verify current recipes for every crafting queue. var isLiquidStatesChanged = privateState.IsLiquidStatesChanged; ManufacturingMechanic.UpdateRecipeOnly( worldObject, manufacturingStateRawPetroleum, this.ManufacturingConfig, force: isLiquidStatesChanged); ManufacturingMechanic.UpdateRecipeOnly( worldObject, manufacturingStateGasoline, this.ManufacturingConfigGasoline, force: isLiquidStatesChanged); ManufacturingMechanic.UpdateRecipeOnly( worldObject, manufacturingStateMineralOil, this.ManufacturingConfigMineralOil, force: isLiquidStatesChanged); privateState.IsLiquidStatesChanged = false; // Update fuel state: // need fuel when any of the output liquids capacity are not full // or any of the manufacturing states has active recipe. var isOutputLiquidCapacityFull = liquidStateGasoline.Amount >= this.LiquidConfigGasoline.Capacity || liquidStateMineralOil.Amount >= this.LiquidConfigMineralOil.Capacity; var isNeedElectricityNow = !isOutputLiquidCapacityFull && liquidStateRawPetroleum.Amount > 0; // Consuming electricity. // Active only if electricity state is on and has active recipe. var isActive = false; var publicState = data.PublicState; if (publicState.ElectricityConsumerState == ElectricityConsumerState.PowerOnActive) { isActive = isNeedElectricityNow; } // set IsActive flag in public state - this is used to play sound and animation on client data.PublicState.IsActive = isActive; // Update crafting queue for raw petroleum: // on complete it will consume petroleum canister (if available), increase oil level, produce empty canister. ManufacturingMechanic.UpdateCraftingQueueOnly(manufacturingStateRawPetroleum, deltaTime); if (isActive) // process liquids (consume raw petroleum and produce gasoline and mineral oil) { // apply extraction rate multiplier (it applies to oil refinery production rate) var deltaTimeLiquidProcessing = deltaTime; deltaTimeLiquidProcessing *= RateManufacturingSpeedMultiplier.SharedValue; // active, we can "transfer" liquids and progress crafting queues for output liquids // try transfer ("use") raw petroleum bar LiquidContainerSystem.UpdateWithoutManufacturing( liquidStateRawPetroleum, this.LiquidConfigRawPetroleum, deltaTimeLiquidProcessing, // petroleum is not produced via this system (it's produced on recipe completion) isProduceLiquid: false, // use petroleum liquid if other capacities are not full isUseRequested: !isOutputLiquidCapacityFull, wasUsed: out var wasUsedPetroleum, resetAmountToZeroWhenNotEnoughToUse: true); if (wasUsedPetroleum) { // increase gasoline level (if possible) LiquidContainerSystem.UpdateWithoutManufacturing( liquidStateGasoline, this.LiquidConfigGasoline, deltaTimeLiquidProcessing, isProduceLiquid: true, isUseRequested: false, wasUsed: out _); // increase mineral oil level (if possible) LiquidContainerSystem.UpdateWithoutManufacturing( liquidStateMineralOil, this.LiquidConfigMineralOil, deltaTimeLiquidProcessing, isProduceLiquid: true, isUseRequested: false, wasUsed: out _); // this flag is required to force recipes checking on next iteration privateState.IsLiquidStatesChanged = true; } } // progress crafting queues for output liquids (craft canisters with according liquids) ManufacturingMechanic.UpdateCraftingQueueOnly(manufacturingStateGasoline, deltaTime); ManufacturingMechanic.UpdateCraftingQueueOnly(manufacturingStateMineralOil, deltaTime); }
protected override void ServerUpdate(ServerUpdateData data) { var privateState = data.PrivateState; var publicState = data.PublicState; var liquidContainerState = privateState.LiquidState; var isFull = liquidContainerState.Amount >= this.LiquidContainerConfig.Capacity; ManufacturingMechanic.UpdateRecipeOnly( data.GameObject, privateState.ManufacturingState, this.ManufacturingConfig, force: !isFull); ManufacturingMechanic.UpdateCraftingQueueOnly( privateState.ManufacturingState, deltaTime: data.DeltaTime); // refill liquid LiquidContainerSystem.UpdateWithoutManufacturing( liquidContainerState, this.LiquidContainerConfig, data.DeltaTime, isProduceLiquid: false, wasUsed: out _, isUseRequested: privateState.CurrentTemperature >= SteamTemperatureGenerationStart, resetAmountToZeroWhenNotEnoughToUse: true); var isActive = privateState.LiquidState.Amount > 0; var fuelBurningState = privateState.FuelBurningState; if (fuelBurningState != null) { // progress fuel burning FuelBurningMechanic.Update( data.GameObject, fuelBurningState, privateState.FuelBurningByproductsQueue, this.ManufacturingConfig, data.DeltaTime * FuelBurningSpeedMultiplier, byproductsQueueRate: 1, isNeedFuelNow: publicState.ElectricityProducerState == ElectricityProducerState.PowerOnActive && privateState.LiquidState.Amount > 0); // active only when fuel is burning isActive = fuelBurningState.FuelUseTimeRemainsSeconds > 0; } publicState.IsActive = isActive; // update the temperature var temperature = privateState.CurrentTemperature; var delta = isActive ? (float)(SteamTemperatureIncreasePerSecond * data.DeltaTime) : -(float)(SteamTemperatureDecreasePerSecond * data.DeltaTime); // apply some variance in temperature gain delta *= RandomHelper.Range(0.8f, 1.2f); temperature += delta; privateState.CurrentTemperature = MathHelper.Clamp(temperature, SteamTemperatureMin, SteamTemperatureMax); }
protected override void ServerUpdate(ServerUpdateData data) { var worldObject = data.GameObject; var deltaTime = data.DeltaTime; var privateState = data.PrivateState; var fuelBurningState = privateState.FuelBurningState; var manufacturingStateRawPetroleum = data.PrivateState.ManufacturingState; var manufacturingStateProcessedGasoline = data.PrivateState.ManufacturingStateGasoline; var manufacturingStateProcessedMineralOil = data.PrivateState.ManufacturingStateMineralOil; var liquidStateRawPetroleum = privateState.LiquidStateRawPetroleum; var liquidStateProcessedGasoline = privateState.LiquidStateGasoline; var liquidStateProcessedMineralOil = privateState.LiquidStateMineralOil; // Force update all recipes: // it will auto-detect and verify current recipes for every crafting queue. var isLiquidStatesChanged = privateState.IsLiquidStatesChanged; ManufacturingMechanic.UpdateRecipeOnly( worldObject, manufacturingStateRawPetroleum, this.ManufacturingConfig, force: isLiquidStatesChanged); ManufacturingMechanic.UpdateRecipeOnly( worldObject, manufacturingStateProcessedGasoline, this.ManufacturingConfigGasoline, force: isLiquidStatesChanged); ManufacturingMechanic.UpdateRecipeOnly( worldObject, manufacturingStateProcessedMineralOil, this.ManufacturingConfigMineralOil, force: isLiquidStatesChanged); privateState.IsLiquidStatesChanged = false; // Update fuel state: // need fuel when processed liquids capacities are not full // or any of the manufacturing states has active recipe. var isLiquidsCapacitiesFull = liquidStateProcessedGasoline.Amount >= this.LiquidConfigGasoline.Capacity && liquidStateProcessedMineralOil.Amount >= this.LiquidConfigMineralOil.Capacity; var isNeedFuelNow = (!isLiquidsCapacitiesFull && liquidStateRawPetroleum.Amount > 0) || manufacturingStateProcessedGasoline.HasActiveRecipe || manufacturingStateProcessedMineralOil.HasActiveRecipe; // update fuel burning progress FuelBurningMechanic.Update( worldObject, fuelBurningState, privateState.FuelBurningByproductsQueue, this.ManufacturingConfig, data.DeltaTime, isNeedFuelNow, forceRefreshFuel: isLiquidStatesChanged); var isFuelBurning = fuelBurningState.FuelUseTimeRemainsSeconds > 0; // set IsActive flag in public state - this is used to play sound and animation on client data.PublicState.IsManufacturingActive = isFuelBurning; // Update crafting queue for raw petroleum: // on complete it will consume petroleum canister (if available), increase oil level, produce empty canister. ManufacturingMechanic.UpdateCraftingQueueOnly(manufacturingStateRawPetroleum, deltaTime); if (!isFuelBurning) { // cannot progress while fuel is not burning return; } // fuel is burning, we can "transfer" liquids and progress crafting queues for processed liquids // try transfer ("use") raw petroleum bar LiquidContainerSystem.UpdateWithoutManufacturing( liquidStateRawPetroleum, this.LiquidConfigRawPetroleum, deltaTime, // petroleum is not produced via this system (it's produced on recipe completion) isProduceLiquid: false, // use petroleum liquid if other capacities are not full isUseRequested: !isLiquidsCapacitiesFull, wasUsed: out var wasUsedPetroleum, resetAmountToZeroWhenNotEnoughToUse: true); if (wasUsedPetroleum) { // increase gasoline level (if possible) LiquidContainerSystem.UpdateWithoutManufacturing( liquidStateProcessedGasoline, this.LiquidConfigGasoline, deltaTime, isProduceLiquid: true, isUseRequested: false, wasUsed: out _); // increase mineral oil level (if possible) LiquidContainerSystem.UpdateWithoutManufacturing( liquidStateProcessedMineralOil, this.LiquidConfigMineralOil, deltaTime, isProduceLiquid: true, isUseRequested: false, wasUsed: out _); // this flag is required to force recipes checking on next iteration privateState.IsLiquidStatesChanged = true; } // progress crafting queues for processed liquids (craft canisters with according liquids) ManufacturingMechanic.UpdateCraftingQueueOnly(manufacturingStateProcessedGasoline, deltaTime); ManufacturingMechanic.UpdateCraftingQueueOnly(manufacturingStateProcessedMineralOil, deltaTime); }