* Initial * Cleanup a bunch of things * some changes dunno * RequireAnchored * a * stuff * more work * Lots of progress * delete pipe visualizer * a * b * pipenet and pipenode cleanup * Fixes * Adds GasValve * Adds GasMiner * Fix stuff, maybe? * More fixes * Ignored components on the client * Adds thermomachine behavior, change a bunch of stuff * Remove Anchored * some work, but it's shitcode * significantly more ECS * ECS AtmosDevices * Cleanup * fix appearance * when the pipe direction is sus * Gas tanks and canisters * pipe anchoring and stuff * coding is my passion * Unsafe pipes take longer to unanchor * turns out we're no longer using eris canisters * Gas canister inserted tank appearance, improvements * Work on a bunch of appearances * Scrubber appearance * Reorganize AtmosphereSystem.Piping into a bunch of different systems * Appearance for vent/scrubber/pump turns off when leaving atmosphere * ThermoMachine appearance * Cleanup gas tanks * Remove passive gate unused imports * remove old canister UI functionality * PipeNode environment air, make everything use AssumeAir instead of merging manually * a * Reorganize atmos to follow new structure * ????? * Canister UI, restructure client * Restructure shared * Fix build tho * listen, at least the canister UI works entirely... * fix build : ) * Atmos device prototypes have names and descriptions * gas canister ui slider doesn't jitter * trinary prototypes * sprite for miners * ignore components * fix YAML * Fix port system doing useless thing * Fix build * fix thinking moment * fix build again because * canister direction * pipenode is a word * GasTank Air will throw on invalid states * fix build.... * Unhardcode volume pump thresholds * Volume pump and filter take time into account * Rename Join/Leave atmosphere events to AtmosDeviceEnabled/Disabled Event * Gas tank node volume is set by initial mixtuer * I love node container
113 lines
3.4 KiB
C#
113 lines
3.4 KiB
C#
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Content.Server.Body.Behavior;
|
|
using Content.Server.Nutrition.Components;
|
|
using Content.Shared.Body.Components;
|
|
using Content.Shared.Chemistry.Reagent;
|
|
using Content.Shared.Interaction;
|
|
using Content.Shared.Interaction.Helpers;
|
|
using Content.Shared.Notification.Managers;
|
|
using Robust.Shared.Audio;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.Localization;
|
|
using Robust.Shared.Player;
|
|
using Robust.Shared.Serialization.Manager.Attributes;
|
|
using Robust.Shared.ViewVariables;
|
|
|
|
namespace Content.Server.Chemistry.Components
|
|
{
|
|
[RegisterComponent]
|
|
public class PillComponent : FoodComponent, IUse, IAfterInteract
|
|
{
|
|
public override string Name => "Pill";
|
|
|
|
[ViewVariables]
|
|
[DataField("useSound")]
|
|
protected override string? UseSound { get; set; } = default;
|
|
|
|
[ViewVariables]
|
|
[DataField("trash")]
|
|
protected override string? TrashPrototype { get; set; } = default;
|
|
|
|
[ViewVariables]
|
|
[DataField("transferAmount")]
|
|
protected override ReagentUnit TransferAmount { get; set; } = ReagentUnit.New(1000);
|
|
|
|
[ViewVariables]
|
|
private SolutionContainerComponent _contents = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
Owner.EnsureComponentWarn(out _contents);
|
|
}
|
|
|
|
bool IUse.UseEntity(UseEntityEventArgs eventArgs)
|
|
{
|
|
return TryUseFood(eventArgs.User, null);
|
|
}
|
|
|
|
// Feeding someone else
|
|
async Task<bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
|
|
{
|
|
if (eventArgs.Target == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TryUseFood(eventArgs.User, eventArgs.Target);
|
|
return true;
|
|
}
|
|
|
|
public override bool TryUseFood(IEntity? user, IEntity? target, UtensilComponent? utensilUsed = null)
|
|
{
|
|
if (user == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var trueTarget = target ?? user;
|
|
|
|
if (!trueTarget.TryGetComponent(out SharedBodyComponent? body) ||
|
|
!body.TryGetMechanismBehaviors<StomachBehavior>(out var stomachs))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!user.InRangeUnobstructed(trueTarget, popup: true))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var transferAmount = ReagentUnit.Min(TransferAmount, _contents.CurrentVolume);
|
|
var split = _contents.SplitSolution(transferAmount);
|
|
|
|
var firstStomach = stomachs.FirstOrDefault(stomach => stomach.CanTransferSolution(split));
|
|
|
|
if (firstStomach == null)
|
|
{
|
|
_contents.TryAddSolution(split);
|
|
trueTarget.PopupMessage(user, Loc.GetString("You can't eat any more!"));
|
|
return false;
|
|
}
|
|
|
|
// TODO: Account for partial transfer.
|
|
|
|
split.DoEntityReaction(trueTarget, ReactionMethod.Ingestion);
|
|
|
|
firstStomach.TryTransferSolution(split);
|
|
|
|
if (UseSound != null)
|
|
{
|
|
SoundSystem.Play(Filter.Pvs(trueTarget), UseSound, trueTarget, AudioParams.Default.WithVolume(-1f));
|
|
}
|
|
|
|
trueTarget.PopupMessage(user, Loc.GetString("You swallow the pill."));
|
|
|
|
Owner.QueueDelete();
|
|
return true;
|
|
}
|
|
}
|
|
}
|