diff --git a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs index 1fdcf87bde..29355268de 100644 --- a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs @@ -8,6 +8,7 @@ using Content.Shared.Atmos; using Content.Shared.Atmos.EntitySystems; using Content.Shared.CCVar; using Content.Shared.GameTicking; +using Content.Shared.Rounding; using JetBrains.Annotations; using Robust.Server.Player; using Robust.Shared; @@ -29,7 +30,6 @@ namespace Content.Server.Atmos.EntitySystems [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly IConfigurationManager _configManager = default!; /// /// The tiles that have had their atmos data updated since last tick @@ -49,6 +49,7 @@ namespace Content.Server.Atmos.EntitySystems /// How far away do we update gas overlays (minimum; due to chunking further away tiles may also be updated). /// private float _updateRange; + // Because the gas overlay updates aren't run every tick we need to avoid the pop-in that might occur with // the regular PVS range. private const float RangeOffset = 6.0f; @@ -60,6 +61,8 @@ namespace Content.Server.Atmos.EntitySystems private AtmosphereSystem _atmosphereSystem = default!; + private int _thresholds; + public override void Initialize() { base.Initialize(); @@ -67,6 +70,10 @@ namespace Content.Server.Atmos.EntitySystems _atmosphereSystem = Get(); _playerManager.PlayerStatusChanged += OnPlayerStatusChanged; _mapManager.OnGridRemoved += OnGridRemoved; + var configManager = IoCManager.Resolve(); + configManager.OnValueChanged(CCVars.NetGasOverlayTickRate, value => _updateCooldown = value > 0.0f ? 1 / value : float.MaxValue, true); + configManager.OnValueChanged(CVars.NetMaxUpdateRange, value => _updateRange = value + RangeOffset, true); + configManager.OnValueChanged(CCVars.GasOverlayThresholds, value => _thresholds = value, true); } public override void Shutdown() @@ -164,7 +171,8 @@ namespace Content.Server.Atmos.EntitySystems if (moles < gas.GasMolesVisible) continue; - var data = new GasData(i, (byte) (MathHelper.Clamp01(moles / gas.GasMolesVisibleMax) * 255)); + var opacity = (byte) (ContentHelpers.RoundToLevels(MathHelper.Clamp01(moles / gas.GasMolesVisibleMax) * 255, byte.MaxValue, _thresholds) * 255 / (_thresholds - 1)); + var data = new GasData(i, opacity); tileData.Add(data); } @@ -229,15 +237,10 @@ namespace Content.Server.Atmos.EntitySystems public override void Update(float frameTime) { + base.Update(frameTime); AccumulatedFrameTime += frameTime; - _updateCooldown = 1 / _configManager.GetCVar(CCVars.NetGasOverlayTickRate); - if (AccumulatedFrameTime < _updateCooldown) - { - return; - } - - _updateRange = _configManager.GetCVar(CVars.NetMaxUpdateRange) + RangeOffset; + if (AccumulatedFrameTime < _updateCooldown) return; // TODO: So in the worst case scenario we still have to send a LOT of tile data per tick if there's a fire. // If we go with say 15 tile radius then we have up to 900 tiles to update per tick. diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 2729f229af..b67f343f63 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -221,6 +221,9 @@ namespace Content.Shared.CCVar public static readonly CVarDef NetGasOverlayTickRate = CVarDef.Create("net.gasoverlaytickrate", 3.0f); + public static readonly CVarDef GasOverlayThresholds = + CVarDef.Create("net.gasoverlaythresholds", 20); + /* * Admin stuff */