Skip to content

Commit

Permalink
Merge pull request WWhiteDreamProject#114 from WWhiteDreamProject/kno…
Browse files Browse the repository at this point in the history
…ckdown

[Port/Feature] Knockdown / Сбитие С Ног
  • Loading branch information
Spatison authored Dec 1, 2024
2 parents 37d3783 + 6a359d0 commit fcf51c5
Show file tree
Hide file tree
Showing 40 changed files with 440 additions and 162 deletions.
2 changes: 1 addition & 1 deletion Content.Client/Weapons/Melee/MeleeWeaponSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public override void Update(float frameTime)
// Unarmed will try to disarm
// Melee weapons will wideswing
// Ranged weapons will do a light attack.
if (altDown == BoundKeyState.Down)
if (altDown == BoundKeyState.Down && weapon.CanHeavyAttack) // WD EDIT
{
// Get the target that was clicked on
EntityUid? target = null;
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Explosion/EntitySystems/TriggerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ private void HandleExplodeTrigger(EntityUid uid, ExplodeOnTriggerComponent compo
private void HandleFlashTrigger(EntityUid uid, FlashOnTriggerComponent component, TriggerEvent args)
{
// TODO Make flash durations sane ffs.
_flashSystem.FlashArea(uid, args.User, component.Range, component.Duration * 1000f, probability: component.Probability);
_flashSystem.FlashArea(uid, args.User, component.Range, component.Duration * 1000f, probability: component.Probability, stunTime: component.StunTime, knockdownTime: component.KnockdownTime); // WD EDIT
args.Handled = true;
}

Expand Down
44 changes: 41 additions & 3 deletions Content.Server/Flash/FlashSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using Content.Server._White.Flash;
using Content.Server.Flash.Components;
using Content.Shared.Flash.Components;
using Content.Server.Light.EntitySystems;
Expand All @@ -24,6 +25,8 @@
using Content.Shared.Traits.Assorted.Components;
using Robust.Shared.Random;
using Content.Shared.Eye.Blinding.Systems;
using Content.Shared.Standing;


namespace Content.Server.Flash
{
Expand Down Expand Up @@ -167,7 +170,39 @@ public void Flash(EntityUid target,
}
}

public void FlashArea(Entity<FlashComponent?> source, EntityUid? user, float range, float duration, float slowTo = 0.8f, bool displayPopup = false, float probability = 1f, SoundSpecifier? sound = null)
// WD EDIT START
private void FlashStun(EntityUid target, float stunDuration, float knockdownDuration, float distance, float range)
{
if (stunDuration <= 0 && knockdownDuration <= 0)
return;

if (TryComp<FlashSoundSuppressionComponent>(target, out var suppression))
range = MathF.Min(range, suppression.MaxRange);

var ev = new FlashbangedEvent(range);
RaiseLocalEvent(target, ev);

range = MathF.Min(range, ev.MaxRange);
if (range <= 0f)
return;

if (distance < 0f)
distance = 0f;

if (distance > range)
return;

var knockdownTime = float.Lerp(knockdownDuration, 0f, distance / range);
if (knockdownTime > 0f)
_stun.TryKnockdown(target, TimeSpan.FromSeconds(knockdownTime), true, DropHeldItemsBehavior.DropIfStanding);

var stunTime = float.Lerp(stunDuration, 0f, distance / range);
if (stunTime > 0f)
_stun.TryStun(target, TimeSpan.FromSeconds(stunTime), true);
}
// WD EDIT END

public void FlashArea(Entity<FlashComponent?> source, EntityUid? user, float range, float duration, float slowTo = 0.8f, bool displayPopup = false, float probability = 1f, SoundSpecifier? sound = null, float stunTime = 0f, float knockdownTime = 0f) // WD EDIT
{
var transform = Transform(source);
var mapPosition = _transform.GetMapCoordinates(transform);
Expand All @@ -187,6 +222,11 @@ public void FlashArea(Entity<FlashComponent?> source, EntityUid? user, float ran

// They shouldn't have flash removed in between right?
Flash(entity, user, source, duration, slowTo, displayPopup, flashableQuery.GetComponent(entity));

// WD EDIT START
var distance = (mapPosition.Position - _transform.GetMapCoordinates(entity).Position).Length();
FlashStun(entity, stunTime, knockdownTime, distance, range);
// WD EDIT END
}

_audio.PlayPvs(sound, source, AudioParams.Default.WithVolume(1f).WithMaxDistance(3f));
Expand Down Expand Up @@ -251,6 +291,4 @@ public AfterFlashedEvent(EntityUid target, EntityUid? user, EntityUid? used)
Used = used;
}
}


}
2 changes: 1 addition & 1 deletion Content.Server/Speech/EntitySystems/StutteringSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public sealed class StutteringSystem : SharedStutteringSystem
[Dependency] private readonly IRobustRandom _random = default!;

