Reactive 3.0 (#5443)
* probably scrapping this * reimpl old behavior * misc fixes and initial yaml * works basically first try
This commit is contained in:
@@ -37,7 +37,7 @@ namespace Content.Server.Chemistry.Components
|
||||
internals.AreInternalsWorking())
|
||||
return;
|
||||
|
||||
var chemistry = EntitySystem.Get<ChemistrySystem>();
|
||||
var chemistry = EntitySystem.Get<ReactiveSystem>();
|
||||
var cloneSolution = solution.Clone();
|
||||
var transferAmount = FixedPoint2.Min(cloneSolution.TotalVolume * solutionFraction, bloodstream.EmptyVolume);
|
||||
var transferSolution = cloneSolution.SplitSolution(transferAmount);
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace Content.Server.Chemistry.Components
|
||||
if (!EntitySystem.Get<SolutionContainerSystem>().TryGetSolution(Owner.Uid, SolutionName, out var solution))
|
||||
return;
|
||||
|
||||
var chemistry = EntitySystem.Get<ChemistrySystem>();
|
||||
var chemistry = EntitySystem.Get<ReactiveSystem>();
|
||||
var mapGrid = MapManager.GetGrid(Owner.Transform.GridID);
|
||||
var tile = mapGrid.GetTileRef(Owner.Transform.Coordinates.ToVector2i(Owner.EntityManager, MapManager));
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
{
|
||||
public partial class SmokingSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ChemistrySystem _chemistrySystem = default!;
|
||||
[Dependency] private readonly ReactiveSystem _reactiveSystem = default!;
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
|
||||
|
||||
private const float UpdateTimer = 3f;
|
||||
@@ -98,7 +98,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
!containerManager.Owner.TryGetComponent(out BloodstreamComponent? bloodstream))
|
||||
continue;
|
||||
|
||||
_chemistrySystem.ReactionEntity(containerManager.Owner.Uid, ReactionMethod.Ingestion, inhaledSolution);
|
||||
_reactiveSystem.ReactionEntity(containerManager.Owner.Uid, ReactionMethod.Ingestion, inhaledSolution);
|
||||
bloodstream.TryTransferSolution(inhaledSolution);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,19 +1,31 @@
|
||||
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
|
||||
{
|
||||
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;
|
||||
|
||||
/// <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]
|
||||
@@ -27,5 +39,7 @@ namespace Content.Shared.Chemistry.Reaction
|
||||
|
||||
[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,6 +40,33 @@ namespace Content.Shared.Chemistry
|
||||
var args = new ReagentEffectArgs(uid, null, source, reagent,
|
||||
source?.GetReagentQuantity(reagent.ID) ?? reactVolume, EntityManager, method);
|
||||
|
||||
// First, check if the reagent wants to apply any effects.
|
||||
if (reagent.ReactiveEffects != null && reactive.ReactiveGroups != null)
|
||||
{
|
||||
foreach (var (key, val) in reagent.ReactiveEffects)
|
||||
{
|
||||
if (!val.Methods.Contains(method))
|
||||
continue;
|
||||
|
||||
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))
|
||||
@@ -59,3 +86,4 @@ namespace Content.Shared.Chemistry
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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!;
|
||||
}
|
||||
}
|
||||
|
||||
5
Resources/Prototypes/Chemistry/reactive_groups.yml
Normal file
5
Resources/Prototypes/Chemistry/reactive_groups.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
- type: reactiveGroup
|
||||
id: Flammable
|
||||
|
||||
- type: reactiveGroup
|
||||
id: Extinguish
|
||||
@@ -5,15 +5,9 @@
|
||||
suffix: AI
|
||||
components:
|
||||
- type: Reactive
|
||||
reactions:
|
||||
- reagents: [Water]
|
||||
methods: [Touch]
|
||||
effects:
|
||||
- !type:ExtinguishReaction
|
||||
- reagents: [WeldingFuel, Thermite, Plasma, Ethanol]
|
||||
methods: [Touch]
|
||||
effects:
|
||||
- !type:FlammableReaction
|
||||
groups:
|
||||
Flammable: [Touch]
|
||||
Extinguish: [Touch]
|
||||
- type: UtilityAI
|
||||
behaviorSets:
|
||||
# - Clothing
|
||||
|
||||
@@ -11,15 +11,10 @@
|
||||
- CanPilot
|
||||
- FootstepSound
|
||||
- type: Reactive
|
||||
groups:
|
||||
Flammable: [ Touch ]
|
||||
Extinguish: [ Touch ]
|
||||
reactions:
|
||||
- reagents: [Water]
|
||||
methods: [Touch]
|
||||
effects:
|
||||
- !type:ExtinguishReaction
|
||||
- reagents: [WeldingFuel, Thermite, Plasma, Ethanol]
|
||||
methods: [Touch]
|
||||
effects:
|
||||
- !type:FlammableReaction
|
||||
- reagents: [Water, SpaceCleaner]
|
||||
methods: [Touch]
|
||||
effects:
|
||||
|
||||
@@ -60,14 +60,12 @@
|
||||
- type: reagent
|
||||
id: Ethanol
|
||||
name: ethanol
|
||||
parent: BaseAlcohol
|
||||
desc: A simple alcohol, makes you drunk if consumed, flammable.
|
||||
physicalDesc: strong-smelling
|
||||
color: "#b05b3c"
|
||||
boilingPoint: 78.2
|
||||
meltingPoint: -114.1
|
||||
tileReactions:
|
||||
- !type:FlammableTileReaction
|
||||
temperatureMultiplier: 1.35
|
||||
metabolisms:
|
||||
Poison:
|
||||
effects:
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
effects:
|
||||
- !type:SatiateThirst
|
||||
factor: 3
|
||||
reactiveEffects:
|
||||
Extinguish:
|
||||
methods: [ Touch ]
|
||||
effects:
|
||||
- !type:ExtinguishReaction
|
||||
plantMetabolism:
|
||||
- !type:PlantAdjustWater
|
||||
amount: 1
|
||||
@@ -38,6 +43,11 @@
|
||||
effects:
|
||||
- !type:SatiateThirst
|
||||
factor: 2
|
||||
reactiveEffects:
|
||||
Flammable:
|
||||
methods: [ Touch ]
|
||||
effects:
|
||||
- !type:FlammableReaction
|
||||
tileReactions:
|
||||
- !type:FlammableTileReaction
|
||||
temperatureMultiplier: 1.35
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
- type: reagent
|
||||
id: BasePyrotechnic
|
||||
reactiveEffects:
|
||||
Flammable:
|
||||
methods: [ Touch ]
|
||||
effects:
|
||||
- !type:FlammableReaction
|
||||
|
||||
- type: reagent
|
||||
id: Thermite
|
||||
name: thermite
|
||||
parent: BasePyrotechnic
|
||||
desc: A mixture that becomes extremely hot when ignited, and which can burn straight through walls when applied and ignited. It'll slowly inflict burn damage to anybody dumb enough to ingest it, but can't be ignited inside inside said dumb person.
|
||||
physicalDesc: grainy
|
||||
color: "#757245"
|
||||
@@ -20,6 +29,7 @@
|
||||
- type: reagent
|
||||
id: FoamingAgent
|
||||
name: foaming agent
|
||||
parent: BasePyrotechnic
|
||||
desc: Makes foam such as that's required in metal foam grenades.
|
||||
physicalDesc: foamy
|
||||
color: "#215263"
|
||||
@@ -29,6 +39,7 @@
|
||||
- type: reagent
|
||||
id: WeldingFuel
|
||||
name: welding fuel
|
||||
parent: BasePyrotechnic
|
||||
desc: Used by welders to weld.
|
||||
physicalDesc: oily
|
||||
color: "#a76b1c"
|
||||
@@ -40,6 +51,7 @@
|
||||
- type: reagent
|
||||
id: Fluorosurfactant
|
||||
name: fluorosurfactant
|
||||
parent: BasePyrotechnic
|
||||
desc: A perfluoronated sulfonic acid that forms a foam when mixed with water.
|
||||
physicalDesc: opaque
|
||||
color: "#9e6b38"
|
||||
|
||||
@@ -115,6 +115,11 @@
|
||||
- !type:RemoveReagent
|
||||
reagent: Inaprovaline
|
||||
amount: 2
|
||||
reactiveEffects:
|
||||
Flammable:
|
||||
methods: [ Touch ]
|
||||
effects:
|
||||
- !type:FlammableReaction
|
||||
|
||||
- type: reagent
|
||||
id: UnstableMutagen
|
||||
|
||||
Reference in New Issue
Block a user