Skip to content

Commit

Permalink
fix: Shadow shackles can now be removed
Browse files Browse the repository at this point in the history
  • Loading branch information
Spatison committed Jan 9, 2025
1 parent b473505 commit 02bcd18
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 77 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Content.Server.Chat.Systems;
using Content.Shared.WhiteDream.BloodCult.Items.BaseAura;
using Content.Shared.WhiteDream.BloodCult.Spells;

namespace Content.Server.WhiteDream.BloodCult.Items.BaseAura;

public abstract class BaseAuraSystem<T> : EntitySystem where T : BaseAuraComponent
{
[Dependency] private readonly ChatSystem _chat = default!;

public override void Initialize()
{
SubscribeLocalEvent<T, SpeakOnAuraUseEvent>(OnAuraUse);
}

private void OnAuraUse(EntityUid uid, T component, SpeakOnAuraUseEvent args)
{
// TODO: The charge of the aura spell should be spent here
if (component.Speech != null)
_chat.TrySendInGameICMessage(args.User, component.Speech, component.ChatType, false);
}
}
Original file line number Diff line number Diff line change
@@ -1,77 +1,25 @@
using System.Linq;
using Content.Server.Chat.Systems;
using Content.Server.Cuffs;
using Content.Server.DoAfter;
using Content.Shared.Cuffs.Components;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Server.WhiteDream.BloodCult.Items.BaseAura;
using Content.Shared.Speech.Muting;
using Content.Shared.StatusEffect;
using Content.Shared.Weapons.Melee.Events;
using Content.Shared.WhiteDream.BloodCult.BloodCultist;
using Content.Shared.WhiteDream.BloodCult.Spells;
using Robust.Server.GameObjects;
using Content.Shared.WhiteDream.BloodCult.Items.ShadowShacklesAura;
using Robust.Shared.Containers;

namespace Content.Server.WhiteDream.BloodCult.Items.ShadowShacklesAura;

public sealed class ShadowShacklesAuraSystem : EntitySystem
public sealed class ShadowShacklesAuraSystem : BaseAuraSystem<ShadowShacklesAuraComponent>
{
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
[Dependency] private readonly ChatSystem _chat = default!;
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly CuffableSystem _cuffable = default!;
[Dependency] private readonly DoAfterSystem _doAfter = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<ShadowShacklesAuraComponent, MeleeHitEvent>(OnMeleeHit);
SubscribeLocalEvent<ShadowShacklesAuraComponent, ShadowShacklesDoAfterEvent>(OnDoAfter);
SubscribeLocalEvent<ShadowShacklesAuraComponent, EntRemovedFromContainerMessage>(OnShackles);
}

private void OnMeleeHit(EntityUid uid, ShadowShacklesAuraComponent component, MeleeHitEvent args)
private void OnShackles(EntityUid uid, ShadowShacklesAuraComponent component, EntRemovedFromContainerMessage args)
{
if (!args.HitEntities.Any())
return;

var target = args.HitEntities.First();
if (uid == target || HasComp<BloodCultistComponent>(target) || !HasComp<CuffableComponent>(target))
return;

if (component.Speech != null)
_chat.TrySendInGameICMessage(args.User, component.Speech, component.ChatType, false);

var doAfterArgs = new DoAfterArgs(
EntityManager,
args.User,
component.Delay,
new ShadowShacklesDoAfterEvent(),
uid,
target,
uid)
{
DistanceThreshold = SharedInteractionSystem.InteractionRange,
BreakOnDamage = true,
BreakOnMove = true,
};

_doAfter.TryStartDoAfter(doAfterArgs, out _);
}

