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:
@@ -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,
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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-
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user