medibot fixes and refactoring (#21852)

Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
deltanedas
2023-12-06 21:30:32 +00:00
committed by GitHub
parent f31b015591
commit 47359cf70f
6 changed files with 141 additions and 93 deletions

View File

@@ -1,40 +1,28 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Mobs;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Silicons.Bots;
/// <summary>
/// Replaced the medibot's meds with these when emagged. Could be poison, could be fun.
/// Replaces the medibot's meds with these when emagged. Could be poison, could be fun.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[RegisterComponent, NetworkedComponent]
[Access(typeof(MedibotSystem))]
public sealed partial class EmaggableMedibotComponent : Component
{
/// <summary>
/// Med the bot will inject when UNDER the standard med damage threshold.
/// Treatments to replace from the original set.
/// </summary>
[DataField("standardMed", customTypeSerializer: typeof(PrototypeIdSerializer<ReagentPrototype>)), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public string StandardMed = "Tricordrazine";
[DataField("standardMedAmount"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float StandardMedAmount = 15f;
/// <summary>
/// Med the bot will inject when OVER the emergency med damage threshold.
/// </summary>
[DataField("emergencyMed", customTypeSerializer: typeof(PrototypeIdSerializer<ReagentPrototype>)), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public string EmergencyMed = "Inaprovaline";
[DataField("emergencyMedAmount"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float EmergencyMedAmount = 15f;
[DataField(required: true), ViewVariables(VVAccess.ReadWrite)]
public Dictionary<MobState, MedibotTreatment> Replacements = new();
/// <summary>
/// Sound to play when the bot has been emagged
/// </summary>
[DataField("sparkSound")] public SoundSpecifier SparkSound = new SoundCollectionSpecifier("sparks")
[DataField]
public SoundSpecifier SparkSound = new SoundCollectionSpecifier("sparks")
{
Params = AudioParams.Default.WithVolume(8f),
Params = AudioParams.Default.WithVolume(8f)
};
}

View File

@@ -1,6 +1,8 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs;
using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Prototypes;
namespace Content.Shared.Silicons.Bots;
@@ -13,30 +15,56 @@ namespace Content.Shared.Silicons.Bots;
public sealed partial class MedibotComponent : Component
{
/// <summary>
/// Med the bot will inject when UNDER the standard med damage threshold.
/// Treatments the bot will apply for each mob state.
/// </summary>
[DataField("standardMed", customTypeSerializer: typeof(PrototypeIdSerializer<ReagentPrototype>))]
public string StandardMed = "Tricordrazine";
[DataField("standardMedAmount")]
public float StandardMedAmount = 30f;
/// <summary>
/// Med the bot will inject when OVER the emergency med damage threshold.
/// </summary>
[DataField("emergencyMed", customTypeSerializer: typeof(PrototypeIdSerializer<ReagentPrototype>))]
public string EmergencyMed = "Inaprovaline";
[DataField("emergencyMedAmount")]
public float EmergencyMedAmount = 15f;
[DataField(required: true)]
public Dictionary<MobState, MedibotTreatment> Treatments = new();
/// <summary>
/// Sound played after injecting a patient.
/// </summary>
[DataField("injectSound")]
public SoundSpecifier InjectSound = new SoundPathSpecifier("/Audio/Items/hypospray.ogg");
public const float StandardMedDamageThreshold = 0f;
public const float StandardMedDamageThresholdStop = 50f;
public const float EmergencyMedDamageThreshold = 100f;
}
/// <summary>
/// An injection to treat the patient with.
/// </summary>
[DataDefinition]
public sealed partial class MedibotTreatment
{
/// <summary>
/// Reagent to inject into the patient.
/// </summary>
[DataField(required: true)]
public ProtoId<ReagentPrototype> Reagent = string.Empty;
/// <summary>
/// How much of the reagent to inject.
/// </summary>
[DataField(required: true)]
public FixedPoint2 Quantity;
/// <summary>
/// Do nothing when the patient is at or below this total damage.
/// When null this will inject meds into completely healthy patients.
/// </summary>
[DataField]
public FixedPoint2? MinDamage;
/// <summary>
/// Do nothing when the patient is at or above this total damage.
/// Useful for tricordrazine which does nothing above 50 damage.
/// </summary>
[DataField]
public FixedPoint2? MaxDamage;
/// <summary>
/// Returns whether the treatment will probably work for an amount of damage.
/// Doesn't account for specific damage types only total amount.
/// </summary>
public bool IsValid(FixedPoint2 damage)
{
return (MaxDamage == null || damage < MaxDamage) && (MinDamage == null || damage > MinDamage);
}
}

View File

@@ -1,11 +1,12 @@
using Content.Shared.Emag.Systems;
using Robust.Shared.Audio;
using Content.Shared.Mobs;
using Robust.Shared.Audio.Systems;
using System.Diagnostics.CodeAnalysis;
namespace Content.Shared.Silicons.Bots;
/// <summary>
/// Handles emagging medibots
/// Handles emagging medibots and provides api.
/// </summary>
public sealed class MedibotSystem : EntitySystem
{
@@ -25,10 +26,22 @@ public sealed class MedibotSystem : EntitySystem
_audio.PlayPredicted(comp.SparkSound, uid, args.UserUid);
medibot.StandardMed = comp.StandardMed;
medibot.StandardMedAmount = comp.StandardMedAmount;
medibot.EmergencyMed = comp.EmergencyMed;
medibot.EmergencyMedAmount = comp.EmergencyMedAmount;
foreach (var (state, treatment) in comp.Replacements)
{
medibot.Treatments[state] = treatment;
}
args.Handled = true;
}
/// <summary>
/// Get a treatment for a given mob state.
/// </summary>
/// <remarks>
/// This only exists because allowing other execute would allow modifying the dictionary, and Read access does not cover TryGetValue.
/// </remarks>
public bool TryGetTreatment(MedibotComponent comp, MobState state, [NotNullWhen(true)] out MedibotTreatment? treatment)
{
return comp.Treatments.TryGetValue(state, out treatment);
}
}