Allow drag-and-drop insertion of reagents into the ChemMaster (#19796)

* Add DumpableSolutionComponent

Separates out the component from "DrainComponent" that allows one to drag a bucket/any reagent container onto a drain/sink/toilet to empty it and allows other reagent containers to reuse the code effortlessly.

* Give the ChemMaster 4000 the DumpableSolution Component

Allows drag and dropping solutions into the ChemMaster much like you used to be able to do exclusively with drains. This also allows dumping jugs into them.
This commit is contained in:
TNE
2023-09-04 14:53:13 +02:00
committed by GitHub
parent d67569786c
commit 52ef8f9b70
9 changed files with 82 additions and 12 deletions

View File

@@ -91,6 +91,21 @@ public sealed partial class SolutionContainerSystem
return true; return true;
} }
public bool TryGetDumpableSolution(EntityUid uid,
[NotNullWhen(true)] out Solution? solution,
DumpableSolutionComponent? dumpable = null,
SolutionContainerManagerComponent? manager = null)
{
if (!Resolve(uid, ref dumpable, ref manager, false)
|| !manager.Solutions.TryGetValue(dumpable.Solution, out solution))
{
solution = null;
return false;
}
return true;
}
public bool TryGetDrawableSolution(EntityUid uid, public bool TryGetDrawableSolution(EntityUid uid,
[NotNullWhen(true)] out Solution? solution, [NotNullWhen(true)] out Solution? solution,
DrawableSolutionComponent? drawable = null, DrawableSolutionComponent? drawable = null,

View File

@@ -24,20 +24,26 @@ public sealed partial class PuddleSystem
return; return;
} }
TryComp<DrainableSolutionComponent>(args.Target, out var drainable); // Dump reagents into DumpableSolution
if (TryComp<DumpableSolutionComponent>(args.Target, out var dump))
_solutionContainerSystem.TryGetDrainableSolution(args.Target, out var drainableSolution, drainable);
// Dump reagents into drain
if (TryComp<DrainComponent>(args.Target, out var drain) && drainable != null)
{ {
if (drainableSolution == null || solution == null) _solutionContainerSystem.TryGetDumpableSolution(args.Target, out var dumpableSolution, dump);
if (dumpableSolution == null || solution == null)
return; return;
var split = _solutionContainerSystem.SplitSolution(uid, solution, drainableSolution.AvailableVolume); bool success = true;
if (dump.Unlimited)
{
var split = _solutionContainerSystem.SplitSolution(uid, solution, solution.Volume);
dumpableSolution.AddSolution(split, _prototypeManager);
}
else
{
var split = _solutionContainerSystem.SplitSolution(uid, solution, dumpableSolution.AvailableVolume);
success = _solutionContainerSystem.TryAddSolution(args.Target, dumpableSolution, split);
}
// TODO: Drane refactor if (success)
if (_solutionContainerSystem.TryAddSolution(args.Target, drainableSolution, split))
{ {
_audio.PlayPvs(AbsorbentComponent.DefaultTransferSound, args.Target); _audio.PlayPvs(AbsorbentComponent.DefaultTransferSound, args.Target);
} }
@@ -49,6 +55,10 @@ public sealed partial class PuddleSystem
return; return;
} }
TryComp<DrainableSolutionComponent>(args.Target, out var drainable);
_solutionContainerSystem.TryGetDrainableSolution(args.Target, out var drainableSolution, drainable);
// Take reagents from target // Take reagents from target
if (drainable != null) if (drainable != null)
{ {

View File

@@ -89,6 +89,7 @@ namespace Content.Server.Interaction
var dropArgs = new DragDropTargetEvent(user.Value, msg.Dragged); var dropArgs = new DragDropTargetEvent(user.Value, msg.Dragged);
// trigger dragdrops on the target entity (what you are dropping onto)
RaiseLocalEvent(msg.Target, ref dropArgs); RaiseLocalEvent(msg.Target, ref dropArgs);
} }

View File

@@ -0,0 +1,25 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Chemistry.Components;
/// <summary>
/// Denotes the solution that can be easily dumped into (completely removed from the dumping container into this one)
/// Think pouring a container fully into this.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class DumpableSolutionComponent : Component
{
/// <summary>
/// Solution name that can be dumped into.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("solution")]
public string Solution { get; set; } = "default";
/// <summary>
/// Whether the solution can be dumped into infinitely.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("unlimited")]
public bool Unlimited { get; set; } = false;
}

