diff --git a/Content.Shared/_Forge/FireModes/HybridAmmoProviderComponent.cs b/Content.Shared/_Forge/FireModes/HybridAmmoProviderComponent.cs
new file mode 100644
index 000000000000..c6bd1d0bd6f3
--- /dev/null
+++ b/Content.Shared/_Forge/FireModes/HybridAmmoProviderComponent.cs
@@ -0,0 +1,45 @@
+using Content.Shared._Forge.TripleModeWeapon;
+using Content.Shared.Weapons.Ranged.Components;
+using Content.Shared.Weapons.Ranged.Systems;
+using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Content.Shared._Forge.FireModes
+{
+
+ ///
+ /// Allows battery weapons to fire different types of projectiles
+ ///
+ [RegisterComponent, NetworkedComponent]
+ [Access(typeof(HybridModeWeaponSystem), typeof(SharedGunSystem))]
+ public sealed partial class HybridAmmoProviderComponent : AmmoProviderComponent
+ {
+ ///
+ /// How much battery it costs to fire once.
+ ///
+ [DataField("fireCost"), ViewVariables(VVAccess.ReadWrite)]
+ public float FireCost = 100;
+
+ [ViewVariables(VVAccess.ReadWrite)]
+ public int Shots;
+
+ [ViewVariables(VVAccess.ReadWrite)]
+ public int Capacity;
+
+ [ViewVariables(VVAccess.ReadWrite), DataField("soundAutoEject")]
+ public SoundSpecifier? SoundAutoEject = new SoundPathSpecifier("/Audio/Weapons/Guns/EmptyAlarm/smg_empty_alarm.ogg");
+
+ ///
+ /// Should the magazine automatically eject when empty.
+ ///
+ [ViewVariables(VVAccess.ReadWrite), DataField("autoEject")]
+ public bool AutoEject = false;
+ }
+}
diff --git a/Content.Shared/_Forge/HybridModeWeapon/HybridModeWeaponComponent.cs b/Content.Shared/_Forge/HybridModeWeapon/HybridModeWeaponComponent.cs
new file mode 100644
index 000000000000..190fdd6d1646
--- /dev/null
+++ b/Content.Shared/_Forge/HybridModeWeapon/HybridModeWeaponComponent.cs
@@ -0,0 +1,32 @@
+using Content.Shared._Forge.FireModes;
+using Content.Shared.Access;
+using Content.Shared.Weapons.Ranged.Components;
+using Content.Shared.Weapons.Ranged.Systems;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Content.Shared._Forge.TripleModeWeapon
+{
+ [RegisterComponent, NetworkedComponent]
+ [Access(typeof(HybridModeWeaponSystem))]
+ [AutoGenerateComponentState]
+ public sealed partial class HybridModeWeaponComponent: Component
+ {
+ [DataField("fireModes", required: true)]
+ [AutoNetworkedField]
+ public Dictionary, string> FireModes = default!;
+
+ [DataField("proto", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string Prototype = default!;
+
+ [DataField]
+ [AutoNetworkedField]
+ public int CurrentFireMode;
+ }
+}
diff --git a/Content.Shared/_Forge/HybridModeWeapon/HybridModeWeaponSystem.cs b/Content.Shared/_Forge/HybridModeWeapon/HybridModeWeaponSystem.cs
new file mode 100644
index 000000000000..d80bc9ba3a81
--- /dev/null
+++ b/Content.Shared/_Forge/HybridModeWeapon/HybridModeWeaponSystem.cs
@@ -0,0 +1,232 @@
+using Content.Shared._Forge.FireModes;
+using Content.Shared.Access.Systems;
+using Content.Shared.Body.Systems;
+using Content.Shared.Chemistry.Reaction;
+using Content.Shared.Database;
+using Content.Shared.DoAfter;
+using Content.Shared.Examine;
+using Content.Shared.Interaction.Events;
+using Content.Shared.Inventory;
+using Content.Shared.Popups;
+using Content.Shared.Verbs;
+using Content.Shared.Weapons.Ranged;
+using Content.Shared.Weapons.Ranged.Components;
+using Content.Shared.Weapons.Ranged.Events;
+using Content.Shared.Weapons.Ranged.Systems;
+using Robust.Shared.Containers;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Map;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Toolshed.TypeParsers;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Content.Shared._Forge.TripleModeWeapon
+{
+
+ public sealed class HybridModeWeaponSystem : EntitySystem
+ {
+ protected const string ChamberSlot = "gun_chamber";
+
+ [Dependency] private readonly SharedGunSystem _sharedGunSystem = default!;
+ [Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+ [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
+ [Dependency] private readonly IComponentFactory _factory = default!;
+ [Dependency] protected readonly SharedContainerSystem _containerSystem = default!;
+
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnUseInHand);
+ SubscribeLocalEvent>(OnGetVerb);
+ SubscribeLocalEvent(OnExamined);
+ SubscribeLocalEvent(OnAmmoCount);
+
+ }
+
+ private void OnAmmoCount(EntityUid uid, HybridAmmoProviderComponent component, ref GetAmmoCountEvent args)
+ {
+ args.Count = component.Shots;
+ args.Capacity = component.Capacity;
+ }
+
+ private ProtoId GetMode(HybridModeWeaponComponent component)
+ {
+ return component.FireModes.ElementAt(component.CurrentFireMode).Key;
+ }
+
+
+ private void OnExamined(EntityUid uid, HybridModeWeaponComponent component, ExaminedEvent args)
+ {
+ if (component.FireModes.Count < 2)
+ return;
+
+ var fireMode = GetMode(component);
+
+ HitscanPrototype? hitscanPrototype = null;
+
+ if (!_prototypeManager.TryIndex(fireMode, out var prototype) && !_prototypeManager.TryIndex(fireMode, out hitscanPrototype))
+ return;
+
+ if (prototype is not null)
+ args.PushMarkup(Loc.GetString("gun-set-fire-mode", ("mode", prototype.Name)));
+
+ if (hitscanPrototype is not null)
+ args.PushMarkup("Лазер");
+ }
+
+ private void OnGetVerb(EntityUid uid, HybridModeWeaponComponent component, GetVerbsEvent args)
+ {
+ if (!args.CanAccess || !args.CanInteract || !args.CanComplexInteract)
+ return;
+
+ if (component.FireModes.Count < 2)
+ return;
+
+ if (!_accessReaderSystem.IsAllowed(args.User, uid))
+ return;
+
+ for (var i = 0; i < component.FireModes.Count; i++)
+ {
+ var fireMode = component.FireModes.ElementAt(i);
+ EntityPrototype? entProto = null;
+ HitscanPrototype? hitProto = null;
+ if (_prototypeManager.TryIndex(fireMode.Key, out var prototype))
+ {
+ entProto = prototype;
+ }
+
+ if (_prototypeManager.TryIndex(fireMode.Key, out var hitscanPrototype))
+ {
+ hitProto = hitscanPrototype;
+ }
+ var index = i;
+
+ if (hitProto is null && entProto is null)
+ return;
+
+ var v = new Verb
+ {
+ Priority = 1,
+ Category = VerbCategory.SelectType,
+ Text = entProto?.Name ?? "Лазер",
+ Disabled = i == component.CurrentFireMode,
+ Impact = LogImpact.Medium,
+ DoContactInteraction = true,
+ Act = () =>
+ {
+ TrySetFireMode(uid, component, index, args.User);
+ }
+ };
+
+ args.Verbs.Add(v);
+ }
+ }
+
+ private void OnUseInHand(EntityUid uid, HybridModeWeaponComponent component, ref UseInHandEvent args)
+ {
+ if (args.Handled)
+ return;
+
+ args.Handled = true;
+ TryCycleFireMode(uid, component, args.User);
+ }
+
+ public void TryCycleFireMode(EntityUid uid, HybridModeWeaponComponent component, EntityUid? user = null)
+ {
+ if (component.FireModes.Count < 2)
+ return;
+
+ var index = (component.CurrentFireMode + 1) % component.FireModes.Count;
+ TrySetFireMode(uid, component, index, user);
+ }
+
+ public bool TrySetFireMode(EntityUid uid, HybridModeWeaponComponent component, int index, EntityUid? user = null)
+ {
+ if (index < 0 || index >= component.FireModes.Count)
+ return false;
+
+ if (user != null && !_accessReaderSystem.IsAllowed(user.Value, uid))
+ return false;
+
+ SetFireMode(uid, component, index, user);
+
+ return true;
+ }
+
+ private void SetFireMode(EntityUid uid, HybridModeWeaponComponent component, int index, EntityUid? user = null)
+ {
+ component.CurrentFireMode = index;
+ var fireMode = component.FireModes.ElementAt(index);
+ var fireModeName = fireMode.Value;
+ EntityPrototype? prototype;
+ GunComponent? gunComponent = null;
+
+ if (_prototypeManager.TryIndex(fireMode.Key, out prototype))
+ {
+ if (TryComp(uid, out var appearance))
+ _appearanceSystem.SetData(uid, BatteryWeaponFireModeVisuals.State, prototype.ID, appearance);
+
+ if (user != null)
+ _popupSystem.PopupClient(Loc.GetString("gun-set-fire-mode", ("mode", prototype.Name)), uid, user.Value);
+ }
+
+ if (_prototypeManager.TryIndex(fireMode.Key, out var hitscanPrototype))
+ {
+ if (TryComp(uid, out var appearance))
+ _appearanceSystem.SetData(uid, BatteryWeaponFireModeVisuals.State, hitscanPrototype.ID, appearance);
+
+ if (user != null)
+ _popupSystem.PopupClient("Лазер", uid, user.Value);
+ }
+
+ if (TryComp(uid, out var hitscanAmmoProvider))
+ RemComp(uid);
+
+ if (TryComp(uid, out var magazineAmmoProvider))
+ RemComp(uid);
+
+
+ if (TryComp(uid, out var hybridAmmoProviderComponent))
+ RemComp(uid);
+
+
+ switch (fireModeName)
+ {
+ case "battery":
+ if (hitscanPrototype is not null)
+ {
+ var hitscanComponent = (HitscanBatteryAmmoProviderComponent)_factory.GetComponent(typeof(HitscanBatteryAmmoProviderComponent));
+
+ hitscanComponent.NetSyncEnabled = false;
+ hitscanComponent.Prototype = hitscanPrototype.ID;
+ AddComp(uid, hitscanComponent);
+ Dirty(uid, hitscanComponent);
+ }
+
+ break;
+ case "ammo":
+ AddComp(uid);
+ break;
+ case "hybrid":
+ AddComp(uid);
+ break;
+ }
+
+ Dirty(uid, component);
+
+ var updateClientAmmoEvent = new UpdateClientAmmoEvent();
+
+ RaiseLocalEvent(uid, ref updateClientAmmoEvent);
+ }
+ }
+}
diff --git a/Resources/Prototypes/_Forge/HybridWeapon/hybrid_weapon.yml b/Resources/Prototypes/_Forge/HybridWeapon/hybrid_weapon.yml
new file mode 100644
index 000000000000..51f171c2bba8
--- /dev/null
+++ b/Resources/Prototypes/_Forge/HybridWeapon/hybrid_weapon.yml
@@ -0,0 +1,140 @@
+# - type: entity
+# name: hybrid laser gun
+# parent: [ WeaponAdvancedLaser, BaseXenoborgContraband ]
+# id: HybridLaserGun
+# components:
+# - type: HybridAmmoProvider
+# proto: NFRedHeavyLaser # Frontier: use NF variant
+
+- type: entity
+ name: hybrid laser gun
+ parent: [BaseWeaponBatterySmall, BaseC1Contraband] # Frontier: added BaseC1Contraband
+ id: HybridLaserGun
+ description: Better pray it won't burn your hands off. At least it's legal.
+ components:
+ - type: Sprite
+ sprite: Objects/Weapons/Guns/Battery/makeshift.rsi
+ layers:
+ - state: base
+ map: ["enum.GunVisualLayers.Base"]
+ - state: mag-unshaded-4
+ map: ["enum.GunVisualLayers.MagUnshaded"]
+ shader: unshaded
+ - type: MagazineVisuals
+ magState: mag
+ steps: 5
+ zeroVisible: false
+ - type: Appearance
+ - type: Clothing
+ sprite: Objects/Weapons/Guns/Battery/makeshift.rsi
+ - type: HybridAmmoProvider
+ proto: NFRedLightLaser # Frontier: use NF variant
+ fireCost: 62.5
+ - type: HybridModeWeapon
+ proto: NFAnomalousParticleDeltaStrong
+ fireModes:
+ NFPulse: battery
+ WeaponRifleAkHybrid: ammo
+ HybridLaserGun: hybrid
+ - type: ItemSlots
+ slots:
+ gun_magazine:
+ name: Magazine
+ # startingItem: MagazineLightRifle # Frontier
+ insertSound: /Audio/Weapons/Guns/MagIn/ltrifle_magin.ogg
+ ejectSound: /Audio/Weapons/Guns/MagOut/ltrifle_magout.ogg
+ priority: 2
+ whitelist:
+ tags:
+ - MagazineLightRifle
+ - type: ContainerContainer
+ containers:
+ gun_magazine: !type:ContainerSlot
+
+
+- type: entity
+ categories: [ HideSpawnMenu ] # Frontier
+ name: AKMS
+ parent: [BaseWeaponRifle] # Frontier: BaseSecurityContraband