Reactive 3.0 (#5443)
* probably scrapping this * reimpl old behavior * misc fixes and initial yaml * works basically first try
This commit is contained in:
@@ -334,7 +334,7 @@ namespace Content.Shared.Chemistry.Components
|
||||
|
||||
public void DoEntityReaction(EntityUid uid, ReactionMethod method)
|
||||
{
|
||||
var chemistry = EntitySystem.Get<ChemistrySystem>();
|
||||
var chemistry = EntitySystem.Get<ReactiveSystem>();
|
||||
|
||||
foreach (var (reagentId, quantity) in Contents.ToArray())
|
||||
{
|
||||
|
||||
@@ -1,31 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
|
||||
|
||||
namespace Content.Shared.Chemistry.Reaction
|
||||
namespace Content.Shared.Chemistry.Reaction;
|
||||
|
||||
[RegisterComponent]
|
||||
public class ReactiveComponent : Component
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class ReactiveComponent : Component
|
||||
{
|
||||
public override string Name => "Reactive";
|
||||
public override string Name => "Reactive";
|
||||
|
||||
[DataField("reactions", required: true, readOnly: true, serverOnly: true)]
|
||||
public List<ReactiveReagentEffectEntry> Reactions { get; } = default!;
|
||||
}
|
||||
/// <summary>
|
||||
/// A dictionary of reactive groups -> methods that work on them.
|
||||
/// </summary>
|
||||
[DataField("groups", readOnly: true, serverOnly: true,
|
||||
customTypeSerializer:
|
||||
typeof(PrototypeIdDictionarySerializer<HashSet<ReactionMethod>, ReactiveGroupPrototype>))]
|
||||
public Dictionary<string, HashSet<ReactionMethod>>? ReactiveGroups;
|
||||
|
||||
[DataDefinition]
|
||||
public class ReactiveReagentEffectEntry
|
||||
{
|
||||
[DataField("methods")]
|
||||
public HashSet<ReactionMethod> Methods = default!;
|
||||
|
||||
[DataField("reagents", customTypeSerializer: typeof(PrototypeIdHashSetSerializer<ReagentPrototype>))]
|
||||
public HashSet<string>? Reagents = null;
|
||||
|
||||
[DataField("effects", required: true)]
|
||||
public List<ReagentEffect> Effects = default!;
|
||||
}
|
||||
/// <summary>
|
||||
/// Special reactions that this prototype can specify, outside of any that reagents already apply.
|
||||
/// Useful for things like monkey cubes, which have a really prototype-specific effect.
|
||||
/// </summary>
|
||||
[DataField("reactions", true, serverOnly: true)]
|
||||
public List<ReactiveReagentEffectEntry>? Reactions;
|
||||
}
|
||||
|
||||
[DataDefinition]
|
||||
public class ReactiveReagentEffectEntry
|
||||
{
|
||||
[DataField("methods")]
|
||||
public HashSet<ReactionMethod> Methods = default!;
|
||||
|
||||
[DataField("reagents", customTypeSerializer: typeof(PrototypeIdHashSetSerializer<ReagentPrototype>))]
|
||||
public HashSet<string>? Reagents = null;
|
||||
|
||||
[DataField("effects", required: true)]
|
||||
public List<ReagentEffect> Effects = default!;
|
||||
[DataField("groups", required: true, readOnly: true, serverOnly: true,
|
||||
customTypeSerializer:typeof(PrototypeIdDictionarySerializer<HashSet<ReactionMethod>, ReactiveGroupPrototype>))]
|
||||
public Dictionary<string, HashSet<ReactionMethod>> ReactiveGroups { get; } = default!;
|
||||
}
|
||||
|
||||
11
Content.Shared/Chemistry/Reaction/ReactiveGroupPrototype.cs
Normal file
11
Content.Shared/Chemistry/Reaction/ReactiveGroupPrototype.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Shared.Chemistry.Reaction;
|
||||
|
||||
[Prototype("reactiveGroup")]
|
||||
public class ReactiveGroupPrototype : IPrototype
|
||||
{
|
||||
[DataField("id", required: true)]
|
||||
public string ID { get; } = default!;
|
||||
}
|
||||
@@ -11,7 +11,7 @@ using Robust.Shared.Random;
|
||||
namespace Content.Shared.Chemistry
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public partial class ChemistrySystem : EntitySystem
|
||||
public class ReactiveSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||
@@ -40,20 +40,48 @@ namespace Content.Shared.Chemistry
|
||||
var args = new ReagentEffectArgs(uid, null, source, reagent,
|
||||
source?.GetReagentQuantity(reagent.ID) ?? reactVolume, EntityManager, method);
|
||||
|
||||
foreach (var entry in reactive.Reactions)
|
||||
// First, check if the reagent wants to apply any effects.
|
||||
if (reagent.ReactiveEffects != null && reactive.ReactiveGroups != null)
|
||||
{
|
||||
if (!entry.Methods.Contains(method))
|
||||
continue;
|
||||
|
||||
if (entry.Reagents != null && !entry.Reagents.Contains(reagent.ID))
|
||||
continue;
|
||||
|
||||
foreach (var effect in entry.Effects)
|
||||
foreach (var (key, val) in reagent.ReactiveEffects)
|
||||
{
|
||||
if (!effect.ShouldApply(args, _robustRandom))
|
||||
if (!val.Methods.Contains(method))
|
||||
continue;
|
||||
|
||||
effect.Effect(args);
|
||||
if (!reactive.ReactiveGroups.ContainsKey(key))
|
||||
continue;
|
||||
|
||||
if (!reactive.ReactiveGroups[key].Contains(method))
|
||||
continue;
|
||||
|
||||
foreach (var effect in val.Effects)
|
||||
{
|
||||
if (!effect.ShouldApply(args, _robustRandom))
|
||||
continue;
|
||||
|
||||
effect.Effect(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then, check if the prototype has any effects it can apply as well.
|
||||
if (reactive.Reactions != null)
|
||||
{
|
||||
foreach (var entry in reactive.Reactions)
|
||||
{
|
||||
if (!entry.Methods.Contains(method))
|
||||
continue;
|
||||
|
||||
if (entry.Reagents != null && !entry.Reagents.Contains(reagent.ID))
|
||||
continue;
|
||||
|
||||
foreach (var effect in entry.Effects)
|
||||
{
|
||||
if (!effect.ShouldApply(args, _robustRandom))
|
||||
continue;
|
||||
|
||||
effect.Effect(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,15 +23,6 @@ namespace Content.Shared.Chemistry.Reagent
|
||||
[DataDefinition]
|
||||
public class ReagentPrototype : IPrototype, IInheritingPrototype
|
||||
{
|
||||
[DataField("metabolisms", serverOnly: true, customTypeSerializer: typeof(PrototypeIdDictionarySerializer<ReagentEffectsEntry, MetabolismGroupPrototype>))]
|
||||
public Dictionary<string, ReagentEffectsEntry>? Metabolisms = null;
|
||||
|
||||
[DataField("tileReactions", serverOnly: true)]
|
||||
private readonly List<ITileReaction> _tileReactions = new(0);
|
||||
|
||||
[DataField("plantMetabolism", serverOnly: true)]
|
||||
private readonly List<ReagentEffect> _plantMetabolism = new(0);
|
||||
|
||||
[ViewVariables]
|
||||
[DataField("id", required: true)]
|
||||
public string ID { get; } = default!;
|
||||
@@ -64,9 +55,17 @@ namespace Content.Shared.Chemistry.Reagent
|
||||
[DataField("spritePath")]
|
||||
public string SpriteReplacementPath { get; } = string.Empty;
|
||||
|
||||
//List of metabolism effects this reagent has, should really only be used server-side.
|
||||
public IReadOnlyList<ITileReaction> TileReactions => _tileReactions;
|
||||
public IReadOnlyList<ReagentEffect> PlantMetabolism => _plantMetabolism;
|
||||
[DataField("metabolisms", serverOnly: true, customTypeSerializer: typeof(PrototypeIdDictionarySerializer<ReagentEffectsEntry, MetabolismGroupPrototype>))]
|
||||
public Dictionary<string, ReagentEffectsEntry>? Metabolisms = null;
|
||||
|
||||
[DataField("reactiveEffects", serverOnly: true, customTypeSerializer:typeof(PrototypeIdDictionarySerializer<ReactiveReagentEffectEntry, ReactiveGroupPrototype>))]
|
||||
public Dictionary<string, ReactiveReagentEffectEntry>? ReactiveEffects = null;
|
||||
|
||||
[DataField("tileReactions", serverOnly: true)]
|
||||
public readonly List<ITileReaction> TileReactions = new(0);
|
||||
|
||||
[DataField("plantMetabolism", serverOnly: true)]
|
||||
public readonly List<ReagentEffect> PlantMetabolisms = new(0);
|
||||
|
||||
/// <summary>
|
||||
/// If the substance color is too dark we user a lighter version to make the text color readable when the user examines a solution.
|
||||
@@ -93,7 +92,7 @@ namespace Content.Shared.Chemistry.Reagent
|
||||
if (tile.Tile.IsEmpty)
|
||||
return removed;
|
||||
|
||||
foreach (var reaction in _tileReactions)
|
||||
foreach (var reaction in TileReactions)
|
||||
{
|
||||
removed += reaction.TileReact(tile, this, reactVolume - removed);
|
||||
|
||||
@@ -115,7 +114,7 @@ namespace Content.Shared.Chemistry.Reagent
|
||||
var entMan = IoCManager.Resolve<IEntityManager>();
|
||||
var random = IoCManager.Resolve<IRobustRandom>();
|
||||
var args = new ReagentEffectArgs(plantHolder.Value, null, solution, this, amount.Quantity, entMan, null);
|
||||
foreach (var plantMetabolizable in _plantMetabolism)
|
||||
foreach (var plantMetabolizable in PlantMetabolisms)
|
||||
{
|
||||
if (!plantMetabolizable.ShouldApply(args, random))
|
||||
continue;
|
||||
@@ -140,4 +139,14 @@ namespace Content.Shared.Chemistry.Reagent
|
||||
[DataField("effects", required: true)]
|
||||
public ReagentEffect[] Effects = default!;
|
||||
}
|
||||
|
||||
[DataDefinition]
|
||||
public class ReactiveReagentEffectEntry
|
||||
{
|
||||
[DataField("methods", required: true)]
|
||||
public HashSet<ReactionMethod> Methods = default!;
|
||||
|
||||
[DataField("effects", required: true)]
|
||||
public ReagentEffect[] Effects = default!;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user