2020-08-18 14:39:08 +02:00
|
|
|
|
using System.Threading.Tasks;
|
2020-04-05 11:36:12 +02:00
|
|
|
|
using Content.Shared.Chemistry;
|
2020-09-01 12:34:53 +02:00
|
|
|
|
using Content.Shared.Interfaces;
|
2020-07-18 22:51:56 -07:00
|
|
|
|
using Content.Shared.Interfaces.GameObjects.Components;
|
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
|
2020-01-28 20:07:02 -05:00
|
|
|
|
{
|
|
|
|
|
|
public override string Name => "Pourable";
|
|
|
|
|
|
|
2020-04-05 11:36:12 +02:00
|
|
|
|
private ReagentUnit _transferAmount;
|
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>
|
2020-09-08 13:30:22 +02:00
|
|
|
|
[ViewVariables(VVAccess.ReadWrite)]
|
2020-04-05 11:36:12 +02:00
|
|
|
|
public ReagentUnit TransferAmount
|
2020-01-28 20:07:02 -05:00
|
|
|
|
{
|
|
|
|
|
|
get => _transferAmount;
|
|
|
|
|
|
set => _transferAmount = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void ExposeData(ObjectSerializer serializer)
|
|
|
|
|
|
{
|
|
|
|
|
|
base.ExposeData(serializer);
|
2020-06-13 01:28:28 -04:00
|
|
|
|
serializer.DataField(ref _transferAmount, "transferAmount", ReagentUnit.New(5.0));
|
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>
|
2020-08-18 14:39:08 +02:00
|
|
|
|
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
|
2020-01-28 20:07:02 -05:00
|
|
|
|
{
|
2020-05-25 01:29:09 +03:00
|
|
|
|
//Get target solution component
|
2020-09-09 18:32:31 -04:00
|
|
|
|
if (!Owner.TryGetComponent<SolutionContainerComponent>(out var targetSolution))
|
2020-01-28 20:07:02 -05:00
|
|
|
|
return false;
|
|
|
|
|
|
|
2020-05-25 01:29:09 +03:00
|
|
|
|
//Get attack solution component
|
2020-05-23 17:23:25 +02:00
|
|
|
|
var attackEntity = eventArgs.Using;
|
2020-09-09 18:32:31 -04:00
|
|
|
|
if (!attackEntity.TryGetComponent<SolutionContainerComponent>(out var attackSolution))
|
2020-01-28 20:07:02 -05:00
|
|
|
|
return false;
|
2020-05-25 01:29:09 +03:00
|
|
|
|
|
|
|
|
|
|
// Calculate possibe solution transfer
|
2020-09-09 18:32:31 -04:00
|
|
|
|
if (targetSolution.CanAddSolutions && attackSolution.CanRemoveSolutions)
|
2020-05-25 01:29:09 +03:00
|
|
|
|
{
|
|
|
|
|
|
// default logic (beakers and glasses)
|
|
|
|
|
|
// transfer solution from object in hand to attacked
|
|
|
|
|
|
return TryTransfer(eventArgs, attackSolution, targetSolution);
|
|
|
|
|
|
}
|
2020-09-09 18:32:31 -04:00
|
|
|
|
else if (targetSolution.CanRemoveSolutions && attackSolution.CanAddSolutions)
|
2020-05-25 01:29:09 +03:00
|
|
|
|
{
|
|
|
|
|
|
// storage tanks and sinks logic
|
|
|
|
|
|
// drain solution from attacked object to object in hand
|
|
|
|
|
|
return TryTransfer(eventArgs, targetSolution, attackSolution);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// No transfer possible
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-09 18:32:31 -04:00
|
|
|
|
bool TryTransfer(InteractUsingEventArgs eventArgs, SolutionContainerComponent fromSolution, SolutionContainerComponent toSolution)
|
2020-05-25 01:29:09 +03:00
|
|
|
|
{
|
|
|
|
|
|
var fromEntity = fromSolution.Owner;
|
2020-09-09 18:32:31 -04:00
|
|
|
|
|
2020-05-25 01:29:09 +03:00
|
|
|
|
if (!fromEntity.TryGetComponent<PourableComponent>(out var fromPourable))
|
2020-09-09 18:32:31 -04:00
|
|
|
|
{
|
2020-01-28 20:07:02 -05:00
|
|
|
|
return false;
|
2020-09-09 18:32:31 -04:00
|
|
|
|
}
|
2020-01-28 20:07:02 -05:00
|
|
|
|
|
|
|
|
|
|
//Get transfer amount. May be smaller than _transferAmount if not enough room
|
2020-05-25 01:29:09 +03:00
|
|
|
|
var realTransferAmount = ReagentUnit.Min(fromPourable.TransferAmount, toSolution.EmptyVolume);
|
2020-09-09 18:32:31 -04:00
|
|
|
|
|
|
|
|
|
|
if (realTransferAmount <= 0) // Special message if container is full
|
2020-01-28 20:07:02 -05:00
|
|
|
|
{
|
2020-09-09 18:32:31 -04:00
|
|
|
|
Owner.PopupMessage(eventArgs.User, Loc.GetString("{0:theName} is full!", toSolution.Owner));
|
2020-01-28 20:07:02 -05:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2020-09-09 18:32:31 -04:00
|
|
|
|
|
2020-02-06 10:13:32 -05:00
|
|
|
|
//Move units from attackSolution to targetSolution
|
2020-05-25 01:29:09 +03:00
|
|
|
|
var removedSolution = fromSolution.SplitSolution(realTransferAmount);
|
2020-09-09 18:32:31 -04:00
|
|
|
|
|
|
|
|
|
|
if (removedSolution.TotalVolume <= ReagentUnit.Zero)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-25 01:29:09 +03:00
|
|
|
|
if (!toSolution.TryAddSolution(removedSolution))
|
2020-09-09 18:32:31 -04:00
|
|
|
|
{
|
2020-01-28 20:07:02 -05:00
|
|
|
|
return false;
|
2020-09-09 18:32:31 -04:00
|
|
|
|
}
|
2020-01-28 20:07:02 -05:00
|
|
|
|
|
2020-09-09 18:32:31 -04:00
|
|
|
|
Owner.PopupMessage(eventArgs.User, Loc.GetString("You transfer {0}u to {1:theName}.", removedSolution.TotalVolume, toSolution.Owner));
|
2020-01-28 20:07:02 -05:00
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|