* Fix SCRAM implant not being usable while in cuffs. Also fix freedom implant from working while dead/crit as a side effect
* Move check up to apply to all actions and do thing I forgor to do before
* Change check into an ActionBlocker check that also checks whether the user is sleeping.
* Make checking for Consciousness the default for actions
Went through and chose what I believe to be sensible defaults for actions that had CheckCanInteract.
* Fix typos my beloved
I had an unbelievable skill issue
* Fix major skill issue
component.Container = EnsureEntity<T>(state.Container, uid);
component.EntityIcon = EnsureEntity<T>(state.EntityIcon, uid);
component.CheckCanInteract = state.CheckCanInteract;
+ component.CheckConsciousness = state.CheckConsciousness;
component.ClientExclusive = state.ClientExclusive;
component.Priority = state.Priority;
component.AttachedEntity = EnsureEntity<T>(state.AttachedEntity, uid);
using Content.Shared.Examine;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
+using Content.Shared.Interaction.Events;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Slippery;
SubscribeLocalEvent<SleepingComponent, InteractHandEvent>(OnInteractHand);
SubscribeLocalEvent<SleepingComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<SleepingComponent, SlipAttemptEvent>(OnSlip);
+ SubscribeLocalEvent<SleepingComponent, ConsciousAttemptEvent>(OnConsciousAttempt);
SubscribeLocalEvent<ForcedSleepingComponent, ComponentInit>(OnInit);
}
args.Cancel();
}
+ private void OnConsciousAttempt(EntityUid uid, SleepingComponent component, ConsciousAttemptEvent args)
+ {
+ args.Cancel();
+ }
+
+
private void OnInit(EntityUid uid, ForcedSleepingComponent component, ComponentInit args)
{
TrySleeping(uid);
+using Content.Shared.Bed.Sleep;
using Content.Shared.Body.Events;
using Content.Shared.DragDrop;
using Content.Shared.Emoting;
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;
/// <returns></returns>
public bool CanInteract(EntityUid user, EntityUid? target)
{
+ if (!CanConsciouslyPerformAction(user))
+ return false;
+
var ev = new InteractionAttemptEvent(user, target);
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);
-using Robust.Shared.Audio;
+using Content.Shared.Mobs;
+using Robust.Shared.Audio;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
/// </summary>
[DataField("checkCanInteract")] public bool CheckCanInteract = true;
+ /// <summary>
+ /// Whether to check if the user is conscious or not. Can be used instead of <see cref="CheckCanInteract"/>
+ /// for a more permissive check.
+ /// </summary>
+ [DataField] public bool CheckConsciousness = true;
+
/// <summary>
/// If true, this will cause the action to only execute locally without ever notifying the server.
/// </summary>
public NetEntity? Container;
public NetEntity? EntityIcon;
public bool CheckCanInteract;
+ public bool CheckConsciousness;
public bool ClientExclusive;
public int Priority;
public NetEntity? AttachedEntity;
MaxCharges = component.MaxCharges;
RenewCharges = component.RenewCharges;
CheckCanInteract = component.CheckCanInteract;
+ CheckConsciousness = component.CheckConsciousness;
ClientExclusive = component.ClientExclusive;
Priority = component.Priority;
AutoPopulate = component.AutoPopulate;
using Content.Shared.Interaction;
using Content.Shared.Inventory.Events;
using Content.Shared.Mind;
+using Content.Shared.Mobs.Components;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
BaseActionEvent? performEvent = null;
+ if (action.CheckConsciousness && !_actionBlockerSystem.CanConsciouslyPerformAction(user))
+ return;
+
// Validate request by checking action blockers and the like:
switch (action)
{
public EntityUid? Target { get; }
}
+ /// <summary>
+ /// Raised to determine whether an entity is conscious to perform an action.
+ /// </summary>
+ public sealed class ConsciousAttemptEvent(EntityUid Uid) : CancellableEntityEventArgs
+ {
+ public EntityUid Uid { get; } = Uid;
+ }
+
/// <summary>
/// Event raised directed at the target entity of an interaction to see if the user is allowed to perform some
/// generic interaction.
SubscribeLocalEvent<MobStateComponent, ChangeDirectionAttemptEvent>(CheckAct);
SubscribeLocalEvent<MobStateComponent, UseAttemptEvent>(CheckAct);
SubscribeLocalEvent<MobStateComponent, AttackAttemptEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, InteractionAttemptEvent>(CheckAct);
+ SubscribeLocalEvent<MobStateComponent, ConsciousAttemptEvent>(CheckAct);
SubscribeLocalEvent<MobStateComponent, ThrowAttemptEvent>(CheckAct);
SubscribeLocalEvent<MobStateComponent, SpeakAttemptEvent>(OnSpeakAttempt);
SubscribeLocalEvent<MobStateComponent, IsEquippingAttemptEvent>(OnEquipAttempt);
-# Actions added to mobs in crit.
+# Actions added to mobs in crit.
- type: entity
id: ActionCritSuccumb
name: Succumb
- type: InstantAction
itemIconStyle: NoItem
checkCanInteract: false
+ checkConsciousness: false
icon:
sprite: Mobs/Ghosts/ghost_human.rsi
state: icon
- type: InstantAction
itemIconStyle: NoItem
checkCanInteract: false
+ checkConsciousness: false
icon:
sprite: Interface/Actions/actions_crit.rsi
state: fakedeath
- type: InstantAction
itemIconStyle: NoItem
checkCanInteract: false
+ checkConsciousness: false
icon:
sprite: Interface/Actions/actions_crit.rsi
state: lastwords
icon: Mobs/Species/Diona/organs.rsi/brain.png
event: !type:GibActionEvent {}
checkCanInteract: false
+ checkConsciousness: false
- type: entity
id: DionaReformAction
components:
- type: InstantAction
checkCanInteract: false
+ checkConsciousness: false
icon: Interface/Actions/zombie-turn.png
event: !type:ZombifySelfActionEvent
components:
- type: InstantAction
checkCanInteract: false
+ checkConsciousness: false
itemIconStyle: BigAction
priority: -20
icon:
components:
- type: InstantAction
checkCanInteract: false
+ checkConsciousness: false
itemIconStyle: BigAction
priority: -20
icon:
noSpawn: true
components:
- type: InstantAction
+ checkCanInteract: false
charges: 2
useDelay: 5
itemIconStyle: BigAction
components:
- type: InstantAction
checkCanInteract: false
+ checkConsciousness: false
icon: Interface/Actions/harmOff.png
iconOn: Interface/Actions/harm.png
event: !type:ToggleCombatActionEvent
- type: InstantAction
clientExclusive: true
checkCanInteract: false
+ checkConsciousness: false
temporary: true
icon: { sprite: Objects/Tools/multitool.rsi, state: icon }
event: !type:ClearAllOverlaysEvent
components:
- type: InstantAction
checkCanInteract: false
+ checkConsciousness: false
icon: { sprite: Clothing/Head/Hats/pyjamasyndicatered.rsi, state: icon }
event: !type:SleepActionEvent
- type: InstantAction
icon: { sprite: Clothing/Head/Hats/pyjamasyndicatered.rsi, state: icon }
checkCanInteract: false
+ checkConsciousness: false
event: !type:WakeActionEvent
- type: entity
event: !type:ToggleEyesActionEvent
useDelay: 1 # so u cant give yourself and observers eyestrain by rapidly spamming the action
checkCanInteract: false
+ checkConsciousness: false
- type: entity
id: ActionToggleWagging
event: !type:GuardianToggleActionEvent
useDelay: 2
checkCanInteract: false
+ checkConsciousness: false
components:
- type: InstantAction
checkCanInteract: false
+ checkConsciousness: false
icon: Interface/Actions/pai-midi.png
event: !type:OpenUiActionEvent
key: enum.InstrumentUiKey.Key
components:
- type: InstantAction
checkCanInteract: false
+ checkConsciousness: false
icon: { sprite: Interface/Actions/pai-map.rsi, state: icon }
event: !type:OpenUiActionEvent
key: enum.StationMapUiKey.Key
entity: ReinforcedWindow
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: WallSolid
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: WallReinforced
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: Window
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: Firelock
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: Grille
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
icon: Interface/VerbIcons/delete.svg.192dpi.png
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: GasPipeStraight
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: GasPipeBend
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: GasPipeTJunction
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: GasPipeFourway
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: GasVentScrubber
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: GasVentPump
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: AirAlarm
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: FireAlarm
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: APCBasic
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: CableApcExtension
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: CableMV
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: CableHV
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: SubstationBasic
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: Poweredlight
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: EmergencyLight
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: SMESBasic
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: TableWood
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: Table
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: ChairWood
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: Chair
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: ChairOfficeLight
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: StoolBar
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: Stool
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: Rack
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: ChairOfficeDark
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: LampGold
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: DisposalPipe
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: DisposalBend
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: DisposalJunction
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: DisposalJunctionFlipped
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: DisposalRouter
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: DisposalRouterFlipped
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: DisposalUnit
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: DisposalTrunk
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: SignDisposalSpace
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: Windoor
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: WindowDirectional
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: WindowReinforcedDirectional
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: PlasmaWindowDirectional
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: Railing
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: RailingCorner
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: RailingCornerSmall
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
name: RailingRound
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: AirlockMaintLocked
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: AirlockGlass
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: AirlockServiceLocked
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: AirlockSecurityLocked
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: AirlockCommand
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: AirlockScience
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: AirlockMedical
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: AirlockEngineering
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
entity: AirlockCargo
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
state: bot_left
iconColor: '#EFB34196'
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
state: delivery
iconColor: '#EFB34196'
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
state: warn_full
iconColor: '#EFB34196'
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
state: halftile_overlay
iconColor: '#EFB34196'
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
state: halftile_overlay
iconColor: '#334E6DC8'
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
state: halftile_overlay
iconColor: '#52B4E996'
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
state: halftile_overlay
iconColor: '#9FED5896'
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
state: halftile_overlay
iconColor: '#DE3A3A96'
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
state: halftile_overlay
iconColor: '#D381C996'
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
state: halftile_overlay
iconColor: '#A4610696'
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
icon: /Textures/Tiles/steel.png
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
icon: /Textures/Tiles/plating.png
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True
icon: /Textures/Tiles/cropped_parallax.png
keywords: []
checkCanInteract: False
+ checkConsciousness: False
clientExclusive: True
autoPopulate: False
temporary: True