Handcuff system (#1831)
* Implemented most serverside logic * All serverside cuff logic complete * SFX, Clientside HUD stuff, Other logic. * fffff * Cuffs 1.0 * missing loc string * Cuffs are stored in the balls now. * Basic integrationtest * Support stripping menu. * rrr * Fixes * properties * gun emoji * fixes * get rid of unused * reeee * Update Content.Shared/GameObjects/ContentNetIDs.cs Co-authored-by: Víctor Aguilera Puerto <6766154+Zumorica@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Interfaces.ResourceManagement;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.ActionBlocking;
|
||||
using Content.Shared.Preferences.Appearance;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.ActionBlocking
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class CuffableComponent : SharedCuffableComponent
|
||||
{
|
||||
[ViewVariables]
|
||||
private string _currentRSI = default;
|
||||
|
||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
||||
{
|
||||
if (!(curState is CuffableComponentState cuffState))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CanStillInteract = cuffState.CanStillInteract;
|
||||
|
||||
if (Owner.TryGetComponent<SpriteComponent>(out var sprite))
|
||||
{
|
||||
sprite.LayerSetVisible(HumanoidVisualLayers.Handcuffs, cuffState.NumHandsCuffed > 0);
|
||||
sprite.LayerSetColor(HumanoidVisualLayers.Handcuffs, cuffState.Color);
|
||||
|
||||
if (cuffState.NumHandsCuffed > 0)
|
||||
{
|
||||
if (_currentRSI != cuffState.RSI) // we don't want to keep loading the same RSI
|
||||
{
|
||||
_currentRSI = cuffState.RSI;
|
||||
sprite.LayerSetState(HumanoidVisualLayers.Handcuffs, new RSI.StateId(cuffState.IconState), new ResourcePath(cuffState.RSI));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(HumanoidVisualLayers.Handcuffs, new RSI.StateId(cuffState.IconState)); // TODO: safety check to see if RSI contains the state?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnRemove()
|
||||
{
|
||||
base.OnRemove();
|
||||
|
||||
if (Owner.TryGetComponent<SpriteComponent>(out var sprite))
|
||||
{
|
||||
sprite.LayerSetVisible(HumanoidVisualLayers.Handcuffs, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.ActionBlocking;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.ActionBlocking
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class HandcuffComponent : SharedHandcuffComponent
|
||||
{
|
||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
||||
{
|
||||
var cuffState = curState as HandcuffedComponentState;
|
||||
|
||||
if (cuffState == null || cuffState.IconState == string.Empty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Owner.TryGetComponent<SpriteComponent>(out var sprite))
|
||||
{
|
||||
sprite.LayerSetState(0, new RSI.StateId(cuffState.IconState)); // TODO: safety check to see if RSI contains the state?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,10 @@ using Content.Shared.GameObjects.Components.GUI;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects.Components.UserInterface;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components.UserInterface;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using Robust.Shared.Localization;
|
||||
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.HUD.Inventory
|
||||
@@ -15,6 +17,7 @@ namespace Content.Client.GameObjects.Components.HUD.Inventory
|
||||
{
|
||||
public Dictionary<Slots, string> Inventory { get; private set; }
|
||||
public Dictionary<string, string> Hands { get; private set; }
|
||||
public Dictionary<EntityUid, string> Handcuffs { get; private set; }
|
||||
|
||||
[ViewVariables]
|
||||
private StrippingMenu _strippingMenu;
|
||||
@@ -49,7 +52,8 @@ namespace Content.Client.GameObjects.Components.HUD.Inventory
|
||||
|
||||
_strippingMenu.ClearButtons();
|
||||
|
||||
if(Inventory != null)
|
||||
if (Inventory != null)
|
||||
{
|
||||
foreach (var (slot, name) in Inventory)
|
||||
{
|
||||
_strippingMenu.AddButton(EquipmentSlotDefines.SlotNames[slot], name, (ev) =>
|
||||
@@ -57,8 +61,10 @@ namespace Content.Client.GameObjects.Components.HUD.Inventory
|
||||
SendMessage(new StrippingInventoryButtonPressed(slot));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(Hands != null)
|
||||
if (Hands != null)
|
||||
{
|
||||
foreach (var (hand, name) in Hands)
|
||||
{
|
||||
_strippingMenu.AddButton(hand, name, (ev) =>
|
||||
@@ -66,6 +72,18 @@ namespace Content.Client.GameObjects.Components.HUD.Inventory
|
||||
SendMessage(new StrippingHandButtonPressed(hand));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (Handcuffs != null)
|
||||
{
|
||||
foreach (var (id, name) in Handcuffs)
|
||||
{
|
||||
_strippingMenu.AddButton(Loc.GetString("Restraints"), name, (ev) =>
|
||||
{
|
||||
SendMessage(new StrippingHandcuffButtonPressed(id));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
@@ -76,6 +94,7 @@ namespace Content.Client.GameObjects.Components.HUD.Inventory
|
||||
|
||||
Inventory = stripState.Inventory;
|
||||
Hands = stripState.Hands;
|
||||
Handcuffs = stripState.Handcuffs;
|
||||
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
@@ -156,7 +156,8 @@ namespace Content.Client.GameObjects.Components.Items
|
||||
}
|
||||
else
|
||||
{
|
||||
var (rsi, state) = maybeInHands.Value;
|
||||
var (rsi, state, color) = maybeInHands.Value;
|
||||
_sprite.LayerSetColor($"hand-{name}", color);
|
||||
_sprite.LayerSetVisible($"hand-{name}", true);
|
||||
_sprite.LayerSetState($"hand-{name}", state, rsi);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ using Robust.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Items
|
||||
@@ -25,6 +26,8 @@ namespace Content.Client.GameObjects.Components.Items
|
||||
|
||||
[ViewVariables] protected ResourcePath RsiPath;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)] protected Color Color;
|
||||
|
||||
private string _equippedPrefix;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
@@ -40,7 +43,7 @@ namespace Content.Client.GameObjects.Components.Items
|
||||
}
|
||||
}
|
||||
|
||||
public (RSI rsi, RSI.StateId stateId)? GetInHandStateInfo(HandLocation hand)
|
||||
public (RSI rsi, RSI.StateId stateId, Color color)? GetInHandStateInfo(HandLocation hand)
|
||||
{
|
||||
if (RsiPath == null)
|
||||
{
|
||||
@@ -52,7 +55,7 @@ namespace Content.Client.GameObjects.Components.Items
|
||||
var stateId = EquippedPrefix != null ? $"{EquippedPrefix}-inhand-{handName}" : $"inhand-{handName}";
|
||||
if (rsi.TryGetState(stateId, out _))
|
||||
{
|
||||
return (rsi, stateId);
|
||||
return (rsi, stateId, Color);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -62,6 +65,7 @@ namespace Content.Client.GameObjects.Components.Items
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
serializer.DataFieldCached(ref Color, "color", Color.White);
|
||||
serializer.DataFieldCached(ref RsiPath, "sprite", null);
|
||||
serializer.DataFieldCached(ref _equippedPrefix, "HeldPrefix", null);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Preferences.Appearance;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Content.Client.GameObjects.Components.ActionBlocking;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Mobs
|
||||
{
|
||||
@@ -49,6 +50,15 @@ namespace Content.Client.GameObjects.Components.Mobs
|
||||
|
||||
sprite.LayerSetVisible(HumanoidVisualLayers.StencilMask, Sex == Sex.Female);
|
||||
|
||||
if (Owner.TryGetComponent<CuffableComponent>(out var cuffed))
|
||||
{
|
||||
sprite.LayerSetVisible(HumanoidVisualLayers.Handcuffs, !cuffed.CanStillInteract);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetVisible(HumanoidVisualLayers.Handcuffs, false);
|
||||
}
|
||||
|
||||
var hairStyle = Appearance.HairStyleName;
|
||||
if (string.IsNullOrWhiteSpace(hairStyle) || !HairStyles.HairStylesMap.ContainsKey(hairStyle))
|
||||
hairStyle = HairStyles.DefaultHairStyle;
|
||||
|
||||
Reference in New Issue
Block a user