Chem guidebook (#17123)

* im good at atomizing. welcome to half-finished chem guides.

* wagh

* e

* save work

* aa

* woweee UI

* finishing the last of it

* don't actually update the engine :(

---------

Co-authored-by: moonheart08 <moonheart08@users.noreply.github.com>
This commit is contained in:
Nemanja
2023-06-04 16:45:02 -04:00
committed by GitHub
parent 1e6dbd0b67
commit b9fb66f005
72 changed files with 1411 additions and 12 deletions

View File

@@ -0,0 +1,47 @@
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Console;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.Commands;
[AdminCommand(AdminFlags.Debug)]
public sealed class DumpReagentGuideText : IConsoleCommand
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IEntitySystemManager _entSys = default!;
public string Command => "dumpreagentguidetext";
public string Description => "Dumps the guidebook text for a reagent to the console";
public string Help => "dumpreagentguidetext <reagent>";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
shell.WriteError("Must have only 1 argument");
return;
}
if (!_prototype.TryIndex<ReagentPrototype>(args[0], out var reagent))
{
shell.WriteError($"Invalid prototype: {args[0]}");
return;
}
if (reagent.Metabolisms is null)
{
shell.WriteLine("Nothing to dump.");
return;
}
foreach (var (_, entry) in reagent.Metabolisms)
{
foreach (var effect in entry.Effects)
{
shell.WriteLine(effect.GuidebookEffectDescription(_prototype, _entSys) ?? $"[skipped effect of type {effect.GetType()}]");
}
}
}
}

View File

@@ -0,0 +1,67 @@
using Content.Shared.Chemistry;
using Content.Shared.Chemistry.Reagent;
using Robust.Server.Player;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.EntitySystems;
public sealed class ChemistryGuideDataSystem : SharedChemistryGuideDataSystem
{
[Dependency] private readonly IPlayerManager _player = default!;
/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();
PrototypeManager.PrototypesReloaded += PrototypeManagerReload;
_player.PlayerStatusChanged += OnPlayerStatusChanged;
InitializeServerRegistry();
}
private void InitializeServerRegistry()
{
var changeset = new ReagentGuideChangeset(new Dictionary<string, ReagentGuideEntry>(), new HashSet<string>());
foreach (var proto in PrototypeManager.EnumeratePrototypes<ReagentPrototype>())
{
var entry = new ReagentGuideEntry(proto, PrototypeManager, EntityManager.EntitySysManager);
changeset.GuideEntries.Add(proto.ID, entry);
Registry[proto.ID] = entry;
}
var ev = new ReagentGuideRegistryChangedEvent(changeset);
RaiseNetworkEvent(ev);
}
private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e)
{
if (e.NewStatus != SessionStatus.Connected)
return;
var sendEv = new ReagentGuideRegistryChangedEvent(new ReagentGuideChangeset(Registry, new HashSet<string>()));
RaiseNetworkEvent(sendEv, e.Session);
}
private void PrototypeManagerReload(PrototypesReloadedEventArgs obj)
{
if (!obj.ByType.TryGetValue(typeof(ReagentPrototype), out var reagents))
return;
var changeset = new ReagentGuideChangeset(new Dictionary<string, ReagentGuideEntry>(), new HashSet<string>());
foreach (var (id, proto) in reagents.Modified)
{
var reagentProto = (ReagentPrototype) proto;
var entry = new ReagentGuideEntry(reagentProto, PrototypeManager, EntityManager.EntitySysManager);
changeset.GuideEntries.Add(id, entry);
Registry[id] = entry;
}
var ev = new ReagentGuideRegistryChangedEvent(changeset);
RaiseNetworkEvent(ev);
}
}

View File

@@ -45,6 +45,10 @@ namespace Content.Server.Chemistry.ReactionEffects
[DataField("sound", required: true)] private SoundSpecifier _sound = default!;
public override bool ShouldLog => true;
protected override string ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-missing");
public override LogImpact LogImpact => LogImpact.High;
public override void Effect(ReagentEffectArgs args)

View File

