Disease Stages But Epic (#9043)
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
48
Content.IntegrationTests/Tests/DiseaseTest.cs
Normal file
48
Content.IntegrationTests/Tests/DiseaseTest.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Disease;
|
||||
using NUnit.Framework;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.IntegrationTests.Tests;
|
||||
|
||||
[TestFixture]
|
||||
public sealed class DiseaseTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Asserts that a disease prototype has valid stages for its effects and cures.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task Stages()
|
||||
{
|
||||
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
|
||||
var server = pairTracker.Pair.Server;
|
||||
|
||||
var protoManager = server.ResolveDependency<IPrototypeManager>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
foreach (var proto in protoManager.EnumeratePrototypes<DiseasePrototype>())
|
||||
{
|
||||
var stages = proto.Stages;
|
||||
|
||||
foreach (var effect in proto.Effects)
|
||||
{
|
||||
for (var i = 0; i < effect.Stages.Length; i++)
|
||||
{
|
||||
Assert.That(stages.Contains(i), $"Disease {proto.ID} has an effect with an incorrect stage, {i}!");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var cure in proto.Cures)
|
||||
{
|
||||
for (var i = 0; i < cure.Stages.Length; i++)
|
||||
{
|
||||
Assert.That(stages.Contains(i), $"Disease {proto.ID} has a cure with an incorrect stage, {i}!");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await pairTracker.CleanReturnAsync();
|
||||
}
|
||||
}
|
||||
@@ -99,6 +99,7 @@ namespace Content.Server.Disease
|
||||
{
|
||||
var disease = carrierComp.Diseases[i];
|
||||
disease.Accumulator += frameTime;
|
||||
disease.TotalAccumulator += frameTime;
|
||||
|
||||
if (disease.Accumulator < disease.TickTime) continue;
|
||||
|
||||
@@ -107,9 +108,21 @@ namespace Content.Server.Disease
|
||||
var args = new DiseaseEffectArgs(carrierComp.Owner, disease, EntityManager);
|
||||
disease.Accumulator -= disease.TickTime;
|
||||
|
||||
int stage = 0; //defaults to stage 0 because you should always have one
|
||||
float lastThreshold = 0;
|
||||
for (var j = 0; j < disease.Stages.Count; j++)
|
||||
{
|
||||
if (disease.TotalAccumulator >= disease.Stages[j] &&
|
||||
disease.Stages[j] > lastThreshold)
|
||||
{
|
||||
lastThreshold = disease.Stages[j];
|
||||
stage = j;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var cure in disease.Cures)
|
||||
{
|
||||
if (cure.Cure(args))
|
||||
if (cure.Stages.AsSpan().Contains(stage) && cure.Cure(args))
|
||||
CureDisease(carrierComp, disease);
|
||||
}
|
||||
|
||||
@@ -117,7 +130,7 @@ namespace Content.Server.Disease
|
||||
{
|
||||
foreach (var effect in disease.Effects)
|
||||
{
|
||||
if (_random.Prob(effect.Probability))
|
||||
if (effect.Stages.AsSpan().Contains(stage) && _random.Prob(effect.Probability))
|
||||
effect.Effect(args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,12 @@ namespace Content.Shared.Disease
|
||||
/// and false otherwise
|
||||
/// </summary>
|
||||
public abstract bool Cure(DiseaseEffectArgs args);
|
||||
|
||||
/// <summary>
|
||||
/// What stages the cure applies to.
|
||||
/// probably should be all, but go wild
|
||||
/// </summary>
|
||||
[DataField("stages")]
|
||||
public readonly int[] Stages = { 0 };
|
||||
/// <summary>
|
||||
/// This is used by the disease diangoser machine
|
||||
/// to generate reports to tell people all of a disease's
|
||||
|
||||
@@ -12,6 +12,11 @@ namespace Content.Shared.Disease
|
||||
[DataField("probability")]
|
||||
public float Probability = 1.0f;
|
||||
/// <summary>
|
||||
/// What stages this effect triggers on
|
||||
/// </summary>
|
||||
[DataField("stages")]
|
||||
public readonly int[] Stages = { 0 };
|
||||
/// <summary>
|
||||
/// What effect the disease will have.
|
||||
/// </summary>
|
||||
public abstract void Effect(DiseaseEffectArgs args);
|
||||
|
||||
@@ -37,6 +37,19 @@ namespace Content.Shared.Disease
|
||||
/// </summary>
|
||||
public float Accumulator = 0f;
|
||||
/// <summary>
|
||||
/// Since accumulator is reset with TickTime, this just tracks
|
||||
/// the total amount of time a disease has been present.
|
||||
/// </summary>
|
||||
public float TotalAccumulator = 0f;
|
||||
/// <summary>
|
||||
/// Stores all the separate stages of the disease plus the time
|
||||
/// thresholds for their activation
|
||||
/// int: the disease stage (0 for baseline, 1, 2, etc.)
|
||||
/// float: the time it takes for the stage to begin.
|
||||
/// </summary>
|
||||
[DataField("stages", serverOnly: true)]
|
||||
public readonly List<float> Stages = new() { 0f };
|
||||
/// <summary>
|
||||
/// List of effects the disease has that will
|
||||
/// run every second (by default anyway)
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user