Miasma outbreaks give every mob the same disease (#9232)

This commit is contained in:
Rane
2022-07-02 22:25:31 -04:00
committed by GitHub
parent 745c1bf609
commit 87cf078d42
11 changed files with 135 additions and 21 deletions

View File

@@ -6,6 +6,7 @@ using Content.Server.Temperature.Systems;
using Content.Server.Body.Components; using Content.Server.Body.Components;
using Content.Shared.Examine; using Content.Shared.Examine;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Random;
namespace Content.Server.Atmos.Miasma namespace Content.Server.Atmos.Miasma
{ {
@@ -13,12 +14,70 @@ namespace Content.Server.Atmos.Miasma
{ {
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = 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) public override void Update(float frameTime)
{ {
base.Update(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>()) foreach (var (rotting, perishable) in EntityQuery<RottingComponent, PerishableComponent>())
{ {
if (!perishable.Progressing) if (!perishable.Progressing)
@@ -29,10 +88,10 @@ namespace Content.Server.Atmos.Miasma
continue; continue;
perishable.RotAccumulator += frameTime; 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; continue;
perishable.RotAccumulator -= UpdateRate; perishable.RotAccumulator -= _rotUpdateRate;
EnsureComp<FliesComponent>(perishable.Owner); EnsureComp<FliesComponent>(perishable.Owner);
@@ -46,7 +105,7 @@ namespace Content.Server.Atmos.Miasma
continue; continue;
// We need a way to get the mass of the mob alone without armor etc in the future // 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); var tileMix = _atmosphereSystem.GetTileMixture(Transform(perishable.Owner).Coordinates);
if (tileMix != null) if (tileMix != null)
@@ -69,6 +128,9 @@ namespace Content.Server.Atmos.Miasma
// Fly audiovisual stuff // Fly audiovisual stuff
SubscribeLocalEvent<FliesComponent, ComponentInit>(OnFliesInit); SubscribeLocalEvent<FliesComponent, ComponentInit>(OnFliesInit);
SubscribeLocalEvent<FliesComponent, ComponentShutdown>(OnFliesShutdown); SubscribeLocalEvent<FliesComponent, ComponentShutdown>(OnFliesShutdown);
// Init disease pool
_poolDisease = _random.Pick(MiasmaDiseasePool);
} }
private void OnShutdown(EntityUid uid, RottingComponent component, ComponentShutdown args) private void OnShutdown(EntityUid uid, RottingComponent component, ComponentShutdown args)
@@ -170,5 +232,12 @@ namespace Content.Server.Atmos.Miasma
perishable.Progressing = false; perishable.Progressing = false;
RemComp<FliesComponent>(uid); 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;
}
} }
} }

View File

@@ -7,7 +7,7 @@ using JetBrains.Annotations;
namespace Content.Server.Chemistry.ReagentEffects namespace Content.Server.Chemistry.ReagentEffects
{ {
/// <summary> /// <summary>
/// Default metabolism for medicine reagents. /// Causes a random disease from a list, if the user is not already diseased.
/// </summary> /// </summary>
[UsedImplicitly] [UsedImplicitly]
public sealed class ChemCauseRandomDisease : ReagentEffect public sealed class ChemCauseRandomDisease : ReagentEffect

View File

@@ -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);
}
}
}

View File

@@ -13,6 +13,7 @@ reagent-physical-desc-cold = cold
reagent-physical-desc-bee-guts = bee guts reagent-physical-desc-bee-guts = bee guts
reagent-physical-desc-tangy = tangy reagent-physical-desc-tangy = tangy
reagent-physical-desc-fizzy = fizzy reagent-physical-desc-fizzy = fizzy
reagent-physical-desc-fuzzy = fuzzy
reagent-physical-desc-spicy = spicy reagent-physical-desc-spicy = spicy
reagent-physical-desc-abrasive = abrasive reagent-physical-desc-abrasive = abrasive
reagent-physical-desc-chalky = chalky reagent-physical-desc-chalky = chalky

View File

