diff --git a/Content.Server/IgnitionSource/IgniteOnTriggerComponent.cs b/Content.Server/IgnitionSource/IgniteOnTriggerComponent.cs new file mode 100644 index 0000000000..2037b2ea49 --- /dev/null +++ b/Content.Server/IgnitionSource/IgniteOnTriggerComponent.cs @@ -0,0 +1,30 @@ +using Robust.Shared.Audio; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Server.IgnitionSource; + +/// +/// Ignites for a certain length of time when triggered. +/// Requires along with triggering components. +/// +[RegisterComponent, Access(typeof(IgniteOnTriggerSystem))] +public sealed partial class IgniteOnTriggerComponent : Component +{ + /// + /// Once ignited, the time it will unignite at. + /// + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)] + public TimeSpan IgnitedUntil = TimeSpan.Zero; + + /// + /// How long the ignition source is active for after triggering. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public TimeSpan IgnitedTime = TimeSpan.FromSeconds(0.5); + + /// + /// Sound to play when igniting. + /// + [DataField] + public SoundSpecifier IgniteSound = new SoundCollectionSpecifier("WelderOn"); +} diff --git a/Content.Server/IgnitionSource/IgniteOnTriggerSystem.cs b/Content.Server/IgnitionSource/IgniteOnTriggerSystem.cs new file mode 100644 index 0000000000..1e42588699 --- /dev/null +++ b/Content.Server/IgnitionSource/IgniteOnTriggerSystem.cs @@ -0,0 +1,55 @@ +using Content.Server.Explosion.EntitySystems; +using Content.Shared.Timing; +using Robust.Shared.Audio; +using Robust.Shared.Timing; + +namespace Content.Server.IgnitionSource; + +/// +/// Handles igniting when triggered and stopping ignition after the delay. +/// +public sealed class IgniteOnTriggerSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IgnitionSourceSystem _source = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly UseDelaySystem _useDelay = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnTrigger); + } + + public override void Update(float deltaTime) + { + base.Update(deltaTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var comp, out var source)) + { + if (!source.Ignited) + continue; + + if (_timing.CurTime < comp.IgnitedUntil) + continue; + + _source.SetIgnited(uid, false, source); + } + } + + private void OnTrigger(EntityUid uid, IgniteOnTriggerComponent comp, TriggerEvent args) + { + // prevent spamming sound and ignition + TryComp(uid, out var delay); + if (_useDelay.ActiveDelay(uid, delay)) + return; + + _source.SetIgnited(uid); + _audio.PlayPvs(comp.IgniteSound, uid); + + _useDelay.BeginDelay(uid, delay); + comp.IgnitedUntil = _timing.CurTime + comp.IgnitedTime; + } +} diff --git a/Content.Server/IgnitionSource/IgnitionSourceSystem.cs b/Content.Server/IgnitionSource/IgnitionSourceSystem.cs index 25a625180d..6984dbf56b 100644 --- a/Content.Server/IgnitionSource/IgnitionSourceSystem.cs +++ b/Content.Server/IgnitionSource/IgnitionSourceSystem.cs @@ -23,12 +23,18 @@ public sealed class IgnitionSourceSystem : EntitySystem private void OnIsHot(EntityUid uid, IgnitionSourceComponent component, IsHotEvent args) { - SetIgnited(uid,component,args.IsHot); + SetIgnited(uid, args.IsHot, component); } - private void SetIgnited(EntityUid uid, IgnitionSourceComponent component, bool newState) + /// + /// Simply sets the ignited field to the ignited param. + /// + public void SetIgnited(EntityUid uid, bool ignited = true, IgnitionSourceComponent? comp = null) { - component.Ignited = newState; + if (!Resolve(uid, ref comp)) + return; + + comp.Ignited = ignited; } public override void Update(float frameTime) diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/robotics.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/robotics.yml index 94e46d371a..06a7398a23 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/robotics.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/robotics.yml @@ -5,6 +5,7 @@ Flash: 4 ProximitySensor: 3 RemoteSignaller: 3 + Igniter: 3 # its more ordnance but yeah HandheldHealthAnalyzer: 3 Scalpel: 2 SawElectric: 2 diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/vendomat.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/vendomat.yml index 2ef1ad62fe..da7e30fd76 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/vendomat.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/vendomat.yml @@ -2,10 +2,11 @@ id: VendomatInventory startingInventory: RemoteSignaller: 1 + Igniter: 2 Wirecutter: 1 CableApcStack: 2 FlashlightLantern: 2 PowerCellSmallPrinted: 3 MatterBinStockPart: 4 CapacitorStockPart: 4 - MicroManipulatorStockPart: 4 \ No newline at end of file + MicroManipulatorStockPart: 4 diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/igniter.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/igniter.yml new file mode 100644 index 0000000000..24843f608a --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/igniter.yml @@ -0,0 +1,25 @@ +- type: entity + parent: BaseItem + id: Igniter + name: igniter + description: Creates a spark when activated by a signal. + components: + - type: Sprite + sprite: Objects/Devices/igniter.rsi + state: icon + - type: IgnitionSource + temperature: 800 + - type: IgniteOnTrigger + - type: TriggerOnSignal + - type: DeviceNetwork + deviceNetId: Wireless + receiveFrequencyId: BasicDevice + - type: WirelessNetworkConnection + range: 200 + - type: DeviceLinkSink + ports: + - Trigger + - type: UseDelay # prevent sound spam + - type: Tag + tags: + - Igniter diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index b1ea5f9e3d..045ee40556 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -243,6 +243,7 @@ - Signaller - SignalTrigger - VoiceTrigger + - Igniter - PowerCellMedium - PowerCellHigh - WeaponPistolCHIMP diff --git a/Resources/Prototypes/Recipes/Lathes/devices.yml b/Resources/Prototypes/Recipes/Lathes/devices.yml index ed73dc1b64..01178b386c 100644 --- a/Resources/Prototypes/Recipes/Lathes/devices.yml +++ b/Resources/Prototypes/Recipes/Lathes/devices.yml @@ -22,6 +22,15 @@ Steel: 300 Plastic: 200 +- type: latheRecipe + id: Igniter + result: Igniter + completetime: 2 + materials: + Steel: 300 + Plastic: 100 + Glass: 100 + - type: latheRecipe id: ChemicalPayload result: ChemicalPayload diff --git a/Resources/Prototypes/Research/arsenal.yml b/Resources/Prototypes/Research/arsenal.yml index cfd0faecd3..75107a1b5e 100644 --- a/Resources/Prototypes/Research/arsenal.yml +++ b/Resources/Prototypes/Research/arsenal.yml @@ -51,6 +51,7 @@ - TimerTrigger - FlashPayload - ExplosivePayload + - Igniter - type: technology id: WeaponizedLaserManipulation diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index ccd042dd00..d7397d483c 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -599,6 +599,9 @@ - type: Tag id: Hotsauce +- type: Tag + id: Igniter + - type: Tag #Drop this innate tool instead of deleting it. id: InnateDontDelete diff --git a/Resources/Textures/Objects/Devices/igniter.rsi/icon.png b/Resources/Textures/Objects/Devices/igniter.rsi/icon.png new file mode 100644 index 0000000000..4074df0087 Binary files /dev/null and b/Resources/Textures/Objects/Devices/igniter.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Devices/igniter.rsi/meta.json b/Resources/Textures/Objects/Devices/igniter.rsi/meta.json new file mode 100644 index 0000000000..81a3a32786 --- /dev/null +++ b/Resources/Textures/Objects/Devices/igniter.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/blob/9a401d19045574f3ea7f2cf3feebf65989903ccc/icons/obj/assemblies/new_assemblies.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + } + ] +}