adds the ability to "mix" solutions (reactions caused by using an item on a solution holder) (#13015)

* everything for mixing aside from yaml changes

* add recipe and canmix to bottles and the holy mixer tag to the bible

* fixes as a result of testing

* remove unused usings

* remove emptylines that are not required

Co-authored-by: 0x6273 <0x40@keemail.me>

* more empty line removal!

Co-authored-by: 0x6273 <0x40@keemail.me>

* add single space between if statement and condition

Co-authored-by: 0x6273 <0x40@keemail.me>

* fixes indentation on TryGetMixableSolution

* raise new AfterMixingEvent after attempting to mix a solution

* before mixing event and attempt get mixable solution event

* update reaction tests to be a beaker that can be mixed, and then pass a mixer component in to simulate mixing

* make two more beaker types mixable, add attribute for mixing feedback

* bible mix message

* mixing feedback on success

* updates test to use SpawnEntity over new as per feedback

Co-authored-by: 0x6273 <0x40@keemail.me>
This commit is contained in:
Timothy Teakettle
2022-12-20 04:05:02 +00:00
committed by GitHub
parent a497167e45
commit c046666578
14 changed files with 168 additions and 9 deletions

View File

@@ -28,5 +28,6 @@ public sealed partial class ChemistrySystem : EntitySystem
// Why ChemMaster duplicates reagentdispenser nobody knows.
InitializeHypospray();
InitializeInjector();
InitializeMixing();
}
}

View File

@@ -0,0 +1,41 @@
using Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Components;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reaction;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
using Robust.Shared.Player;
namespace Content.Server.Chemistry.EntitySystems;
public sealed partial class ChemistrySystem
{
public void InitializeMixing()
{
SubscribeLocalEvent<ReactionMixerComponent, AfterInteractEvent>(OnAfterInteract);
}
private void OnAfterInteract(EntityUid uid, ReactionMixerComponent component, AfterInteractEvent args)
{
if (!args.Target.HasValue || !args.CanReach)
return;
var mixAttemptEvent = new MixingAttemptEvent(uid);
RaiseLocalEvent(uid, ref mixAttemptEvent);
if(mixAttemptEvent.Cancelled)
{
return;
}
Solution? solution = null;
if (!_solutions.TryGetMixableSolution(args.Target.Value, out solution))
return;
_popup.PopupEntity(Loc.GetString(component.MixMessage, ("mixed", Identity.Entity(args.Target.Value, EntityManager)), ("mixer", Identity.Entity(uid, EntityManager))), args.User, Filter.Entities(args.User)); ;
_solutions.UpdateChemicals(args.Target.Value, solution, true, component);
var afterMixingEvent = new AfterMixingEvent(uid, args.Target.Value);
RaiseLocalEvent(uid, afterMixingEvent);
}
}

View File

@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.Chemistry.Components.SolutionManager;
using Content.Shared.Chemistry;
using Content.Shared.Chemistry.Components;
@@ -8,6 +9,7 @@ using Content.Shared.Examine;
using Content.Shared.FixedPoint;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.Chemistry.EntitySystems;
@@ -115,12 +117,12 @@ public sealed partial class SolutionContainerSystem : EntitySystem
return splitSol;
}
public void UpdateChemicals(EntityUid uid, Solution solutionHolder, bool needsReactionsProcessing = false)
public void UpdateChemicals(EntityUid uid, Solution solutionHolder, bool needsReactionsProcessing = false, ReactionMixerComponent? mixerComponent = null)
{
// Process reactions
if (needsReactionsProcessing && solutionHolder.CanReact)
{
_chemistrySystem.FullyReactSolution(solutionHolder, uid, solutionHolder.MaxVolume);
_chemistrySystem.FullyReactSolution(solutionHolder, uid, solutionHolder.MaxVolume, mixerComponent);
}
UpdateAppearance(uid, solutionHolder);
@@ -333,6 +335,36 @@ public sealed partial class SolutionContainerSystem : EntitySystem
return reagentQuantity;
}
public bool TryGetMixableSolution(EntityUid uid,
[NotNullWhen(true)] out Solution? solution,
SolutionContainerManagerComponent? solutionsMgr = null)
{
if (!Resolve(uid, ref solutionsMgr, false))
{
solution = null;
return false;
}
var getMixableSolutionAttempt = new GetMixableSolutionAttemptEvent(uid);
RaiseLocalEvent(uid, ref getMixableSolutionAttempt);
if(getMixableSolutionAttempt.MixedSolution != null)
{
solution = getMixableSolutionAttempt.MixedSolution;
return true;
}
var tryGetSolution = solutionsMgr.Solutions.FirstOrNull(x => x.Value.CanMix);
if (tryGetSolution.HasValue)
{
solution = tryGetSolution.Value.Value;
return true;
}
solution = null;
return false;
}
// Thermal energy and temperature management.