mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-17 13:37:47 +03:00
## Mirror of PR #25978: [Fix SCRAM implant not working while cuffed. Incidentally fix freedom implant working while dead/crit](https://github.com/space-wizards/space-station-14/pull/25978) from <img src="https://avatars.githubusercontent.com/u/10567778?v=4" alt="space-wizards" width="22"/> [space-wizards](https://github.com/space-wizards)/[space-station-14](https://github.com/space-wizards/space-station-14) ###### `22e9d6562f21bdd4f0962d6e3b6fcdd81bb4c253` PR opened by <img src="https://avatars.githubusercontent.com/u/32041239?v=4" width="16"/><a href="https://github.com/nikthechampiongr"> nikthechampiongr</a> at 2024-03-10 19:33:05 UTC --- PR changed 13 files with 142 additions and 3 deletions. The PR had the following labels: - Status: Needs Review --- <details open="true"><summary><h1>Original Body</h1></summary> > fixes #25662 > > <!-- Please read these guidelines before opening your PR: https://docs.spacestation14.io/en/getting-started/pr-guideline --> > <!-- The text between the arrows are comments - they will not be visible on your PR. --> > > ## About the PR > <!-- What did you change in this PR? --> > This pr makes it so you can use the SCRAM implant while cuffed. Also fixes the freedom implant working while you are in crit, or even dead. > > ## Why / Balance > <!-- Why was it changed? Link any discussions or issues here. Please discuss how this would affect game balance. --> > The implant is made so you can escape horrible situations. It should as such work while in crit. > > ## Technical details > <!-- If this is a code change, summarize at high level how your new code works. This makes it easier to review. --> > ActionBlockers now has a specific check to see if someone is conscious. It is also used in the Interaction check now. Actions can now use that check if the bool is set. The bool is now set for the freedom and SCRAM! implant actions. Additionally the SCRAM! action now ignores whether the user can interact in order to be able to use it while cuffed. > > ## Media > <!-- > PRs which make ingame changes (adding clothing, items, new features, etc) are required to have media attached that showcase the changes. > Small fixes/refactors are exempt. > Any media may be used in SS14 progress reports, with clear credit given. > > If you're unsure whether your PR will require media, ask a maintainer. > > Check the box below to confirm that you have in fact seen this (put an X in the brackets, like [X]): > --> > > - [x] I have added screenshots/videos to this PR showcasing its changes ingame, **or** this PR does not require an ingame showcase > > ## Breaking changes > <!-- > List any breaking changes, including namespace, public class/method/field changes, prototype renames; and provide instructions for fixing them. This will be pasted in #codebase-changes. > --> > > **Changelog** > <!-- > Make players aware of new features and changes that could affect how they play the game by adding a Changelog entry. Please read the Changelog guidelines located at: https://docs.spacestation14.io/en/getting-started/pr-guideline#changelog > --> > > <!-- > Make sure to take this Changelog template out of the comment block in order for it to show up. > 🆑 > - add: Added fun! > - remove: Removed fun! > - tweak: Changed fun! > - fix: Fixed fun! > --> > 🆑 > fix: You can now use the SCRAM! implant while cuffed. > fix: The freedom implant can no longer be used while in crit, or dead. </details> Co-authored-by: SimpleStation14 <Unknown>
219 lines
7.0 KiB
C#
219 lines
7.0 KiB
C#
using Content.Shared.Bed.Sleep;
|
|
using Content.Shared.Body.Events;
|
|
using Content.Shared.DragDrop;
|
|
using Content.Shared.Emoting;
|
|
using Content.Shared.Hands;
|
|
using Content.Shared.Interaction;
|
|
using Content.Shared.Interaction.Events;
|
|
using Content.Shared.Item;
|
|
using Content.Shared.Mobs;
|
|
using Content.Shared.Mobs.Components;
|
|
using Content.Shared.Movement.Components;
|
|
using Content.Shared.Movement.Events;
|
|
using Content.Shared.Speech;
|
|
using Content.Shared.Throwing;
|
|
using Content.Shared.Weapons.Melee;
|
|
using JetBrains.Annotations;
|
|
using Robust.Shared.Containers;
|
|
|
|
namespace Content.Shared.ActionBlocker
|
|
{
|
|
/// <summary>
|
|
/// Utility methods to check if a specific entity is allowed to perform an action.
|
|
/// </summary>
|
|
[UsedImplicitly]
|
|
public sealed class ActionBlockerSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly SharedContainerSystem _container = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
SubscribeLocalEvent<InputMoverComponent, ComponentStartup>(OnMoverStartup);
|
|
}
|
|
|
|
private void OnMoverStartup(EntityUid uid, InputMoverComponent component, ComponentStartup args)
|
|
{
|
|
UpdateCanMove(uid, component);
|
|
}
|
|
|
|
public bool CanMove(EntityUid uid, InputMoverComponent? component = null)
|
|
{
|
|
return Resolve(uid, ref component, false) && component.CanMove;
|
|
}
|
|
|
|
public bool UpdateCanMove(EntityUid uid, InputMoverComponent? component = null)
|
|
{
|
|
if (!Resolve(uid, ref component, false))
|
|
return false;
|
|
|
|
var ev = new UpdateCanMoveEvent(uid);
|
|
RaiseLocalEvent(uid, ev);
|
|
|
|
if (component.CanMove == ev.Cancelled)
|
|
Dirty(uid, component);
|
|
|
|
component.CanMove = !ev.Cancelled;
|
|
return !ev.Cancelled;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Raises an event directed at both the user and the target entity to check whether a user is capable of
|
|
/// interacting with this entity.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// If this is a generic interaction without a target (e.g., stop-drop-and-roll when burning), the target
|
|
/// may be null. Note that this is checked by <see cref="SharedInteractionSystem"/>. In the majority of
|
|
/// cases, systems that provide interactions will not need to check this themselves, though they may need to
|
|
/// check other blockers like <see cref="CanPickup(EntityUid)"/>
|
|
/// </remarks>
|
|
/// <returns></returns>
|
|
public bool CanInteract(EntityUid user, EntityUid? target)
|
|
{
|
|
if (!CanConsciouslyPerformAction(user))
|
|
return false;
|
|
|
|
var ev = new InteractionAttemptEvent(user, target);
|
|
RaiseLocalEvent(user, ev);
|
|
|
|
if (ev.Cancelled)
|
|
return false;
|
|
|
|
if (target == null || target == user)
|
|
return true;
|
|
|
|
var targetEv = new GettingInteractedWithAttemptEvent(user, target);
|
|
RaiseLocalEvent(target.Value, targetEv);
|
|
|
|
return !targetEv.Cancelled;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Can a user utilize the entity that they are currently holding in their hands.
|
|
/// </summary>>
|
|
/// <remarks>
|
|
/// This event is automatically checked by <see cref="SharedInteractionSystem"/> for any interactions that
|
|
/// involve using a held entity. In the majority of cases, systems that provide interactions will not need
|
|
/// to check this themselves.
|
|
/// </remarks>
|
|
public bool CanUseHeldEntity(EntityUid user)
|
|
{
|
|
var ev = new UseAttemptEvent(user);
|
|
RaiseLocalEvent(user, ev);
|
|
|
|
return !ev.Cancelled;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Whether a user conscious to perform an action.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This should be used when you want a much more permissive check than <see cref="CanInteract"/>
|
|
/// </remarks>
|
|
public bool CanConsciouslyPerformAction(EntityUid user)
|
|
{
|
|
var ev = new ConsciousAttemptEvent(user);
|
|
RaiseLocalEvent(user, ev);
|
|
|
|
return !ev.Cancelled;
|
|
}
|
|
|
|
public bool CanThrow(EntityUid user, EntityUid itemUid)
|
|
{
|
|
var ev = new ThrowAttemptEvent(user, itemUid);
|
|
RaiseLocalEvent(user, ev);
|
|
|
|
return !ev.Cancelled;
|
|
}
|
|
|
|
public bool CanSpeak(EntityUid uid)
|
|
{
|
|
// This one is used as broadcast
|
|
var ev = new SpeakAttemptEvent(uid);
|
|
RaiseLocalEvent(uid, ev, true);
|
|
|
|
return !ev.Cancelled;
|
|
}
|
|
|
|
public bool CanDrop(EntityUid uid)
|
|
{
|
|
var ev = new DropAttemptEvent();
|
|
RaiseLocalEvent(uid, ev);
|
|
|
|
return !ev.Cancelled;
|
|
}
|
|
|
|
public bool CanPickup(EntityUid user, EntityUid item)
|
|
{
|
|
var userEv = new PickupAttemptEvent(user, item);
|
|
RaiseLocalEvent(user, userEv);
|
|
|
|
if (userEv.Cancelled)
|
|
return false;
|
|
|
|
var itemEv = new GettingPickedUpAttemptEvent(user, item);
|
|
RaiseLocalEvent(item, itemEv);
|
|
|
|
return !itemEv.Cancelled;
|
|
}
|
|
|
|
public bool CanEmote(EntityUid uid)
|
|
{
|
|
// This one is used as broadcast
|
|
var ev = new EmoteAttemptEvent(uid);
|
|
RaiseLocalEvent(uid, ev, true);
|
|
|
|
return !ev.Cancelled;
|
|
}
|
|
|
|
public bool CanAttack(EntityUid uid, EntityUid? target = null, Entity<MeleeWeaponComponent>? weapon = null, bool disarm = false)
|
|
{
|
|
_container.TryGetOuterContainer(uid, Transform(uid), out var outerContainer);
|
|
if (target != null && target != outerContainer?.Owner && _container.IsEntityInContainer(uid))
|
|
{
|
|
var containerEv = new CanAttackFromContainerEvent(uid, target);
|
|
RaiseLocalEvent(uid, containerEv);
|
|
return containerEv.CanAttack;
|
|
}
|
|
|
|
var ev = new AttackAttemptEvent(uid, target, weapon, disarm);
|
|
RaiseLocalEvent(uid, ev);
|
|
|
|
if (ev.Cancelled)
|
|
return false;
|
|
|
|
if (target == null)
|
|
return true;
|
|
|
|
var tev = new GettingAttackedAttemptEvent();
|
|
RaiseLocalEvent(target.Value, ref tev);
|
|
return !tev.Cancelled;
|
|
}
|
|
|
|
public bool CanChangeDirection(EntityUid uid)
|
|
{
|
|
var ev = new ChangeDirectionAttemptEvent(uid);
|
|
RaiseLocalEvent(uid, ev);
|
|
|
|
return !ev.Cancelled;
|
|
}
|
|
|
|
public bool CanShiver(EntityUid uid)
|
|
{
|
|
var ev = new ShiverAttemptEvent(uid);
|
|
RaiseLocalEvent(uid, ev);
|
|
|
|
return !ev.Cancelled;
|
|
}
|
|
|
|
public bool CanSweat(EntityUid uid)
|
|
{
|
|
var ev = new SweatAttemptEvent(uid);
|
|
RaiseLocalEvent(uid, ev);
|
|
|
|
return !ev.Cancelled;
|
|
}
|
|
}
|
|
}
|