using System; using System.Collections.Generic; using System.Text.Json.Serialization; using Content.Shared.Administration.Logs; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reagent; using Content.Shared.Database; using Content.Shared.FixedPoint; using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Random; using Robust.Shared.Serialization.Manager.Attributes; namespace Content.Shared.Chemistry.Reagent { /// /// Reagent effects describe behavior that occurs when a reagent is ingested and metabolized by some /// organ. They only trigger when all of are satisfied. /// [ImplicitDataDefinitionForInheritors] [MeansImplicitUse] public abstract class ReagentEffect { [JsonPropertyName("id")] private protected string _id => this.GetType().Name; /// /// The list of conditions required for the effect to activate. Not required. /// [JsonPropertyName("conditions")] [DataField("conditions")] public ReagentEffectCondition[]? Conditions; /// /// What's the chance, from 0 to 1, that this effect will occur? /// [JsonPropertyName("probability")] [DataField("probability")] public float Probability = 1.0f; [JsonIgnore] [DataField("logImpact")] public virtual LogImpact LogImpact { get; } = LogImpact.Low; /// /// Should this reagent effect log at all? /// [JsonIgnore] [DataField("shouldLog")] public virtual bool ShouldLog { get; } = false; public abstract void Effect(ReagentEffectArgs args); } public static class ReagentEffectExt { public static bool ShouldApply(this ReagentEffect effect, ReagentEffectArgs args, IRobustRandom? random = null) { if (random == null) random = IoCManager.Resolve(); if (effect.Probability < 1.0f && !random.Prob(effect.Probability)) return false; if (effect.Conditions != null) { foreach (var cond in effect.Conditions) { if (!cond.Condition(args)) return false; } } return true; } } public enum ReactionMethod { Touch, Injection, Ingestion, } public readonly record struct ReagentEffectArgs( EntityUid SolutionEntity, EntityUid? OrganEntity, Solution? Source, ReagentPrototype Reagent, FixedPoint2 Quantity, IEntityManager EntityManager, ReactionMethod? Method ); }