View File

@@ -17,8 +17,9 @@ public abstract class SharedPuddleSystem : EntitySystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<RefillableSolutionComponent, CanDragEvent>(OnRefillableCanDrag); SubscribeLocalEvent<RefillableSolutionComponent, CanDragEvent>(OnRefillableCanDrag);
SubscribeLocalEvent<RefillableSolutionComponent, CanDropDraggedEvent>(OnRefillableCanDropDragged); SubscribeLocalEvent<DumpableSolutionComponent, CanDropTargetEvent>(OnDumpCanDropTarget);
SubscribeLocalEvent<DrainableSolutionComponent, CanDropTargetEvent>(OnDrainCanDropTarget); SubscribeLocalEvent<DrainableSolutionComponent, CanDropTargetEvent>(OnDrainCanDropTarget);
SubscribeLocalEvent<RefillableSolutionComponent, CanDropDraggedEvent>(OnRefillableCanDropDragged);
} }
private void OnRefillableCanDrag(EntityUid uid, RefillableSolutionComponent component, ref CanDragEvent args) private void OnRefillableCanDrag(EntityUid uid, RefillableSolutionComponent component, ref CanDragEvent args)
@@ -26,6 +27,15 @@ public abstract class SharedPuddleSystem : EntitySystem
args.Handled = true; args.Handled = true;
} }
private void OnDumpCanDropTarget(EntityUid uid, DumpableSolutionComponent component, ref CanDropTargetEvent args)
{
if (HasComp<DrainableSolutionComponent>(args.Dragged))
{
args.CanDrop = true;
args.Handled = true;
}
}
private void OnDrainCanDropTarget(EntityUid uid, DrainableSolutionComponent component, ref CanDropTargetEvent args) private void OnDrainCanDropTarget(EntityUid uid, DrainableSolutionComponent component, ref CanDropTargetEvent args)
{ {
if (HasComp<RefillableSolutionComponent>(args.Dragged)) if (HasComp<RefillableSolutionComponent>(args.Dragged))
@@ -37,7 +47,7 @@ public abstract class SharedPuddleSystem : EntitySystem
private void OnRefillableCanDropDragged(EntityUid uid, RefillableSolutionComponent component, ref CanDropDraggedEvent args) private void OnRefillableCanDropDragged(EntityUid uid, RefillableSolutionComponent component, ref CanDropDraggedEvent args)
{ {
if (!HasComp<DrainableSolutionComponent>(args.Target) && !HasComp<DrainComponent>(args.Target)) if (!HasComp<DrainableSolutionComponent>(args.Target) && !HasComp<DumpableSolutionComponent>(args.Target))
return; return;
args.CanDrop = true; args.CanDrop = true;

View File

@@ -417,6 +417,8 @@
sound: sound:
path: /Audio/Ambience/Objects/drain.ogg path: /Audio/Ambience/Objects/drain.ogg
- type: Drain - type: Drain
- type: DumpableSolution
solution: drainBuffer
- type: Appearance - type: Appearance
- type: SolutionContainerVisuals - type: SolutionContainerVisuals
maxFillLevels: 1 maxFillLevels: 1

View File

@@ -37,6 +37,8 @@
- type: ReagentTank - type: ReagentTank
- type: Drain - type: Drain
autoDrain: false autoDrain: false
- type: DumpableSolution
solution: drainBuffer
- type: Damageable - type: Damageable
damageContainer: Inorganic damageContainer: Inorganic
damageModifierSet: Metallic damageModifierSet: Metallic

View File

@@ -36,6 +36,8 @@
- type: Appearance - type: Appearance
- type: Drain - type: Drain
autoDrain: false autoDrain: false
- type: DumpableSolution
solution: drainBuffer
- type: SolutionContainerVisuals - type: SolutionContainerVisuals
maxFillLevels: 1 maxFillLevels: 1
fillBaseName: fill- fillBaseName: fill-

View File

@@ -86,6 +86,9 @@
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
buffer: {} buffer: {}
- type: DumpableSolution
solution: buffer
unlimited: true
- type: GuideHelp - type: GuideHelp
guides: guides:
- Chemicals - Chemicals