diff --git a/Content.Server/Explosion/Components/DeleteOnTriggerComponent.cs b/Content.Server/Explosion/Components/DeleteOnTriggerComponent.cs deleted file mode 100644 index 023a0894bd..0000000000 --- a/Content.Server/Explosion/Components/DeleteOnTriggerComponent.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Content.Server.Explosion.EntitySystems; - -namespace Content.Server.Explosion.Components -{ - /// - /// Will delete the attached entity upon a . - /// - [RegisterComponent] - public sealed class DeleteOnTriggerComponent : Component - { - } -} diff --git a/Content.Server/Explosion/Components/ExplodeOnTriggerComponent.cs b/Content.Server/Explosion/Components/ExplodeOnTriggerComponent.cs deleted file mode 100644 index 0c487e1e47..0000000000 --- a/Content.Server/Explosion/Components/ExplodeOnTriggerComponent.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Content.Server.Explosion.Components -{ - /// - /// Explode using the entity's if Triggered. - /// - [RegisterComponent] - public sealed class ExplodeOnTriggerComponent : Component - { - } -} diff --git a/Content.Server/Explosion/Components/OnTrigger/AnchorOnTriggerComponent.cs b/Content.Server/Explosion/Components/OnTrigger/AnchorOnTriggerComponent.cs new file mode 100644 index 0000000000..41c58c171f --- /dev/null +++ b/Content.Server/Explosion/Components/OnTrigger/AnchorOnTriggerComponent.cs @@ -0,0 +1,13 @@ +using Content.Server.Explosion.EntitySystems; + +namespace Content.Server.Explosion.Components; + +/// +/// Will anchor the attached entity upon a . +/// +[RegisterComponent] +public sealed class AnchorOnTriggerComponent : Component +{ + [DataField("removeOnTrigger")] + public bool RemoveOnTrigger = true; +} diff --git a/Content.Server/Explosion/Components/OnTrigger/DeleteOnTriggerComponent.cs b/Content.Server/Explosion/Components/OnTrigger/DeleteOnTriggerComponent.cs new file mode 100644 index 0000000000..c0f19d9048 --- /dev/null +++ b/Content.Server/Explosion/Components/OnTrigger/DeleteOnTriggerComponent.cs @@ -0,0 +1,11 @@ +using Content.Server.Explosion.EntitySystems; + +namespace Content.Server.Explosion.Components; + +/// +/// Will delete the attached entity upon a . +/// +[RegisterComponent] +public sealed class DeleteOnTriggerComponent : Component +{ +} diff --git a/Content.Server/Explosion/Components/OnTrigger/ExplodeOnTriggerComponent.cs b/Content.Server/Explosion/Components/OnTrigger/ExplodeOnTriggerComponent.cs new file mode 100644 index 0000000000..a6f2a324ae --- /dev/null +++ b/Content.Server/Explosion/Components/OnTrigger/ExplodeOnTriggerComponent.cs @@ -0,0 +1,9 @@ +namespace Content.Server.Explosion.Components; + +/// +/// Explode using the entity's if Triggered. +/// +[RegisterComponent] +public sealed class ExplodeOnTriggerComponent : Component +{ +} diff --git a/Content.Server/Explosion/Components/GibOnTriggerComponent.cs b/Content.Server/Explosion/Components/OnTrigger/GibOnTriggerComponent.cs similarity index 89% rename from Content.Server/Explosion/Components/GibOnTriggerComponent.cs rename to Content.Server/Explosion/Components/OnTrigger/GibOnTriggerComponent.cs index 7f0b22faa6..554b5b25d0 100644 --- a/Content.Server/Explosion/Components/GibOnTriggerComponent.cs +++ b/Content.Server/Explosion/Components/OnTrigger/GibOnTriggerComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.Explosion.Components; +namespace Content.Server.Explosion.Components; /// /// Gibs on trigger, self explanatory. diff --git a/Content.Server/Explosion/Components/OnTrigger/SoundOnTriggerComponent.cs b/Content.Server/Explosion/Components/OnTrigger/SoundOnTriggerComponent.cs new file mode 100644 index 0000000000..0df3d58731 --- /dev/null +++ b/Content.Server/Explosion/Components/OnTrigger/SoundOnTriggerComponent.cs @@ -0,0 +1,17 @@ +using Content.Server.Explosion.EntitySystems; +using Robust.Shared.Audio; + +namespace Content.Server.Explosion.Components; + +/// +/// Will play sound from the attached entity upon a . +/// +[RegisterComponent] +public sealed class SoundOnTriggerComponent : Component +{ + [DataField("removeOnTrigger")] + public bool RemoveOnTrigger = true; + + [DataField("sound")] + public SoundSpecifier? Sound = new SoundPathSpecifier("/Audio/Effects/Grenades/supermatter_start.ogg"); +} diff --git a/Content.Server/Explosion/Components/OnTrigger/TwoStageTriggerComponent.cs b/Content.Server/Explosion/Components/OnTrigger/TwoStageTriggerComponent.cs new file mode 100644 index 0000000000..90cc5e3e3b --- /dev/null +++ b/Content.Server/Explosion/Components/OnTrigger/TwoStageTriggerComponent.cs @@ -0,0 +1,30 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Server.Explosion.Components.OnTrigger; + +/// +/// After being triggered applies the specified components and runs triggers again. +/// +[RegisterComponent] +public sealed class TwoStageTriggerComponent : Component +{ + /// + /// How long it takes for the second stage to be triggered. + /// + [ViewVariables(VVAccess.ReadWrite)] + [DataField("triggerDelay")] + public TimeSpan TriggerDelay = TimeSpan.FromSeconds(10); + + /// + /// This list of components that will be added for the second trigger. + /// + [ViewVariables(VVAccess.ReadOnly)] + [DataField("components", required: true)] + public ComponentRegistry SecondStageComponents = new(); + + [DataField("nextTriggerTime", customTypeSerializer: typeof(TimeOffsetSerializer))] + public TimeSpan? NextTriggerTime; + + [ViewVariables(VVAccess.ReadWrite), DataField("triggered")] public bool Triggered = false; +} diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs index ee47c016e5..57ece48b3b 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs @@ -58,6 +58,7 @@ namespace Content.Server.Explosion.EntitySystems [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly BodySystem _body = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly RadioSystem _radioSystem = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; @@ -84,9 +85,32 @@ namespace Content.Server.Explosion.EntitySystems SubscribeLocalEvent(HandleExplodeTrigger); SubscribeLocalEvent(HandleFlashTrigger); SubscribeLocalEvent(HandleGibTrigger); + + SubscribeLocalEvent(OnAnchorTrigger); + SubscribeLocalEvent(OnSoundTrigger); SubscribeLocalEvent(HandleRattleTrigger); } + private void OnSoundTrigger(EntityUid uid, SoundOnTriggerComponent component, TriggerEvent args) + { + _audio.PlayPvs(component.Sound, uid); + if (component.RemoveOnTrigger) + RemCompDeferred(uid); + } + + private void OnAnchorTrigger(EntityUid uid, AnchorOnTriggerComponent component, TriggerEvent args) + { + var xform = Transform(uid); + + if (xform.Anchored) + return; + + _transformSystem.AnchorEntity(uid, xform); + + if(component.RemoveOnTrigger) + RemCompDeferred(uid); + } + private void OnSpawnTrigger(EntityUid uid, SpawnOnTriggerComponent component, TriggerEvent args) { var xform = Transform(uid); @@ -105,14 +129,12 @@ namespace Content.Server.Explosion.EntitySystems args.Handled = true; } - #region Flash 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); args.Handled = true; } - #endregion private void HandleDeleteTrigger(EntityUid uid, DeleteOnTriggerComponent component, TriggerEvent args) { diff --git a/Content.Server/Explosion/EntitySystems/TwoStageTriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TwoStageTriggerSystem.cs new file mode 100644 index 0000000000..03837236b4 --- /dev/null +++ b/Content.Server/Explosion/EntitySystems/TwoStageTriggerSystem.cs @@ -0,0 +1,71 @@ +using Robust.Shared.Timing; +using Robust.Shared.Serialization.Manager; +using Content.Server.Explosion.Components.OnTrigger; + +namespace Content.Server.Explosion.EntitySystems; + +public sealed class TwoStageTriggerSystem : EntitySystem +{ + [Dependency] private readonly IComponentFactory _factory = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly ISerializationManager _serializationManager = default!; + [Dependency] private readonly TriggerSystem _triggerSystem = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnTriggerUnpaused); + SubscribeLocalEvent(OnTrigger); + } + + private void OnTriggerUnpaused(EntityUid uid, TwoStageTriggerComponent component, ref EntityUnpausedEvent args) + { + if (component.NextTriggerTime != null) + component.NextTriggerTime = component.NextTriggerTime.Value + args.PausedTime; + } + + private void OnTrigger(EntityUid uid, TwoStageTriggerComponent component, TriggerEvent args) + { + if (component.Triggered) + return; + + component.Triggered = true; + component.NextTriggerTime = _timing.CurTime + component.TriggerDelay; + } + + public void LoadComponents(EntityUid uid, TwoStageTriggerComponent component) + { + foreach (var (name, entry) in component.SecondStageComponents) + { + var comp = (Component) _factory.GetComponent(name); + var temp = (object) comp; + + if (EntityManager.TryGetComponent(uid, entry.Component.GetType(), out var c)) + RemComp(uid, c); + + comp.Owner = uid; + _serializationManager.CopyTo(entry.Component, ref temp); + EntityManager.AddComponent(uid, comp); + } + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var enumerator = EntityQueryEnumerator(); + + while (enumerator.MoveNext(out var uid, out var component)) + { + if (component.NextTriggerTime == null) + continue; + + if (_timing.CurTime < component.NextTriggerTime) + continue; + + component.NextTriggerTime = null; + LoadComponents(uid, component); + _triggerSystem.Trigger(uid); + } + } +} diff --git a/Resources/Audio/Effects/Grenades/Supermatter/licenses.yml b/Resources/Audio/Effects/Grenades/Supermatter/licenses.yml new file mode 100644 index 0000000000..a4b80f3830 --- /dev/null +++ b/Resources/Audio/Effects/Grenades/Supermatter/licenses.yml @@ -0,0 +1,9 @@ +- files: + - supermatter_end.ogg + - supermatter_loop.ogg + - supermatter_start.ogg + - whitehole_loop.ogg + - whitehole_start.ogg + - smbeep.ogg + license: "CC-BY-SA-3.0" + copyright: "Made by AlexMorgan3817 https://soundcloud.com/alexmorgan3817" diff --git a/Resources/Audio/Effects/Grenades/Supermatter/smbeep.ogg b/Resources/Audio/Effects/Grenades/Supermatter/smbeep.ogg new file mode 100644 index 0000000000..eecad35896 Binary files /dev/null and b/Resources/Audio/Effects/Grenades/Supermatter/smbeep.ogg differ diff --git a/Resources/Audio/Effects/Grenades/Supermatter/supermatter_end.ogg b/Resources/Audio/Effects/Grenades/Supermatter/supermatter_end.ogg new file mode 100644 index 0000000000..1f67de0855 Binary files /dev/null and b/Resources/Audio/Effects/Grenades/Supermatter/supermatter_end.ogg differ diff --git a/Resources/Audio/Effects/Grenades/Supermatter/supermatter_loop.ogg b/Resources/Audio/Effects/Grenades/Supermatter/supermatter_loop.ogg new file mode 100644 index 0000000000..d6a0939fd0 Binary files /dev/null and b/Resources/Audio/Effects/Grenades/Supermatter/supermatter_loop.ogg differ diff --git a/Resources/Audio/Effects/Grenades/Supermatter/supermatter_start.ogg b/Resources/Audio/Effects/Grenades/Supermatter/supermatter_start.ogg new file mode 100644 index 0000000000..00e2c3b029 Binary files /dev/null and b/Resources/Audio/Effects/Grenades/Supermatter/supermatter_start.ogg differ diff --git a/Resources/Audio/Effects/Grenades/Supermatter/whitehole_loop.ogg b/Resources/Audio/Effects/Grenades/Supermatter/whitehole_loop.ogg new file mode 100644 index 0000000000..be0af4168f Binary files /dev/null and b/Resources/Audio/Effects/Grenades/Supermatter/whitehole_loop.ogg differ diff --git a/Resources/Audio/Effects/Grenades/Supermatter/whitehole_start.ogg b/Resources/Audio/Effects/Grenades/Supermatter/whitehole_start.ogg new file mode 100644 index 0000000000..9068685b4f Binary files /dev/null and b/Resources/Audio/Effects/Grenades/Supermatter/whitehole_start.ogg differ diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl index f91dc88fe2..9005f70a24 100644 --- a/Resources/Locale/en-US/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/store/uplink-catalog.ftl @@ -36,6 +36,12 @@ uplink-flash-grenade-desc = A standard-issue flashbang, capable of blinding and uplink-mini-bomb-name = Minibomb uplink-mini-bomb-desc = A low-yield, high-impact precision sabotage explosive with a five-second long fuse. Perfect for quickly destroying a machine, dead body, or whatever else needs to go. +uplink-supermatter-grenade-name = Supermatter Grenade +uplink-supermatter-grenade-desc = Grenade that simulates delamination of a suppermatter engine, generates powerful gravity well. Explosion comparable to a Mini Bomb. + +uplink-whitehole-grenade-name = Whitehole Grenade +uplink-whitehole-grenade-desc = Grenade that are repulses everything around for about 10 seconds. Very useful in small rooms and for chasing someone. + uplink-penguin-grenade-name = Grenade Penguin uplink-penguin-grenade-desc = A small, highly-aggressive penguin with a grenade strapped around its neck. Harvested by the Syndicate from icy shit-hole planets. diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 53e9704c1d..50a86ab80b 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -148,6 +148,26 @@ categories: - UplinkExplosives +- type: listing + id: UplinkSupermatterGrenade + name: uplink-supermatter-grenade-name + description: uplink-supermatter-grenade-desc + productEntity: SupermatterGrenade + cost: + Telecrystal: 6 + categories: + - UplinkExplosives + +- type: listing + id: UplinkWhiteholeGrenade + name: uplink-whitehole-grenade-name + description: uplink-whitehole-grenade-desc + productEntity: WhiteholeGrenade + cost: + Telecrystal: 3 + categories: + - UplinkExplosives + - type: listing id: UplinkGrenadePenguin name: uplink-penguin-grenade-name diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml index 607260f3f5..0f2aa3b687 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml @@ -112,6 +112,117 @@ params: volume: 12 +- type: entity + name: supermatter grenade + description: Grenade that simulates delamination of the supermatter engine, pulling things in a heap and exploding after some time. + parent: GrenadeBase + id: SupermatterGrenade + components: + - type: Sprite + sprite: Objects/Weapons/Grenades/supermattergrenade.rsi + - type: OnUseTimerTrigger + delay: 3 + beepInterval: 0.46 + beepSound: + path: /Audio/Effects/Grenades/Supermatter/smbeep.ogg + params: + volume: -5 + - type: TimerTriggerVisuals + primingSound: + path: /Audio/Effects/Grenades/Supermatter/smbeep.ogg + params: + volume: -5 + - type: Explosive + explosionType: Default + totalIntensity: 200 + intensitySlope: 30 + maxIntensity: 120 + - type: SoundOnTrigger + removeOnTrigger: true + sound: + path: /Audio/Effects/Grenades/Supermatter/supermatter_start.ogg + volume: 5 + - type: AnchorOnTrigger + removeOnTrigger: true + - type: TwoStageTrigger + triggerDelay: 10 + components: + - type: AmbientSound + enabled: true + volume: -5 + range: 14 + sound: + path: /Audio/Effects/Grenades/Supermatter/supermatter_loop.ogg + - type: GravityWell + maxRange: 8 + baseRadialAcceleration: 145 + baseTangentialAcceleration: 5 + gravPulsePeriod: 0.01 + - type: SingularityDistortion + intensity: 150 + falloffPower: 1.5 + - type: PointLight + enabled: true + color: "#ffaa44" + energy: 8 + radius: 6 + softness: 1 + offset: "0, 0" + - type: SoundOnTrigger + sound: + path: /Audio/Effects/Grenades/Supermatter/supermatter_end.ogg + params: + volume: 5 + - type: ExplodeOnTrigger + +- type: entity + name: whitehole grenade + description: Grenade that repulses everything around for some time. + parent: SupermatterGrenade + id: WhiteholeGrenade + components: + - type: Sprite + sprite: Objects/Weapons/Grenades/whiteholegrenade.rsi + - type: OnUseTimerTrigger + delay: 3 + beepInterval: 0.69 + - type: SoundOnTrigger + removeOnTrigger: true + sound: + path: /Audio/Effects/Grenades/Supermatter/whitehole_start.ogg + volume: 5 + - type: AmbientSound + enabled: false + volume: -5 + range: 14 + sound: + path: /Audio/Effects/Grenades/Supermatter/whitehole_loop.ogg + - type: TwoStageTrigger + triggerDelay: 10 + components: + - type: GravityWell + maxRange: 10 + baseRadialAcceleration: -180 + baseTangentialAcceleration: -5 + gravPulsePeriod: 0.01 + - type: SingularityDistortion + intensity: -200 + falloffPower: 1.5 + - type: PointLight + enabled: true + color: "#ffffff" + energy: 8 + radius: 6 + softness: 1 + offset: "0, 0" + - type: SoundOnTrigger + sound: + path: /Audio/Effects/Grenades/Supermatter/supermatter_end.ogg + params: + volume: 5 + - type: DeleteOnTrigger + + - type: entity name: the nuclear option description: Please don't throw it, think of the children. diff --git a/Resources/Textures/Objects/Weapons/Grenades/supermattergrenade.rsi/icon.png b/Resources/Textures/Objects/Weapons/Grenades/supermattergrenade.rsi/icon.png new file mode 100644 index 0000000000..19c9ce9994 Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Grenades/supermattergrenade.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Weapons/Grenades/supermattergrenade.rsi/meta.json b/Resources/Textures/Objects/Weapons/Grenades/supermattergrenade.rsi/meta.json new file mode 100644 index 0000000000..2be285f94e --- /dev/null +++ b/Resources/Textures/Objects/Weapons/Grenades/supermattergrenade.rsi/meta.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Changed sprites taken from infinity baystation 12, https://github.com/infinitystation/Baystation12/blob/073f678cdce92edb8fcd55f9ffc9f0523bf31506/icons/obj/grenade.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "primed", + "delays": + [ + [ + 0.1, + 0.1 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Weapons/Grenades/supermattergrenade.rsi/primed.png b/Resources/Textures/Objects/Weapons/Grenades/supermattergrenade.rsi/primed.png new file mode 100644 index 0000000000..ca9e5a6402 Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Grenades/supermattergrenade.rsi/primed.png differ diff --git a/Resources/Textures/Objects/Weapons/Grenades/whiteholegrenade.rsi/icon.png b/Resources/Textures/Objects/Weapons/Grenades/whiteholegrenade.rsi/icon.png new file mode 100644 index 0000000000..89f6491df0 Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Grenades/whiteholegrenade.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Weapons/Grenades/whiteholegrenade.rsi/meta.json b/Resources/Textures/Objects/Weapons/Grenades/whiteholegrenade.rsi/meta.json new file mode 100644 index 0000000000..2be285f94e --- /dev/null +++ b/Resources/Textures/Objects/Weapons/Grenades/whiteholegrenade.rsi/meta.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Changed sprites taken from infinity baystation 12, https://github.com/infinitystation/Baystation12/blob/073f678cdce92edb8fcd55f9ffc9f0523bf31506/icons/obj/grenade.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "primed", + "delays": + [ + [ + 0.1, + 0.1 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Weapons/Grenades/whiteholegrenade.rsi/primed.png b/Resources/Textures/Objects/Weapons/Grenades/whiteholegrenade.rsi/primed.png new file mode 100644 index 0000000000..04c7aca027 Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Grenades/whiteholegrenade.rsi/primed.png differ