Add WieldingBlockerComponent (#37778)

initial commit
This commit is contained in:
slarticodefast
2025-05-26 05:50:30 +02:00
committed by GitHub
parent 68d5d940cf
commit e8bc811f7a
6 changed files with 124 additions and 12 deletions

View File

@@ -1,11 +1,12 @@
using System.Linq;
using Content.Shared.Camera;
using Content.Shared.Examine;
using Content.Shared.Hands;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction.Events;
using Content.Shared.Inventory;
using Content.Shared.Inventory.Events;
using Content.Shared.Inventory.VirtualItem;
using Content.Shared.Item;
using Content.Shared.Movement.Components;
@@ -22,7 +23,6 @@ using Content.Shared.Weapons.Ranged.Systems;
using Content.Shared.Wieldable.Components;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Collections;
using Robust.Shared.Network;
using Robust.Shared.Timing;
namespace Content.Shared.Wieldable;
@@ -51,6 +51,12 @@ public abstract class SharedWieldableSystem : EntitySystem
SubscribeLocalEvent<WieldableComponent, GetVerbsEvent<InteractionVerb>>(AddToggleWieldVerb);
SubscribeLocalEvent<WieldableComponent, HandDeselectedEvent>(OnDeselectWieldable);
SubscribeLocalEvent<WieldingBlockerComponent, GotEquippedEvent>(OnBlockerEquipped);
SubscribeLocalEvent<WieldingBlockerComponent, GotEquippedHandEvent>(OnBlockerEquippedHand);
SubscribeLocalEvent<WieldingBlockerComponent, WieldAttemptEvent>(OnBlockerAttempt);
SubscribeLocalEvent<WieldingBlockerComponent, InventoryRelayedEvent<WieldAttemptEvent>>(OnBlockerAttempt);
SubscribeLocalEvent<WieldingBlockerComponent, HeldRelayedEvent<WieldAttemptEvent>>(OnBlockerAttempt);
SubscribeLocalEvent<MeleeRequiresWieldComponent, AttemptMeleeEvent>(OnMeleeAttempt);
SubscribeLocalEvent<GunRequiresWieldComponent, ExaminedEvent>(OnExamineRequires);
SubscribeLocalEvent<GunRequiresWieldComponent, ShotAttemptedEvent>(OnShootAttempt);
@@ -186,14 +192,55 @@ public abstract class SharedWieldableSystem : EntitySystem
return;
if (!component.Wielded)
args.Handled = TryWield(uid, component, args.User);
{
TryWield(uid, component, args.User);
args.Handled = true; // always mark as handled or we will cycle ammo when wielding is blocked
}
else if (component.UnwieldOnUse)
args.Handled = TryUnwield(uid, component, args.User);
{
TryUnwield(uid, component, args.User);
args.Handled = true;
}
if (HasComp<UseDelayComponent>(uid) && !component.UseDelayOnWield)
args.ApplyDelay = false;
}
private void OnBlockerEquipped(Entity<WieldingBlockerComponent> ent, ref GotEquippedEvent args)
{
if (ent.Comp.BlockEquipped)
UnwieldAll(args.Equipee, force: true);
}
private void OnBlockerEquippedHand(Entity<WieldingBlockerComponent> ent, ref GotEquippedHandEvent args)
{
if (ent.Comp.BlockInHand)
UnwieldAll(args.User, force: true);
}
private void OnBlockerAttempt(Entity<WieldingBlockerComponent> ent, ref InventoryRelayedEvent<WieldAttemptEvent> args)
{
if (ent.Comp.BlockEquipped)
{
args.Args.Message = Loc.GetString("wieldable-component-blocked-wield", ("blocker", ent.Owner), ("item", args.Args.Wielded));
args.Args.Cancelled = true;
}
}
private void OnBlockerAttempt(Entity<WieldingBlockerComponent> ent, ref HeldRelayedEvent<WieldAttemptEvent> args)
{
if (ent.Comp.BlockInHand)
{
args.Args.Message = Loc.GetString("wieldable-component-blocked-wield", ("blocker", ent.Owner), ("item", args.Args.Wielded));
args.Args.Cancelled = true;
}
}
private void OnBlockerAttempt(Entity<WieldingBlockerComponent> ent, ref WieldAttemptEvent args)
{
args.Cancelled = true;
}
public bool CanWield(EntityUid uid, WieldableComponent component, EntityUid user, bool quiet = false)
{
// Do they have enough hands free?
@@ -242,11 +289,15 @@ public abstract class SharedWieldableSystem : EntitySystem
return false;
}
var attemptEv = new WieldAttemptEvent(user);
RaiseLocalEvent(used, ref attemptEv);
var attemptEv = new WieldAttemptEvent(user, used);
RaiseLocalEvent(user, ref attemptEv);
if (attemptEv.Cancelled)
{
if (attemptEv.Message != null)
_popup.PopupClient(attemptEv.Message, user, user);
return false;
}
if (TryComp<ItemComponent>(used, out var item))
{
@@ -298,11 +349,15 @@ public abstract class SharedWieldableSystem : EntitySystem
if (!force)
{
var attemptEv = new UnwieldAttemptEvent(user);
RaiseLocalEvent(used, ref attemptEv);
var attemptEv = new UnwieldAttemptEvent(user, used);
RaiseLocalEvent(user, ref attemptEv);
if (attemptEv.Cancelled)
{
if (attemptEv.Message != null)
_popup.PopupClient(attemptEv.Message, user, user);
return false;
}
}
SetWielded((used, component), false);
@@ -312,6 +367,19 @@ public abstract class SharedWieldableSystem : EntitySystem
return true;
}
/// <summary>
/// Makes an entity unwield all currently wielded items.
/// </summary>
/// <param name="force">If this is true we will bypass UnwieldAttemptEvent.</param>
public void UnwieldAll(Entity<HandsComponent?> wielder, bool force = false)
{
foreach (var held in _hands.EnumerateHeld(wielder.Owner, wielder.Comp))
{
if (TryComp<WieldableComponent>(held, out var wieldable))
TryUnwield(held, wieldable, wielder, force);
}
}
/// <summary>
/// Sets wielded without doing any checks.
/// </summary>