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"
+ }
+ ]
+}