Miasma outbreaks give every mob the same disease (#9232)
This commit is contained in:
@@ -6,6 +6,7 @@ using Content.Server.Temperature.Systems;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Shared.Examine;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Atmos.Miasma
|
||||
{
|
||||
@@ -13,12 +14,70 @@ namespace Content.Server.Atmos.Miasma
|
||||
{
|
||||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||
/// Feel free to weak this if there are perf concerns
|
||||
private float UpdateRate = 5f;
|
||||
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
/// System Variables
|
||||
|
||||
/// Rotting
|
||||
|
||||
/// <summary>
|
||||
/// How often the rotting ticks.
|
||||
/// Feel free to weak this if there are perf concerns.
|
||||
/// </summary>
|
||||
private float _rotUpdateRate = 5f;
|
||||
|
||||
/// Miasma Disease Pool
|
||||
/// Miasma outbreaks are not per-entity,
|
||||
/// so this ensures that each entity in the same incident
|
||||
/// receives the same disease.
|
||||
|
||||
public readonly IReadOnlyList<string> MiasmaDiseasePool = new[]
|
||||
{
|
||||
"VentCough",
|
||||
"AMIV",
|
||||
"SpaceCold",
|
||||
"SpaceFlu",
|
||||
"BirdFlew",
|
||||
"VanAusdallsRobovirus",
|
||||
"BleedersBite",
|
||||
"Plague"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The current pool disease.
|
||||
/// </summary>
|
||||
private string _poolDisease = "";
|
||||
|
||||
/// <summary>
|
||||
/// The list of diseases in the pool.
|
||||
/// </summary>
|
||||
|
||||
/// <summary>
|
||||
/// This ticks up to PoolRepickTime.
|
||||
/// After that, it resets to 0.
|
||||
/// Any infection will also reset it to 0.
|
||||
/// </summary>
|
||||
private float _poolAccumulator = 0f;
|
||||
|
||||
/// <summmary>
|
||||
/// How long without an infection before we pick a new disease.
|
||||
/// </summary>
|
||||
private TimeSpan _poolRepickTime = TimeSpan.FromMinutes(5);
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
// Disease pool
|
||||
_poolAccumulator += frameTime;
|
||||
|
||||
if (_poolAccumulator > _poolRepickTime.TotalSeconds)
|
||||
{
|
||||
_poolAccumulator = 0f;
|
||||
_poolDisease = _random.Pick(MiasmaDiseasePool);
|
||||
}
|
||||
|
||||
// Rotting
|
||||
foreach (var (rotting, perishable) in EntityQuery<RottingComponent, PerishableComponent>())
|
||||
{
|
||||
if (!perishable.Progressing)
|
||||
@@ -29,10 +88,10 @@ namespace Content.Server.Atmos.Miasma
|
||||
continue;
|
||||
|
||||
perishable.RotAccumulator += frameTime;
|
||||
if (perishable.RotAccumulator < UpdateRate) // This is where it starts to get noticable on larger animals, no need to run every second
|
||||
if (perishable.RotAccumulator < _rotUpdateRate) // This is where it starts to get noticable on larger animals, no need to run every second
|
||||
continue;
|
||||
|
||||
perishable.RotAccumulator -= UpdateRate;
|
||||
perishable.RotAccumulator -= _rotUpdateRate;
|
||||
|
||||
EnsureComp<FliesComponent>(perishable.Owner);
|
||||
|
||||
@@ -46,7 +105,7 @@ namespace Content.Server.Atmos.Miasma
|
||||
continue;
|
||||
// We need a way to get the mass of the mob alone without armor etc in the future
|
||||
|
||||
float molRate = perishable.MolsPerSecondPerUnitMass * UpdateRate;
|
||||
float molRate = perishable.MolsPerSecondPerUnitMass * _rotUpdateRate;
|
||||
|
||||
var tileMix = _atmosphereSystem.GetTileMixture(Transform(perishable.Owner).Coordinates);
|
||||
if (tileMix != null)
|
||||
@@ -69,6 +128,9 @@ namespace Content.Server.Atmos.Miasma
|
||||
// Fly audiovisual stuff
|
||||
SubscribeLocalEvent<FliesComponent, ComponentInit>(OnFliesInit);
|
||||
SubscribeLocalEvent<FliesComponent, ComponentShutdown>(OnFliesShutdown);
|
||||
|
||||
// Init disease pool
|
||||
_poolDisease = _random.Pick(MiasmaDiseasePool);
|
||||
}
|
||||
|
||||
private void OnShutdown(EntityUid uid, RottingComponent component, ComponentShutdown args)
|
||||
@@ -170,5 +232,12 @@ namespace Content.Server.Atmos.Miasma
|
||||
perishable.Progressing = false;
|
||||
RemComp<FliesComponent>(uid);
|
||||
}
|
||||
|
||||
public string RequestPoolDisease()
|
||||
{
|
||||
// We reset the current time on this outbreak so people don't get unlucky at the transition time
|
||||
_poolAccumulator = 0f;
|
||||
return _poolDisease;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ using JetBrains.Annotations;
|
||||
namespace Content.Server.Chemistry.ReagentEffects
|
||||
{
|
||||
/// <summary>
|
||||
/// Default metabolism for medicine reagents.
|
||||
/// Causes a random disease from a list, if the user is not already diseased.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public sealed class ChemCauseRandomDisease : ReagentEffect
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using JetBrains.Annotations;
|
||||
using Content.Server.Atmos.Miasma;
|
||||
using Content.Server.Disease;
|
||||
|
||||
namespace Content.Server.Chemistry.ReagentEffects
|
||||
{
|
||||
/// <summary>
|
||||
/// The miasma system rotates between 1 disease at a time.
|
||||
/// This gives all entities the disease the miasme system is currently on.
|
||||
/// For things ingested by one person, you probably want ChemCauseRandomDisease instead.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public sealed class ChemMiasmaPoolSource : ReagentEffect
|
||||
{
|
||||
public override void Effect(ReagentEffectArgs args)
|
||||
{
|
||||
string disease = EntitySystem.Get<MiasmaSystem>().RequestPoolDisease();
|
||||
|
||||
EntitySystem.Get<DiseaseSystem>().TryAddDisease(args.SolutionEntity, disease);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user