@@ -4,6 +4,9 @@ reagent-desc-toxin = A toxic chemical.
reagent-name-carpotoxin = carpotoxin reagent-name-carpotoxin = carpotoxin
reagent-desc-carpotoxin = Toxic secretions of a space carp. Causes a painful burning sensation. reagent-desc-carpotoxin = Toxic secretions of a space carp. Causes a painful burning sensation.
reagent-name-mold = mold
reagent-desc-mold = Often found in dark, humid places or on old bread.
reagent-name-polytrinic-acid = polytrinic acid reagent-name-polytrinic-acid = polytrinic acid
reagent-desc-polytrinic-acid = An extremely corrosive chemical substance. The slightest touch of it will melt off most masks and headgear, and it deals extreme damage to anyone who comes directly into contact with it. reagent-desc-polytrinic-acid = An extremely corrosive chemical substance. The slightest touch of it will melt off most masks and headgear, and it deals extreme damage to anyone who comes directly into contact with it.

View File

@@ -71,7 +71,7 @@
maxLength: 100 maxLength: 100
- type: disease - type: disease
id: Bird Flew id: BirdFlew
name: bird flew name: bird flew
cureResist: 0.08 cureResist: 0.08
effects: effects:

View File

@@ -110,7 +110,7 @@
- AMIV - AMIV
- SpaceCold - SpaceCold
- SpaceFlu - SpaceFlu
- Bird Flew - BirdFlew
- VanAusdallsRobovirus - VanAusdallsRobovirus
- BleedersBite - BleedersBite
- Plague - Plague
@@ -192,7 +192,7 @@
- AMIV - AMIV
- SpaceCold - SpaceCold
- SpaceFlu - SpaceFlu
- Bird Flew - BirdFlew
- VanAusdallsRobovirus - VanAusdallsRobovirus
- BleedersBite - BleedersBite
- Plague - Plague

View File

@@ -434,7 +434,7 @@
reagents: reagents:
- ReagentId: Nutriment - ReagentId: Nutriment
Quantity: 4 Quantity: 4
- ReagentId: Amatoxin - ReagentId: Mold
Quantity: 7 Quantity: 7
# Tastes like decaying fungus. # Tastes like decaying fungus.

View File

@@ -350,7 +350,7 @@
reagents: reagents:
- ReagentId: Nutriment - ReagentId: Nutriment
Quantity: 2 Quantity: 2
- ReagentId: Amatoxin - ReagentId: Mold
Quantity: 2 Quantity: 2
- ReagentId: Vitamin - ReagentId: Vitamin
Quantity: 1 Quantity: 1

View File

@@ -163,7 +163,7 @@
metabolisms: metabolisms:
Gas: Gas:
effects: effects:
- !type:ChemCauseRandomDisease - !type:ChemMiasmaPoolSource
conditions: conditions:
- !type:OrganType - !type:OrganType
type: Rat type: Rat
@@ -171,15 +171,6 @@
- !type:ReagentThreshold - !type:ReagentThreshold
reagent: Miasma reagent: Miasma
min: 1 min: 1
diseases:
- VentCough
- AMIV
- SpaceCold
- SpaceFlu
- Bird Flew
- VanAusdallsRobovirus
- BleedersBite
- Plague
- !type:HealthChange - !type:HealthChange
conditions: conditions:
- !type:OrganType - !type:OrganType

View File

@@ -42,6 +42,33 @@
messages: [ "generic-reagent-effect-burning-insides" ] messages: [ "generic-reagent-effect-burning-insides" ]
probability: 0.33 probability: 0.33
- type: reagent
id: Mold
name: reagent-name-mold
group: Toxins
desc: reagent-desc-mold
color: "#8a9a5b"
physicalDesc: reagent-physical-desc-fuzzy
metabolisms:
Poison:
effects:
- !type:HealthChange
damage:
types:
Poison: 1
- !type:ChemCauseRandomDisease
conditions:
- !type:ReagentThreshold
reagent: Mold
min: 1
diseases:
- VentCough
- SpaceCold
- SpaceFlu
- BirdFlew
- Plague
- type: reagent - type: reagent
id: PolytrinicAcid id: PolytrinicAcid
name: reagent-name-polytrinic-acid name: reagent-name-polytrinic-acid