@@ -19,6 +19,12 @@ public sealed class CreateEntityReactionEffect : ReagentEffect
[DataField("number")]
public uint Number = 1;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-create-entity-reaction-effect",
("chance", Probability),
("entname", IoCManager.Resolve<IPrototypeManager>().Index<EntityPrototype>(Entity).Name),
("amount", Number));
public override void Effect(ReagentEffectArgs args)
{
var transform = args.EntityManager.GetComponent<TransformComponent>(args.SolutionEntity);

View File

@@ -3,6 +3,7 @@ using Content.Server.Explosion.EntitySystems;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Database;
using Content.Shared.Explosion;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Chemistry.ReactionEffects
@@ -24,7 +25,7 @@ namespace Content.Server.Chemistry.ReactionEffects
[DataField("maxIntensity")]
[JsonIgnore]
public float MaxIntensity = 5;
/// <summary>
/// How quickly intensity drops off as you move away from the epicenter
/// </summary>
@@ -51,6 +52,9 @@ namespace Content.Server.Chemistry.ReactionEffects
public float IntensityPerUnit = 1;
public override bool ShouldLog => true;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-explosion-reaction-effect", ("chance", Probability));
public override LogImpact LogImpact => LogImpact.High;
public override void Effect(ReagentEffectArgs args)

View File

@@ -0,0 +1 @@


View File

@@ -16,6 +16,10 @@ namespace Content.Server.Chemistry.ReactionEffects
/// </summary>
[DataField("temperature", required: true)] private float _temperature;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-set-solution-temperature-effect",
("chance", Probability), ("temperature", _temperature));
public override void Effect(ReagentEffectArgs args)
{
var solution = args.Source;
@@ -52,6 +56,10 @@ namespace Content.Server.Chemistry.ReactionEffects
/// </summary>
[DataField("scaled")] private bool _scaled;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-adjust-solution-temperature-effect",
("chance", Probability), ("deltasign", MathF.Sign(_delta)), ("mintemp", _minTemp), ("maxtemp", _maxTemp));
public override void Effect(ReagentEffectArgs args)
{
var solution = args.Source;
@@ -101,11 +109,15 @@ namespace Content.Server.Chemistry.ReactionEffects
var heatCap = solution.GetHeatCapacity(null);
var deltaT = _scaled
? _delta / heatCap * (float) args.Quantity
? _delta / heatCap * (float) args.Quantity
: _delta / heatCap;
solution.Temperature = Math.Clamp(solution.Temperature + deltaT, _minTemp, _maxTemp);
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-adjust-solution-temperature-effect",
("chance", Probability), ("deltasign", MathF.Sign(_delta)), ("mintemp", _minTemp), ("maxtemp", _maxTemp));
}
}

View File

@@ -1,5 +1,6 @@
using Content.Server.Temperature.Components;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffectConditions
{
@@ -13,7 +14,7 @@ namespace Content.Server.Chemistry.ReagentEffectConditions
public float Min = 0;
[DataField("max")]
public float Max = float.MaxValue;
public float Max = float.PositiveInfinity;
public override bool Condition(ReagentEffectArgs args)
{
if (args.EntityManager.TryGetComponent(args.SolutionEntity, out TemperatureComponent? temp))
@@ -24,5 +25,12 @@ namespace Content.Server.Chemistry.ReagentEffectConditions
return false;
}
public override string GuidebookExplanation(IPrototypeManager prototype)
{
return Loc.GetString("reagent-effect-condition-guidebook-body-temperature",
("max", float.IsPositiveInfinity(Max) ? (float) int.MaxValue : Max),
("min", Min));
}
}
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Tag;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Chemistry.ReagentEffectConditions;
@@ -21,4 +22,10 @@ public sealed class HasTag : ReagentEffectCondition
return false;
}
public override string GuidebookExplanation(IPrototypeManager prototype)
{
// this should somehow be made (much) nicer.
return Loc.GetString("reagent-effect-condition-guidebook-has-tag", ("tag", Tag), ("invert", Invert));
}
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffectConditions
{
@@ -21,6 +22,11 @@ namespace Content.Server.Chemistry.ReagentEffectConditions
return false;
}
public override string GuidebookExplanation(IPrototypeManager prototype)
{
return Loc.GetString("reagent-effect-condition-guidebook-mob-state-condition", ("state", mobstate));
}
}
}

