Files
crystall-punk-14/Content.Server/GameObjects/Components/Chemistry/PourableComponent.cs

114 lines
4.3 KiB
C#
Raw Normal View History

using System.Threading.Tasks;
2020-04-05 11:36:12 +02:00
using Content.Shared.Chemistry;
using Content.Shared.Interfaces;
using Content.Shared.Interfaces.GameObjects.Components;
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.
2020-01-28 20:07:02 -05:00
using Robust.Shared.GameObjects;
using Robust.Shared.Localization;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.Chemistry
{
/// <summary>
/// Gives an entity click behavior for pouring reagents into
/// other entities and being poured into. The entity must have
/// a SolutionComponent or DrinkComponent for this to work.
/// (DrinkComponent adds a SolutionComponent if one isn't present).
/// </summary>
[RegisterComponent]
2020-05-23 17:23:25 +02:00
class PourableComponent : Component, IInteractUsing
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.
2020-01-28 20:07:02 -05:00
{
public override string Name => "Pourable";
2020-04-05 11:36:12 +02:00
private ReagentUnit _transferAmount;
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.
2020-01-28 20:07:02 -05:00
/// <summary>
/// The amount of solution to be transferred from this solution when clicking on other solutions with it.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
2020-04-05 11:36:12 +02:00
public ReagentUnit TransferAmount
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.
2020-01-28 20:07:02 -05:00
{
get => _transferAmount;
set => _transferAmount = value;
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _transferAmount, "transferAmount", ReagentUnit.New(5.0));
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.
2020-01-28 20:07:02 -05:00
}
/// <summary>
/// Called when the owner of this component is clicked on with another entity.
/// The owner of this component is the target.
/// The entity used to click on this one is the attacker.
/// </summary>
/// <param name="eventArgs">Attack event args</param>
/// <returns></returns>
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
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.
2020-01-28 20:07:02 -05:00
{
//Get target solution component
if (!Owner.TryGetComponent<SolutionContainerComponent>(out var targetSolution))
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.
2020-01-28 20:07:02 -05:00
return false;
//Get attack solution component
2020-05-23 17:23:25 +02:00
var attackEntity = eventArgs.Using;
if (!attackEntity.TryGetComponent<SolutionContainerComponent>(out var attackSolution))
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.
2020-01-28 20:07:02 -05:00
return false;
// Calculate possibe solution transfer
if (targetSolution.CanAddSolutions && attackSolution.CanRemoveSolutions)
{
// default logic (beakers and glasses)
// transfer solution from object in hand to attacked
return TryTransfer(eventArgs, attackSolution, targetSolution);
}
else if (targetSolution.CanRemoveSolutions && attackSolution.CanAddSolutions)
{
// storage tanks and sinks logic
// drain solution from attacked object to object in hand
return TryTransfer(eventArgs, targetSolution, attackSolution);
}
// No transfer possible
return false;
}
bool TryTransfer(InteractUsingEventArgs eventArgs, SolutionContainerComponent fromSolution, SolutionContainerComponent toSolution)
{
var fromEntity = fromSolution.Owner;
if (!fromEntity.TryGetComponent<PourableComponent>(out var fromPourable))
{
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.
2020-01-28 20:07:02 -05:00
return false;
}
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.
2020-01-28 20:07:02 -05:00
//Get transfer amount. May be smaller than _transferAmount if not enough room
var realTransferAmount = ReagentUnit.Min(fromPourable.TransferAmount, toSolution.EmptyVolume);
if (realTransferAmount <= 0) // Special message if container is full
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.
2020-01-28 20:07:02 -05:00
{
Owner.PopupMessage(eventArgs.User, Loc.GetString("{0:theName} is full!", toSolution.Owner));
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.
2020-01-28 20:07:02 -05:00
return false;
}
//Move units from attackSolution to targetSolution
var removedSolution = fromSolution.SplitSolution(realTransferAmount);
if (removedSolution.TotalVolume <= ReagentUnit.Zero)
{
return false;
}
if (!toSolution.TryAddSolution(removedSolution))
{
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.
2020-01-28 20:07:02 -05:00
return false;
}
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.
2020-01-28 20:07:02 -05:00
Owner.PopupMessage(eventArgs.User, Loc.GetString("You transfer {0}u to {1:theName}.", removedSolution.TotalVolume, toSolution.Owner));
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.
2020-01-28 20:07:02 -05:00
return true;
}
}
}