1
0

EntityEffect.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using System.Linq;
  2. using System.Text.Json.Serialization;
  3. using Content.Shared.Chemistry;
  4. using Content.Shared.Chemistry.Components;
  5. using Content.Shared.Database;
  6. using Content.Shared.FixedPoint;
  7. using Content.Shared.Localizations;
  8. using JetBrains.Annotations;
  9. using Robust.Shared.Prototypes;
  10. using Robust.Shared.Random;
  11. using Content.Shared.Chemistry.Reagent;
  12. using Robust.Shared.Toolshed.TypeParsers;
  13. namespace Content.Shared.EntityEffects;
  14. /// <summary>
  15. /// Entity effects describe behavior that occurs on different kinds of triggers, e.g. when a reagent is ingested and metabolized by some
  16. /// organ. They only trigger when all of <see cref="Conditions"/> are satisfied.
  17. /// </summary>
  18. [ImplicitDataDefinitionForInheritors]
  19. [MeansImplicitUse]
  20. public abstract partial class EntityEffect
  21. {
  22. private protected string _id => this.GetType().Name;
  23. /// <summary>
  24. /// The list of conditions required for the effect to activate. Not required.
  25. /// </summary>
  26. [DataField("conditions")]
  27. public EntityEffectCondition[]? Conditions;
  28. public virtual string ReagentEffectFormat => "guidebook-reagent-effect-description";
  29. protected abstract string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys);
  30. /// <summary>
  31. /// What's the chance, from 0 to 1, that this effect will occur?
  32. /// </summary>
  33. [DataField("probability")]
  34. public float Probability = 1.0f;
  35. public virtual LogImpact LogImpact { get; private set; } = LogImpact.Low;
  36. /// <summary>
  37. /// Should this entity effect log at all?
  38. /// </summary>
  39. public virtual bool ShouldLog { get; private set; } = false;
  40. public abstract void Effect(EntityEffectBaseArgs args);
  41. /// <summary>
  42. /// Produces a localized, bbcode'd guidebook description for this effect.
  43. /// </summary>
  44. /// <returns></returns>
  45. public string? GuidebookEffectDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
  46. {
  47. var effect = ReagentEffectGuidebookText(prototype, entSys);
  48. if (effect is null)
  49. return null;
  50. return Loc.GetString(ReagentEffectFormat, ("effect", effect), ("chance", Probability),
  51. ("conditionCount", Conditions?.Length ?? 0),
  52. ("conditions",
  53. ContentLocalizationManager.FormatList(Conditions?.Select(x => x.GuidebookExplanation(prototype)).ToList() ??
  54. new List<string>())));
  55. }
  56. }
  57. public static class EntityEffectExt
  58. {
  59. public static bool ShouldApply(this EntityEffect effect, EntityEffectBaseArgs args,
  60. IRobustRandom? random = null)
  61. {
  62. if (random == null)
  63. random = IoCManager.Resolve<IRobustRandom>();
  64. if (effect.Probability < 1.0f && !random.Prob(effect.Probability))
  65. return false;
  66. if (effect.Conditions != null)
  67. {
  68. foreach (var cond in effect.Conditions)
  69. {
  70. if (!cond.Condition(args))
  71. return false;
  72. }
  73. }
  74. return true;
  75. }
  76. }
  77. /// <summary>
  78. /// EntityEffectBaseArgs only contains the target of an effect.
  79. /// If a trigger wants to include more info (e.g. the quantity of the chemical triggering the effect), it can be extended (see EntityEffectReagentArgs).
  80. /// </summary>
  81. public record class EntityEffectBaseArgs
  82. {
  83. public EntityUid TargetEntity;
  84. public IEntityManager EntityManager = default!;
  85. public EntityEffectBaseArgs(EntityUid targetEntity, IEntityManager entityManager)
  86. {
  87. TargetEntity = targetEntity;
  88. EntityManager = entityManager;
  89. }
  90. }
  91. public record class EntityEffectReagentArgs : EntityEffectBaseArgs
  92. {
  93. public EntityUid? OrganEntity;
  94. public Solution? Source;
  95. public FixedPoint2 Quantity;
  96. public ReagentPrototype? Reagent;
  97. public ReactionMethod? Method;
  98. public FixedPoint2 Scale;
  99. public EntityEffectReagentArgs(EntityUid targetEntity, IEntityManager entityManager, EntityUid? organEntity, Solution? source, FixedPoint2 quantity, ReagentPrototype? reagent, ReactionMethod? method, FixedPoint2 scale) : base(targetEntity, entityManager)
  100. {
  101. OrganEntity = organEntity;
  102. Source = source;
  103. Quantity = quantity;
  104. Reagent = reagent;
  105. Method = method;
  106. Scale = scale;
  107. }
  108. }