View File

@@ -1,6 +1,7 @@
using Content.Server.Body.Components;
using Content.Shared.Body.Prototypes;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Chemistry.ReagentEffectConditions
@@ -30,5 +31,12 @@ namespace Content.Server.Chemistry.ReagentEffectConditions
return ShouldHave;
return !ShouldHave;
}
public override string GuidebookExplanation(IPrototypeManager prototype)
{
return Loc.GetString("reagent-effect-condition-guidebook-organ-type",
("name", prototype.Index<MetabolizerTypePrototype>(Type).Name),
("shouldhave", ShouldHave));
}
}
}

View File

@@ -1,5 +1,6 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffectConditions
{
@@ -35,5 +36,17 @@ namespace Content.Server.Chemistry.ReagentEffectConditions
return quant >= Min && quant <= Max;
}
public override string GuidebookExplanation(IPrototypeManager prototype)
{
ReagentPrototype? reagentProto = null;
if (Reagent is not null)
prototype.TryIndex(Reagent, out reagentProto);
return Loc.GetString("reagent-effect-condition-guidebook-reagent-threshold",
("reagent", reagentProto?.LocalizedName ?? "this reagent"),
("max", Max == FixedPoint2.MaxValue ? (float) int.MaxValue : Max.Float()),
("min", Min.Float()));
}
}
}

View File

@@ -1,4 +1,5 @@
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffectConditions
{
@@ -24,5 +25,12 @@ namespace Content.Server.Chemistry.ReagentEffectConditions
return true;
}
public override string GuidebookExplanation(IPrototypeManager prototype)
{
return Loc.GetString("reagent-effect-condition-guidebook-solution-temperature",
("max", float.IsPositiveInfinity(Max) ? (float) int.MaxValue : Max),
("min", Min));
}
}
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffectConditions
{
@@ -23,5 +24,12 @@ namespace Content.Server.Chemistry.ReagentEffectConditions
return false;
}
public override string GuidebookExplanation(IPrototypeManager prototype)
{
return Loc.GetString("reagent-effect-condition-guidebook-total-damage",
("max", Max == FixedPoint2.MaxValue ? (float) int.MaxValue : Max.Float()),
("min", Min.Float()));
}
}
}

View File

@@ -1,5 +1,6 @@
using Content.Server.Xenoarchaeology.XenoArtifacts;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -10,4 +11,7 @@ public sealed class ActivateArtifact : ReagentEffect
var artifact = args.EntityManager.EntitySysManager.GetEntitySystem<ArtifactSystem>();
artifact.TryActivateArtifact(args.SolutionEntity);
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) =>
Loc.GetString("reagent-effect-guidebook-activate-artifact", ("chance", Probability));
}

View File

@@ -1,6 +1,7 @@
using Content.Server.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Reagent;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects
{
@@ -24,5 +25,8 @@ namespace Content.Server.Chemistry.ReagentEffects
.TryAddReagent(args.SolutionEntity, solutionContainer, args.Reagent.ID, args.Quantity, out var accepted))
args.Source?.RemoveReagent(args.Reagent.ID, accepted);
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) =>
Loc.GetString("reagent-effect-guidebook-missing", ("chance", Probability));
}
}

View File

@@ -1,5 +1,6 @@
using Content.Shared.Alert;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -18,6 +19,9 @@ public sealed class AdjustAlert : ReagentEffect
[DataField("time")]
public float Time;
//JUSTIFICATION: This just changes some visuals, doesn't need to be documented.
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => null;
public override void Effect(ReagentEffectArgs args)
{
var alertSys = EntitySystem.Get<AlertsSystem>();

View File

@@ -60,5 +60,27 @@ namespace Content.Server.Chemistry.ReagentEffects
}
}
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
{
if (Reagent is not null && prototype.TryIndex(Reagent, out ReagentPrototype? reagentProto))
{
return Loc.GetString("reagent-effect-guidebook-adjust-reagent-reagent",
("chance", Probability),
("deltasign", MathF.Sign(Amount.Float())),
("reagent", reagentProto.LocalizedName),
("amount", MathF.Abs(Amount.Float())));
}
else if (Group is not null && prototype.TryIndex(Group, out MetabolismGroupPrototype? groupProto))
{
return Loc.GetString("reagent-effect-guidebook-adjust-reagent-group",
("chance", Probability),
("deltasign", MathF.Sign(Amount.Float())),
("group", groupProto.ID),
("amount", MathF.Abs(Amount.Float())));
}
throw new NotImplementedException();
}
}
}

