Add solution pouring / click-transfer (#574)

* Add click-based solution transfer

For example, clicking on a beaker with a soda can to transfer the soda to the beaker. Works on plain solution containers like beakers and also on open drink containers like soda cans as long as they have the `PourIn` and `PourOut` solution  capabilities. If no `SolutionComponent` is added to a drink entity, the `DrinkComponent` will give the entity one. This PR extends that behavior slightly by also giving these default `SolutionComponent`'s the proper capabilities for pouring in/out.

* Improve fix for poured drinks not immediately disappearing

Instead of making `DrinkComponent.Use` public this 
 splits out the code important to both users and made that function public, leaving `Use` private.

* Shorten solution transfer popup

* Make code review changes

- Move pouring code from SolutionComponent to new PourableComponent. Added PourableComponent to client ignore list and added to existing container prototypes.
- Added EmptyVolume property to shared SolutionComponent for convenience.
- Removed DrinkComponent fix from pouring AttackBy code. Instead DrinkComponent subscribes to the SolutionChanged action and updates its self when necessary.
- Fixed pouring being able to add more than a containers max volume and sometimes deleting reagents.
- Added message for when a container is full.

* More code review changes

- Remove IAttackBy ComponentReference attribute in PourableComponent
- Remove _transferAmount from shared SolutionComponent. Left over var from previous commit not being used anymore.
This commit is contained in:
moneyl
2020-01-28 20:07:02 -05:00
committed by GitHub
parent 7bc40ab13d
commit 972d601664
8 changed files with 209 additions and 31 deletions

View File

@@ -42,6 +42,12 @@ namespace Content.Shared.GameObjects.Components.Chemistry
[ViewVariables]
public int CurrentVolume => _containedSolution.TotalVolume;
/// <summary>
/// The volume without reagents remaining in the container.
/// </summary>
[ViewVariables]
public int EmptyVolume => MaxVolume - CurrentVolume;
/// <summary>
/// The current blended color of all the reagents in the container.
/// </summary>
@@ -60,6 +66,15 @@ namespace Content.Shared.GameObjects.Components.Chemistry
public IReadOnlyList<Solution.ReagentQuantity> ReagentList => _containedSolution.Contents;
/// <summary>
/// Shortcut for Capabilities PourIn flag to avoid binary operators.
/// </summary>
public bool CanPourIn => (Capabilities & SolutionCaps.PourIn) != 0;
/// <summary>
/// Shortcut for Capabilities PourOut flag to avoid binary operators.
/// </summary>
public bool CanPourOut => (Capabilities & SolutionCaps.PourOut) != 0;
/// <inheritdoc />
public override string Name => "Solution";
@@ -108,11 +123,20 @@ namespace Content.Shared.GameObjects.Components.Chemistry
return true;
}
public bool TryRemoveSolution(int quantity)
/// <summary>
/// Attempt to remove the specified quantity from this solution
/// </summary>
/// <param name="quantity">Quantity of this solution to remove</param>
/// <param name="removedSolution">Out arg. The removed solution. Useful for adding removed solution
/// into other solutions. For example, when pouring from one container to another.</param>
/// <returns>Whether or not the solution was successfully removed</returns>
public bool TryRemoveSolution(int quantity, out Solution removedSolution)
{
if (CurrentVolume == 0) return false;
removedSolution = new Solution();
if (CurrentVolume == 0)
return false;
_containedSolution.RemoveSolution(quantity);
_containedSolution.RemoveSolution(quantity, out removedSolution);
OnSolutionChanged();
return true;
}