// Regex of characters to stutter.
private static readonly Regex Stutter = new(@"[b-df-hj-np-tv-wxyz]",
private static readonly Regex Stutter = new(@"[b-df-hj-np-tv-wxyz-б-вд-к-лмн-прст]", // WD EDIT
RegexOptions.Compiled | RegexOptions.IgnoreCase);

public override void Initialize()
Expand Down
16 changes: 0 additions & 16 deletions Content.Server/Stunnable/Components/KnockdownOnHitComponent.cs

This file was deleted.

40 changes: 0 additions & 40 deletions Content.Server/Stunnable/Systems/KnockdownOnHitSystem.cs

This file was deleted.

22 changes: 19 additions & 3 deletions Content.Server/Stunnable/Systems/StunbatonSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using Content.Shared.Popups;
using Content.Shared.PowerCell.Components;
using Content.Shared.Stunnable;
using Content.Shared.Stunnable.Events;


namespace Content.Server.Stunnable.Systems
{
Expand All @@ -32,18 +34,25 @@ public override void Initialize()
SubscribeLocalEvent<StunbatonComponent, ItemToggledEvent>(ToggleDone);
SubscribeLocalEvent<StunbatonComponent, ChargeChangedEvent>(OnChargeChanged);
SubscribeLocalEvent<StunbatonComponent, PowerCellChangedEvent>(OnPowerCellChanged); // WD EDIT
SubscribeLocalEvent<StunbatonComponent, KnockdownOnHitAttemptEvent>(OnKnockdownHitAttempt); // WD EDIT
}

private void OnStaminaHitAttempt(Entity<StunbatonComponent> entity, ref StaminaDamageOnHitAttemptEvent args)
{
// WD EDIT START
if (!_itemToggle.IsActivated(entity.Owner)
|| !_battery.TryGetBatteryComponent(entity, out var battery, out var batteryUid)
|| !_battery.TryUseCharge(batteryUid.Value, entity.Comp.EnergyPerUse, battery))
if (!_itemToggle.IsActivated(entity.Owner) || TryUseCharge(entity))
args.Cancelled = true;
// WD EDIT END
}

// WD EDIT START
private void OnKnockdownHitAttempt(Entity<StunbatonComponent> entity, ref KnockdownOnHitAttemptEvent args)
{
if (!_itemToggle.IsActivated(entity.Owner) || TryUseCharge(entity))
args.Cancelled = true;
}
// WD EDIT END

private void OnExamined(Entity<StunbatonComponent> entity, ref ExaminedEvent args)
{
var onMsg = _itemToggle.IsActivated(entity.Owner)
Expand Down Expand Up @@ -126,6 +135,13 @@ private void CheckCharge(Entity<StunbatonComponent> entity)
|| battery.CurrentCharge < entity.Comp.EnergyPerUse)
_itemToggle.TryDeactivate(entity.Owner, predicted: false);
}

private bool TryUseCharge(Entity<StunbatonComponent> entity)
{
return _battery.TryGetBatteryComponent(entity, out var battery, out var batteryUid)
&& battery.CurrentCharge >= entity.Comp.EnergyPerUse
&& _battery.TryUseCharge(batteryUid.Value, entity.Comp.EnergyPerUse / 2, battery);
}
// WD EDIT END
}
}
8 changes: 8 additions & 0 deletions Content.Server/_White/Flash/FlashSoundSuppressionComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Content.Server._White.Flash;

[RegisterComponent]
public sealed partial class FlashSoundSuppressionComponent : Component
{
[DataField]
public float MaxRange = 2f;
}
19 changes: 19 additions & 0 deletions Content.Server/_White/Flash/FlashSoundSuppressionSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Content.Shared.Flash;
using Content.Shared.Inventory;

namespace Content.Server._White.Flash;

public sealed class FlashSoundSuppressionSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<FlashSoundSuppressionComponent, InventoryRelayedEvent<FlashbangedEvent>>(OnFlashbanged);
}

private void OnFlashbanged(Entity<FlashSoundSuppressionComponent> ent, ref InventoryRelayedEvent<FlashbangedEvent> args)
{
args.Args.MaxRange = MathF.Min(args.Args.MaxRange, ent.Comp.MaxRange);
}
}
22 changes: 22 additions & 0 deletions Content.Server/_White/Knockdown/BaseKnockdownOnComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Content.Shared.Standing;


namespace Content.Server._White.Knockdown;

public abstract partial class BaseKnockdownOnComponent : Component
{
[DataField]
public TimeSpan Delay = TimeSpan.FromSeconds(2);

[DataField]
public TimeSpan KnockdownTime = TimeSpan.FromSeconds(5);

[DataField]
public DropHeldItemsBehavior DropHeldItemsBehavior = DropHeldItemsBehavior.DropIfStanding;

[DataField]
public TimeSpan JitterTime = TimeSpan.FromSeconds(15);

[DataField]
public TimeSpan StutterTime = TimeSpan.FromSeconds(15);
}
17 changes: 17 additions & 0 deletions Content.Server/_White/Knockdown/KnockComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Content.Shared.Standing;