View File

@@ -1,6 +1,7 @@
using Content.Server.Temperature.Components;
using Content.Server.Temperature.Systems;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects
{
@@ -9,6 +10,12 @@ namespace Content.Server.Chemistry.ReagentEffects
[DataField("amount")]
public float Amount;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-adjust-temperature",
("chance", Probability),
("deltasign", MathF.Sign(Amount)),
("amount", MathF.Abs(Amount)));
public override void Effect(ReagentEffectArgs args)
{
if (args.EntityManager.TryGetComponent(args.SolutionEntity, out TemperatureComponent? temp))

View File

@@ -1,6 +1,7 @@
using Content.Shared.Chemistry.Reagent;
using JetBrains.Annotations;
using Content.Server.Body.Systems;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReactionEffects
{
@@ -12,6 +13,10 @@ namespace Content.Server.Chemistry.ReactionEffects
{
[DataField("cleanseRate")]
public float CleanseRate = 3.0f;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-chem-clean-bloodstream", ("chance", Probability));
public override void Effect(ReagentEffectArgs args)
{
if (args.Source == null || args.Reagent == null)

View File

@@ -2,6 +2,7 @@ using Content.Shared.Chemistry.Reagent;
using Content.Shared.Eye.Blinding;
using Content.Shared.Eye.Blinding.Systems;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects
{
@@ -17,6 +18,9 @@ namespace Content.Server.Chemistry.ReagentEffects
[DataField("amount")]
public int Amount = -1;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-cure-eye-damage", ("chance", Probability), ("deltasign", MathF.Sign(Amount)));
public override void Effect(ReagentEffectArgs args)
{
if (args.Scale != 1f) // huh?

View File

@@ -1,6 +1,7 @@
using Content.Shared.Chemistry.Reagent;
using Content.Server.Medical;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects
{
@@ -17,6 +18,9 @@ namespace Content.Server.Chemistry.ReagentEffects
[DataField("hungerAmount")]
public float HungerAmount = -40f;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-chem-vomit", ("chance", Probability));
public override void Effect(ReagentEffectArgs args)
{
if (args.Scale != 1f)

View File

@@ -2,6 +2,7 @@
using Content.Shared.Atmos;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Database;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -17,6 +18,17 @@ public sealed class CreateGas : ReagentEffect
public float Multiplier = 3f;
public override bool ShouldLog => true;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
{
var atmos = entSys.GetEntitySystem<AtmosphereSystem>();
var gasProto = atmos.GetGas(Gas);
return Loc.GetString("reagent-effect-guidebook-create-gas",
("chance", Probability),
("moles", Multiplier),
("gas", gasProto.Name));
}
public override LogImpact LogImpact => LogImpact.High;
public override void Effect(ReagentEffectArgs args)

View File

@@ -1,5 +1,6 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Drunk;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -17,6 +18,9 @@ public sealed class Drunk : ReagentEffect
[DataField("slurSpeech")]
public bool SlurSpeech = true;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-drunk", ("chance", Probability));
public override void Effect(ReagentEffectArgs args)
{
var boozePower = BoozePower;

View File

@@ -1,5 +1,6 @@
using Content.Server.Electrocution;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -14,6 +15,9 @@ public sealed class Electrocute : ReagentEffect
/// </remarks>
[DataField("refresh")] public bool Refresh = true;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-electrocute", ("chance", Probability), ("time", ElectrocuteTime));
public override bool ShouldLog => true;
public override void Effect(ReagentEffectArgs args)

View File

@@ -2,6 +2,7 @@ using Content.Server.Chat.Systems;
using Content.Shared.Chat.Prototypes;
using Content.Shared.Chemistry.Reagent;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -18,6 +19,10 @@ public sealed class Emote : ReagentEffect
[DataField("showInChat")]
public bool ShowInChat;
// JUSTIFICATION: Emoting is flavor, so same reason popup messages are not in here.
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> null;
public override void Effect(ReagentEffectArgs args)
{
if (EmoteId == null)

View File

@@ -2,12 +2,16 @@ using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Shared.Chemistry.Reagent;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects
{
[UsedImplicitly]
public sealed class ExtinguishReaction : ReagentEffect
{
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-extinguish-reaction", ("chance", Probability));
public override void Effect(ReagentEffectArgs args)
{
if (!args.EntityManager.TryGetComponent(args.SolutionEntity, out FlammableComponent? flammable)) return;

View File

@@ -3,6 +3,7 @@ using Content.Server.Atmos.EntitySystems;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Database;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects
{
@@ -13,6 +14,10 @@ namespace Content.Server.Chemistry.ReagentEffects
public float Multiplier = 0.05f;
public override bool ShouldLog => true;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-flammable-reaction", ("chance", Probability));
public override LogImpact LogImpact => LogImpact.Medium;
public override void Effect(ReagentEffectArgs args)

View File

@@ -1,8 +1,11 @@
using System.Linq;
using System.Text.Json.Serialization;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Content.Shared.Localizations;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects
{
@@ -31,6 +34,38 @@ namespace Content.Server.Chemistry.ReagentEffects
[JsonPropertyName("ignoreResistances")]
public bool IgnoreResistances = true;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
{
var damages = new List<string>();
var heals = false;
var deals = false;
// TODO: This should be smarter. Namely, not showing a damage type as being in a group unless every damage type in the group is present and equal in value.
foreach (var (kind, amount) in Damage.GetDamagePerGroup())
{
var sign = MathF.Sign(amount.Float());
if (sign < 0)
heals = true;
if (sign > 0)
deals = true;
damages.Add(
Loc.GetString("health-change-display",
("kind", kind),
("amount", MathF.Abs(amount.Float())),
("deltasign", sign)
));
}
var healsordeals = heals ? (deals ? "both" : "heals") : (deals ? "deals" : "none");
return Loc.GetString("reagent-effect-guidebook-health-change",
("chance", Probability),
("changes", ContentLocalizationManager.FormatList(damages)),
("healsordeals", healsordeals));
}
public override void Effect(ReagentEffectArgs args)
{
var scale = ScaleByQuantity ? args.Quantity : FixedPoint2.New(1);

View File

@@ -1,6 +1,7 @@
using Content.Server.Atmos.EntitySystems;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Database;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -10,6 +11,10 @@ namespace Content.Server.Chemistry.ReagentEffects;
public sealed class Ignite : ReagentEffect
{
public override bool ShouldLog => true;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-ignite", ("chance", Probability));
public override LogImpact LogImpact => LogImpact.Medium;
public override void Effect(ReagentEffectArgs args)

View File

@@ -2,11 +2,16 @@ using Content.Server.Ghost.Roles.Components;
using Content.Server.Mind.Components;
using Content.Server.Speech.Components;
using Content.Shared.Chemistry.Reagent;
using Content.Server.Ghost.Roles.Components;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
public sealed class MakeSentient : ReagentEffect
{
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-make-sentient", ("chance", Probability));
public override void Effect(ReagentEffectArgs args)
{
var entityManager = args.EntityManager;

View File

@@ -1,6 +1,7 @@
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -12,6 +13,10 @@ public sealed class ModifyBleedAmount : ReagentEffect
[DataField("amount")]
public float Amount = -1.0f;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-modify-bleed-amount", ("chance", Probability),
("deltasign", MathF.Sign(Amount)));
public override void Effect(ReagentEffectArgs args)
{
if (args.EntityManager.TryGetComponent<BloodstreamComponent>(args.SolutionEntity, out var blood))

View File

@@ -2,6 +2,7 @@
using Content.Server.Body.Systems;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -13,6 +14,10 @@ public sealed class ModifyBloodLevel : ReagentEffect
[DataField("amount")]
public FixedPoint2 Amount = 1.0f;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-modify-blood-level", ("chance", Probability),
("deltasign", MathF.Sign(Amount.Float())));
public override void Effect(ReagentEffectArgs args)
{
if (args.EntityManager.TryGetComponent<BloodstreamComponent>(args.SolutionEntity, out var blood))

View File

@@ -1,6 +1,7 @@
using Content.Server.Body.Components;
using Content.Shared.Atmos;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -9,6 +10,10 @@ public sealed class ModifyLungGas : ReagentEffect
[DataField("ratios", required: true)]
private Dictionary<Gas, float> _ratios = default!;
// JUSTIFICATION: This is internal magic that players never directly interact with.
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> null;
public override void Effect(ReagentEffectArgs args)
{
if (args.EntityManager.TryGetComponent<LungComponent>(args.OrganEntity, out var lung))

View File

@@ -1,6 +1,7 @@
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Movement.Systems;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Server.Chemistry.ReagentEffects
@@ -29,6 +30,14 @@ namespace Content.Server.Chemistry.ReagentEffects
[DataField("statusLifetime")]
public float StatusLifetime = 2f;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
{
return Loc.GetString("reagent-effect-guidebook-movespeed-modifier",
("chance", Probability),
("walkspeed", WalkSpeedModifier),
("time", StatusLifetime));
}
/// <summary>
/// Remove reagent at set rate, changes the movespeed modifiers and adds a MovespeedModifierMetabolismComponent if not already there.
/// </summary>

View File

@@ -1,6 +1,7 @@
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -9,6 +10,10 @@ public sealed class Oxygenate : ReagentEffect
[DataField("factor")]
public float Factor = 1f;
// JUSTIFICATION: This is internal magic that players never directly interact with.
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> null;
public override void Effect(ReagentEffectArgs args)
{
if (args.EntityManager.TryGetComponent<RespiratorComponent>(args.SolutionEntity, out var resp))

View File

@@ -1,5 +1,6 @@
using Content.Shared.Chemistry.Reagent;
using Content.Server.Stunnable;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -12,6 +13,11 @@ public sealed class Paralyze : ReagentEffect
/// </remarks>
[DataField("refresh")] public bool Refresh = true;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-paralyze",
("chance", Probability),
("time", ParalyzeTime));
public override void Effect(ReagentEffectArgs args)
{
var paralyzeTime = ParalyzeTime;

View File

@@ -1,6 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Botany.Components;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
@@ -35,5 +36,7 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
// Dependencies are never injected for reagents if you intend to do that for this.
return !(Prob <= 0f) && IoCManager.Resolve<IRobustRandom>().Prob(Prob);
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-missing", ("chance", Probability));
}
}

View File

@@ -1,6 +1,7 @@
using Content.Server.Botany.Components;
using Content.Shared.Chemistry.Reagent;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
@@ -26,5 +27,7 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
plantHolderComp.SkipAging++;
plantHolderComp.ForceUpdate = true;
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-missing", ("chance", Probability));
}
}

View File

@@ -2,6 +2,7 @@ using Content.Server.Botany.Components;
using Content.Server.Botany.Systems;
using Content.Shared.Chemistry.Reagent;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
@@ -34,5 +35,7 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
plantHolderComp.Seed.Endurance++;
}
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-missing", ("chance", Probability));
}
}

View File

@@ -2,6 +2,7 @@ using Content.Server.Botany.Components;
using Content.Server.Botany.Systems;
using Content.Shared.Chemistry.Reagent;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
@@ -47,5 +48,7 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
plantHolderComp.Seed.Yield--;
}
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-missing", ("chance", Probability));
}
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Popups;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.Chemistry.ReagentEffects
@@ -16,6 +17,10 @@ namespace Content.Server.Chemistry.ReagentEffects
[DataField("visualType")]
public PopupType VisualType = PopupType.Small;
// JUSTIFICATION: This is purely cosmetic.
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> null;
public override void Effect(ReagentEffectArgs args)
{
var popupSys = args.EntityManager.EntitySysManager.GetEntitySystem<SharedPopupSystem>();

View File

@@ -1,6 +1,7 @@
using Content.Server.Traits.Assorted;
using Content.Shared.Chemistry.Reagent;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects;
@@ -16,6 +17,9 @@ public sealed class ResetNarcolepsy : ReagentEffect
[DataField("TimerReset")]
public int TimerReset = 600;
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-reset-narcolepsy", ("chance", Probability));
public override void Effect(ReagentEffectArgs args)
{
if (args.Scale != 1f)

View File

@@ -2,6 +2,7 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Nutrition.Components;
using Content.Shared.Nutrition.EntitySystems;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects
{
@@ -11,10 +12,12 @@ namespace Content.Server.Chemistry.ReagentEffects
/// </summary>
public sealed class SatiateHunger : ReagentEffect
{
private const float DefaultNutritionFactor = 3.0f;
/// <summary>
/// How much hunger is satiated when 1u of the reagent is metabolized
/// </summary>
[DataField("factor")] public float NutritionFactor { get; set; } = 3.0f;
[DataField("factor")] public float NutritionFactor { get; set; } = DefaultNutritionFactor;
//Remove reagent at set rate, satiate hunger if a HungerComponent can be found
public override void Effect(ReagentEffectArgs args)
@@ -24,5 +27,8 @@ namespace Content.Server.Chemistry.ReagentEffects
return;
entman.System<HungerSystem>().ModifyHunger(args.SolutionEntity, NutritionFactor * (float) args.Quantity, hunger);
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-satiate-hunger", ("chance", Probability), ("relative", NutritionFactor / DefaultNutritionFactor));
}
}

View File

@@ -1,6 +1,7 @@
using Content.Server.Nutrition.Components;
using Content.Shared.Chemistry.Reagent;
using Content.Server.Nutrition.EntitySystems;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects
{
@@ -10,10 +11,12 @@ namespace Content.Server.Chemistry.ReagentEffects
/// </summary>
public sealed class SatiateThirst : ReagentEffect
{
private const float DefaultHydrationFactor = 3.0f;
/// How much thirst is satiated each metabolism tick. Not currently tied to
/// rate or anything.
[DataField("factor")]
public float HydrationFactor { get; set; } = 3.0f;
public float HydrationFactor { get; set; } = DefaultHydrationFactor;
/// Satiate thirst if a ThirstComponent can be found
public override void Effect(ReagentEffectArgs args)
@@ -21,5 +24,8 @@ namespace Content.Server.Chemistry.ReagentEffects
if (args.EntityManager.TryGetComponent(args.SolutionEntity, out ThirstComponent? thirst))
EntitySystem.Get<ThirstSystem>().UpdateThirst(thirst, HydrationFactor);
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-satiate-thirst", ("chance", Probability), ("relative", HydrationFactor / DefaultHydrationFactor));
}
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.StatusEffect;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects.StatusEffects
{
@@ -57,6 +58,13 @@ namespace Content.Server.Chemistry.ReagentEffects.StatusEffects
statusSys.TrySetTime(args.SolutionEntity, Key, TimeSpan.FromSeconds(time));
}
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString(
"reagent-effect-guidebook-status-effect",
("chance", Probability),
("type", Type),
("time", Time),
("key", $"reagent-effect-status-effect-{Key}"));
}
public enum StatusEffectMetabolismType

View File

@@ -1,5 +1,6 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Jittering;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects.StatusEffects
{
@@ -33,5 +34,8 @@ namespace Content.Server.Chemistry.ReagentEffects.StatusEffects
args.EntityManager.EntitySysManager.GetEntitySystem<SharedJitteringSystem>()
.DoJitter(args.SolutionEntity, TimeSpan.FromSeconds(time), Refresh, Amplitude, Frequency);
}
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) =>
Loc.GetString("reagent-effect-guidebook-jittering", ("chance", Probability));
}
}

View File

@@ -2,12 +2,16 @@ using Content.Server.Nutrition.EntitySystems;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Nutrition.Components;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.ReagentEffects
{
[UsedImplicitly]
public sealed class WashCreamPieReaction : ReagentEffect
{
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
=> Loc.GetString("reagent-effect-guidebook-wash-cream-pie-reaction", ("chance", Probability));
public override void Effect(ReagentEffectArgs args)
{
if (!args.EntityManager.TryGetComponent(args.SolutionEntity, out CreamPiedComponent? creamPied)) return;