Add explosive banana peel 2 (#14491)
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
namespace Content.Server.Explosion.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed class TriggerOnSlipComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -9,6 +9,7 @@ using Content.Shared.Database;
|
||||
using Content.Shared.Implants.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Payload.Components;
|
||||
using Content.Shared.Slippery;
|
||||
using Content.Shared.StepTrigger.Systems;
|
||||
using Content.Shared.Trigger;
|
||||
using JetBrains.Annotations;
|
||||
@@ -61,6 +62,7 @@ namespace Content.Server.Explosion.EntitySystems
|
||||
SubscribeLocalEvent<TriggerOnActivateComponent, ActivateInWorldEvent>(OnActivate);
|
||||
SubscribeLocalEvent<TriggerImplantActionComponent, ActivateImplantEvent>(OnImplantTrigger);
|
||||
SubscribeLocalEvent<TriggerOnStepTriggerComponent, StepTriggeredEvent>(OnStepTriggered);
|
||||
SubscribeLocalEvent<TriggerOnSlipComponent, SlipEvent>(OnSlipTriggered);
|
||||
|
||||
SubscribeLocalEvent<DeleteOnTriggerComponent, TriggerEvent>(HandleDeleteTrigger);
|
||||
SubscribeLocalEvent<ExplodeOnTriggerComponent, TriggerEvent>(HandleExplodeTrigger);
|
||||
@@ -122,6 +124,11 @@ namespace Content.Server.Explosion.EntitySystems
|
||||
Trigger(uid, args.Tripper);
|
||||
}
|
||||
|
||||
private void OnSlipTriggered(EntityUid uid, TriggerOnSlipComponent component, ref SlipEvent args)
|
||||
{
|
||||
Trigger(uid, args.Slipped);
|
||||
}
|
||||
|
||||
public bool Trigger(EntityUid trigger, EntityUid? user = null)
|
||||
{
|
||||
var triggerEvent = new TriggerEvent(trigger, user);
|
||||
|
||||
@@ -11,110 +11,115 @@ using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
|
||||
namespace Content.Shared.Slippery
|
||||
namespace Content.Shared.Slippery;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class SlipperySystem : EntitySystem
|
||||
{
|
||||
[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()
|
||||
{
|
||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
||||
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
base.Initialize();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SlipperyComponent, StepTriggerAttemptEvent>(HandleAttemptCollide);
|
||||
SubscribeLocalEvent<SlipperyComponent, StepTriggeredEvent>(HandleStepTrigger);
|
||||
SubscribeLocalEvent<NoSlipComponent, SlipAttemptEvent>(OnNoSlipAttempt);
|
||||
// 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));
|
||||
SubscribeLocalEvent<SlipperyComponent, ComponentGetState>(OnSlipperyGetState);
|
||||
SubscribeLocalEvent<SlipperyComponent, ComponentHandleState>(OnSlipperyHandleState);
|
||||
}
|
||||
|
||||
private void OnSlipperyHandleState(EntityUid uid, SlipperyComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not SlipperyComponentState state) return;
|
||||
|
||||
component.ParalyzeTime = state.ParalyzeTime;
|
||||
component.LaunchForwardsMultiplier = state.LaunchForwardsMultiplier;
|
||||
component.SlipSound = new SoundPathSpecifier(state.SlipSound);
|
||||
}
|
||||
|
||||
private void OnSlipperyGetState(EntityUid uid, SlipperyComponent component, ref ComponentGetState args)
|
||||
{
|
||||
args.State = new SlipperyComponentState(component.ParalyzeTime, component.LaunchForwardsMultiplier, _audio.GetSound(component.SlipSound));
|
||||
}
|
||||
|
||||
private void HandleStepTrigger(EntityUid uid, SlipperyComponent component, ref StepTriggeredEvent args)
|
||||
{
|
||||
TrySlip(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 bool CanSlip(EntityUid uid, EntityUid toSlip)
|
||||
{
|
||||
return !_container.IsEntityInContainer(uid)
|
||||
&& _statusEffectsSystem.CanApplyEffect(toSlip, "Stun"); //Should be KnockedDown instead?
|
||||
}
|
||||
|
||||
private void TrySlip(SlipperyComponent component, EntityUid other)
|
||||
{
|
||||
if (HasComp<KnockedDownComponent>(other))
|
||||
return;
|
||||
|
||||
var ev = new SlipAttemptEvent();
|
||||
RaiseLocalEvent(other, ev, false);
|
||||
if (ev.Cancelled)
|
||||
return;
|
||||
|
||||
if (TryComp(other, out PhysicsComponent? physics))
|
||||
_physics.SetLinearVelocity(other, physics.LinearVelocity * component.LaunchForwardsMultiplier, body: physics);
|
||||
|
||||
var playSound = !_statusEffectsSystem.HasStatusEffect(other, "KnockedDown");
|
||||
|
||||
_stunSystem.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(component.Owner):entity}");
|
||||
}
|
||||
|
||||
public void CopyConstruct(EntityUid destUid, SlipperyComponent srcSlip)
|
||||
{
|
||||
var destEvaporation = EntityManager.EnsureComponent<SlipperyComponent>(destUid);
|
||||
destEvaporation.SlipSound = srcSlip.SlipSound;
|
||||
destEvaporation.ParalyzeTime = srcSlip.ParalyzeTime;
|
||||
destEvaporation.LaunchForwardsMultiplier = srcSlip.LaunchForwardsMultiplier;
|
||||
}
|
||||
SubscribeLocalEvent<SlipperyComponent, StepTriggerAttemptEvent>(HandleAttemptCollide);
|
||||
SubscribeLocalEvent<SlipperyComponent, StepTriggeredEvent>(HandleStepTrigger);
|
||||
SubscribeLocalEvent<NoSlipComponent, SlipAttemptEvent>(OnNoSlipAttempt);
|
||||
// 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));
|
||||
SubscribeLocalEvent<SlipperyComponent, ComponentGetState>(OnSlipperyGetState);
|
||||
SubscribeLocalEvent<SlipperyComponent, ComponentHandleState>(OnSlipperyHandleState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised on an entity to determine if it can slip or not.
|
||||
/// </summary>
|
||||
public sealed class SlipAttemptEvent : CancellableEntityEventArgs, IInventoryRelayEvent
|
||||
private void OnSlipperyHandleState(EntityUid uid, SlipperyComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
public SlotFlags TargetSlots { get; } = SlotFlags.FEET;
|
||||
if (args.Current is not SlipperyComponentState state) return;
|
||||
|
||||
component.ParalyzeTime = state.ParalyzeTime;
|
||||
component.LaunchForwardsMultiplier = state.LaunchForwardsMultiplier;
|
||||
component.SlipSound = new SoundPathSpecifier(state.SlipSound);
|
||||
}
|
||||
|
||||
private void OnSlipperyGetState(EntityUid uid, SlipperyComponent component, ref ComponentGetState args)
|
||||
{
|
||||
args.State = new SlipperyComponentState(component.ParalyzeTime, component.LaunchForwardsMultiplier, _audio.GetSound(component.SlipSound));
|
||||
}
|
||||
|
||||
private void HandleStepTrigger(EntityUid uid, SlipperyComponent component, ref StepTriggeredEvent 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 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))
|
||||
return;
|
||||
|
||||
var attemptEv = new SlipAttemptEvent();
|
||||
RaiseLocalEvent(other, attemptEv);
|
||||
if (attemptEv.Cancelled)
|
||||
return;
|
||||
|
||||
var ev = new SlipEvent(other);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
if (TryComp(other, out PhysicsComponent? physics))
|
||||
_physics.SetLinearVelocity(other, physics.LinearVelocity * component.LaunchForwardsMultiplier, body: physics);
|
||||
|
||||
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}");
|
||||
}
|
||||
|
||||
public void CopyConstruct(EntityUid destUid, SlipperyComponent srcSlip)
|
||||
{
|
||||
var destEvaporation = EntityManager.EnsureComponent<SlipperyComponent>(destUid);
|
||||
destEvaporation.SlipSound = srcSlip.SlipSound;
|
||||
destEvaporation.ParalyzeTime = srcSlip.ParalyzeTime;
|
||||
destEvaporation.LaunchForwardsMultiplier = srcSlip.LaunchForwardsMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
|
||||
[ByRefEvent]
|
||||
public readonly record struct SlipEvent(EntityUid Slipped);
|
||||
|
||||
@@ -151,6 +151,9 @@ uplink-necronomicon-desc = An unholy book capable of summoning a demonic familia
|
||||
uplink-revolver-cap-gun-fake-name = Fake Cap Gun
|
||||
uplink-revolver-cap-gun-fake-desc = Fool your enemy! It can use both cap and magnum bullets. Comes loaded with magnum bullets.
|
||||
|
||||
uplink-banana-peel-explosive-name = Explosive Banana Peel
|
||||
uplink-banana-peel-explosive-desc = They will burst into laughter when they slip on it!
|
||||
|
||||
# Armor
|
||||
uplink-chameleon-name = Chameleon Kit
|
||||
uplink-chameleon-desc = A backpack full of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more!
|
||||
|
||||
@@ -594,6 +594,20 @@
|
||||
- Mime
|
||||
- Clown
|
||||
|
||||
- type: listing
|
||||
id: uplinkBananaPeelExplosive
|
||||
name: uplink-banana-peel-explosive-name
|
||||
description: uplink-banana-peel-explosive-desc
|
||||
productEntity: TrashBananaPeelExplosive
|
||||
cost:
|
||||
Telecrystal: 2
|
||||
categories:
|
||||
- UplinkJob
|
||||
conditions:
|
||||
- !type:BuyerJobCondition
|
||||
whitelist:
|
||||
- Clown
|
||||
|
||||
# Armor
|
||||
|
||||
- type: listing
|
||||
|
||||
@@ -216,6 +216,25 @@
|
||||
- type: Recyclable
|
||||
- type: SpaceGarbage
|
||||
|
||||
- type: entity
|
||||
name: banana peel
|
||||
suffix: Explosive
|
||||
parent: TrashBananaPeel
|
||||
id: TrashBananaPeelExplosive
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Specific/Hydroponics/banana.rsi
|
||||
state: primed
|
||||
- type: TriggerOnSlip
|
||||
- type: ExplodeOnTrigger
|
||||
- type: Explosive
|
||||
explosionType: Default
|
||||
maxIntensity: 2
|
||||
totalIntensity: 10
|
||||
canCreateVacuum: false
|
||||
- type: DeleteOnTrigger
|
||||
- type: AnimationPlayer
|
||||
|
||||
- type: entity
|
||||
name: carrot
|
||||
parent: FoodProduceBase
|
||||
|
||||
@@ -53,6 +53,15 @@
|
||||
},
|
||||
{
|
||||
"name": "stage-6"
|
||||
},
|
||||
{
|
||||
"name": "primed",
|
||||
"delays": [
|
||||
[
|
||||
4.9,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 940 B |
Reference in New Issue
Block a user