namespace Content.Server._White.Knockdown;

[RegisterComponent]
public sealed partial class KnockComponent : Component
{
[DataField]
public TimeSpan Delay = TimeSpan.FromSeconds(2);

[DataField]
public TimeSpan KnockdownTime = TimeSpan.FromSeconds(5);

[DataField]
public DropHeldItemsBehavior DropHeldItemsBehavior = DropHeldItemsBehavior.DropIfStanding;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Content.Server._White.Knockdown;

[RegisterComponent]
public sealed partial class KnockdownOnCollideComponent : BaseKnockdownOnComponent;
4 changes: 4 additions & 0 deletions Content.Server/_White/Knockdown/KnockdownOnHitComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Content.Server._White.Knockdown;

[RegisterComponent]
public sealed partial class KnockdownOnHitComponent : BaseKnockdownOnComponent;
79 changes: 79 additions & 0 deletions Content.Server/_White/Knockdown/KnockdownSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Content.Server.Jittering;
using Content.Server.Speech.EntitySystems;
using Content.Server.Stunnable;
using Content.Shared.Projectiles;
using Content.Shared.StatusEffect;
using Content.Shared.Stunnable.Events;
using Content.Shared.Throwing;
using Content.Shared.Weapons.Melee.Events;
using Robust.Shared.Timing;

namespace Content.Server._White.Knockdown;

public sealed class KnockdownSystem : EntitySystem
{
[Dependency] private readonly StunSystem _sharedStun = default!;
[Dependency] private readonly JitteringSystem _jitter = default!;
[Dependency] private readonly StutteringSystem _stutter = default!;
[Dependency] private readonly IGameTiming _timing = default!;

public override void Initialize()
{
SubscribeLocalEvent<KnockdownOnHitComponent, MeleeHitEvent>(OnMeleeHit);
SubscribeLocalEvent<KnockdownOnCollideComponent, ProjectileHitEvent>(OnProjectileHit);
SubscribeLocalEvent<KnockdownOnCollideComponent, ThrowDoHitEvent>(OnThrowDoHit);
}

private void OnMeleeHit(EntityUid uid, KnockdownOnHitComponent component, MeleeHitEvent args)
{
var ev = new KnockdownOnHitAttemptEvent();
RaiseLocalEvent(uid, ref ev);
if (ev.Cancelled)
return;

foreach (var hitEntity in args.HitEntities)
Knockdown(hitEntity, component);
}

private void OnProjectileHit(EntityUid uid, KnockdownOnCollideComponent component, ProjectileHitEvent args) => Knockdown(args.Target, component);

private void OnThrowDoHit(EntityUid uid, KnockdownOnCollideComponent component, ThrowDoHitEvent args) => Knockdown(args.Target, component);

private void Knockdown(EntityUid target, BaseKnockdownOnComponent component)
{
if (!TryComp<StatusEffectsComponent>(target, out var statusEffects))
return;

if (component.JitterTime > TimeSpan.Zero)
_jitter.DoJitter(target, component.JitterTime, true, status: statusEffects);

if (component.StutterTime > TimeSpan.Zero)
_stutter.DoStutter(target, component.StutterTime, true, statusEffects);

if (component.Delay == TimeSpan.Zero)
{
_sharedStun.TryKnockdown(target, component.KnockdownTime, true, statusEffects);
return;
}

var knockdown = EnsureComp<KnockComponent>(target);
knockdown.Delay = _timing.CurTime + component.Delay;
knockdown.KnockdownTime = component.KnockdownTime;
knockdown.DropHeldItemsBehavior = component.DropHeldItemsBehavior;
}

public override void Update(float frameTime)
{
base.Update(frameTime);

var query = EntityQueryEnumerator<KnockComponent>();
while (query.MoveNext(out var uid, out var delayedKnockdown))
{
if (delayedKnockdown.Delay > _timing.CurTime)
continue;

_sharedStun.TryKnockdown(uid, delayedKnockdown.KnockdownTime, true, delayedKnockdown.DropHeldItemsBehavior);
RemCompDeferred<KnockComponent>(uid);
}
}
}
8 changes: 8 additions & 0 deletions Content.Shared/Flash/Components/FlashOnTriggerComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,12 @@ public sealed partial class FlashOnTriggerComponent : Component
[DataField] public float Range = 1.0f;
[DataField] public float Duration = 8.0f;
[DataField] public float Probability = 1.0f;

// WD EDIT START
[DataField]
public float StunTime;

[DataField]
public float KnockdownTime;
// WD EDIT END
}
Loading

0 comments on commit fcf51c5

Please sign in to comment.