From f785ec4efbd15bd289f43caaad042538774509c2 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Wed, 28 Oct 2020 10:16:40 +0100 Subject: [PATCH] Add pulling taking up a hand (#2405) * Add pulling taking up a hand * Revert unnecessary refactor --- .../Components/Items/HandsComponent.cs | 61 ++++++++- Content.Client/UserInterface/HandButton.cs | 12 +- Content.Client/UserInterface/HandsGui.cs | 3 +- .../Components/GUI/HandsComponent.cs | 125 ++++++++++++------ .../Components/Items/SharedHandsComponent.cs | 32 ++++- .../Physics/Pull/PullAttemptMessage.cs | 11 ++ Content.Shared/Physics/Pull/PullController.cs | 16 +++ .../Textures/Interface/Inventory/blocked.png | Bin 0 -> 273 bytes 8 files changed, 209 insertions(+), 51 deletions(-) create mode 100644 Content.Shared/Physics/Pull/PullAttemptMessage.cs create mode 100644 Resources/Textures/Interface/Inventory/blocked.png diff --git a/Content.Client/GameObjects/Components/Items/HandsComponent.cs b/Content.Client/GameObjects/Components/Items/HandsComponent.cs index 2750547ad3..c967a7e4d7 100644 --- a/Content.Client/GameObjects/Components/Items/HandsComponent.cs +++ b/Content.Client/GameObjects/Components/Items/HandsComponent.cs @@ -21,7 +21,6 @@ namespace Content.Client.GameObjects.Components.Items private HandsGui? _gui; - /// private readonly List _hands = new List(); [ViewVariables] public IReadOnlyList Hands => _hands; @@ -90,7 +89,7 @@ namespace Content.Client.GameObjects.Components.Items { if (!TryHand(sharedHand.Name, out var hand)) { - hand = new Hand(sharedHand, Owner.EntityManager); + hand = new Hand(this, sharedHand, Owner.EntityManager); AddHand(hand); } else @@ -102,6 +101,8 @@ namespace Content.Client.GameObjects.Components.Items : null; } + hand.Enabled = sharedHand.Enabled; + UpdateHandSprites(hand); } @@ -197,10 +198,35 @@ namespace Content.Client.GameObjects.Components.Items _gameHud.HandsContainer.AddChild(_gui); _gui.UpdateHandIcons(); break; - case PlayerDetachedMsg _: _gui?.Parent?.RemoveChild(_gui); break; + case HandEnabledMsg msg: + { + var hand = GetHand(msg.Name); + + if (hand?.Button == null) + { + break; + } + + hand.Button.Blocked.Visible = false; + + break; + } + case HandDisabledMsg msg: + { + var hand = GetHand(msg.Name); + + if (hand?.Button == null) + { + break; + } + + hand.Button.Blocked.Visible = true; + + break; + } } } @@ -235,9 +261,11 @@ namespace Content.Client.GameObjects.Components.Items public class Hand { - // TODO: Separate into server hand and client hand - public Hand(SharedHand hand, IEntityManager manager, HandButton? button = null) + private bool _enabled = true; + + public Hand(HandsComponent parent, SharedHand hand, IEntityManager manager, HandButton? button = null) { + Parent = parent; Index = hand.Index; Name = hand.Name; Location = hand.Location; @@ -252,10 +280,33 @@ namespace Content.Client.GameObjects.Components.Items Entity = entity; } + private HandsComponent Parent { get; } public int Index { get; } public string Name { get; } public HandLocation Location { get; set; } public IEntity? Entity { get; set; } public HandButton? Button { get; set; } + + public bool Enabled + { + get => _enabled; + set + { + if (_enabled == value) + { + return; + } + + _enabled = value; + Parent.Dirty(); + + var message = value + ? (ComponentMessage) new HandEnabledMsg(Name) + : new HandDisabledMsg(Name); + + Parent.HandleMessage(message, Parent); + Parent.Owner.SendMessage(Parent, message); + } + } } } diff --git a/Content.Client/UserInterface/HandButton.cs b/Content.Client/UserInterface/HandButton.cs index d249cda3bd..af152d5d6b 100644 --- a/Content.Client/UserInterface/HandButton.cs +++ b/Content.Client/UserInterface/HandButton.cs @@ -1,15 +1,25 @@ using Content.Shared.GameObjects.Components.Items; using Robust.Client.Graphics; +using Robust.Client.UserInterface.Controls; namespace Content.Client.UserInterface { public class HandButton : ItemSlotButton { - public HandButton(Texture texture, Texture storageTexture, HandLocation location) : base(texture, storageTexture) + public HandButton(Texture texture, Texture storageTexture, Texture blockedTexture, HandLocation location) : base(texture, storageTexture) { Location = location; + + AddChild(Blocked = new TextureRect + { + Texture = blockedTexture, + TextureScale = (2, 2), + MouseFilter = MouseFilterMode.Stop, + Visible = false + }); } public HandLocation Location { get; } + public TextureRect Blocked { get; } } } diff --git a/Content.Client/UserInterface/HandsGui.cs b/Content.Client/UserInterface/HandsGui.cs index 3297fb467b..fca20f2b9a 100644 --- a/Content.Client/UserInterface/HandsGui.cs +++ b/Content.Client/UserInterface/HandsGui.cs @@ -111,7 +111,8 @@ namespace Content.Client.UserInterface { var buttonTexture = HandTexture(buttonLocation); var storageTexture = _resourceCache.GetTexture("/Textures/Interface/Inventory/back.png"); - var button = new HandButton(buttonTexture, storageTexture, buttonLocation); + var blockedTexture = _resourceCache.GetTexture("/Textures/Interface/Inventory/blocked.png"); + var button = new HandButton(buttonTexture, storageTexture, blockedTexture, buttonLocation); var slot = hand.Name; button.OnPressed += args => HandKeyBindDown(args, slot); diff --git a/Content.Server/GameObjects/Components/GUI/HandsComponent.cs b/Content.Server/GameObjects/Components/GUI/HandsComponent.cs index 092076d26d..27246cd39f 100644 --- a/Content.Server/GameObjects/Components/GUI/HandsComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/HandsComponent.cs @@ -4,12 +4,10 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Server.GameObjects.Components.Items.Storage; -using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.EntitySystems.Click; using Content.Server.Interfaces.GameObjects.Components.Items; using Content.Shared.GameObjects.Components.Body.Part; using Content.Shared.GameObjects.Components.Items; -using Content.Shared.GameObjects.Components.Mobs; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Physics.Pull; using Robust.Server.GameObjects; @@ -18,7 +16,6 @@ using Robust.Server.GameObjects.EntitySystemMessages; using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; -using Robust.Shared.GameObjects.Components.Transform; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; @@ -26,7 +23,6 @@ using Robust.Shared.Log; using Robust.Shared.Maths; using Robust.Shared.Players; using Robust.Shared.ViewVariables; -using Content.Server.GameObjects.Components.Pulling; using Robust.Shared.Map; namespace Content.Server.GameObjects.Components.GUI @@ -119,7 +115,8 @@ namespace Content.Server.GameObjects.Components.GUI : GetItem(ActiveHand); /// - /// Enumerates over the hand keys, returning the active hand first. + /// Enumerates over the enabled hand keys, + /// returning the active hand first. /// public IEnumerable ActivePriorityEnumerable() { @@ -135,6 +132,11 @@ namespace Content.Server.GameObjects.Components.GUI continue; } + if (!hand.Enabled) + { + continue; + } + yield return hand.Name; } } @@ -205,7 +207,11 @@ namespace Content.Server.GameObjects.Components.GUI if (mobCheck && !ActionBlockerSystem.CanPickup(Owner)) return false; - return GetHand(index)?.Container.CanInsert(item.Owner) == true; + var hand = GetHand(index); + + return hand != null && + hand.Enabled && + hand.Container.CanInsert(item.Owner) == true; } /// @@ -411,7 +417,7 @@ namespace Content.Server.GameObjects.Components.GUI } var container = ContainerManagerComponent.Create($"hand {_nextHand++}", Owner); - var hand = new Hand(name, container); + var hand = new Hand(this, name, container); _hands.Add(hand); @@ -515,6 +521,53 @@ namespace Content.Server.GameObjects.Components.GUI return false; } + public override void HandleMessage(ComponentMessage message, IComponent? component) + { + base.HandleMessage(message, component); + + if (message is PullMessage pullMessage && + pullMessage.Puller.Owner != Owner) + { + return; + } + + switch (message) + { + case PullAttemptMessage msg: + if (!_hands.Any(hand => hand.Enabled)) + { + msg.Cancelled = true; + } + + break; + case PullStartedMessage _: + var firstFreeHand = _hands.FirstOrDefault(hand => hand.Enabled); + + if (firstFreeHand == null) + { + break; + } + + firstFreeHand.Enabled = false; + + break; + case PullStoppedMessage _: + var firstOccupiedHand = _hands.FirstOrDefault(hand => !hand.Enabled); + + if (firstOccupiedHand == null) + { + break; + } + + firstOccupiedHand.Enabled = true; + + break; + case HandDisabledMsg msg: + Drop(msg.Name, false); + break; + } + } + public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession? session = null) { base.HandleNetworkMessage(message, channel, session); @@ -625,34 +678,6 @@ namespace Content.Server.GameObjects.Components.GUI } } - private void AddPullingStatuses(IEntity pulled) - { - if (pulled.TryGetComponent(out ServerStatusEffectsComponent? pulledStatus)) - { - pulledStatus.ChangeStatusEffectIcon(StatusEffect.Pulled, - "/Textures/Interface/StatusEffects/Pull/pulled.png"); - } - - if (Owner.TryGetComponent(out ServerStatusEffectsComponent? ownerStatus)) - { - ownerStatus.ChangeStatusEffectIcon(StatusEffect.Pulling, - "/Textures/Interface/StatusEffects/Pull/pulling.png"); - } - } - - private void RemovePullingStatuses(IEntity pulled) - { - if (pulled.TryGetComponent(out ServerStatusEffectsComponent? pulledStatus)) - { - pulledStatus.RemoveStatusEffect(StatusEffect.Pulled); - } - - if (Owner.TryGetComponent(out ServerStatusEffectsComponent? ownerStatus)) - { - ownerStatus.RemoveStatusEffect(StatusEffect.Pulling); - } - } - void IBodyPartAdded.BodyPartAdded(BodyPartAddedEventArgs args) { if (args.Part.PartType != BodyPartType.Hand) @@ -676,16 +701,42 @@ namespace Content.Server.GameObjects.Components.GUI public class Hand : IDisposable { - public Hand(string name, ContainerSlot container) + private bool _enabled = true; + + public Hand(HandsComponent parent, string name, ContainerSlot container) { + Parent = parent; Name = name; Container = container; } + private HandsComponent Parent { get; } public string Name { get; } public IEntity? Entity => Container.ContainedEntity; public ContainerSlot Container { get; } + public bool Enabled + { + get => _enabled; + set + { + if (_enabled == value) + { + return; + } + + _enabled = value; + Parent.Dirty(); + + var message = value + ? (ComponentMessage) new HandEnabledMsg(Name) + : new HandDisabledMsg(Name); + + Parent.HandleMessage(message, Parent); + Parent.Owner.SendMessage(Parent, message); + } + } + public void Dispose() { Container.Shutdown(); // TODO verify this @@ -693,7 +744,7 @@ namespace Content.Server.GameObjects.Components.GUI public SharedHand ToShared(int index, HandLocation location) { - return new SharedHand(index, Name, Entity?.Uid, location); + return new SharedHand(index, Name, Entity?.Uid, location, Enabled); } } diff --git a/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs b/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs index dbb31f2883..c8eb3a5255 100644 --- a/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs +++ b/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs @@ -1,13 +1,7 @@ #nullable enable using System; -using Content.Shared.GameObjects.Components.Pulling; -using Content.Shared.Physics.Pull; -using Robust.Shared.Containers; using Robust.Shared.GameObjects; -using Robust.Shared.GameObjects.Components; -using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Serialization; -using Robust.Shared.ViewVariables; namespace Content.Shared.GameObjects.Components.Items { @@ -24,13 +18,15 @@ namespace Content.Shared.GameObjects.Components.Items public readonly string Name; public readonly EntityUid? EntityUid; public readonly HandLocation Location; + public readonly bool Enabled; - public SharedHand(int index, string name, EntityUid? entityUid, HandLocation location) + public SharedHand(int index, string name, EntityUid? entityUid, HandLocation location, bool enabled) { Index = index; Name = name; EntityUid = entityUid; Location = location; + Enabled = enabled; } } @@ -99,6 +95,28 @@ namespace Content.Shared.GameObjects.Components.Items } } + [Serializable, NetSerializable] + public class HandEnabledMsg : ComponentMessage + { + public string Name { get; } + + public HandEnabledMsg(string name) + { + Name = name; + } + } + + [Serializable, NetSerializable] + public class HandDisabledMsg : ComponentMessage + { + public string Name { get; } + + public HandDisabledMsg(string name) + { + Name = name; + } + } + public enum HandLocation : byte { Left, diff --git a/Content.Shared/Physics/Pull/PullAttemptMessage.cs b/Content.Shared/Physics/Pull/PullAttemptMessage.cs new file mode 100644 index 0000000000..8a3a31bab4 --- /dev/null +++ b/Content.Shared/Physics/Pull/PullAttemptMessage.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameObjects.Components; + +namespace Content.Shared.Physics.Pull +{ + public class PullAttemptMessage : PullMessage + { + public PullAttemptMessage(IPhysicsComponent puller, IPhysicsComponent pulled) : base(puller, pulled) { } + + public bool Cancelled { get; set; } + } +} diff --git a/Content.Shared/Physics/Pull/PullController.cs b/Content.Shared/Physics/Pull/PullController.cs index 5884a0a6ff..b34b571dcc 100644 --- a/Content.Shared/Physics/Pull/PullController.cs +++ b/Content.Shared/Physics/Pull/PullController.cs @@ -100,6 +100,22 @@ namespace Content.Shared.Physics.Pull return false; } + var pullAttempt = new PullAttemptMessage(puller, ControlledComponent); + + puller.Owner.SendMessage(null, pullAttempt); + + if (pullAttempt.Cancelled) + { + return false; + } + + ControlledComponent.Owner.SendMessage(null, pullAttempt); + + if (pullAttempt.Cancelled) + { + return false; + } + _puller = puller; var message = new PullStartedMessage(this, _puller, ControlledComponent); diff --git a/Resources/Textures/Interface/Inventory/blocked.png b/Resources/Textures/Interface/Inventory/blocked.png new file mode 100644 index 0000000000000000000000000000000000000000..0d6482f99e08549783ceaf9a99c1fc17d04186be GIT binary patch literal 273 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5D0tY@ z#WAE}&fBSud@Tw*t}~BFKb(7~a>mU{b<4?<)&AY^5wQz6ye!t~@^>!R{IAXl?)7SM9KjY1%_3y$4M8tIoCU U>DahoHqbi^p00i_>zopr0H+&mLI3~& literal 0 HcmV?d00001