private void OnDoAfter(EntityUid uid, ShadowShacklesAuraComponent component, ShadowShacklesDoAfterEvent args)
{
if (!args.Target.HasValue)
return;

var shackles = Spawn(component.ShacklesProto, _transform.GetMapCoordinates(args.User));
if (!_cuffable.TryAddNewCuffs(args.Target.Value, args.User, shackles))
{
QueueDel(shackles);
return;
}

_statusEffects.TryAddStatusEffect<MutedComponent>(args.Target.Value, "Muted", component.MuteDuration, true);
QueueDel(uid);
_statusEffects.TryAddStatusEffect<MutedComponent>(component.Target, "Muted", component.MuteDuration, true);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Content.Server.WhiteDream.BloodCult.Items.BaseAura;
using Content.Shared.Chat;
using Content.Shared.WhiteDream.BloodCult.Items.BaseAura;

namespace Content.Server.WhiteDream.BloodCult.Items.StunAura;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
using System.Linq;
using Content.Server.Chat.Systems;
using Content.Server.Stunnable;
using Content.Server.WhiteDream.BloodCult.Items.BaseAura;
using Content.Shared.Speech.Muting;
using Content.Shared.StatusEffect;
using Content.Shared.Weapons.Melee.Events;
using Content.Shared.WhiteDream.BloodCult.BloodCultist;
using Content.Shared.WhiteDream.BloodCult.Constructs;
using Content.Shared.WhiteDream.BloodCult.Spells;

namespace Content.Server.WhiteDream.BloodCult.Items.StunAura;

public sealed class StunAuraSystem : EntitySystem
public sealed class StunAuraSystem : BaseAuraSystem<StunAuraComponent>
{
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
[Dependency] private readonly StunSystem _stun = default!;
[Dependency] private readonly ChatSystem _chat = default!;

public override void Initialize()
{
Expand All @@ -28,13 +28,10 @@ private void OnMeleeHit(EntityUid uid, StunAuraComponent component, MeleeHitEven
return;

var target = args.HitEntities.First();
if (uid == target
|| HasComp<BloodCultistComponent>(target)
|| HasComp<ConstructComponent>(target))
if (uid == target || HasComp<BloodCultistComponent>(target) || HasComp<ConstructComponent>(target))
return;

if (component.Speech != null)
_chat.TrySendInGameICMessage(args.User, component.Speech, component.ChatType, false);
RaiseLocalEvent(uid, new SpeakOnAuraUseEvent(args.User));

_statusEffects.TryAddStatusEffect<MutedComponent>(target, "Muted", component.MuteDuration, true);
_stun.TryParalyze(target, component.ParalyzeDuration, true);
Expand Down
4 changes: 2 additions & 2 deletions Content.Shared/Cuffs/SharedCuffableSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ public bool TryAddNewCuffs(EntityUid target, EntityUid user, EntityUid handcuff,
}

/// <returns>False if the target entity isn't cuffable.</returns>
public bool TryCuffing(EntityUid user, EntityUid target, EntityUid handcuff, HandcuffComponent? handcuffComponent = null, CuffableComponent? cuffable = null)
public bool TryCuffing(EntityUid user, EntityUid target, EntityUid handcuff, HandcuffComponent? handcuffComponent = null, CuffableComponent? cuffable = null, float distanceThreshold = 0.3f)
{
if (!Resolve(handcuff, ref handcuffComponent) || !Resolve(target, ref cuffable, false))
return false;
Expand Down Expand Up @@ -515,7 +515,7 @@ public bool TryCuffing(EntityUid user, EntityUid target, EntityUid handcuff, Han
BreakOnWeightlessMove = false,
BreakOnDamage = true,
NeedHand = true,
DistanceThreshold = 0.3f
DistanceThreshold = distanceThreshold
};

if (!_doAfter.TryStartDoAfter(doAfterEventArgs))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Content.Shared.Chat;

namespace Content.Server.WhiteDream.BloodCult.Items.BaseAura;
namespace Content.Shared.WhiteDream.BloodCult.Items.BaseAura;

public abstract partial class BaseAuraComponent : Component
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Content.Server.WhiteDream.BloodCult.Items.BaseAura;
using Content.Shared.WhiteDream.BloodCult.Items.BaseAura;
using Robust.Shared.Prototypes;

namespace Content.Server.WhiteDream.BloodCult.Items.ShadowShacklesAura;
namespace Content.Shared.WhiteDream.BloodCult.Items.ShadowShacklesAura;

[RegisterComponent]
public sealed partial class ShadowShacklesAuraComponent : BaseAuraComponent
Expand All @@ -13,5 +13,11 @@ public sealed partial class ShadowShacklesAuraComponent : BaseAuraComponent
public TimeSpan MuteDuration = TimeSpan.FromSeconds(5);

[DataField]
public TimeSpan Delay = TimeSpan.FromSeconds(3);
public float DistanceThreshold = 1.5f;

[ViewVariables(VVAccess.ReadOnly)]
public EntityUid Shackles;

[ViewVariables(VVAccess.ReadOnly)]
public EntityUid Target;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Linq;
using Content.Shared.Cuffs;
using Content.Shared.Cuffs.Components;
using Content.Shared.Weapons.Melee.Events;
using Content.Shared.WhiteDream.BloodCult.BloodCultist;
using Content.Shared.WhiteDream.BloodCult.Spells;
using Robust.Shared.Containers;

namespace Content.Shared.WhiteDream.BloodCult.Items.ShadowShacklesAura;

public sealed class SharedShadowShacklesAuraSystem : EntitySystem
{
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedCuffableSystem _cuffable = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<ShadowShacklesAuraComponent, MeleeHitEvent>(OnMeleeHit);
SubscribeLocalEvent<ShadowShacklesAuraComponent, ComponentInit>(OnInit);
}

private void OnMeleeHit(EntityUid uid, ShadowShacklesAuraComponent component, MeleeHitEvent args)
{
if (!args.HitEntities.Any())
return;

component.Target = args.HitEntities.First();
if (uid == component.Target || HasComp<BloodCultistComponent>(component.Target) || !HasComp<CuffableComponent>(component.Target))
return;

if (_cuffable.TryCuffing(args.User, component.Target, component.Shackles, distanceThreshold:component.DistanceThreshold))
RaiseLocalEvent(uid, new SpeakOnAuraUseEvent(args.User));
}

private void OnInit(EntityUid uid, ShadowShacklesAuraComponent component, ComponentInit args)
{
var container = _container.EnsureContainer<Container>(uid, "shackles");
component.Shackles = Spawn(component.ShacklesProto, _transform.GetMapCoordinates(uid));
_container.Insert(component.Shackles, container);
}
}
6 changes: 4 additions & 2 deletions Content.Shared/WhiteDream/BloodCult/Spells/Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,7 @@ public sealed partial class TeleportActionDoAfterEvent : SimpleDoAfterEvent
[Serializable, NetSerializable]
public sealed partial class BloodRitesExtractDoAfterEvent : SimpleDoAfterEvent;

[Serializable, NetSerializable]
public sealed partial class ShadowShacklesDoAfterEvent : SimpleDoAfterEvent;
public sealed partial class SpeakOnAuraUseEvent(EntityUid user) : EntityEventArgs
{
public EntityUid User = user;
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@
- type: Sprite
sprite: WhiteDream/BloodCult/actions.rsi
state: cuff
- type: UseDelay
delay: 6

- type: entity
parent: BaseItem
Expand Down

0 comments on commit 02bcd18

Please sign in to comment.