Fix snares (#16699)
The alert for snares will appear again. Previously it was being updated on the snare itself and not the player. It is no longer possible to infinitely ensnare someone; the maximum number is dependent on the target's legs. Only one snare at a time will be removed now. Clarified the wording and logic around CanMoveBreakout. It was inconsistent. Made multiple snares impose cumulative speed penalties. It is no longer possible to remove bolas while moving.
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Part;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Ensnaring;
|
||||
using Content.Shared.Ensnaring.Components;
|
||||
@@ -12,6 +16,7 @@ public sealed partial class EnsnareableSystem
|
||||
{
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly BodySystem _body = default!;
|
||||
|
||||
public void InitializeEnsnaring()
|
||||
{
|
||||
@@ -60,12 +65,19 @@ public sealed partial class EnsnareableSystem
|
||||
if (!TryComp<EnsnareableComponent>(target, out var ensnareable))
|
||||
return;
|
||||
|
||||
var legs = _body.GetBodyChildrenOfType(target, BodyPartType.Leg).Count();
|
||||
var ensnaredLegs = (2 * ensnareable.Container.ContainedEntities.Count);
|
||||
var freeLegs = legs - ensnaredLegs;
|
||||
|
||||
if (freeLegs <= 0)
|
||||
return;
|
||||
|
||||
component.Ensnared = target;
|
||||
ensnareable.Container.Insert(ensnare);
|
||||
ensnareable.IsEnsnared = true;
|
||||
Dirty(ensnareable);
|
||||
|
||||
UpdateAlert(ensnare, ensnareable);
|
||||
UpdateAlert(target, ensnareable);
|
||||
var ev = new EnsnareEvent(component.WalkSpeed, component.SprintSpeed);
|
||||
RaiseLocalEvent(target, ev);
|
||||
}
|
||||
@@ -84,7 +96,7 @@ public sealed partial class EnsnareableSystem
|
||||
return;
|
||||
|
||||
var freeTime = user == target ? component.BreakoutTime : component.FreeTime;
|
||||
var breakOnMove = user != target || !component.CanMoveBreakout;
|
||||
var breakOnMove = !component.CanMoveBreakout;
|
||||
|
||||
var doAfterEventArgs = new DoAfterArgs(user, freeTime, new EnsnareableDoAfterEvent(), target, target: target, used: ensnare)
|
||||
{
|
||||
@@ -109,24 +121,33 @@ public sealed partial class EnsnareableSystem
|
||||
/// </summary>
|
||||
public void ForceFree(EntityUid ensnare, EnsnaringComponent component)
|
||||
{
|
||||
if (component.Ensnared == null)
|
||||
return;
|
||||
|
||||
if (!TryComp<EnsnareableComponent>(component.Ensnared, out var ensnareable))
|
||||
return;
|
||||
|
||||
ensnareable.Container.ForceRemove(ensnare);
|
||||
ensnareable.IsEnsnared = false;
|
||||
var target = component.Ensnared.Value;
|
||||
|
||||
ensnareable.Container.Remove(ensnare, force: true);
|
||||
ensnareable.IsEnsnared = ensnareable.Container.ContainedEntities.Count > 0;
|
||||
Dirty(ensnareable);
|
||||
component.Ensnared = null;
|
||||
|
||||
UpdateAlert(ensnare, ensnareable);
|
||||
var ev = new EnsnareRemoveEvent();
|
||||
UpdateAlert(target, ensnareable);
|
||||
var ev = new EnsnareRemoveEvent(component.WalkSpeed, component.SprintSpeed);
|
||||
RaiseLocalEvent(ensnare, ev);
|
||||
}
|
||||
|
||||
public void UpdateAlert(EntityUid ensnare, EnsnareableComponent component)
|
||||
/// <summary>
|
||||
/// Update the Ensnared alert for an entity.
|
||||
/// </summary>
|
||||
/// <param name="target">The entity that has been affected by a snare</param>
|
||||
public void UpdateAlert(EntityUid target, EnsnareableComponent component)
|
||||
{
|
||||
if (!component.IsEnsnared)
|
||||
_alerts.ClearAlert(ensnare, AlertType.Ensnared);
|
||||
_alerts.ClearAlert(target, AlertType.Ensnared);
|
||||
else
|
||||
_alerts.ShowAlert(ensnare, AlertType.Ensnared);
|
||||
_alerts.ShowAlert(target, AlertType.Ensnared);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user