Decouple interactions from hands, cleanup old events, add new fears (#28393)
* ok basic shit * second part * pretend it isn't real it can't hurt you. * 👁️ 👁️ * shadowcommander review
This commit is contained in:
@@ -148,7 +148,7 @@ public sealed class GuidebookSystem : EntitySystem
|
|||||||
|
|
||||||
public void FakeClientActivateInWorld(EntityUid activated)
|
public void FakeClientActivateInWorld(EntityUid activated)
|
||||||
{
|
{
|
||||||
var activateMsg = new ActivateInWorldEvent(GetGuidebookUser(), activated);
|
var activateMsg = new ActivateInWorldEvent(GetGuidebookUser(), activated, true);
|
||||||
RaiseLocalEvent(activated, activateMsg);
|
RaiseLocalEvent(activated, activateMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ namespace Content.IntegrationTests.Tests.Buckle
|
|||||||
components:
|
components:
|
||||||
- type: Buckle
|
- type: Buckle
|
||||||
- type: Hands
|
- type: Hands
|
||||||
|
- type: ComplexInteraction
|
||||||
- type: InputMover
|
- type: InputMover
|
||||||
- type: Body
|
- type: Body
|
||||||
prototype: Human
|
prototype: Human
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
|
|||||||
components:
|
components:
|
||||||
- type: Cuffable
|
- type: Cuffable
|
||||||
- type: Hands
|
- type: Hands
|
||||||
|
- type: ComplexInteraction
|
||||||
- type: Body
|
- type: Body
|
||||||
prototype: Human
|
prototype: Human
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Content.Server.Interaction;
|
|||||||
using Content.Shared.Hands.Components;
|
using Content.Shared.Hands.Components;
|
||||||
using Content.Shared.Hands.EntitySystems;
|
using Content.Shared.Hands.EntitySystems;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Shared.Interaction.Components;
|
||||||
using Content.Shared.Item;
|
using Content.Shared.Item;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -64,6 +65,7 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
|
|||||||
{
|
{
|
||||||
user = sEntities.SpawnEntity(null, coords);
|
user = sEntities.SpawnEntity(null, coords);
|
||||||
sEntities.EnsureComponent<HandsComponent>(user);
|
sEntities.EnsureComponent<HandsComponent>(user);
|
||||||
|
sEntities.EnsureComponent<ComplexInteractionComponent>(user);
|
||||||
handSys.AddHand(user, "hand", HandLocation.Left);
|
handSys.AddHand(user, "hand", HandLocation.Left);
|
||||||
target = sEntities.SpawnEntity(null, coords);
|
target = sEntities.SpawnEntity(null, coords);
|
||||||
item = sEntities.SpawnEntity(null, coords);
|
item = sEntities.SpawnEntity(null, coords);
|
||||||
@@ -205,6 +207,7 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
|
|||||||
{
|
{
|
||||||
user = sEntities.SpawnEntity(null, coords);
|
user = sEntities.SpawnEntity(null, coords);
|
||||||
sEntities.EnsureComponent<HandsComponent>(user);
|
sEntities.EnsureComponent<HandsComponent>(user);
|
||||||
|
sEntities.EnsureComponent<ComplexInteractionComponent>(user);
|
||||||
handSys.AddHand(user, "hand", HandLocation.Left);
|
handSys.AddHand(user, "hand", HandLocation.Left);
|
||||||
target = sEntities.SpawnEntity(null, new MapCoordinates(new Vector2(SharedInteractionSystem.InteractionRange - 0.1f, 0), mapId));
|
target = sEntities.SpawnEntity(null, new MapCoordinates(new Vector2(SharedInteractionSystem.InteractionRange - 0.1f, 0), mapId));
|
||||||
item = sEntities.SpawnEntity(null, coords);
|
item = sEntities.SpawnEntity(null, coords);
|
||||||
@@ -347,6 +350,7 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
|
|||||||
{
|
{
|
||||||
user = sEntities.SpawnEntity(null, coords);
|
user = sEntities.SpawnEntity(null, coords);
|
||||||
sEntities.EnsureComponent<HandsComponent>(user);
|
sEntities.EnsureComponent<HandsComponent>(user);
|
||||||
|
sEntities.EnsureComponent<ComplexInteractionComponent>(user);
|
||||||
handSys.AddHand(user, "hand", HandLocation.Left);
|
handSys.AddHand(user, "hand", HandLocation.Left);
|
||||||
target = sEntities.SpawnEntity(null, coords);
|
target = sEntities.SpawnEntity(null, coords);
|
||||||
item = sEntities.SpawnEntity(null, coords);
|
item = sEntities.SpawnEntity(null, coords);
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ public abstract partial class InteractionTest
|
|||||||
prototype: Aghost
|
prototype: Aghost
|
||||||
- type: DoAfter
|
- type: DoAfter
|
||||||
- type: Hands
|
- type: Hands
|
||||||
|
- type: ComplexInteraction
|
||||||
- type: MindContainer
|
- type: MindContainer
|
||||||
- type: Stripping
|
- type: Stripping
|
||||||
- type: Tag
|
- type: Tag
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ namespace Content.IntegrationTests.Tests
|
|||||||
id: HumanVendingDummy
|
id: HumanVendingDummy
|
||||||
components:
|
components:
|
||||||
- type: Hands
|
- type: Hands
|
||||||
|
- type: ComplexInteraction
|
||||||
- type: Body
|
- type: Body
|
||||||
prototype: Human
|
prototype: Human
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public sealed class ActionOnInteractSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivate(EntityUid uid, ActionOnInteractComponent component, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, ActionOnInteractComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (component.ActionEntities is not {} actionEnts)
|
if (component.ActionEntities is not {} actionEnts)
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
private void OnExtinguishActivateInWorld(EntityUid uid, ExtinguishOnInteractComponent component, ActivateInWorldEvent args)
|
private void OnExtinguishActivateInWorld(EntityUid uid, ExtinguishOnInteractComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryComp(uid, out FlammableComponent? flammable))
|
if (!TryComp(uid, out FlammableComponent? flammable))
|
||||||
|
|||||||
@@ -246,6 +246,9 @@ public sealed class AirAlarmSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivate(EntityUid uid, AirAlarmComponent component, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, AirAlarmComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (!args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (TryComp<WiresPanelComponent>(uid, out var panel) && panel.Open)
|
if (TryComp<WiresPanelComponent>(uid, out var panel) && panel.Open)
|
||||||
{
|
{
|
||||||
args.Handled = false;
|
args.Handled = false;
|
||||||
|
|||||||
@@ -103,6 +103,9 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems
|
|||||||
|
|
||||||
private void OnPumpActivate(EntityUid uid, GasPressurePumpComponent pump, ActivateInWorldEvent args)
|
private void OnPumpActivate(EntityUid uid, GasPressurePumpComponent pump, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,12 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems
|
|||||||
|
|
||||||
private void OnActivate(EntityUid uid, GasValveComponent component, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, GasValveComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
Toggle(uid, component);
|
Toggle(uid, component);
|
||||||
_audio.PlayPvs(component.ValveSound, uid, AudioParams.Default.WithVariation(0.25f));
|
_audio.PlayPvs(component.ValveSound, uid, AudioParams.Default.WithVariation(0.25f));
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set(EntityUid uid, GasValveComponent component, bool value)
|
public void Set(EntityUid uid, GasValveComponent component, bool value)
|
||||||
|
|||||||
@@ -133,6 +133,9 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems
|
|||||||
|
|
||||||
private void OnPumpActivate(EntityUid uid, GasVolumePumpComponent pump, ActivateInWorldEvent args)
|
private void OnPumpActivate(EntityUid uid, GasVolumePumpComponent pump, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,9 @@ namespace Content.Server.Atmos.Piping.Trinary.EntitySystems
|
|||||||
|
|
||||||
private void OnFilterActivate(EntityUid uid, GasFilterComponent filter, ActivateInWorldEvent args)
|
private void OnFilterActivate(EntityUid uid, GasFilterComponent filter, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,9 @@ namespace Content.Server.Atmos.Piping.Trinary.EntitySystems
|
|||||||
|
|
||||||
private void OnMixerActivate(EntityUid uid, GasMixerComponent mixer, ActivateInWorldEvent args)
|
private void OnMixerActivate(EntityUid uid, GasMixerComponent mixer, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -201,6 +201,9 @@ public sealed class GasCanisterSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnCanisterActivate(EntityUid uid, GasCanisterComponent component, ActivateInWorldEvent args)
|
private void OnCanisterActivate(EntityUid uid, GasCanisterComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (!args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!TryComp<ActorComponent>(args.User, out var actor))
|
if (!TryComp<ActorComponent>(args.User, out var actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,12 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
|||||||
|
|
||||||
private void OnActivate(EntityUid uid, GasOutletInjectorComponent component, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, GasOutletInjectorComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
component.Enabled = !component.Enabled;
|
component.Enabled = !component.Enabled;
|
||||||
UpdateAppearance(uid, component);
|
UpdateAppearance(uid, component);
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateAppearance(EntityUid uid, GasOutletInjectorComponent component, AppearanceComponent? appearance = null)
|
public void UpdateAppearance(EntityUid uid, GasOutletInjectorComponent component, AppearanceComponent? appearance = null)
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
|
|||||||
SubscribeLocalEvent<CardboardBoxComponent, StorageAfterCloseEvent>(AfterStorageClosed);
|
SubscribeLocalEvent<CardboardBoxComponent, StorageAfterCloseEvent>(AfterStorageClosed);
|
||||||
SubscribeLocalEvent<CardboardBoxComponent, GetAdditionalAccessEvent>(OnGetAdditionalAccess);
|
SubscribeLocalEvent<CardboardBoxComponent, GetAdditionalAccessEvent>(OnGetAdditionalAccess);
|
||||||
SubscribeLocalEvent<CardboardBoxComponent, ActivateInWorldEvent>(OnInteracted);
|
SubscribeLocalEvent<CardboardBoxComponent, ActivateInWorldEvent>(OnInteracted);
|
||||||
SubscribeLocalEvent<CardboardBoxComponent, InteractedNoHandEvent>(OnNoHandInteracted);
|
|
||||||
SubscribeLocalEvent<CardboardBoxComponent, EntInsertedIntoContainerMessage>(OnEntInserted);
|
SubscribeLocalEvent<CardboardBoxComponent, EntInsertedIntoContainerMessage>(OnEntInserted);
|
||||||
SubscribeLocalEvent<CardboardBoxComponent, EntRemovedFromContainerMessage>(OnEntRemoved);
|
SubscribeLocalEvent<CardboardBoxComponent, EntRemovedFromContainerMessage>(OnEntRemoved);
|
||||||
|
|
||||||
@@ -45,9 +44,18 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
|
|||||||
|
|
||||||
private void OnInteracted(EntityUid uid, CardboardBoxComponent component, ActivateInWorldEvent args)
|
private void OnInteracted(EntityUid uid, CardboardBoxComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!TryComp<EntityStorageComponent>(uid, out var box))
|
if (!TryComp<EntityStorageComponent>(uid, out var box))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!args.Complex)
|
||||||
|
{
|
||||||
|
if (box.Open || !box.Contents.Contains(args.User))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
_storage.ToggleOpen(args.User, uid, box);
|
_storage.ToggleOpen(args.User, uid, box);
|
||||||
|
|
||||||
@@ -58,15 +66,6 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnNoHandInteracted(EntityUid uid, CardboardBoxComponent component, InteractedNoHandEvent args)
|
|
||||||
{
|
|
||||||
//Free the mice please
|
|
||||||
if (!TryComp<EntityStorageComponent>(uid, out var box) || box.Open || !box.Contents.Contains(args.User))
|
|
||||||
return;
|
|
||||||
|
|
||||||
_storage.OpenStorage(uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnGetAdditionalAccess(EntityUid uid, CardboardBoxComponent component, ref GetAdditionalAccessEvent args)
|
private void OnGetAdditionalAccess(EntityUid uid, CardboardBoxComponent component, ref GetAdditionalAccessEvent args)
|
||||||
{
|
{
|
||||||
if (component.Mover == null)
|
if (component.Mover == null)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public sealed class SignalSwitchSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivated(EntityUid uid, SignalSwitchComponent comp, ActivateInWorldEvent args)
|
private void OnActivated(EntityUid uid, SignalSwitchComponent comp, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
comp.State = !comp.State;
|
comp.State = !comp.State;
|
||||||
|
|||||||
@@ -152,6 +152,9 @@ public sealed class MailingUnitSystem : EntitySystem
|
|||||||
|
|
||||||
private void HandleActivate(EntityUid uid, MailingUnitComponent component, ActivateInWorldEvent args)
|
private void HandleActivate(EntityUid uid, MailingUnitComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -263,6 +263,9 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
|||||||
|
|
||||||
private void OnActivate(EntityUid uid, SharedDisposalUnitComponent component, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, SharedDisposalUnitComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!TryComp(args.User, out ActorComponent? actor))
|
if (!TryComp(args.User, out ActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ public sealed class AirlockSystem : SharedAirlockSystem
|
|||||||
|
|
||||||
private void OnActivate(EntityUid uid, AirlockComponent component, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, AirlockComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (TryComp<WiresPanelComponent>(uid, out var panel) &&
|
if (TryComp<WiresPanelComponent>(uid, out var panel) &&
|
||||||
panel.Open &&
|
panel.Open &&
|
||||||
TryComp<ActorComponent>(args.User, out var actor))
|
TryComp<ActorComponent>(args.User, out var actor))
|
||||||
|
|||||||
@@ -218,6 +218,9 @@ namespace Content.Server.Explosion.EntitySystems
|
|||||||
|
|
||||||
private void OnActivate(EntityUid uid, TriggerOnActivateComponent component, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, TriggerOnActivateComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
Trigger(uid, args.User);
|
Trigger(uid, args.User);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
SubscribeLocalEvent<AbsorbentComponent, ComponentInit>(OnAbsorbentInit);
|
SubscribeLocalEvent<AbsorbentComponent, ComponentInit>(OnAbsorbentInit);
|
||||||
SubscribeLocalEvent<AbsorbentComponent, AfterInteractEvent>(OnAfterInteract);
|
SubscribeLocalEvent<AbsorbentComponent, AfterInteractEvent>(OnAfterInteract);
|
||||||
SubscribeLocalEvent<AbsorbentComponent, InteractNoHandEvent>(OnInteractNoHand);
|
SubscribeLocalEvent<AbsorbentComponent, UserActivateInWorldEvent>(OnActivateInWorld);
|
||||||
SubscribeLocalEvent<AbsorbentComponent, SolutionContainerChangedEvent>(OnAbsorbentSolutionChange);
|
SubscribeLocalEvent<AbsorbentComponent, SolutionContainerChangedEvent>(OnAbsorbentSolutionChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,12 +84,12 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
|
|||||||
Dirty(uid, component);
|
Dirty(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInteractNoHand(EntityUid uid, AbsorbentComponent component, InteractNoHandEvent args)
|
private void OnActivateInWorld(EntityUid uid, AbsorbentComponent component, UserActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled || args.Target == null)
|
if (args.Handled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Mop(uid, args.Target.Value, uid, component);
|
Mop(uid, args.Target, uid, component);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,10 +38,14 @@ public sealed partial class GatherableSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivate(Entity<GatherableComponent> gatherable, ref ActivateInWorldEvent args)
|
private void OnActivate(Entity<GatherableComponent> gatherable, ref ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (gatherable.Comp.ToolWhitelist?.IsValid(args.User, EntityManager) != true)
|
if (gatherable.Comp.ToolWhitelist?.IsValid(args.User, EntityManager) != true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Gather(gatherable, args.User);
|
Gather(gatherable, args.User);
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Gather(EntityUid gatheredUid, EntityUid? gatherer = null, GatherableComponent? component = null)
|
public void Gather(EntityUid gatheredUid, EntityUid? gatherer = null, GatherableComponent? component = null)
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
|
|
||||||
private void OnActivate(Entity<HandheldLightComponent> ent, ref ActivateInWorldEvent args)
|
private void OnActivate(Entity<HandheldLightComponent> ent, ref ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled || !ent.Comp.ToggleOnInteract)
|
if (args.Handled || !args.Complex || !ent.Comp.ToggleOnInteract)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ToggleStatus(args.User, ent))
|
if (ToggleStatus(args.User, ent))
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public sealed class MechGrabberSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<MechGrabberComponent, MechEquipmentRemovedEvent>(OnEquipmentRemoved);
|
SubscribeLocalEvent<MechGrabberComponent, MechEquipmentRemovedEvent>(OnEquipmentRemoved);
|
||||||
SubscribeLocalEvent<MechGrabberComponent, AttemptRemoveMechEquipmentEvent>(OnAttemptRemove);
|
SubscribeLocalEvent<MechGrabberComponent, AttemptRemoveMechEquipmentEvent>(OnAttemptRemove);
|
||||||
|
|
||||||
SubscribeLocalEvent<MechGrabberComponent, InteractNoHandEvent>(OnInteract);
|
SubscribeLocalEvent<MechGrabberComponent, UserActivateInWorldEvent>(OnInteract);
|
||||||
SubscribeLocalEvent<MechGrabberComponent, GrabberDoAfterEvent>(OnMechGrab);
|
SubscribeLocalEvent<MechGrabberComponent, GrabberDoAfterEvent>(OnMechGrab);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,10 +123,11 @@ public sealed class MechGrabberSystem : EntitySystem
|
|||||||
args.States.Add(GetNetEntity(uid), state);
|
args.States.Add(GetNetEntity(uid), state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInteract(EntityUid uid, MechGrabberComponent component, InteractNoHandEvent args)
|
private void OnInteract(EntityUid uid, MechGrabberComponent component, UserActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled || args.Target is not {} target)
|
if (args.Handled)
|
||||||
return;
|
return;
|
||||||
|
var target = args.Target;
|
||||||
|
|
||||||
if (args.Target == args.User || component.DoAfter != null)
|
if (args.Target == args.User || component.DoAfter != null)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
|||||||
|
|
||||||
private void OnCigarActivatedEvent(Entity<CigarComponent> entity, ref ActivateInWorldEvent args)
|
private void OnCigarActivatedEvent(Entity<CigarComponent> entity, ref ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!EntityManager.TryGetComponent(entity, out SmokableComponent? smokable))
|
if (!EntityManager.TryGetComponent(entity, out SmokableComponent? smokable))
|
||||||
|
|||||||
@@ -45,10 +45,15 @@ public sealed class PinpointerSystem : SharedPinpointerSystem
|
|||||||
|
|
||||||
private void OnActivate(EntityUid uid, PinpointerComponent component, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, PinpointerComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
TogglePinpointer(uid, component);
|
TogglePinpointer(uid, component);
|
||||||
|
|
||||||
if (!component.CanRetarget)
|
if (!component.CanRetarget)
|
||||||
LocateTarget(uid, component);
|
LocateTarget(uid, component);
|
||||||
|
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLocateTarget(ref FTLCompletedEvent ev)
|
private void OnLocateTarget(ref FTLCompletedEvent ev)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public sealed class GeigerSystem : SharedGeigerSystem
|
|||||||
|
|
||||||
private void OnActivate(Entity<GeigerComponent> geiger, ref ActivateInWorldEvent args)
|
private void OnActivate(Entity<GeigerComponent> geiger, ref ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled || geiger.Comp.AttachedToSuit)
|
if (args.Handled || !args.Complex || geiger.Comp.AttachedToSuit)
|
||||||
return;
|
return;
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ public sealed class JammerSystem : SharedJammerSystem
|
|||||||
|
|
||||||
private void OnActivate(EntityUid uid, RadioJammerComponent comp, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, RadioJammerComponent comp, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
var activated = !HasComp<ActiveRadioJammerComponent>(uid) &&
|
var activated = !HasComp<ActiveRadioJammerComponent>(uid) &&
|
||||||
_powerCell.TryGetBatteryFromSlot(uid, out var battery) &&
|
_powerCell.TryGetBatteryFromSlot(uid, out var battery) &&
|
||||||
battery.CurrentCharge > GetCurrentWattage(comp);
|
battery.CurrentCharge > GetCurrentWattage(comp);
|
||||||
|
|||||||
@@ -81,6 +81,9 @@ public sealed class RadioDeviceSystem : EntitySystem
|
|||||||
#region Toggling
|
#region Toggling
|
||||||
private void OnActivateMicrophone(EntityUid uid, RadioMicrophoneComponent component, ActivateInWorldEvent args)
|
private void OnActivateMicrophone(EntityUid uid, RadioMicrophoneComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (!args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!component.ToggleOnInteract)
|
if (!component.ToggleOnInteract)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -90,6 +93,9 @@ public sealed class RadioDeviceSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivateSpeaker(EntityUid uid, RadioSpeakerComponent component, ActivateInWorldEvent args)
|
private void OnActivateSpeaker(EntityUid uid, RadioSpeakerComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (!args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!component.ToggleOnInteract)
|
if (!component.ToggleOnInteract)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public sealed partial class RevenantSystem
|
|||||||
|
|
||||||
private void InitializeAbilities()
|
private void InitializeAbilities()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<RevenantComponent, InteractNoHandEvent>(OnInteract);
|
SubscribeLocalEvent<RevenantComponent, UserActivateInWorldEvent>(OnInteract);
|
||||||
SubscribeLocalEvent<RevenantComponent, SoulEvent>(OnSoulSearch);
|
SubscribeLocalEvent<RevenantComponent, SoulEvent>(OnSoulSearch);
|
||||||
SubscribeLocalEvent<RevenantComponent, HarvestEvent>(OnHarvest);
|
SubscribeLocalEvent<RevenantComponent, HarvestEvent>(OnHarvest);
|
||||||
|
|
||||||
@@ -53,11 +53,14 @@ public sealed partial class RevenantSystem
|
|||||||
SubscribeLocalEvent<RevenantComponent, RevenantMalfunctionActionEvent>(OnMalfunctionAction);
|
SubscribeLocalEvent<RevenantComponent, RevenantMalfunctionActionEvent>(OnMalfunctionAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInteract(EntityUid uid, RevenantComponent component, InteractNoHandEvent args)
|
private void OnInteract(EntityUid uid, RevenantComponent component, UserActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Target == args.User || args.Target == null)
|
if (args.Handled)
|
||||||
return;
|
return;
|
||||||
var target = args.Target.Value;
|
|
||||||
|
if (args.Target == args.User)
|
||||||
|
return;
|
||||||
|
var target = args.Target;
|
||||||
|
|
||||||
if (HasComp<PoweredLightComponent>(target))
|
if (HasComp<PoweredLightComponent>(target))
|
||||||
{
|
{
|
||||||
@@ -78,6 +81,8 @@ public sealed partial class RevenantSystem
|
|||||||
{
|
{
|
||||||
BeginHarvestDoAfter(uid, target, component, essence);
|
BeginHarvestDoAfter(uid, target, component, essence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BeginSoulSearchDoAfter(EntityUid uid, EntityUid target, RevenantComponent revenant)
|
private void BeginSoulSearchDoAfter(EntityUid uid, EntityUid target, RevenantComponent revenant)
|
||||||
|
|||||||
@@ -128,15 +128,20 @@ public sealed class ThrusterSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivateThruster(EntityUid uid, ThrusterComponent component, ActivateInWorldEvent args)
|
private void OnActivateThruster(EntityUid uid, ThrusterComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
component.Enabled ^= true;
|
component.Enabled ^= true;
|
||||||
|
|
||||||
if (!component.Enabled)
|
if (!component.Enabled)
|
||||||
{
|
{
|
||||||
DisableThruster(uid, component);
|
DisableThruster(uid, component);
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
else if (CanEnable(uid, component))
|
else if (CanEnable(uid, component))
|
||||||
{
|
{
|
||||||
EnableThruster(uid, component);
|
EnableThruster(uid, component);
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,6 +141,9 @@ namespace Content.Server.Tabletop
|
|||||||
|
|
||||||
private void OnTabletopActivate(EntityUid uid, TabletopGameComponent component, ActivateInWorldEvent args)
|
private void OnTabletopActivate(EntityUid uid, TabletopGameComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
// Check that a player is attached to the entity.
|
// Check that a player is attached to the entity.
|
||||||
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ using Content.Shared.Damage;
|
|||||||
using Content.Shared.Hands.Components;
|
using Content.Shared.Hands.Components;
|
||||||
using Content.Shared.Hands.EntitySystems;
|
using Content.Shared.Hands.EntitySystems;
|
||||||
using Content.Shared.Humanoid;
|
using Content.Shared.Humanoid;
|
||||||
|
using Content.Shared.Interaction.Components;
|
||||||
using Content.Shared.Mobs;
|
using Content.Shared.Mobs;
|
||||||
using Content.Shared.Mobs.Components;
|
using Content.Shared.Mobs.Components;
|
||||||
using Content.Shared.Mobs.Systems;
|
using Content.Shared.Mobs.Systems;
|
||||||
@@ -106,6 +107,7 @@ namespace Content.Server.Zombies
|
|||||||
RemComp<ReproductiveComponent>(target);
|
RemComp<ReproductiveComponent>(target);
|
||||||
RemComp<ReproductivePartnerComponent>(target);
|
RemComp<ReproductivePartnerComponent>(target);
|
||||||
RemComp<LegsParalyzedComponent>(target);
|
RemComp<LegsParalyzedComponent>(target);
|
||||||
|
RemComp<ComplexInteractionComponent>(target);
|
||||||
|
|
||||||
//funny voice
|
//funny voice
|
||||||
var accentType = "zombie";
|
var accentType = "zombie";
|
||||||
|
|||||||
@@ -96,9 +96,9 @@ namespace Content.Shared.ActionBlocker
|
|||||||
/// involve using a held entity. In the majority of cases, systems that provide interactions will not need
|
/// involve using a held entity. In the majority of cases, systems that provide interactions will not need
|
||||||
/// to check this themselves.
|
/// to check this themselves.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public bool CanUseHeldEntity(EntityUid user)
|
public bool CanUseHeldEntity(EntityUid user, EntityUid used)
|
||||||
{
|
{
|
||||||
var ev = new UseAttemptEvent(user);
|
var ev = new UseAttemptEvent(user, used);
|
||||||
RaiseLocalEvent(user, ev);
|
RaiseLocalEvent(user, ev);
|
||||||
|
|
||||||
return !ev.Cancelled;
|
return !ev.Cancelled;
|
||||||
|
|||||||
@@ -83,10 +83,11 @@ public sealed class BurialSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivate(EntityUid uid, GraveComponent component, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, GraveComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_popupSystem.PopupClient(Loc.GetString("grave-digging-requires-tool", ("grave", args.Target)), uid, args.User);
|
_popupSystem.PopupClient(Loc.GetString("grave-digging-requires-tool", ("grave", args.Target)), uid, args.User);
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGraveDigging(EntityUid uid, GraveComponent component, GraveDiggingDoAfterEvent args)
|
private void OnGraveDigging(EntityUid uid, GraveComponent component, GraveDiggingDoAfterEvent args)
|
||||||
|
|||||||
@@ -31,7 +31,11 @@ public abstract class SharedSolutionContainerMixerSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivateInWorld(Entity<SolutionContainerMixerComponent> entity, ref ActivateInWorldEvent args)
|
private void OnActivateInWorld(Entity<SolutionContainerMixerComponent> entity, ref ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
TryStartMix(entity, args.User);
|
TryStartMix(entity, args.User);
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRemoveAttempt(Entity<SolutionContainerMixerComponent> ent, ref ContainerIsRemovingAttemptEvent args)
|
private void OnRemoveAttempt(Entity<SolutionContainerMixerComponent> ent, ref ContainerIsRemovingAttemptEvent args)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace Content.Shared.DeviceLinking.Systems
|
|||||||
|
|
||||||
private void OnActivated(EntityUid uid, TwoWayLeverComponent component, ActivateInWorldEvent args)
|
private void OnActivated(EntityUid uid, TwoWayLeverComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
component.State = component.State switch
|
component.State = component.State switch
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ public abstract partial class SharedDoorSystem : EntitySystem
|
|||||||
#region Interactions
|
#region Interactions
|
||||||
protected void OnActivate(EntityUid uid, DoorComponent door, ActivateInWorldEvent args)
|
protected void OnActivate(EntityUid uid, DoorComponent door, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled || !door.ClickOpen)
|
if (args.Handled || !args.Complex || !door.ClickOpen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryToggleDoor(uid, door, args.User, predicted: true))
|
if (!TryToggleDoor(uid, door, args.User, predicted: true))
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Content.Shared.Examine;
|
|||||||
using Content.Shared.Hands.Components;
|
using Content.Shared.Hands.Components;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Inventory.VirtualItem;
|
using Content.Shared.Inventory.VirtualItem;
|
||||||
using Content.Shared.Localizations;
|
using Content.Shared.Localizations;
|
||||||
using Robust.Shared.Input.Binding;
|
using Robust.Shared.Input.Binding;
|
||||||
@@ -23,6 +24,7 @@ public abstract partial class SharedHandsSystem : EntitySystem
|
|||||||
SubscribeAllEvent<RequestMoveHandItemEvent>(HandleMoveItemFromHand);
|
SubscribeAllEvent<RequestMoveHandItemEvent>(HandleMoveItemFromHand);
|
||||||
SubscribeAllEvent<RequestHandAltInteractEvent>(HandleHandAltInteract);
|
SubscribeAllEvent<RequestHandAltInteractEvent>(HandleHandAltInteract);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<HandsComponent, GetUsedEntityEvent>(OnGetUsedEntity);
|
||||||
SubscribeLocalEvent<HandsComponent, ExaminedEvent>(HandleExamined);
|
SubscribeLocalEvent<HandsComponent, ExaminedEvent>(HandleExamined);
|
||||||
|
|
||||||
CommandBinds.Builder
|
CommandBinds.Builder
|
||||||
@@ -181,6 +183,18 @@ public abstract partial class SharedHandsSystem : EntitySystem
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGetUsedEntity(EntityUid uid, HandsComponent component, ref GetUsedEntityEvent args)
|
||||||
|
{
|
||||||
|
if (args.Handled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: this pattern is super uncommon, but it might be worth changing GetUsedEntityEvent to be recursive.
|
||||||
|
if (TryComp<VirtualItemComponent>(component.ActiveHandEntity, out var virtualItem))
|
||||||
|
args.Used = virtualItem.BlockingEntity;
|
||||||
|
else
|
||||||
|
args.Used = component.ActiveHandEntity;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: Actually shows all items/clothing/etc.
|
//TODO: Actually shows all items/clothing/etc.
|
||||||
private void HandleExamined(EntityUid examinedUid, HandsComponent handsComp, ExaminedEvent args)
|
private void HandleExamined(EntityUid examinedUid, HandsComponent handsComp, ExaminedEvent args)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,14 +18,49 @@ public sealed class ActivateInWorldEvent : HandledEntityEventArgs, ITargetedInte
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public EntityUid Target { get; }
|
public EntityUid Target { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not <see cref="User"/> can perform complex interactions or only basic ones.
|
||||||
|
/// </summary>
|
||||||
|
public bool Complex;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set to true when the activation is logged by a specific logger.
|
/// Set to true when the activation is logged by a specific logger.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool WasLogged { get; set; }
|
public bool WasLogged { get; set; }
|
||||||
|
|
||||||
public ActivateInWorldEvent(EntityUid user, EntityUid target)
|
public ActivateInWorldEvent(EntityUid user, EntityUid target, bool complex)
|
||||||
{
|
{
|
||||||
User = user;
|
User = user;
|
||||||
Target = target;
|
Target = target;
|
||||||
|
Complex = complex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event raised on the user when it activates something in the world
|
||||||
|
/// </summary>
|
||||||
|
[PublicAPI]
|
||||||
|
public sealed class UserActivateInWorldEvent : HandledEntityEventArgs, ITargetedInteractEventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Entity that activated the target world entity.
|
||||||
|
/// </summary>
|
||||||
|
public EntityUid User { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Entity that was activated in the world.
|
||||||
|
/// </summary>
|
||||||
|
public EntityUid Target { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not <see cref="User"/> can perform complex interactions or only basic ones.
|
||||||
|
/// </summary>
|
||||||
|
public bool Complex;
|
||||||
|
|
||||||
|
public UserActivateInWorldEvent(EntityUid user, EntityUid target, bool complex)
|
||||||
|
{
|
||||||
|
User = user;
|
||||||
|
Target = target;
|
||||||
|
Complex = complex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Interaction.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is used for identifying entities as being able to use complex interactions with the environment.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, Access(typeof(SharedInteractionSystem))]
|
||||||
|
public sealed partial class ComplexInteractionComponent : Component;
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
namespace Content.Shared.Interaction.Events
|
namespace Content.Shared.Interaction.Events
|
||||||
{
|
{
|
||||||
public sealed class UseAttemptEvent : CancellableEntityEventArgs
|
public sealed class UseAttemptEvent(EntityUid uid, EntityUid used) : CancellableEntityEventArgs
|
||||||
{
|
{
|
||||||
public UseAttemptEvent(EntityUid uid)
|
public EntityUid Uid { get; } = uid;
|
||||||
{
|
|
||||||
Uid = uid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityUid Uid { get; }
|
public EntityUid Used = used;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,58 +51,4 @@ namespace Content.Shared.Interaction
|
|||||||
Target = target;
|
Target = target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Low-level interaction event used for entities without hands.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// SHIT IS CURSED.
|
|
||||||
/// </remarks>
|
|
||||||
//TODO: KILLLLLLL
|
|
||||||
public sealed class InteractNoHandEvent : HandledEntityEventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Entity that triggered the interaction.
|
|
||||||
/// </summary>
|
|
||||||
public EntityUid User;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Entity that was interacted on.
|
|
||||||
/// </summary>
|
|
||||||
public EntityUid? Target;
|
|
||||||
|
|
||||||
public EntityCoordinates ClickLocation;
|
|
||||||
|
|
||||||
public InteractNoHandEvent(EntityUid user, EntityUid? target, EntityCoordinates clickLocation)
|
|
||||||
{
|
|
||||||
User = user;
|
|
||||||
Target = target;
|
|
||||||
ClickLocation = clickLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reverse of the InteractNoHandEvent - raised on what was interacted on, rather than the other way around.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class InteractedNoHandEvent : HandledEntityEventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Entity that was interacted on
|
|
||||||
/// </summary>
|
|
||||||
public EntityUid Target;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Entity that triggered this interaction
|
|
||||||
/// </summary>
|
|
||||||
public EntityUid User;
|
|
||||||
|
|
||||||
public EntityCoordinates ClickLocation;
|
|
||||||
|
|
||||||
public InteractedNoHandEvent(EntityUid target, EntityUid user, EntityCoordinates clickLocation)
|
|
||||||
{
|
|
||||||
Target = target;
|
|
||||||
User = user;
|
|
||||||
ClickLocation = clickLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ public sealed class InteractionPopupSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivateInWorld(EntityUid uid, InteractionPopupComponent component, ActivateInWorldEvent args)
|
private void OnActivateInWorld(EntityUid uid, InteractionPopupComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (!args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!component.OnActivate)
|
if (!component.OnActivate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ namespace Content.Shared.Interaction
|
|||||||
private EntityQuery<WallMountComponent> _wallMountQuery;
|
private EntityQuery<WallMountComponent> _wallMountQuery;
|
||||||
private EntityQuery<UseDelayComponent> _delayQuery;
|
private EntityQuery<UseDelayComponent> _delayQuery;
|
||||||
private EntityQuery<ActivatableUIComponent> _uiQuery;
|
private EntityQuery<ActivatableUIComponent> _uiQuery;
|
||||||
|
private EntityQuery<ComplexInteractionComponent> _complexInteractionQuery;
|
||||||
|
|
||||||
private const CollisionGroup InRangeUnobstructedMask = CollisionGroup.Impassable | CollisionGroup.InteractImpassable;
|
private const CollisionGroup InRangeUnobstructedMask = CollisionGroup.Impassable | CollisionGroup.InteractImpassable;
|
||||||
|
|
||||||
@@ -98,6 +99,7 @@ namespace Content.Shared.Interaction
|
|||||||
_wallMountQuery = GetEntityQuery<WallMountComponent>();
|
_wallMountQuery = GetEntityQuery<WallMountComponent>();
|
||||||
_delayQuery = GetEntityQuery<UseDelayComponent>();
|
_delayQuery = GetEntityQuery<UseDelayComponent>();
|
||||||
_uiQuery = GetEntityQuery<ActivatableUIComponent>();
|
_uiQuery = GetEntityQuery<ActivatableUIComponent>();
|
||||||
|
_complexInteractionQuery = GetEntityQuery<ComplexInteractionComponent>();
|
||||||
|
|
||||||
SubscribeLocalEvent<BoundUserInterfaceCheckRangeEvent>(HandleUserInterfaceRangeCheck);
|
SubscribeLocalEvent<BoundUserInterfaceCheckRangeEvent>(HandleUserInterfaceRangeCheck);
|
||||||
SubscribeLocalEvent<BoundUserInterfaceMessageAttempt>(OnBoundInterfaceInteractAttempt);
|
SubscribeLocalEvent<BoundUserInterfaceMessageAttempt>(OnBoundInterfaceInteractAttempt);
|
||||||
@@ -360,8 +362,13 @@ namespace Content.Shared.Interaction
|
|||||||
// TODO this needs to be handled better. This probably bypasses many complex can-interact checks in weird roundabout ways.
|
// TODO this needs to be handled better. This probably bypasses many complex can-interact checks in weird roundabout ways.
|
||||||
if (_actionBlockerSystem.CanInteract(user, target))
|
if (_actionBlockerSystem.CanInteract(user, target))
|
||||||
{
|
{
|
||||||
UserInteraction(relay.RelayEntity.Value, coordinates, target, altInteract, checkCanInteract,
|
UserInteraction(relay.RelayEntity.Value,
|
||||||
checkAccess, checkCanUse);
|
coordinates,
|
||||||
|
target,
|
||||||
|
altInteract,
|
||||||
|
checkCanInteract,
|
||||||
|
checkAccess,
|
||||||
|
checkCanUse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -398,25 +405,10 @@ namespace Content.Shared.Interaction
|
|||||||
? !checkAccess || InRangeUnobstructed(user, coordinates)
|
? !checkAccess || InRangeUnobstructed(user, coordinates)
|
||||||
: !checkAccess || InRangeUnobstructed(user, target.Value); // permits interactions with wall mounted entities
|
: !checkAccess || InRangeUnobstructed(user, target.Value); // permits interactions with wall mounted entities
|
||||||
|
|
||||||
// Does the user have hands?
|
|
||||||
if (!_handsQuery.TryComp(user, out var hands) || hands.ActiveHand == null)
|
|
||||||
{
|
|
||||||
var ev = new InteractNoHandEvent(user, target, coordinates);
|
|
||||||
RaiseLocalEvent(user, ev);
|
|
||||||
|
|
||||||
if (target != null)
|
|
||||||
{
|
|
||||||
var interactedEv = new InteractedNoHandEvent(target.Value, user, coordinates);
|
|
||||||
RaiseLocalEvent(target.Value, interactedEv);
|
|
||||||
DoContactInteraction(user, target.Value, ev);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// empty-hand interactions
|
// empty-hand interactions
|
||||||
// combat mode hand interactions will always be true here -- since
|
// combat mode hand interactions will always be true here -- since
|
||||||
// they check this earlier before returning in
|
// they check this earlier before returning in
|
||||||
if (hands.ActiveHandEntity is not { } held)
|
if (!TryGetUsedEntity(user, out var used, checkCanUse))
|
||||||
{
|
{
|
||||||
if (inRangeUnobstructed && target != null)
|
if (inRangeUnobstructed && target != null)
|
||||||
InteractHand(user, target.Value);
|
InteractHand(user, target.Value);
|
||||||
@@ -424,11 +416,7 @@ namespace Content.Shared.Interaction
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can the user use the held entity?
|
if (target == used)
|
||||||
if (checkCanUse && !_actionBlockerSystem.CanUseHeldEntity(user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (target == held)
|
|
||||||
{
|
{
|
||||||
UseInHandInteraction(user, target.Value, checkCanUse: false, checkCanInteract: false);
|
UseInHandInteraction(user, target.Value, checkCanUse: false, checkCanInteract: false);
|
||||||
return;
|
return;
|
||||||
@@ -438,7 +426,7 @@ namespace Content.Shared.Interaction
|
|||||||
{
|
{
|
||||||
InteractUsing(
|
InteractUsing(
|
||||||
user,
|
user,
|
||||||
held,
|
used.Value,
|
||||||
target.Value,
|
target.Value,
|
||||||
coordinates,
|
coordinates,
|
||||||
checkCanInteract: false,
|
checkCanInteract: false,
|
||||||
@@ -449,7 +437,7 @@ namespace Content.Shared.Interaction
|
|||||||
|
|
||||||
InteractUsingRanged(
|
InteractUsingRanged(
|
||||||
user,
|
user,
|
||||||
held,
|
used.Value,
|
||||||
target,
|
target,
|
||||||
coordinates,
|
coordinates,
|
||||||
inRangeUnobstructed);
|
inRangeUnobstructed);
|
||||||
@@ -457,6 +445,18 @@ namespace Content.Shared.Interaction
|
|||||||
|
|
||||||
public void InteractHand(EntityUid user, EntityUid target)
|
public void InteractHand(EntityUid user, EntityUid target)
|
||||||
{
|
{
|
||||||
|
var complexInteractions = SupportsComplexInteractions(user);
|
||||||
|
if (!complexInteractions)
|
||||||
|
{
|
||||||
|
InteractionActivate(user,
|
||||||
|
target,
|
||||||
|
checkCanInteract: false,
|
||||||
|
checkUseDelay: true,
|
||||||
|
checkAccess: false,
|
||||||
|
complexInteractions: complexInteractions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// allow for special logic before main interaction
|
// allow for special logic before main interaction
|
||||||
var ev = new BeforeInteractHandEvent(target);
|
var ev = new BeforeInteractHandEvent(target);
|
||||||
RaiseLocalEvent(user, ev);
|
RaiseLocalEvent(user, ev);
|
||||||
@@ -475,10 +475,12 @@ namespace Content.Shared.Interaction
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Else we run Activate.
|
// Else we run Activate.
|
||||||
InteractionActivate(user, target,
|
InteractionActivate(user,
|
||||||
|
target,
|
||||||
checkCanInteract: false,
|
checkCanInteract: false,
|
||||||
checkUseDelay: true,
|
checkUseDelay: true,
|
||||||
checkAccess: false);
|
checkAccess: false,
|
||||||
|
complexInteractions: complexInteractions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InteractUsingRanged(EntityUid user, EntityUid used, EntityUid? target,
|
public void InteractUsingRanged(EntityUid user, EntityUid used, EntityUid? target,
|
||||||
@@ -921,7 +923,7 @@ namespace Content.Shared.Interaction
|
|||||||
if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, target))
|
if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, target))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (checkCanUse && !_actionBlockerSystem.CanUseHeldEntity(user))
|
if (checkCanUse && !_actionBlockerSystem.CanUseHeldEntity(user, used))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (RangedInteractDoBefore(user, used, target, clickLocation, true))
|
if (RangedInteractDoBefore(user, used, target, clickLocation, true))
|
||||||
@@ -1001,7 +1003,8 @@ namespace Content.Shared.Interaction
|
|||||||
EntityUid used,
|
EntityUid used,
|
||||||
bool checkCanInteract = true,
|
bool checkCanInteract = true,
|
||||||
bool checkUseDelay = true,
|
bool checkUseDelay = true,
|
||||||
bool checkAccess = true)
|
bool checkAccess = true,
|
||||||
|
bool? complexInteractions = null)
|
||||||
{
|
{
|
||||||
_delayQuery.TryComp(used, out var delayComponent);
|
_delayQuery.TryComp(used, out var delayComponent);
|
||||||
if (checkUseDelay && delayComponent != null && _useDelay.IsDelayed((used, delayComponent)))
|
if (checkUseDelay && delayComponent != null && _useDelay.IsDelayed((used, delayComponent)))
|
||||||
@@ -1018,13 +1021,12 @@ namespace Content.Shared.Interaction
|
|||||||
if (checkAccess && !IsAccessible(user, used))
|
if (checkAccess && !IsAccessible(user, used))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Does the user have hands?
|
complexInteractions ??= SupportsComplexInteractions(user);
|
||||||
if (!_handsQuery.HasComp(user))
|
var activateMsg = new ActivateInWorldEvent(user, used, complexInteractions.Value);
|
||||||
return false;
|
|
||||||
|
|
||||||
var activateMsg = new ActivateInWorldEvent(user, used);
|
|
||||||
RaiseLocalEvent(used, activateMsg, true);
|
RaiseLocalEvent(used, activateMsg, true);
|
||||||
if (!activateMsg.Handled)
|
var userEv = new UserActivateInWorldEvent(user, used, complexInteractions.Value);
|
||||||
|
RaiseLocalEvent(user, userEv, true);
|
||||||
|
if (!activateMsg.Handled && !userEv.Handled)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
DoContactInteraction(user, used, activateMsg);
|
DoContactInteraction(user, used, activateMsg);
|
||||||
@@ -1059,7 +1061,7 @@ namespace Content.Shared.Interaction
|
|||||||
if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, used))
|
if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, used))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (checkCanUse && !_actionBlockerSystem.CanUseHeldEntity(user))
|
if (checkCanUse && !_actionBlockerSystem.CanUseHeldEntity(user, used))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var useMsg = new UseInHandEvent(user);
|
var useMsg = new UseInHandEvent(user);
|
||||||
@@ -1259,6 +1261,39 @@ namespace Content.Shared.Interaction
|
|||||||
? BoundUserInterfaceRangeResult.Pass
|
? BoundUserInterfaceRangeResult.Pass
|
||||||
: BoundUserInterfaceRangeResult.Fail;
|
: BoundUserInterfaceRangeResult.Fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the entity that is currently being "used" for the interaction.
|
||||||
|
/// In most cases, this refers to the entity in the character's active hand.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>If there is an entity being used.</returns>
|
||||||
|
public bool TryGetUsedEntity(EntityUid user, [NotNullWhen(true)] out EntityUid? used, bool checkCanUse = true)
|
||||||
|
{
|
||||||
|
var ev = new GetUsedEntityEvent();
|
||||||
|
RaiseLocalEvent(user, ref ev);
|
||||||
|
|
||||||
|
used = ev.Used;
|
||||||
|
if (!ev.Handled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Can the user use the held entity?
|
||||||
|
if (checkCanUse && !_actionBlockerSystem.CanUseHeldEntity(user, ev.Used!.Value))
|
||||||
|
{
|
||||||
|
used = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ev.Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if a given entity is able to do specific complex interactions.
|
||||||
|
/// This is used to gate manipulation to general humanoids. If a mouse shouldn't be able to do something, then it's complex.
|
||||||
|
/// </summary>
|
||||||
|
public bool SupportsComplexInteractions(EntityUid user)
|
||||||
|
{
|
||||||
|
return _complexInteractionQuery.HasComp(user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1284,6 +1319,24 @@ namespace Content.Shared.Interaction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised directed by-ref on an entity to determine what item will be used in interactions.
|
||||||
|
/// </summary>
|
||||||
|
[ByRefEvent]
|
||||||
|
public record struct GetUsedEntityEvent()
|
||||||
|
{
|
||||||
|
public EntityUid? Used = null;
|
||||||
|
|
||||||
|
public bool Handled => Used != null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised directed by-ref on an item and a user to determine if interactions can occur.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Cancelled">Whether the hand interaction should be cancelled.</param>
|
||||||
|
[ByRefEvent]
|
||||||
|
public record struct AttemptUseInteractEvent(EntityUid User, EntityUid Used, bool Cancelled = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised directed by-ref on an item to determine if hand interactions should go through.
|
/// Raised directed by-ref on an item to determine if hand interactions should go through.
|
||||||
/// Defaults to allowing hand interactions to go through. Cancel to force the item to be attacked instead.
|
/// Defaults to allowing hand interactions to go through. Cancel to force the item to be attacked instead.
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public sealed class LockSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivated(EntityUid uid, LockComponent lockComp, ActivateInWorldEvent args)
|
private void OnActivated(EntityUid uid, LockComponent lockComp, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Only attempt an unlock by default on Activate
|
// Only attempt an unlock by default on Activate
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public abstract class SharedMechSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
SubscribeLocalEvent<MechComponent, MechToggleEquipmentEvent>(OnToggleEquipmentAction);
|
SubscribeLocalEvent<MechComponent, MechToggleEquipmentEvent>(OnToggleEquipmentAction);
|
||||||
SubscribeLocalEvent<MechComponent, MechEjectPilotEvent>(OnEjectPilotEvent);
|
SubscribeLocalEvent<MechComponent, MechEjectPilotEvent>(OnEjectPilotEvent);
|
||||||
SubscribeLocalEvent<MechComponent, InteractNoHandEvent>(RelayInteractionEvent);
|
SubscribeLocalEvent<MechComponent, UserActivateInWorldEvent>(RelayInteractionEvent);
|
||||||
SubscribeLocalEvent<MechComponent, ComponentStartup>(OnStartup);
|
SubscribeLocalEvent<MechComponent, ComponentStartup>(OnStartup);
|
||||||
SubscribeLocalEvent<MechComponent, DestructionEventArgs>(OnDestruction);
|
SubscribeLocalEvent<MechComponent, DestructionEventArgs>(OnDestruction);
|
||||||
SubscribeLocalEvent<MechComponent, GetAdditionalAccessEvent>(OnGetAdditionalAccess);
|
SubscribeLocalEvent<MechComponent, GetAdditionalAccessEvent>(OnGetAdditionalAccess);
|
||||||
@@ -71,7 +71,7 @@ public abstract class SharedMechSystem : EntitySystem
|
|||||||
TryEject(uid, component);
|
TryEject(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RelayInteractionEvent(EntityUid uid, MechComponent component, InteractNoHandEvent args)
|
private void RelayInteractionEvent(EntityUid uid, MechComponent component, UserActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
var pilot = component.PilotSlot.ContainedEntity;
|
var pilot = component.PilotSlot.ContainedEntity;
|
||||||
if (pilot == null)
|
if (pilot == null)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public abstract partial class SharedProjectileSystem : EntitySystem
|
|||||||
if (component.RemovalTime == null)
|
if (component.RemovalTime == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (args.Handled || !TryComp<PhysicsComponent>(uid, out var physics) || physics.BodyType != BodyType.Static)
|
if (args.Handled || !args.Complex || !TryComp<PhysicsComponent>(uid, out var physics) || physics.BodyType != BodyType.Static)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public abstract class SharedEntityStorageSystem : EntitySystem
|
|||||||
|
|
||||||
protected void OnInteract(EntityUid uid, SharedEntityStorageComponent component, ActivateInWorldEvent args)
|
protected void OnInteract(EntityUid uid, SharedEntityStorageComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnActivate(EntityUid uid, StorageComponent storageComp, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, StorageComponent storageComp, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled || !CanInteract(args.User, (uid, storageComp), storageComp.ClickInsert))
|
if (args.Handled || !args.Complex || !CanInteract(args.User, (uid, storageComp), storageComp.ClickInsert))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Toggle
|
// Toggle
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public abstract class SharedStrippableSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivateInWorld(EntityUid uid, StrippableComponent component, ActivateInWorldEvent args)
|
private void OnActivateInWorld(EntityUid uid, StrippableComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled || args.Target == args.User)
|
if (args.Handled || !args.Complex || args.Target == args.User)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (TryOpenStrippingUi(args.User, (uid, component)))
|
if (TryOpenStrippingUi(args.User, (uid, component)))
|
||||||
|
|||||||
@@ -26,7 +26,11 @@ public abstract class SharedTrayScannerSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnTrayScannerActivate(EntityUid uid, TrayScannerComponent scanner, ActivateInWorldEvent args)
|
private void OnTrayScannerActivate(EntityUid uid, TrayScannerComponent scanner, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
SetScannerEnabled(uid, !scanner.Enabled, scanner);
|
SetScannerEnabled(uid, !scanner.Enabled, scanner);
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetScannerEnabled(EntityUid uid, bool enabled, TrayScannerComponent? scanner = null)
|
private void SetScannerEnabled(EntityUid uid, bool enabled, TrayScannerComponent? scanner = null)
|
||||||
|
|||||||
@@ -101,6 +101,9 @@ public sealed class SwapTeleporterSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivateInWorld(Entity<SwapTeleporterComponent> ent, ref ActivateInWorldEvent args)
|
private void OnActivateInWorld(Entity<SwapTeleporterComponent> ent, ref ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled || !args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
var (uid, comp) = ent;
|
var (uid, comp) = ent;
|
||||||
var user = args.User;
|
var user = args.User;
|
||||||
if (comp.TeleportTime != null)
|
if (comp.TeleportTime != null)
|
||||||
@@ -130,6 +133,7 @@ public sealed class SwapTeleporterSystem : EntitySystem
|
|||||||
comp.NextTeleportUse = _timing.CurTime + comp.Cooldown;
|
comp.NextTeleportUse = _timing.CurTime + comp.Cooldown;
|
||||||
comp.TeleportTime = _timing.CurTime + comp.TeleportDelay;
|
comp.TeleportTime = _timing.CurTime + comp.TeleportDelay;
|
||||||
Dirty(uid, comp);
|
Dirty(uid, comp);
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DoTeleport(Entity<SwapTeleporterComponent, TransformComponent> ent)
|
public void DoTeleport(Entity<SwapTeleporterComponent, TransformComponent> ent)
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ namespace Content.Shared.Toilet.Systems
|
|||||||
|
|
||||||
private void OnActivateInWorld(EntityUid uid, ToiletComponent comp, ActivateInWorldEvent args)
|
private void OnActivateInWorld(EntityUid uid, ToiletComponent comp, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public abstract partial class SharedToolSystem
|
|||||||
|
|
||||||
private void OnMultipleToolActivated(EntityUid uid, MultipleToolComponent multiple, ActivateInWorldEvent args)
|
private void OnMultipleToolActivated(EntityUid uid, MultipleToolComponent multiple, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
args.Handled = CycleMultipleTool(uid, multiple, args.User);
|
args.Handled = CycleMultipleTool(uid, multiple, args.User);
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ public sealed partial class ActivatableUISystem : EntitySystem
|
|||||||
|
|
||||||
private void OnActivate(EntityUid uid, ActivatableUIComponent component, ActivateInWorldEvent args)
|
private void OnActivate(EntityUid uid, ActivatableUIComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (component.VerbOnly)
|
if (component.VerbOnly)
|
||||||
|
|||||||
@@ -78,28 +78,8 @@ namespace Content.Shared.Verbs
|
|||||||
// call ActionBlocker checks, just cache it for the verb request.
|
// call ActionBlocker checks, just cache it for the verb request.
|
||||||
var canInteract = force || _actionBlockerSystem.CanInteract(user, target);
|
var canInteract = force || _actionBlockerSystem.CanInteract(user, target);
|
||||||
|
|
||||||
EntityUid? @using = null;
|
_interactionSystem.TryGetUsedEntity(user, out var @using);
|
||||||
if (TryComp(user, out HandsComponent? hands) && (force || _actionBlockerSystem.CanUseHeldEntity(user)))
|
TryComp<HandsComponent>(user, out var hands);
|
||||||
{
|
|
||||||
// if we don't actually have any hands, pass in a null value for the events.
|
|
||||||
if (hands.Count == 0)
|
|
||||||
{
|
|
||||||
hands = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
@using = hands.ActiveHandEntity;
|
|
||||||
|
|
||||||
// Check whether the "Held" entity is a virtual pull entity. If yes, set that as the entity being "Used".
|
|
||||||
// This allows you to do things like buckle a dragged person onto a surgery table, without click-dragging
|
|
||||||
// their sprite.
|
|
||||||
|
|
||||||
if (TryComp(@using, out VirtualItemComponent? pull))
|
|
||||||
{
|
|
||||||
@using = pull.BlockingEntity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: fix this garbage and use proper generics or reflection or something else, not this.
|
// TODO: fix this garbage and use proper generics or reflection or something else, not this.
|
||||||
if (types.Contains(typeof(InteractionVerb)))
|
if (types.Contains(typeof(InteractionVerb)))
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ public abstract class SharedGrapplingGunSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnGunActivate(EntityUid uid, GrapplingGunComponent component, ActivateInWorldEvent args)
|
private void OnGunActivate(EntityUid uid, GrapplingGunComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (!Timing.IsFirstTimePredicted || args.Handled)
|
if (!Timing.IsFirstTimePredicted || args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Deleted(component.Projectile))
|
if (Deleted(component.Projectile))
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ public abstract partial class SharedTetherGunSystem
|
|||||||
|
|
||||||
private void OnForceActivate(EntityUid uid, ForceGunComponent component, ActivateInWorldEvent args)
|
private void OnForceActivate(EntityUid uid, ForceGunComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (!args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
StopTether(uid, component);
|
StopTether(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,6 +152,9 @@ public abstract partial class SharedTetherGunSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnTetherActivate(EntityUid uid, TetherGunComponent component, ActivateInWorldEvent args)
|
private void OnTetherActivate(EntityUid uid, TetherGunComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (!args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
StopTether(uid, component);
|
StopTether(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ public sealed class BatteryWeaponFireModesSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnInteractHandEvent(EntityUid uid, BatteryWeaponFireModesComponent component, ActivateInWorldEvent args)
|
private void OnInteractHandEvent(EntityUid uid, BatteryWeaponFireModesComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (!args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (component.FireModes.Count < 2)
|
if (component.FireModes.Count < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ public sealed class RechargeCycleAmmoSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnRechargeCycled(EntityUid uid, RechargeCycleAmmoComponent component, ActivateInWorldEvent args)
|
private void OnRechargeCycled(EntityUid uid, RechargeCycleAmmoComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (!args.Complex)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!TryComp<BasicEntityAmmoProviderComponent>(uid, out var basic) || args.Handled)
|
if (!TryComp<BasicEntityAmmoProviderComponent>(uid, out var basic) || args.Handled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public abstract partial class SharedGunSystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnChamberActivate(EntityUid uid, ChamberMagazineAmmoProviderComponent component, ActivateInWorldEvent args)
|
private void OnChamberActivate(EntityUid uid, ChamberMagazineAmmoProviderComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled || !args.Complex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
|
|||||||
@@ -84,6 +84,7 @@
|
|||||||
- type: Hands
|
- type: Hands
|
||||||
showInHands: false
|
showInHands: false
|
||||||
disableExplosionRecursion: true
|
disableExplosionRecursion: true
|
||||||
|
- type: ComplexInteraction
|
||||||
- type: IntrinsicRadioReceiver
|
- type: IntrinsicRadioReceiver
|
||||||
- type: IntrinsicRadioTransmitter
|
- type: IntrinsicRadioTransmitter
|
||||||
channels:
|
channels:
|
||||||
|
|||||||
@@ -1200,6 +1200,7 @@
|
|||||||
state: "creampie_human"
|
state: "creampie_human"
|
||||||
visible: false
|
visible: false
|
||||||
- type: Hands
|
- type: Hands
|
||||||
|
- type: ComplexInteraction
|
||||||
- type: GenericVisualizer
|
- type: GenericVisualizer
|
||||||
visuals:
|
visuals:
|
||||||
enum.CreamPiedVisuals.Creamed:
|
enum.CreamPiedVisuals.Creamed:
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
- type: NpcFactionMember
|
- type: NpcFactionMember
|
||||||
factions:
|
factions:
|
||||||
- SimpleHostile
|
- SimpleHostile
|
||||||
- type: Hands
|
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
drawdepth: Mobs
|
drawdepth: Mobs
|
||||||
sprite: Structures/Machines/VendingMachines/cola.rsi
|
sprite: Structures/Machines/VendingMachines/cola.rsi
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
factions:
|
factions:
|
||||||
- Xeno
|
- Xeno
|
||||||
- type: Hands
|
- type: Hands
|
||||||
|
- type: ComplexInteraction
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
drawdepth: Mobs
|
drawdepth: Mobs
|
||||||
sprite: Mobs/Aliens/Xenos/burrower.rsi
|
sprite: Mobs/Aliens/Xenos/burrower.rsi
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
canInteract: true
|
canInteract: true
|
||||||
- type: GhostHearing
|
- type: GhostHearing
|
||||||
- type: Hands
|
- type: Hands
|
||||||
|
- type: ComplexInteraction
|
||||||
- type: Puller
|
- type: Puller
|
||||||
- type: CombatMode
|
- type: CombatMode
|
||||||
- type: Physics
|
- type: Physics
|
||||||
|
|||||||
@@ -225,6 +225,7 @@
|
|||||||
- type: Inventory
|
- type: Inventory
|
||||||
templateId: holoclown
|
templateId: holoclown
|
||||||
- type: Hands
|
- type: Hands
|
||||||
|
- type: ComplexInteraction
|
||||||
- type: Clumsy
|
- type: Clumsy
|
||||||
clumsyDamage:
|
clumsyDamage:
|
||||||
types:
|
types:
|
||||||
|
|||||||
@@ -149,6 +149,7 @@
|
|||||||
- type: Identity
|
- type: Identity
|
||||||
- type: IdExaminable
|
- type: IdExaminable
|
||||||
- type: Hands
|
- type: Hands
|
||||||
|
- type: ComplexInteraction
|
||||||
- type: Internals
|
- type: Internals
|
||||||
- type: Inventory
|
- type: Inventory
|
||||||
- type: InventorySlots
|
- type: InventorySlots
|
||||||
@@ -309,6 +310,7 @@
|
|||||||
abstract: true
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: Hands
|
- type: Hands
|
||||||
|
- type: ComplexInteraction
|
||||||
- type: Inventory
|
- type: Inventory
|
||||||
- type: InventorySlots
|
- type: InventorySlots
|
||||||
- type: ContainerContainer
|
- type: ContainerContainer
|
||||||
|
|||||||
Reference in New Issue
Block a user