mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-17 05:27:38 +03:00
## Mirror of PR #22962: [Landmine stepoff](https://github.com/space-wizards/space-station-14/pull/22962) from <img src="https://avatars.githubusercontent.com/u/10567778?v=4" alt="space-wizards" width="22"/> [space-wizards](https://github.com/space-wizards)/[space-station-14](https://github.com/space-wizards/space-station-14) ###### `54dd273f660d6d8d523d0771bb8d8437373b082e` PR opened by <img src="https://avatars.githubusercontent.com/u/59531932?v=4" width="16"/><a href="https://github.com/YuriyKiss"> YuriyKiss</a> at 2023-12-25 12:38:55 UTC --- PR changed 13 files with 95 additions and 47 deletions. The PR had the following labels: - Status: Awaiting Changes --- <details open="true"><summary><h1>Original Body</h1></summary> > ## About the PR > Landmine will explode when player steps off it. Landmine will make a sound effect when player steps on it > Close #21658 (Issue has some other suggestions, turn them into separate issues if relevant) > > Requires https://github.com/space-wizards/RobustToolbox/pull/4883 > > ## Why / Balance > IRL some landmines will only trigger after you release the pressure put on them. > > ## Technical details > There are two landmine modes now, one will make landmine trigger immediately after player steps on them another one will only trigger after player steps off the landmine (this is the default now). > > ## Media > Landmine stepoff in action: > > https://github.com/space-wizards/space-station-14/assets/59531932/6e884619-7217-4301-bd78-6e843e0d78f1 > > - [X] I have added screenshots/videos to this PR showcasing its changes ingame, **or** this PR does not require an ingame showcase > > ## Breaking changes > > > **Changelog** > - tweak: landmines will trigger after you step off them > - add: landmine trigger sound > </details> Signed-off-by: VMSolidus <evilexecutive@gmail.com> Co-authored-by: SimpleStation14 <Unknown> Co-authored-by: VMSolidus <evilexecutive@gmail.com>
134 lines
5.0 KiB
C#
134 lines
5.0 KiB
C#
using Content.Shared.Administration.Logs;
|
|
using Content.Shared.Database;
|
|
using Content.Shared.Inventory;
|
|
using Robust.Shared.Network;
|
|
using Content.Shared.Popups;
|
|
using Content.Shared.StatusEffect;
|
|
using Content.Shared.StepTrigger.Systems;
|
|
using Content.Shared.Stunnable;
|
|
using Content.Shared.Throwing;
|
|
using JetBrains.Annotations;
|
|
using Robust.Shared.Audio.Systems;
|
|
using Robust.Shared.Containers;
|
|
using Robust.Shared.Physics.Components;
|
|
using Robust.Shared.Physics.Systems;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Shared.Slippery;
|
|
|
|
[UsedImplicitly]
|
|
public sealed class SlipperySystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
|
[Dependency] private readonly SharedStunSystem _stun = default!;
|
|
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
|
|
[Dependency] private readonly SharedContainerSystem _container = default!;
|
|
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<SlipperyComponent, StepTriggerAttemptEvent>(HandleAttemptCollide);
|
|
SubscribeLocalEvent<SlipperyComponent, StepTriggeredOffEvent>(HandleStepTrigger);
|
|
SubscribeLocalEvent<NoSlipComponent, SlipAttemptEvent>(OnNoSlipAttempt);
|
|
SubscribeLocalEvent<ThrownItemComponent, SlipCausingAttemptEvent>(OnThrownSlipAttempt);
|
|
// as long as slip-resistant mice are never added, this should be fine (otherwise a mouse-hat will transfer it's power to the wearer).
|
|
SubscribeLocalEvent<NoSlipComponent, InventoryRelayedEvent<SlipAttemptEvent>>((e, c, ev) => OnNoSlipAttempt(e, c, ev.Args));
|
|
}
|
|
|
|
private void HandleStepTrigger(EntityUid uid, SlipperyComponent component, ref StepTriggeredOffEvent args)
|
|
{
|
|
TrySlip(uid, component, args.Tripper);
|
|
}
|
|
|
|
private void HandleAttemptCollide(
|
|
EntityUid uid,
|
|
SlipperyComponent component,
|
|
ref StepTriggerAttemptEvent args)
|
|
{
|
|
args.Continue |= CanSlip(uid, args.Tripper);
|
|
}
|
|
|
|
private static void OnNoSlipAttempt(EntityUid uid, NoSlipComponent component, SlipAttemptEvent args)
|
|
{
|
|
args.Cancel();
|
|
}
|
|
|
|
private void OnThrownSlipAttempt(EntityUid uid, ThrownItemComponent comp, ref SlipCausingAttemptEvent args)
|
|
{
|
|
args.Cancelled = true;
|
|
}
|
|
|
|
private bool CanSlip(EntityUid uid, EntityUid toSlip)
|
|
{
|
|
return !_container.IsEntityInContainer(uid)
|
|
&& _statusEffects.CanApplyEffect(toSlip, "Stun"); //Should be KnockedDown instead?
|
|
}
|
|
|
|
private void TrySlip(EntityUid uid, SlipperyComponent component, EntityUid other)
|
|
{
|
|
if (HasComp<KnockedDownComponent>(other) && !component.SuperSlippery)
|
|
return;
|
|
|
|
var attemptEv = new SlipAttemptEvent();
|
|
RaiseLocalEvent(other, attemptEv);
|
|
if (attemptEv.Cancelled)
|
|
return;
|
|
|
|
var attemptCausingEv = new SlipCausingAttemptEvent();
|
|
RaiseLocalEvent(uid, ref attemptCausingEv);
|
|
if (attemptCausingEv.Cancelled)
|
|
return;
|
|
|
|
var ev = new SlipEvent(other);
|
|
RaiseLocalEvent(uid, ref ev);
|
|
|
|
if (TryComp(other, out PhysicsComponent? physics) && !HasComp<SlidingComponent>(other))
|
|
{
|
|
_physics.SetLinearVelocity(other, physics.LinearVelocity * component.LaunchForwardsMultiplier, body: physics);
|
|
|
|
if (component.SuperSlippery)
|
|
{
|
|
var sliding = EnsureComp<SlidingComponent>(other);
|
|
sliding.CollidingEntities.Add(uid);
|
|
DebugTools.Assert(_physics.GetContactingEntities(other, physics).Contains(uid));
|
|
}
|
|
}
|
|
|
|
var playSound = !_statusEffects.HasStatusEffect(other, "KnockedDown");
|
|
|
|
_stun.TryParalyze(other, TimeSpan.FromSeconds(component.ParalyzeTime), true);
|
|
|
|
// Preventing from playing the slip sound when you are already knocked down.
|
|
if (playSound)
|
|
{
|
|
_audio.PlayPredicted(component.SlipSound, other, other);
|
|
}
|
|
|
|
_adminLogger.Add(LogType.Slip, LogImpact.Low,
|
|
$"{ToPrettyString(other):mob} slipped on collision with {ToPrettyString(uid):entity}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Raised on an entity to determine if it can slip or not.
|
|
/// </summary>
|
|
public sealed class SlipAttemptEvent : CancellableEntityEventArgs, IInventoryRelayEvent
|
|
{
|
|
public SlotFlags TargetSlots { get; } = SlotFlags.FEET;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Raised on an entity that is causing the slip event (e.g, the banana peel), to determine if the slip attempt should be cancelled.
|
|
/// </summary>
|
|
/// <param name="Cancelled">If the slip should be cancelled</param>
|
|
[ByRefEvent]
|
|
public record struct SlipCausingAttemptEvent (bool Cancelled);
|
|
|
|
/// Raised on an entity that CAUSED some other entity to slip (e.g., the banana peel).
|
|
/// <param name="Slipped">The entity being slipped</param>
|
|
[ByRefEvent]
|
|
public readonly record struct SlipEvent(EntityUid Slipped);
|