Metabolism tweaks / metabolism 4.0 (#5246)
* Metabolism tweaks
* use MetabolismArgs and convert ReagentEntityReactions into ReagentEffects
* fork forgor 💀
* fixes
This commit is contained in:
@@ -34,14 +34,36 @@ namespace Content.Shared.Chemistry
|
||||
if (!EntityManager.TryGetComponent(uid, out ReactiveComponent? reactive))
|
||||
return;
|
||||
|
||||
foreach (var reaction in reactive.Reactions)
|
||||
{
|
||||
// If we have a source solution, use the reagent quantity we have left. Otherwise, use the reaction volume specified.
|
||||
reaction.React(method, uid, reagent, source?.GetReagentQuantity(reagent.ID) ?? reactVolume, source, EntityManager);
|
||||
// If we have a source solution, use the reagent quantity we have left. Otherwise, use the reaction volume specified.
|
||||
var args = new ReagentEffectArgs(uid, null, source, reagent,
|
||||
source?.GetReagentQuantity(reagent.ID) ?? reactVolume, EntityManager, method);
|
||||
|
||||
// Make sure we still have enough reagent to go...
|
||||
if (source != null && !source.ContainsReagent(reagent.ID))
|
||||
break;
|
||||
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)
|
||||
{
|
||||
bool failed = false;
|
||||
foreach (var cond in effect.Conditions ?? new ReagentEffectCondition[] { })
|
||||
{
|
||||
if (!cond.Condition(args))
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if (failed)
|
||||
continue;
|
||||
|
||||
effect.Metabolize(args);
|
||||
|
||||
// Make sure we still have enough reagent to go...
|
||||
if (source != null && !source.ContainsReagent(reagent.ID))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
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.Set;
|
||||
|
||||
namespace Content.Shared.Chemistry.Reaction
|
||||
{
|
||||
@@ -10,7 +12,20 @@ namespace Content.Shared.Chemistry.Reaction
|
||||
{
|
||||
public override string Name => "Reactive";
|
||||
|
||||
[DataField("reactions", true, serverOnly:true)]
|
||||
public ReagentEntityReaction[] Reactions { get; } = Array.Empty<ReagentEntityReaction>();
|
||||
[DataField("reactions", required: true, readOnly: true, serverOnly: true)]
|
||||
public List<ReactiveReagentEffectEntry> Reactions { get; } = default!;
|
||||
}
|
||||
|
||||
[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!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.FixedPoint;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
@@ -21,6 +22,23 @@ namespace Content.Shared.Chemistry.Reagent
|
||||
[DataField("conditions")]
|
||||
public ReagentEffectCondition[]? Conditions;
|
||||
|
||||
public abstract void Metabolize(EntityUid solutionEntity, EntityUid organEntity, Solution.ReagentQuantity reagent, IEntityManager entityManager);
|
||||
public abstract void Metabolize(ReagentEffectArgs args);
|
||||
}
|
||||
|
||||
public enum ReactionMethod
|
||||
{
|
||||
Touch,
|
||||
Injection,
|
||||
Ingestion,
|
||||
}
|
||||
|
||||
public readonly record struct ReagentEffectArgs(
|
||||
EntityUid SolutionEntity,
|
||||
EntityUid? OrganEntity,
|
||||
Solution? Source,
|
||||
ReagentPrototype Reagent,
|
||||
FixedPoint2 Metabolizing,
|
||||
IEntityManager EntityManager,
|
||||
ReactionMethod? Method
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,6 @@ namespace Content.Shared.Chemistry.Reagent
|
||||
[MeansImplicitUse]
|
||||
public abstract class ReagentEffectCondition
|
||||
{
|
||||
public abstract bool Condition(EntityUid solutionEntity, EntityUid organEntity, Solution.ReagentQuantity reagent, IEntityManager entityManager);
|
||||
public abstract bool Condition(ReagentEffectArgs args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
using System;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Shared.Chemistry.Reagent
|
||||
{
|
||||
public enum ReactionMethod
|
||||
{
|
||||
Touch,
|
||||
Injection,
|
||||
Ingestion,
|
||||
}
|
||||
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
public abstract class ReagentEntityReaction
|
||||
{
|
||||
[ViewVariables]
|
||||
[DataField("touch")]
|
||||
public bool Touch { get; } = false;
|
||||
|
||||
[ViewVariables]
|
||||
[DataField("injection")]
|
||||
public bool Injection { get; } = false;
|
||||
|
||||
[ViewVariables]
|
||||
[DataField("ingestion")]
|
||||
public bool Ingestion { get; } = false;
|
||||
|
||||
public void React(ReactionMethod method, EntityUid uid, ReagentPrototype reagent, FixedPoint2 volume, Components.Solution? source, IEntityManager entityManager)
|
||||
{
|
||||
switch (method)
|
||||
{
|
||||
case ReactionMethod.Touch:
|
||||
if (!Touch)
|
||||
return;
|
||||
break;
|
||||
case ReactionMethod.Injection:
|
||||
if(!Injection)
|
||||
return;
|
||||
break;
|
||||
case ReactionMethod.Ingestion:
|
||||
if(!Ingestion)
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(method), method, null);
|
||||
}
|
||||
|
||||
React(uid, reagent, volume, source, entityManager);
|
||||
}
|
||||
|
||||
protected abstract void React(EntityUid uid, ReagentPrototype reagent, FixedPoint2 volume, Components.Solution? source, IEntityManager entityManager);
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ namespace Content.Shared.Chemistry.Reagent
|
||||
return removed;
|
||||
}
|
||||
|
||||
public void ReactionPlant(EntityUid? plantHolder, Solution.ReagentQuantity amount)
|
||||
public void ReactionPlant(EntityUid? plantHolder, Solution.ReagentQuantity amount, Solution solution)
|
||||
{
|
||||
if (plantHolder == null)
|
||||
return;
|
||||
@@ -114,7 +114,9 @@ namespace Content.Shared.Chemistry.Reagent
|
||||
var entMan = IoCManager.Resolve<IEntityManager>();
|
||||
foreach (var plantMetabolizable in _plantMetabolism)
|
||||
{
|
||||
plantMetabolizable.Metabolize(plantHolder.Value, plantHolder.Value, amount, entMan);
|
||||
plantMetabolizable.Metabolize(
|
||||
new ReagentEffectArgs(plantHolder.Value, null, solution, this, amount.Quantity, entMan, null)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user