Adds metabolism effects to pretty much every chem already in the game (#5349)

* pass 1

* a little more reagent effect for breakfast

* move lots of stuff around

* implements all medicines

* implement all cleaning & elements

* implement toxins/pyrotechnic

* p

* linter fixies

* fixes + narcotic balancing

* fix and standardize

* reviews

* things
This commit is contained in:
mirrorcult
2021-11-20 16:47:53 -07:00
committed by GitHub
parent 8c64450305
commit 181fd055ce
36 changed files with 1107 additions and 532 deletions

View File

@@ -0,0 +1,22 @@
using Content.Server.Temperature.Components;
using Content.Server.Temperature.Systems;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Server.Chemistry.ReagentEffects
{
public class AdjustTemperature : ReagentEffect
{
[DataField("amount")]
public float Amount;
public override void Metabolize(ReagentEffectArgs args)
{
if (args.EntityManager.TryGetComponent(args.SolutionEntity, out TemperatureComponent temp))
{
var sys = args.EntityManager.EntitySysManager.GetEntitySystem<TemperatureSystem>();
sys.ChangeHeat(args.SolutionEntity, Amount, true, temp);
}
}
}
}

View File

@@ -0,0 +1,37 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Popups;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Player;
using Robust.Shared.Random;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Server.Chemistry.ReagentEffects
{
public class PopupMessage : ReagentEffect
{
[DataField("messages", required: true)]
public string[] Messages = default!;
[DataField("type")]
public PopupType Type = PopupType.Local;
public override void Metabolize(ReagentEffectArgs args)
{
var popupSys = args.EntityManager.EntitySysManager.GetEntitySystem<SharedPopupSystem>();
var random = IoCManager.Resolve<IRobustRandom>();
var msg = random.Pick(Messages);
if (Type == PopupType.Local)
popupSys.PopupEntity(Loc.GetString(msg), args.SolutionEntity, Filter.Entities(args.SolutionEntity));
else if (Type == PopupType.Pvs)
popupSys.PopupEntity(Loc.GetString(msg), args.SolutionEntity, Filter.Pvs(args.SolutionEntity));
}
}
public enum PopupType
{
Pvs,
Local
}
}

View File

@@ -0,0 +1,54 @@
using Content.Server.Chemistry.EntitySystems;
using Content.Shared.Body.Prototypes;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.FixedPoint;
using JetBrains.Annotations;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Chemistry.ReagentEffects
{
[UsedImplicitly]
public class RemoveReagent : ReagentEffect
{
/// <summary>
/// The reagent ID to remove. Only one of this and <see cref="Group"/> should be active.
/// </summary>
[DataField("reagent", customTypeSerializer:typeof(PrototypeIdSerializer<ReagentPrototype>))]
public string? Reagent = null;
/// <summary>
/// The metabolism group to remove, if the reagent satisfies any.
/// Only one of this and <see cref="Reagent"/> should be active.
/// </summary>
[DataField("group", customTypeSerializer:typeof(PrototypeIdSerializer<MetabolismGroupPrototype>))]
public string? Group = null;
[DataField("amount", required: true)]
public FixedPoint2 Amount = default!;
public override void Metabolize(ReagentEffectArgs args)
{
if (args.Source != null)
{
var solutionSys = args.EntityManager.EntitySysManager.GetEntitySystem<SolutionContainerSystem>();
if (Reagent != null && args.Source.ContainsReagent(Reagent))
{
solutionSys.TryRemoveReagent(args.SolutionEntity, args.Source, Reagent, Amount);
}
else if (Group != null)
{
var prototypeMan = IoCManager.Resolve<IPrototypeManager>();
foreach (var quant in args.Source.Contents.ToArray())
{
var proto = prototypeMan.Index<ReagentPrototype>(quant.ReagentId);
if (proto.Metabolisms != null && proto.Metabolisms.ContainsKey(Group))
solutionSys.TryRemoveReagent(args.SolutionEntity, args.Source, quant.ReagentId, Amount);
}
}
}
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.StatusEffect;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Server.Chemistry.ReagentEffects.StatusEffects
{
/// <summary>
/// Adds a generic status effect to the entity,
/// not worrying about things like how to affect the time it lasts for
/// or component fields or anything. Just adds a component to an entity
/// for a given time. Easy.
/// </summary>
/// <remarks>
/// Can be used for things like adding accents or something. I don't know. Go wild.
/// </remarks>
[UsedImplicitly]
public class GenericStatusEffect : ReagentEffect
{
[DataField("key", required: true)]
public string Key = default!;
[DataField("component")]
public string Component = String.Empty;
[DataField("time")]
public float Time = 2.0f;
/// <summary>
/// Should this effect add the status effect, remove time from it, or set its cooldown?
/// </summary>
[DataField("type")]
public StatusEffectMetabolismType Type = StatusEffectMetabolismType.Add;
public override void Metabolize(ReagentEffectArgs args)
{
var statusSys = args.EntityManager.EntitySysManager.GetEntitySystem<StatusEffectsSystem>();
if (Type == StatusEffectMetabolismType.Add && Component != String.Empty)
{
statusSys.TryAddStatusEffect(args.SolutionEntity, Key, TimeSpan.FromSeconds(Time), Component);
}
else if (Type == StatusEffectMetabolismType.Remove)
{
statusSys.TryRemoveTime(args.SolutionEntity, Key, TimeSpan.FromSeconds(Time));
}
else if (Type == StatusEffectMetabolismType.Set)
{
statusSys.TrySetTime(args.SolutionEntity, Key, TimeSpan.FromSeconds(Time));
}
}
}
public enum StatusEffectMetabolismType
{
Add,
Remove,
Set
}
}

View File

@@ -0,0 +1,32 @@
using System;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Jittering;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Server.Chemistry.ReagentEffects.StatusEffects
{
/// <summary>
/// Adds the jitter status effect to a mob.
/// This doesn't use generic status effects because it needs to
/// take in some parameters that JitterSystem needs.
/// </summary>
public class Jitter : ReagentEffect
{
[DataField("amplitude")]
public float Amplitude = 10.0f;
[DataField("frequency")]
public float Frequency = 4.0f;
[DataField("time")]
public float Time = 2.0f;
public override void Metabolize(ReagentEffectArgs args)
{
args.EntityManager.EntitySysManager.GetEntitySystem<SharedJitteringSystem>()
.DoJitter(args.SolutionEntity, TimeSpan.FromSeconds(Time), Amplitude, Frequency);
}
}
}