diff --git a/Content.Server/ADT/NightVision/NightVisionSystem.cs b/Content.Server/ADT/NightVision/NightVisionSystem.cs
new file mode 100644
index 00000000000..5f6a3602a1c
--- /dev/null
+++ b/Content.Server/ADT/NightVision/NightVisionSystem.cs
@@ -0,0 +1,7 @@
+// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995
+
+using Content.Shared.ADT.NightVision;
+
+namespace Content.Server.ADT.NightVision;
+
+public sealed class NightVisionSystem : SharedNightVisionSystem;
diff --git a/Content.Shared/ADT/NightVision/ADTNightVisionVisibleComponent.cs b/Content.Shared/ADT/NightVision/ADTNightVisionVisibleComponent.cs
new file mode 100644
index 00000000000..6c5a997453e
--- /dev/null
+++ b/Content.Shared/ADT/NightVision/ADTNightVisionVisibleComponent.cs
@@ -0,0 +1,25 @@
+// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995
+
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.ADT.NightVision;
+
+///
+/// For rendering sprites on top of FOV when the user has a .
+///
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class NightVisionVisibleComponent : Component
+{
+ ///
+ /// Priority for rendering order.
+ /// Rendered from lowest to highest, which means higher numbers will be rendered above lower numbers.
+ ///
+ [DataField, AutoNetworkedField]
+ public int Priority = 0;
+
+ ///
+ /// Transparency of the rendered sprite.
+ ///
+ [DataField, AutoNetworkedField]
+ public float? Transparency = null;
+}
diff --git a/Content.Shared/ADT/NightVision/NightVisionComponent.cs b/Content.Shared/ADT/NightVision/NightVisionComponent.cs
new file mode 100644
index 00000000000..b0033594900
--- /dev/null
+++ b/Content.Shared/ADT/NightVision/NightVisionComponent.cs
@@ -0,0 +1,38 @@
+// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995
+
+using Content.Shared.Alert;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.ADT.NightVision;
+
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
+[Access(typeof(SharedNightVisionSystem))]
+public sealed partial class NightVisionComponent : Component
+{
+ [DataField]
+ public ProtoId? Alert;
+
+ [DataField, AutoNetworkedField]
+ public NightVisionState State = NightVisionState.Full;
+
+ [DataField, AutoNetworkedField]
+ public bool Overlay;
+
+ [DataField, AutoNetworkedField]
+ public bool Innate;
+
+ [DataField, AutoNetworkedField]
+ public bool SeeThroughContainers;
+}
+
+[Serializable, NetSerializable]
+public enum NightVisionState
+{
+ Off,
+ Half,
+ Full
+}
+
+public sealed partial class ToggleNightVision : BaseAlertEvent;
diff --git a/Content.Shared/ADT/NightVision/NightVisionItemComponent.cs b/Content.Shared/ADT/NightVision/NightVisionItemComponent.cs
new file mode 100644
index 00000000000..887d94c0a5a
--- /dev/null
+++ b/Content.Shared/ADT/NightVision/NightVisionItemComponent.cs
@@ -0,0 +1,28 @@
+// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995
+
+using Content.Shared.Inventory;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.ADT.NightVision;
+
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(SharedNightVisionSystem))]
+public sealed partial class NightVisionItemComponent : Component
+{
+ [DataField, AutoNetworkedField]
+ public EntProtoId ActionId = "ActionToggleNinjaNightVision";
+
+ [DataField, AutoNetworkedField]
+ public EntityUid? Action;
+
+ [DataField, AutoNetworkedField]
+ public EntityUid? User;
+
+ [DataField, AutoNetworkedField]
+ public bool Toggleable = true;
+
+ // Only allows for a single slotflag right now because some code uses strings and some code uses enums to determine slots :(
+ [DataField, AutoNetworkedField]
+ public SlotFlags SlotFlags { get; set; } = SlotFlags.EYES;
+}
diff --git a/Content.Shared/ADT/NightVision/NightVisionItemVisuals.cs b/Content.Shared/ADT/NightVision/NightVisionItemVisuals.cs
new file mode 100644
index 00000000000..a0602cd1910
--- /dev/null
+++ b/Content.Shared/ADT/NightVision/NightVisionItemVisuals.cs
@@ -0,0 +1,11 @@
+// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995
+
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.ADT.NightVision;
+
+[Serializable, NetSerializable]
+public enum NightVisionItemVisuals
+{
+ Active,
+}
diff --git a/Content.Shared/ADT/NightVision/SharedNightVisionSystem.cs b/Content.Shared/ADT/NightVision/SharedNightVisionSystem.cs
new file mode 100644
index 00000000000..85a7bff3663
--- /dev/null
+++ b/Content.Shared/ADT/NightVision/SharedNightVisionSystem.cs
@@ -0,0 +1,201 @@
+// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995
+
+using Content.Shared.Actions;
+using Content.Shared.Alert;
+using Content.Shared.Inventory.Events;
+using Content.Shared.Rounding;
+using Content.Shared.Toggleable;
+using Robust.Shared.Timing;
+
+namespace Content.Shared.ADT.NightVision;
+
+public abstract class SharedNightVisionSystem : EntitySystem
+{
+ [Dependency] private readonly SharedActionsSystem _actions = default!;
+ [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+ [Dependency] private readonly AlertsSystem _alerts = default!;
+ [Dependency] private readonly IGameTiming _timing = default!;
+
+ public override void Initialize()
+ {
+ SubscribeLocalEvent(OnNightVisionStartup);
+ SubscribeLocalEvent(OnNightVisionMapInit);
+ SubscribeLocalEvent(OnNightVisionAfterHandle);
+ SubscribeLocalEvent(OnNightVisionRemove);
+
+ SubscribeLocalEvent(OnNightVisionItemGetActions);
+ SubscribeLocalEvent(OnNightVisionItemToggle);
+ SubscribeLocalEvent(OnNightVisionItemGotEquipped);
+ SubscribeLocalEvent(OnNightVisionItemGotUnequipped);
+ SubscribeLocalEvent(OnNightVisionItemActionRemoved);
+ SubscribeLocalEvent(OnNightVisionItemRemove);
+ SubscribeLocalEvent(OnNightVisionItemTerminating);
+ }
+
+ private void OnNightVisionStartup(Entity ent, ref ComponentStartup args)
+ {
+ NightVisionChanged(ent);
+ }
+
+ private void OnNightVisionAfterHandle(Entity ent, ref AfterAutoHandleStateEvent args)
+ {
+ NightVisionChanged(ent);
+ }
+
+ private void OnNightVisionMapInit(Entity ent, ref MapInitEvent args)
+ {
+ UpdateAlert(ent);
+ }
+
+ private void OnNightVisionRemove(Entity ent, ref ComponentRemove args)
+ {
+ if (ent.Comp.Alert is { } alert)
+ _alerts.ClearAlert(ent, alert);
+
+ NightVisionRemoved(ent);
+ }
+
+ private void OnNightVisionItemGetActions(Entity ent, ref GetItemActionsEvent args)
+ {
+ if (args.InHands || !ent.Comp.Toggleable)
+ return;
+
+ if (ent.Comp.SlotFlags != args.SlotFlags)
+ return;
+
+ args.AddAction(ref ent.Comp.Action, ent.Comp.ActionId);
+ }
+
+ private void OnNightVisionItemToggle(Entity ent, ref ToggleActionEvent args)
+ {
+ if (args.Handled)
+ return;
+
+ args.Handled = true;
+ ToggleNightVisionItem(ent, args.Performer);
+ }
+
+ private void OnNightVisionItemGotEquipped(Entity ent, ref GotEquippedEvent args)
+ {
+ if (ent.Comp.SlotFlags != args.SlotFlags)
+ return;
+
+ EnableNightVisionItem(ent, args.Equipee);
+ }
+
+ private void OnNightVisionItemGotUnequipped(Entity ent, ref GotUnequippedEvent args)
+ {
+ if (ent.Comp.SlotFlags != args.SlotFlags)
+ return;
+
+ DisableNightVisionItem(ent, args.Equipee);
+ }
+
+ private void OnNightVisionItemActionRemoved(Entity ent, ref ActionRemovedEvent args)
+ {
+ DisableNightVisionItem(ent, ent.Comp.User);
+ }
+
+ private void OnNightVisionItemRemove(Entity ent, ref ComponentRemove args)
+ {
+ DisableNightVisionItem(ent, ent.Comp.User);
+ }
+
+ private void OnNightVisionItemTerminating(Entity ent, ref EntityTerminatingEvent args)
+ {
+ DisableNightVisionItem(ent, ent.Comp.User);
+ }
+
+ public void Toggle(Entity ent)
+ {
+ if (!Resolve(ent, ref ent.Comp))
+ return;
+
+ ent.Comp.State = ent.Comp.State switch
+ {
+ NightVisionState.Off => NightVisionState.Half,
+ NightVisionState.Half => NightVisionState.Full,
+ NightVisionState.Full => NightVisionState.Off,
+ _ => throw new ArgumentOutOfRangeException(),
+ };
+
+ Dirty(ent);
+ UpdateAlert((ent, ent.Comp));
+ }
+
+ private void UpdateAlert(Entity ent)
+ {
+ if (ent.Comp.Alert is { } alert)
+ {
+ var level = MathF.Max((int) NightVisionState.Off, (int) ent.Comp.State);
+ var max = _alerts.GetMaxSeverity(alert);
+ var severity = max - ContentHelpers.RoundToLevels(level, (int) NightVisionState.Full, max + 1);
+ _alerts.ShowAlert(ent, alert, (short) severity);
+ }
+
+ NightVisionChanged(ent);
+ }
+
+ private void ToggleNightVisionItem(Entity item, EntityUid user)
+ {
+ if (item.Comp.User == user && item.Comp.Toggleable)
+ {
+ DisableNightVisionItem(item, item.Comp.User);
+ return;
+ }
+
+ EnableNightVisionItem(item, user);
+ }
+
+ private void EnableNightVisionItem(Entity item, EntityUid user)
+ {
+ DisableNightVisionItem(item, item.Comp.User);
+
+ item.Comp.User = user;
+ Dirty(item);
+
+ _appearance.SetData(item, NightVisionItemVisuals.Active, true);
+
+ if (!_timing.ApplyingState)
+ {
+ var nightVision = EnsureComp(user);
+ nightVision.State = NightVisionState.Full;
+ Dirty(user, nightVision);
+ }
+
+ _actions.SetToggled(item.Comp.Action, true);
+ }
+
+ protected virtual void NightVisionChanged(Entity ent)
+ {
+ }
+
+ protected virtual void NightVisionRemoved(Entity ent)
+ {
+ }
+
+ protected void DisableNightVisionItem(Entity item, EntityUid? user)
+ {
+ _actions.SetToggled(item.Comp.Action, false);
+
+ item.Comp.User = null;
+ Dirty(item);
+
+ _appearance.SetData(item, NightVisionItemVisuals.Active, false);
+
+ if (TryComp(user, out NightVisionComponent? nightVision) &&
+ !nightVision.Innate)
+ {
+ RemCompDeferred(user.Value);
+ }
+ }
+
+ public void SetSeeThroughContainers(Entity ent, bool see)
+ {
+ if (!Resolve(ent, ref ent.Comp, false))
+ return;
+
+ ent.Comp.SeeThroughContainers = see;
+ Dirty(ent);
+ }
+}
diff --git a/Content.Shared/ADT/NightVision/ToggleNightVision.cs b/Content.Shared/ADT/NightVision/ToggleNightVision.cs
new file mode 100644
index 00000000000..45c739d015a
--- /dev/null
+++ b/Content.Shared/ADT/NightVision/ToggleNightVision.cs
@@ -0,0 +1,13 @@
+//using Content.Shared.Alert;
+
+//namespace Content.Shared.ADT.NightVision;
+
+//[DataDefinition]
+//public sealed partial class ToggleNightVision : IAlertClick
+//{
+// public void AlertClicked(EntityUid player)
+// {
+// var entities = IoCManager.Resolve();
+// entities.System().Toggle(player);
+// }
+//}
diff --git a/Resources/Prototypes/_Silver/Surgery/implants.yml b/Resources/Prototypes/_Silver/Surgery/implants.yml
new file mode 100644
index 00000000000..259161659e0
--- /dev/null
+++ b/Resources/Prototypes/_Silver/Surgery/implants.yml
@@ -0,0 +1,38 @@
+# - type: NightVisionItem # RMC Night vision
+# - type: ItemToggle
+
+- type: entity
+ parent: BasicCyberneticEyes
+ id: NightVisionCyberneticEyes
+ name: cybernetic eyes
+ description: A pair of cybernetic eyes that enhance your vision, and protect you from eye damage.
+ components:
+ - type: Organ
+ onAdd:
+ - type: InstantAction
+ icon:
+ sprite: Clothing/Eyes/Glasses/ninjavisor.rsi
+ state: icon
+ iconOn:
+ sprite: Clothing/Eyes/Glasses/ninjavisor.rsi
+ state: icon
+ event: !type:ToggleActionEvent
+ useDelay: 0.25
+ - NightVisionComponent
+ - NightVisionItemComponent
+
+- type: entity
+ id: ActionToggleNinjaNightVision
+ categories: [HideSpawnMenu]
+ name: Toggle ninja visor nightvision
+ description: Allows you to see even in complete darkness.
+ components:
+ - type: InstantAction
+ icon:
+ sprite: Clothing/Eyes/Glasses/ninjavisor.rsi
+ state: icon
+ iconOn:
+ sprite: Clothing/Eyes/Glasses/ninjavisor.rsi
+ state: icon
+ event: !type:ToggleActionEvent
+ useDelay: 0.25
\ No newline at end of file
diff --git a/Resources/Prototypes/_Silver/supermatter.yml b/Resources/Prototypes/_Silver/supermatter.yml
index 7718bfe6521..b3b4612e0d3 100644
--- a/Resources/Prototypes/_Silver/supermatter.yml
+++ b/Resources/Prototypes/_Silver/supermatter.yml
@@ -61,3 +61,90 @@
maxIntensity: 25000
intensitySlope: 5
totalIntensity: 25000
+
+- type: entity
+ id: SupermaterGenerator
+ description: Бессконечный источник электричества
+ name: суперматерьевый генератор
+ placement:
+ mode: SnapgridCenter
+ components:
+ - type: AmbientSound
+ range: 5
+ sound:
+ path: /Audio/Ambience/Objects/engine_hum.ogg
+ - type: Clickable
+ - type: InteractionOutline
+ - type: Physics
+ bodyType: Static
+ - type: Fixtures
+ fixtures:
+ fix1:
+ shape:
+ !type:PhysShapeAabb
+ bounds: "-0.4,-0.5,0.4,0.3"
+ density: 190
+ mask:
+ - MachineMask
+ layer:
+ - MachineLayer
+ - type: Transform
+ anchored: true
+ noRot: true
+ - type: Sprite
+ sprite: Structures/Power/power.rsi
+ state: generator
+ snapCardinals: true
+ - type: NodeContainer
+ examinable: true
+ nodes:
+ output:
+ !type:CableDeviceNode
+ nodeGroupID: HVPower
+ - type: PowerMonitoringDevice
+ group: Generator
+ loadNode: output
+ sprite: _Silver\supermattergen.rsi
+ state: supermatter
+ - type: PowerSupplier
+ supplyRate: 30000
+ supplyRampRate: 500
+ supplyRampTolerance: 500
+ - type: Anchorable
+ - type: Pullable
+ - type: Damageable
+ damageContainer: StructuralInorganic
+ damageModifierSet: Metallic
+ - type: PacifismDangerousAttack
+ - type: Destructible
+ thresholds:
+ - trigger:
+ !type:DamageTrigger
+ damage: 200
+ behaviors:
+ - !type:DoActsBehavior
+ acts: [ "Destruction" ]
+ - trigger:
+ !type:DamageTrigger
+ damage: 100
+ behaviors:
+ - !type:DoActsBehavior
+ acts: ["Destruction"]
+ - !type:PlaySoundBehavior
+ sound:
+ collection: MetalBreak
+ - !type:ExplodeBehavior
+ - type: Explosive
+ explosionType: Default
+ # Same as AME, but numbers still picked from a hat.
+ maxIntensity: 300
+ intensitySlope: 2
+ totalIntensity: 600
+ - type: StaticPrice
+ price: 500
+ - type: Electrified
+ onHandInteract: false
+ onInteractUsing: false
+ onBump: false
+ requirePower: true
+ highVoltageNode: output
\ No newline at end of file
diff --git a/Resources/Textures/_Silver/supermattergen.rsi/meta.json b/Resources/Textures/_Silver/supermattergen.rsi/meta.json
new file mode 100644
index 00000000000..7d982d8b585
--- /dev/null
+++ b/Resources/Textures/_Silver/supermattergen.rsi/meta.json
@@ -0,0 +1,14 @@
+{
+ "version": 1,
+ "copyright": "Taken from https://github.com/tgstation/tgstation/blob/master/icons/obj/supermatter.dmi",
+ "license": "CC-BY-SA-3.0",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "supermatter"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/_Silver/supermattergen.rsi/supermatter.png b/Resources/Textures/_Silver/supermattergen.rsi/supermatter.png
new file mode 100644
index 00000000000..8447503b6e8
Binary files /dev/null and b/Resources/Textures/_Silver/supermattergen.rsi/supermatter.png differ