From c947bb75e641c27e77b11131227068a3eed36f78 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sun, 24 Jan 2021 14:18:12 +0100 Subject: [PATCH] You feel a tiny prick (Hypospray) (#3034) --- .../Chemistry/HyposprayComponent.cs | 68 +++++++++ .../Chemistry/HyposprayComponent.cs | 141 ++++++++++++++++++ .../Chemistry/SharedHyposprayComponent.cs | 26 ++++ Content.Shared/GameObjects/ContentNetIDs.cs | 3 +- Resources/Audio/Items/hypospray.ogg | Bin 0 -> 9677 bytes .../Prototypes/Entities/Objects/hypospray.yml | 15 ++ .../Specific/Medical/hypospray.rsi/hypo.png | Bin 0 -> 429 bytes .../Medical/hypospray.rsi/inhand-left.png | Bin 0 -> 319 bytes .../Medical/hypospray.rsi/inhand-right.png | Bin 0 -> 319 bytes .../Specific/Medical/hypospray.rsi/meta.json | 1 + 10 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 Content.Client/GameObjects/Components/Chemistry/HyposprayComponent.cs create mode 100644 Content.Server/GameObjects/Components/Chemistry/HyposprayComponent.cs create mode 100644 Content.Shared/GameObjects/Components/Chemistry/SharedHyposprayComponent.cs create mode 100644 Resources/Audio/Items/hypospray.ogg create mode 100644 Resources/Prototypes/Entities/Objects/hypospray.yml create mode 100644 Resources/Textures/Objects/Specific/Medical/hypospray.rsi/hypo.png create mode 100644 Resources/Textures/Objects/Specific/Medical/hypospray.rsi/inhand-left.png create mode 100644 Resources/Textures/Objects/Specific/Medical/hypospray.rsi/inhand-right.png create mode 100644 Resources/Textures/Objects/Specific/Medical/hypospray.rsi/meta.json diff --git a/Content.Client/GameObjects/Components/Chemistry/HyposprayComponent.cs b/Content.Client/GameObjects/Components/Chemistry/HyposprayComponent.cs new file mode 100644 index 0000000000..979d371e62 --- /dev/null +++ b/Content.Client/GameObjects/Components/Chemistry/HyposprayComponent.cs @@ -0,0 +1,68 @@ +using Content.Client.UserInterface.Stylesheets; +using Content.Client.Utility; +using Content.Shared.Chemistry; +using Content.Shared.GameObjects.Components.Chemistry; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Shared.GameObjects; +using Robust.Shared.Localization; +using Robust.Shared.Timing; +using Robust.Shared.ViewVariables; + +#nullable enable + +namespace Content.Client.GameObjects.Components.Chemistry +{ + [RegisterComponent] + public sealed class HyposprayComponent : SharedHyposprayComponent, IItemStatus + { + [ViewVariables] private ReagentUnit CurrentVolume { get; set; } + [ViewVariables] private ReagentUnit TotalVolume { get; set; } + [ViewVariables(VVAccess.ReadWrite)] private bool _uiUpdateNeeded; + + public override void HandleComponentState(ComponentState? curState, ComponentState? nextState) + { + if (curState is not HyposprayComponentState cState) + return; + + CurrentVolume = cState.CurVolume; + TotalVolume = cState.MaxVolume; + _uiUpdateNeeded = true; + } + + Control IItemStatus.MakeControl() + { + return new StatusControl(this); + } + + private sealed class StatusControl : Control + { + private readonly HyposprayComponent _parent; + private readonly RichTextLabel _label; + + public StatusControl(HyposprayComponent parent) + { + _parent = parent; + _label = new RichTextLabel {StyleClasses = {StyleNano.StyleClassItemStatus}}; + AddChild(_label); + + parent._uiUpdateNeeded = true; + } + + protected override void Update(FrameEventArgs args) + { + base.Update(args); + if (!_parent._uiUpdateNeeded) + { + return; + } + + _parent._uiUpdateNeeded = false; + + _label.SetMarkup(Loc.GetString( + "Volume: [color=white]{0}/{1}[/color]", + _parent.CurrentVolume, _parent.TotalVolume)); + } + } + } +} diff --git a/Content.Server/GameObjects/Components/Chemistry/HyposprayComponent.cs b/Content.Server/GameObjects/Components/Chemistry/HyposprayComponent.cs new file mode 100644 index 0000000000..8b88d21d4b --- /dev/null +++ b/Content.Server/GameObjects/Components/Chemistry/HyposprayComponent.cs @@ -0,0 +1,141 @@ +using System.Threading.Tasks; +using Content.Server.GameObjects.Components.Mobs; +using Content.Server.GameObjects.Components.Mobs.State; +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.Chemistry; +using Content.Shared.GameObjects.Components.Chemistry; +using Content.Shared.GameObjects.EntitySystems; +using Content.Shared.Interfaces; +using Content.Shared.Interfaces.GameObjects.Components; +using Robust.Server.GameObjects.EntitySystems; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.ComponentDependencies; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Localization; +using Robust.Shared.Maths; +using Robust.Shared.Serialization; +using Robust.Shared.ViewVariables; + +#nullable enable + +namespace Content.Server.GameObjects.Components.Chemistry +{ + [RegisterComponent] + public sealed class HyposprayComponent : SharedHyposprayComponent, IAttack, ISolutionChange, IAfterInteract + { + [ViewVariables(VVAccess.ReadWrite)] public float ClumsyFailChance { get; set; } + [ViewVariables(VVAccess.ReadWrite)] public ReagentUnit TransferAmount { get; set; } + + [ComponentDependency] private readonly SolutionContainerComponent? _solution = default!; + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + + serializer.DataField(this, x => x.ClumsyFailChance, "ClumsyFailChance", 0.5f); + serializer.DataField(this, x => x.TransferAmount, "TransferAmount", ReagentUnit.New(5)); + } + + public override void Initialize() + { + base.Initialize(); + + Dirty(); + } + + bool IAttack.ClickAttack(AttackEventArgs eventArgs) + { + var target = eventArgs.TargetEntity; + var user = eventArgs.User; + + return TryDoInject(target, user); + } + + Task IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) + { + TryDoInject(eventArgs.Target, eventArgs.User); + return Task.CompletedTask; + } + + private bool TryDoInject(IEntity? target, IEntity user) + { + if (target == null || !EligibleEntity(target)) + return false; + + var msgFormat = "You inject {0:TheName}."; + + if (target == user) + { + msgFormat = "You inject yourself."; + } + else if (EligibleEntity(user) && ClumsyComponent.TryRollClumsy(user, ClumsyFailChance)) + { + msgFormat = "Oops! You injected yourself!"; + target = user; + } + + if (_solution == null || _solution.CurrentVolume == 0) + { + user.PopupMessageCursor(Loc.GetString("It's empty!")); + return true; + } + + user.PopupMessage(Loc.GetString(msgFormat, target)); + if (target != user) + { + target.PopupMessage(Loc.GetString("You feel a tiny prick!")); + var meleeSys = EntitySystem.Get(); + var angle = new Angle(target.Transform.WorldPosition - user.Transform.WorldPosition); + meleeSys.SendLunge(angle, user); + } + + EntitySystem.Get().PlayFromEntity("/Audio/Items/hypospray.ogg", user); + + var targetSolution = target.GetComponent(); + + // Get transfer amount. May be smaller than _transferAmount if not enough room + var realTransferAmount = ReagentUnit.Min(TransferAmount, targetSolution.EmptyVolume); + + if (realTransferAmount <= 0) + { + user.PopupMessage(user, Loc.GetString("{0:TheName} is already full!", targetSolution.Owner)); + return true; + } + + // Move units from attackSolution to targetSolution + var removedSolution = _solution.SplitSolution(realTransferAmount); + + if (!targetSolution.CanAddSolution(removedSolution)) + { + return true; + } + + removedSolution.DoEntityReaction(target, ReactionMethod.Injection); + + targetSolution.TryAddSolution(removedSolution); + + static bool EligibleEntity(IEntity entity) + { + // TODO: Does checking for BodyComponent make sense as a "can be hypospray'd" tag? + // In SS13 the hypospray ONLY works on mobs, NOT beakers or anything else. + return entity.HasComponent() && entity.HasComponent(); + } + + return true; + } + + void ISolutionChange.SolutionChanged(SolutionChangeEventArgs eventArgs) + { + Dirty(); + } + + public override ComponentState GetComponentState() + { + if (_solution == null) + return new HyposprayComponentState(ReagentUnit.Zero, ReagentUnit.Zero); + + return new HyposprayComponentState(_solution.CurrentVolume, _solution.MaxVolume); + } + } +} diff --git a/Content.Shared/GameObjects/Components/Chemistry/SharedHyposprayComponent.cs b/Content.Shared/GameObjects/Components/Chemistry/SharedHyposprayComponent.cs new file mode 100644 index 0000000000..292e7ff36d --- /dev/null +++ b/Content.Shared/GameObjects/Components/Chemistry/SharedHyposprayComponent.cs @@ -0,0 +1,26 @@ +using System; +using Content.Shared.Chemistry; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization; + +namespace Content.Shared.GameObjects.Components.Chemistry +{ + public abstract class SharedHyposprayComponent : Component + { + public sealed override string Name => "Hypospray"; + public sealed override uint? NetID => ContentNetIDs.HYPOSPRAY; + + [Serializable, NetSerializable] + protected sealed class HyposprayComponentState : ComponentState + { + public ReagentUnit CurVolume { get; } + public ReagentUnit MaxVolume { get; } + + public HyposprayComponentState(ReagentUnit curVolume, ReagentUnit maxVolume) : base(ContentNetIDs.HYPOSPRAY) + { + CurVolume = curVolume; + MaxVolume = maxVolume; + } + } + } +} diff --git a/Content.Shared/GameObjects/ContentNetIDs.cs b/Content.Shared/GameObjects/ContentNetIDs.cs index 0fe7b87c6c..4ce0dfa358 100644 --- a/Content.Shared/GameObjects/ContentNetIDs.cs +++ b/Content.Shared/GameObjects/ContentNetIDs.cs @@ -3,7 +3,8 @@ // Starting from 1000 to avoid crossover with engine. public static class ContentNetIDs { - // 1000 + // As a CMO main I hereby declare the hypospray worthy of ID #1000. + public const uint HYPOSPRAY = 1000; public const uint DESTRUCTIBLE = 1001; public const uint MAGAZINE_BARREL = 1002; public const uint HANDS = 1003; diff --git a/Resources/Audio/Items/hypospray.ogg b/Resources/Audio/Items/hypospray.ogg new file mode 100644 index 0000000000000000000000000000000000000000..92d73147a5376ea15a493152132a932a6c8e79dc GIT binary patch literal 9677 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 D3|1gw literal 0 HcmV?d00001 diff --git a/Resources/Prototypes/Entities/Objects/hypospray.yml b/Resources/Prototypes/Entities/Objects/hypospray.yml new file mode 100644 index 0000000000..a2d11fbc7e --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/hypospray.yml @@ -0,0 +1,15 @@ +- type: entity + name: hypospray + parent: BaseItem + description: A sterile injector for rapid administration of drugs to patients. + id: Hypospray + components: + - type: Sprite + sprite: Objects/Specific/Medical/hypospray.rsi + state: hypo + - type: Item + sprite: Objects/Specific/Medical/hypospray.rsi + - type: SolutionContainer + maxVol: 30 + caps: AddTo, CanExamine + - type: Hypospray diff --git a/Resources/Textures/Objects/Specific/Medical/hypospray.rsi/hypo.png b/Resources/Textures/Objects/Specific/Medical/hypospray.rsi/hypo.png new file mode 100644 index 0000000000000000000000000000000000000000..cab29e5b0afb18444eea7a58194527592dc92392 GIT binary patch literal 429 zcmV;e0aE^nP)1wNA3KCfK@OyN14*acLhe8pS2u6K!AlTtz)^8?@(wyGbjj2ls!*s^kPHfK zl-450rHRslm~*5K=3P!Q9v!LZNcCNbC6)7-1FY9- z#BrRNkCKG@;Shk~<7+N+Fz5jx1a;dck`jP!6lvAU6+x;n46XOsjPc8hkvZguU{T%q zpPNdH+;iQfPK%^mO$46ns;1*`E+tLJq2+m4mUaSqJ+Rwu18_87mC84I#sC*VKnNTL zfwr*`Knl@lH0Var>LVysD%rDTSw>^1y#wWH6)?-+2;jG*4WN|DPQsM}qzz}%ct!y5 zc@^Ic2F4&-0GmS4@Aug`yEZb{2Dt6@D3?myJdD{sy`trL+M}R-87*$T$yrdS(4Xo9 XF~@m1n0(H*00000NkvXXu0mjf=b6JS literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Medical/hypospray.rsi/inhand-left.png b/Resources/Textures/Objects/Specific/Medical/hypospray.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..e2007ee06ab73b7b219f29cb59acdb1f27ab88ce GIT binary patch literal 319 zcmV-F0l@x=P)