Add pulling taking up a hand (#2405)
* Add pulling taking up a hand * Revert unnecessary refactor
This commit is contained in:
@@ -21,7 +21,6 @@ namespace Content.Client.GameObjects.Components.Items
|
||||
|
||||
private HandsGui? _gui;
|
||||
|
||||
/// <inheritdoc />
|
||||
private readonly List<Hand> _hands = new List<Hand>();
|
||||
|
||||
[ViewVariables] public IReadOnlyList<Hand> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates over the hand keys, returning the active hand first.
|
||||
/// Enumerates over the enabled hand keys,
|
||||
/// returning the active hand first.
|
||||
/// </summary>
|
||||
public IEnumerable<string> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -411,7 +417,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
}
|
||||
|
||||
var container = ContainerManagerComponent.Create<ContainerSlot>($"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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
11
Content.Shared/Physics/Pull/PullAttemptMessage.cs
Normal file
11
Content.Shared/Physics/Pull/PullAttemptMessage.cs
Normal file
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
BIN
Resources/Textures/Interface/Inventory/blocked.png
Normal file
BIN
Resources/Textures/Interface/Inventory/blocked.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 273 B |
Reference in New Issue
Block a user