SubscribeLocalEvent<CuffableComponent, ComponentGetState>(OnCuffableGetState);
}
- private void OnCuffableGetState(EntityUid uid, CuffableComponent component, ref ComponentGetState args)
+ private void OnCuffableGetState(Entity<CuffableComponent> entity, ref ComponentGetState args)
{
// there are 2 approaches i can think of to handle the handcuff overlay on players
// 1 - make the current RSI the handcuff type that's currently active. all handcuffs on the player will appear the same.
// approach #2 would be more difficult/time consuming to do and the payoff doesn't make it worth it.
// right now we're doing approach #1.
HandcuffComponent? cuffs = null;
- if (component.CuffedHandCount > 0)
- TryComp(component.LastAddedCuffs, out cuffs);
- args.State = new CuffableComponentState(component.CuffedHandCount,
- component.CanStillInteract,
+ if (TryGetLastCuff((entity, entity.Comp), out var cuff))
+ TryComp(cuff, out cuffs);
+ args.State = new CuffableComponentState(entity.Comp.CuffedHandCount,
+ entity.Comp.CanStillInteract,
cuffs?.CuffedRSI,
- $"{cuffs?.BodyIconState}-{component.CuffedHandCount}",
+ $"{cuffs?.BodyIconState}-{entity.Comp.CuffedHandCount}",
cuffs?.Color);
// the iconstate is formatted as blah-2, blah-4, blah-6, etc.
// the number corresponds to how many hands are cuffed.
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Shared.ActionBlocker;
using Content.Shared.Administration.Components;
{
if (args.Handled)
return;
- TryUncuff(ent, ent, cuffable: ent.Comp);
+ TryUncuff((ent, ent.Comp), ent);
args.Handled = true;
}
Verb verb = new()
{
- Act = () => TryUncuff(uid, args.User, cuffable: component),
+ Act = () => TryUncuff((uid, component), args.User),
DoContactInteraction = true,
Text = Loc.GetString("uncuff-verb-get-data-text")
};
return true;
}
+ /// <inheritdoc cref="TryUncuff(Entity{CuffableComponent?},EntityUid,Entity{HandcuffComponent?})"/>
+ public void TryUncuff(Entity<CuffableComponent?> target, EntityUid user)
+ {
+ if (!TryGetLastCuff(target, out var cuff))
+ return;
+
+ TryUncuff(target, user, cuff.Value);
+ }
+
/// <summary>
/// Attempt to uncuff a cuffed entity. Can be called by the cuffed entity, or another entity trying to help uncuff them.
/// If the uncuffing succeeds, the cuffs will drop on the floor.
/// </summary>
- /// <param name="target"></param>
- /// <param name="user">The cuffed entity</param>
- /// <param name="cuffsToRemove">Optional param for the handcuff entity to remove from the cuffed entity. If null, uses the most recently added handcuff entity.</param>
- /// <param name="cuffable"></param>
- /// <param name="cuff"></param>
- public void TryUncuff(EntityUid target, EntityUid user, EntityUid? cuffsToRemove = null, CuffableComponent? cuffable = null, HandcuffComponent? cuff = null)
- {
- if (!Resolve(target, ref cuffable))
+ /// <param name="target">The entity we're trying to remove cuffs from.</param>
+ /// <param name="user">The entity doing the cuffing.</param>
+ /// <param name="cuff">The handcuff entity we're attempting to remove.</param>
+ public void TryUncuff(Entity<CuffableComponent?> target, EntityUid user, Entity<HandcuffComponent?> cuff)
+ {
+ if (!Resolve(target, ref target.Comp) || !Resolve(cuff, ref cuff.Comp))
return;
- var isOwner = user == target;
-
- if (cuffsToRemove == null)
- {
- if (cuffable.Container.ContainedEntities.Count == 0)
- {
- return;
- }
-
- cuffsToRemove = cuffable.LastAddedCuffs;
- }
- else
- {
- if (!cuffable.Container.ContainedEntities.Contains(cuffsToRemove.Value))
- {
- Log.Warning("A user is trying to remove handcuffs that aren't in the owner's container. This should never happen!");
- }
- }
+ var isOwner = user == target.Owner;
- if (!Resolve(cuffsToRemove.Value, ref cuff))
- return;
+ if (!target.Comp.Container.ContainedEntities.Contains(cuff))
+ Log.Warning("A user is trying to remove handcuffs that aren't in the owner's container. This should never happen!");
var attempt = new UncuffAttemptEvent(user, target);
RaiseLocalEvent(user, ref attempt, true);
return;
}
- if (!isOwner && !_interaction.InRangeUnobstructed(user, target))
+ if (!isOwner && !_interaction.InRangeUnobstructed(user, target.Owner))
{
_popup.PopupClient(Loc.GetString("cuffable-component-cannot-remove-cuffs-too-far-message"), user, user);
return;
}
-
- var ev = new ModifyUncuffDurationEvent(user, target, isOwner ? cuff.BreakoutTime : cuff.UncuffTime);
+ var ev = new ModifyUncuffDurationEvent(user, target, isOwner ? cuff.Comp.BreakoutTime : cuff.Comp.UncuffTime);
RaiseLocalEvent(user, ref ev);
var uncuffTime = ev.Duration;
if (isOwner)
{
- if (!TryComp(cuffsToRemove.Value, out UseDelayComponent? useDelay))
+ if (!TryComp(cuff, out UseDelayComponent? useDelay))
return;
- if (!_delay.TryResetDelay((cuffsToRemove.Value, useDelay), true))
+ if (!_delay.TryResetDelay((cuff, useDelay), true))
{
return;
}
}
- var doAfterEventArgs = new DoAfterArgs(EntityManager, user, uncuffTime, new UnCuffDoAfterEvent(), target, target, cuffsToRemove)
+ var doAfterEventArgs = new DoAfterArgs(EntityManager, user, uncuffTime, new UnCuffDoAfterEvent(), target, target, cuff)
{
BreakOnMove = true,
BreakOnWeightlessMove = false,
_adminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(user):player} is trying to uncuff {ToPrettyString(target):subject}");
- var popupText = user == target
+ var popupText = user == target.Owner
? "cuffable-component-start-uncuffing-self-observer"
: "cuffable-component-start-uncuffing-observer";
_popup.PopupEntity(
.RemoveWhere(e => e.AttachedEntity == target || e.AttachedEntity == user),
true);
- if (target == user)
+ if (isOwner)
{
_popup.PopupClient(Loc.GetString("cuffable-component-start-uncuffing-self"), user, user);
}
target);
}
- _audio.PlayPredicted(isOwner ? cuff.StartBreakoutSound : cuff.StartUncuffSound, target, user);
+ _audio.PlayPredicted(isOwner ? cuff.Comp.StartBreakoutSound : cuff.Comp.StartUncuffSound, target, user);
}
public void Uncuff(EntityUid target, EntityUid? user, EntityUid cuffsToRemove, CuffableComponent? cuffable = null, HandcuffComponent? cuff = null)
#endregion
- public IReadOnlyList<EntityUid> GetAllCuffs(CuffableComponent component)
+ /// <summary>
+ /// Tries to get a list of all the handcuffs stored in an entity's <see cref="CuffableComponent"/>.
+ /// </summary>
+ /// <param name="entity">The cuffable entity in question.</param>
+ /// <param name="cuffs">A list of cuffs if it exists.</param>
+ /// <returns>True if a list of cuffs with cuffs exists. False if no list exists or if it is empty.</returns>
+ public bool TryGetAllCuffs(Entity<CuffableComponent?> entity, out IReadOnlyList<EntityUid> cuffs)
{
- return component.Container.ContainedEntities;
+ cuffs = GetAllCuffs(entity);
+
+ return cuffs.Count > 0;
+ }
+
+ /// <summary>
+ /// Tries to get a list of all the handcuffs stored in a entity's <see cref="CuffableComponent"/>.
+ /// </summary>
+ /// <param name="entity">The cuffable entity in question.</param>
+ /// <returns>A list of cuffs if it exists, or null if there are no cuffs.</returns>
+ public IReadOnlyList<EntityUid> GetAllCuffs(Entity<CuffableComponent?> entity)
+ {
+ if (!Resolve(entity, ref entity.Comp))
+ return [];
+
+ return entity.Comp.Container.ContainedEntities;
+ }
+
+ /// <summary>
+ /// Tries to get the most recently added pair of handcuffs added to an entity with <see cref="CuffableComponent"/>.
+ /// </summary>
+ /// <param name="entity">The cuffable entity in question.</param>
+ /// <param name="cuff">The most recently added cuff.</param>
+ /// <returns>Returns true if a cuff exists and false if one doesn't.</returns>
+ public bool TryGetLastCuff(Entity<CuffableComponent?> entity, [NotNullWhen(true)] out EntityUid? cuff)
+ {
+ cuff = GetLastCuffOrNull(entity);
+
+ return cuff != null;
+ }
+
+ /// <summary>
+ /// Tries to get the most recently added pair of handcuffs added to an entity with <see cref="CuffableComponent"/>.
+ /// </summary>
+ /// <param name="entity">The cuffable entity in question.</param>
+ /// <returns>The most recently added cuff or null if none exists.</returns>
+ public EntityUid? GetLastCuffOrNull(Entity<CuffableComponent?> entity)
+ {
+ if (!Resolve(entity, ref entity.Comp))
+ return null;
+
+ return entity.Comp.Container.ContainedEntities.Count == 0 ? null : entity.Comp.Container.ContainedEntities.Last();
}
}