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.Implants.Components;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Payload.Components;
|
using Content.Shared.Payload.Components;
|
||||||
|
using Content.Shared.Slippery;
|
||||||
using Content.Shared.StepTrigger.Systems;
|
using Content.Shared.StepTrigger.Systems;
|
||||||
using Content.Shared.Trigger;
|
using Content.Shared.Trigger;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@@ -61,6 +62,7 @@ namespace Content.Server.Explosion.EntitySystems
|
|||||||
SubscribeLocalEvent<TriggerOnActivateComponent, ActivateInWorldEvent>(OnActivate);
|
SubscribeLocalEvent<TriggerOnActivateComponent, ActivateInWorldEvent>(OnActivate);
|
||||||
SubscribeLocalEvent<TriggerImplantActionComponent, ActivateImplantEvent>(OnImplantTrigger);
|
SubscribeLocalEvent<TriggerImplantActionComponent, ActivateImplantEvent>(OnImplantTrigger);
|
||||||
SubscribeLocalEvent<TriggerOnStepTriggerComponent, StepTriggeredEvent>(OnStepTriggered);
|
SubscribeLocalEvent<TriggerOnStepTriggerComponent, StepTriggeredEvent>(OnStepTriggered);
|
||||||
|
SubscribeLocalEvent<TriggerOnSlipComponent, SlipEvent>(OnSlipTriggered);
|
||||||
|
|
||||||
SubscribeLocalEvent<DeleteOnTriggerComponent, TriggerEvent>(HandleDeleteTrigger);
|
SubscribeLocalEvent<DeleteOnTriggerComponent, TriggerEvent>(HandleDeleteTrigger);
|
||||||
SubscribeLocalEvent<ExplodeOnTriggerComponent, TriggerEvent>(HandleExplodeTrigger);
|
SubscribeLocalEvent<ExplodeOnTriggerComponent, TriggerEvent>(HandleExplodeTrigger);
|
||||||
@@ -122,6 +124,11 @@ namespace Content.Server.Explosion.EntitySystems
|
|||||||
Trigger(uid, args.Tripper);
|
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)
|
public bool Trigger(EntityUid trigger, EntityUid? user = null)
|
||||||
{
|
{
|
||||||
var triggerEvent = new TriggerEvent(trigger, user);
|
var triggerEvent = new TriggerEvent(trigger, user);
|
||||||
|
|||||||
@@ -11,110 +11,115 @@ using Robust.Shared.GameStates;
|
|||||||
using Robust.Shared.Physics.Components;
|
using Robust.Shared.Physics.Components;
|
||||||
using Robust.Shared.Physics.Systems;
|
using Robust.Shared.Physics.Systems;
|
||||||
|
|
||||||
namespace Content.Shared.Slippery
|
namespace Content.Shared.Slippery;
|
||||||
|
|
||||||
|
[UsedImplicitly]
|
||||||
|
public sealed class SlipperySystem : EntitySystem
|
||||||
{
|
{
|
||||||
[UsedImplicitly]
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||||
public sealed class SlipperySystem : EntitySystem
|
[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!;
|
base.Initialize();
|
||||||
[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!;
|
|
||||||
|
|
||||||
public override void Initialize()
|
SubscribeLocalEvent<SlipperyComponent, StepTriggerAttemptEvent>(HandleAttemptCollide);
|
||||||
{
|
SubscribeLocalEvent<SlipperyComponent, StepTriggeredEvent>(HandleStepTrigger);
|
||||||
base.Initialize();
|
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<SlipperyComponent, StepTriggerAttemptEvent>(HandleAttemptCollide);
|
SubscribeLocalEvent<NoSlipComponent, InventoryRelayedEvent<SlipAttemptEvent>>((e, c, ev) => OnNoSlipAttempt(e, c, ev.Args));
|
||||||
SubscribeLocalEvent<SlipperyComponent, StepTriggeredEvent>(HandleStepTrigger);
|
SubscribeLocalEvent<SlipperyComponent, ComponentGetState>(OnSlipperyGetState);
|
||||||
SubscribeLocalEvent<NoSlipComponent, SlipAttemptEvent>(OnNoSlipAttempt);
|
SubscribeLocalEvent<SlipperyComponent, ComponentHandleState>(OnSlipperyHandleState);
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void OnSlipperyHandleState(EntityUid uid, SlipperyComponent component, ref ComponentHandleState args)
|
||||||
/// 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;
|
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-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-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
|
# Armor
|
||||||
uplink-chameleon-name = Chameleon Kit
|
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!
|
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
|
- Mime
|
||||||
- Clown
|
- 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
|
# Armor
|
||||||
|
|
||||||
- type: listing
|
- type: listing
|
||||||
|
|||||||
@@ -216,6 +216,25 @@
|
|||||||
- type: Recyclable
|
- type: Recyclable
|
||||||
- type: SpaceGarbage
|
- 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
|
- type: entity
|
||||||
name: carrot
|
name: carrot
|
||||||
parent: FoodProduceBase
|
parent: FoodProduceBase
|
||||||
|
|||||||
@@ -53,6 +53,15 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "stage-6"
|
"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