diff --git a/Content.Server/Projectiles/ProjectileSystem.cs b/Content.Server/Projectiles/ProjectileSystem.cs index 4c054a4561..c9578a38aa 100644 --- a/Content.Server/Projectiles/ProjectileSystem.cs +++ b/Content.Server/Projectiles/ProjectileSystem.cs @@ -1,3 +1,4 @@ +using Content.Server._DV.Projectiles.Events; // DeltaV - Addition of the NT-3 using Content.Server.Administration.Logs; using Content.Server.Destructible; using Content.Server.Effects; @@ -88,6 +89,9 @@ public sealed class ProjectileSystem : SharedProjectileSystem component.ProjectileSpent = true; } + var pierceEv = new ProjectilePierceEvent(target, damageRequired); // DeltaV - Addition of the NT-3 + RaiseLocalEvent(uid, ref pierceEv); + // If the object won't be destroyed, it "tanks" the penetration hit. if (modifiedDamage.GetTotal() < damageRequired) { @@ -103,6 +107,9 @@ public sealed class ProjectileSystem : SharedProjectileSystem component.ProjectileSpent = true; } } + + if (component.ProjectileSpent && pierceEv.Pierced) // DeltaV - Addition of the NT-3 + component.ProjectileSpent = false; } else { diff --git a/Content.Server/_DV/Projectiles/Components/PiercingProjectileComponent.cs b/Content.Server/_DV/Projectiles/Components/PiercingProjectileComponent.cs new file mode 100644 index 0000000000..dfb98d8ddd --- /dev/null +++ b/Content.Server/_DV/Projectiles/Components/PiercingProjectileComponent.cs @@ -0,0 +1,53 @@ +using Content.Shared.Tag; +using Robust.Shared.Prototypes; + +namespace Content.Server._DV.Projectiles.Components; + +[RegisterComponent] +public sealed partial class PiercingProjectileComponent : Component +{ + /// + /// The health threshold that a target has to supersede to block the projectile. + /// A normal wall has 200. + /// + [DataField(required: true)] + public float HealthThreshold; + + /// + /// The number of entities it pierced. + /// It'll only count the entities with the . + /// + [DataField] + public float PierceCounter; + + /// + /// The tag that will cause the piercing bullet to increment it's . + /// + [DataField] + public List> PierceBlockTag = ["Wall", "Window"]; + + /// + /// The number of entities it is allowed to pierce before being deleted. + /// When is higher than this number, it'll be deleted. + /// + /// + /// A bullet with a MaxPierceNumberThreshold of 3 will pierce 3 entities with the and be deleted when hitting the fourth. + /// + [DataField] + public float MaxPierceNumberThreshold = 1f; + + /// + /// The cardinal direction that the bullet is flying toward. + /// + [DataField] + public Direction? Direction; + + /// + /// The vertical/horizontal coordinate that will be ignored for . + /// + /// + /// A bullet going positive Y hitting a wall at X 3 and Y 5 will not increment the when hitting other walls at Y 5. + /// + [DataField] + public float? IgnoreRowCoordinate; +} diff --git a/Content.Server/_DV/Projectiles/Events/ProjectilePierceEvent.cs b/Content.Server/_DV/Projectiles/Events/ProjectilePierceEvent.cs new file mode 100644 index 0000000000..502828c26d --- /dev/null +++ b/Content.Server/_DV/Projectiles/Events/ProjectilePierceEvent.cs @@ -0,0 +1,9 @@ +using Content.Shared.FixedPoint; + +namespace Content.Server._DV.Projectiles.Events; + +/// +/// Raised when a piercing projectile hits an entity that doesn't follow upstream piercing rules. +/// +[ByRefEvent] +public record struct ProjectilePierceEvent(EntityUid Target, FixedPoint2 RequiredDamage, bool Pierced = false); diff --git a/Content.Server/_DV/Projectiles/Systems/PiercingProjectileSystem.cs b/Content.Server/_DV/Projectiles/Systems/PiercingProjectileSystem.cs new file mode 100644 index 0000000000..6706ced74f --- /dev/null +++ b/Content.Server/_DV/Projectiles/Systems/PiercingProjectileSystem.cs @@ -0,0 +1,55 @@ +using Content.Server._DV.Projectiles.Components; +using Content.Server._DV.Projectiles.Events; +using Content.Shared.Tag; + +namespace Content.Server._DV.Projectiles.Systems; + +public sealed class PiercingProjectileSystem : EntitySystem +{ + [Dependency] private readonly TagSystem _tagSystem = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnPierce); + } + + private void OnPierce(Entity bullet, ref ProjectilePierceEvent args) + { + // If the target doesn't have any tags to stop the bullet from piercing, it's automatically true. + if (!_tagSystem.HasAnyTag(args.Target, bullet.Comp.PierceBlockTag)) + { + args.Pierced = true; + return; + } + // If it does have the tag to stop it and enough health to count as "strongly armored", it'll block the bullet. + if (bullet.Comp.HealthThreshold < args.RequiredDamage) + return; + + if (bullet.Comp.Direction == null) // Get the direction of the bullet to determine which walls count. + bullet.Comp.Direction = Transform(bullet).LocalRotation.GetCardinalDir(); + + var xTarget = Transform(args.Target); + + var targetPosition = bullet.Comp.Direction is Direction.East or Direction.West + ? xTarget.Coordinates.X // If the bullet is going horizontal, wall rows are vertical. + : xTarget.Coordinates.Y; // And when vertical, the wall rows are horizontal + + // If the wall is part of a wall-row that the bullet already pierced, pierce it too and ignore it for the counter. + if (bullet.Comp.IgnoreRowCoordinate != null + && Math.Abs(targetPosition - bullet.Comp.IgnoreRowCoordinate.Value) < 0.25) + { + args.Pierced = true; + return; + } + + bullet.Comp.PierceCounter++; + + if (bullet.Comp.PierceCounter > bullet.Comp.MaxPierceNumberThreshold) + return; + + // Save the row-position of the last wall it pierced, so we can ignore any other wall part of the same row. + bullet.Comp.IgnoreRowCoordinate = targetPosition; + args.Pierced = true; + } +} diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs index bbab326bc4..d3d66d2f2a 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs @@ -99,6 +99,7 @@ public abstract partial class SharedGunSystem : EntitySystem SubscribeLocalEvent(OnMapInit); InitializeHolders(); // DeltaV + InitializeBipods(); // DeltaV } private void OnMapInit(Entity gun, ref MapInitEvent args) diff --git a/Content.Shared/_DV/Weapons/Ranged/Components/GunBipodComponent.cs b/Content.Shared/_DV/Weapons/Ranged/Components/GunBipodComponent.cs new file mode 100644 index 0000000000..c1b602a954 --- /dev/null +++ b/Content.Shared/_DV/Weapons/Ranged/Components/GunBipodComponent.cs @@ -0,0 +1,65 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared._DV.Weapons.Ranged.Components; + +/// +/// Alters the accuracy and firerate of the gun after a DoAfter, immoblizing the wielder. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class GunBipodComponent : Component +{ + [DataField, AutoNetworkedField] + public Angle MinAngle = Angle.FromDegrees(-43); + + /// + /// Angle bonus applied upon the bipod being used. + /// + [DataField, AutoNetworkedField] + public Angle MaxAngle = Angle.FromDegrees(-43); + + /// + /// Recoil bonuses applied upon the bipod being used. + /// Higher angle decay bonus, quicker recovery. + /// + [DataField, AutoNetworkedField] + public Angle AngleDecay = Angle.FromDegrees(0); + + /// + /// Recoil bonuses applied upon the bipod being used. + /// Lower angle increase bonus (negative numbers), slower buildup. + /// + [DataField, AutoNetworkedField] + public Angle AngleIncrease = Angle.FromDegrees(0); + + /// + /// Firerate bonus applied upon the bipod being used. + /// + [DataField, AutoNetworkedField] + public float FireRateIncrease = 3f; + + /// + /// Time to set up the bipod. + /// + [DataField] + public TimeSpan SetupDelay = TimeSpan.FromSeconds(2); + + /// + /// Is the bipod set up? + /// + [DataField, AutoNetworkedField] + public bool IsSetup; + + [DataField] + public EntProtoId BipodToggleAction = "ActionToggleBipod"; + + [DataField, AutoNetworkedField] + public EntityUid? BipodToggleActionEntity; + + /// + /// The time when the Bipod has begun being set up. + /// Used to stop it from firing while the bipod is being set up. + /// + [AutoNetworkedField] + public TimeSpan BipodSetupTime = TimeSpan.Zero; +} diff --git a/Content.Shared/_DV/Weapons/Ranged/Components/IsUsingBipodComponent.cs b/Content.Shared/_DV/Weapons/Ranged/Components/IsUsingBipodComponent.cs new file mode 100644 index 0000000000..6899a2672b --- /dev/null +++ b/Content.Shared/_DV/Weapons/Ranged/Components/IsUsingBipodComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._DV.Weapons.Ranged.Components; + +/// +/// An entity currently using a bipod weapon has this component. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class IsUsingBipodComponent : Component +{ + /// + /// A list of BipodComponents, so we can shut them down on movement. + /// + [AutoNetworkedField] + public List BipodOwnerUids = []; +} diff --git a/Content.Shared/_DV/Weapons/Ranged/Systems/SharedGunSystem.Bipod.cs b/Content.Shared/_DV/Weapons/Ranged/Systems/SharedGunSystem.Bipod.cs new file mode 100644 index 0000000000..04cf96a9cb --- /dev/null +++ b/Content.Shared/_DV/Weapons/Ranged/Systems/SharedGunSystem.Bipod.cs @@ -0,0 +1,200 @@ +using Content.Shared._DV.Weapons.Ranged.Components; +using Content.Shared.Actions; +using Content.Shared.DoAfter; +using Content.Shared.Hands; +using Content.Shared.IdentityManagement; +using Content.Shared.Interaction.Events; +using Content.Shared.Toggleable; +using Content.Shared.Weapons.Ranged.Events; +using Robust.Shared.Serialization; + +namespace Content.Shared.Weapons.Ranged.Systems; + +public abstract partial class SharedGunSystem +{ + [Dependency] private readonly ActionContainerSystem _actionContainerSystem = default!; + + private void InitializeBipods() + { + SubscribeLocalEvent(OnUnequip); + SubscribeLocalEvent(OnDrop); + + SubscribeLocalEvent(OnGetActions); + SubscribeLocalEvent(OnToggleAction); + + SubscribeLocalEvent(OnMapInit); + + SubscribeLocalEvent(OnGunRefreshModifiers); + SubscribeLocalEvent(SetupBipod); + SubscribeLocalEvent(OnShotAttempted); + SubscribeLocalEvent(OnMove); + } + + private void OnMapInit(Entity weapon, ref MapInitEvent args) + { + _actionContainerSystem.EnsureAction(weapon.Owner, ref weapon.Comp.BipodToggleActionEntity, weapon.Comp.BipodToggleAction); + Dirty(weapon); + } + + private void OnGetActions(Entity ent, ref GetItemActionsEvent args) + { + args.AddAction(ref ent.Comp.BipodToggleActionEntity, ent.Comp.BipodToggleAction); + } + + private void OnUnequip(Entity weapon, ref GotUnequippedHandEvent args) + { + if (weapon.Comp.IsSetup) + PackUpBipod(weapon, args.User, null); + } + + private void OnDrop(Entity weapon, ref DroppedEvent args) + { + if (weapon.Comp.IsSetup) + PackUpBipod(weapon, args.User, null); + } + + private void OnMove(Entity bipodUser, ref MoveEvent args) + { + // This fires when the entity rotates. If the position didn't change, do not undo the bipod. + if (args.OldPosition.Equals(args.NewPosition)) + return; + // Undo the Bipod of every gun currently used. + foreach (var weaponUid in bipodUser.Comp.BipodOwnerUids.ToArray()) + { + if (!TryComp(weaponUid, out var bipod)) + continue; + + PackUpBipod((weaponUid, bipod), bipodUser.Owner, bipodUser.Comp); + } + } + + private void OnToggleAction(Entity ent, ref ToggleActionEvent args) + { + if (args.Handled) + return; + + if (ent.Comp.IsSetup) + PackUpBipod(ent, args.Performer, null); + else + TrySetupBipod(ent, args.Performer); + + args.Handled = true; + } + + private void TrySetupBipod(Entity ent, EntityUid user) + { + var xform = Transform(user); + + //Don't allow someone to set up the bipod if they're not parented to a grid + if (xform.GridUid != xform.ParentUid) + { + CantSetupError(user, Loc.GetString("action-popup-bipod-user-cant-setup")); + return; + } + + // Don't allow someone to set up the bipod if they're not holding the weapon + if (!_hands.IsHolding(user, ent.Owner, out _)) + { + CantSetupError(user, Loc.GetString("action-popup-bipod-user-not-holding")); + return; + } + + var gunName = Name(ent.Owner); + var bipodUser = Identity.Entity(user, EntityManager); + // Show a popup for everyone to show them setting up their bipod. + var msgUser = Loc.GetString("action-popup-bipod-user", ("gunName", gunName)); + var msgOther = Loc.GetString("action-popup-bipod-other", ("bipodUser", bipodUser), ("gunName", gunName)); + + PopupSystem.PopupPredicted(msgUser, msgOther, user, user); + + var doAfterArgs = new DoAfterArgs(EntityManager, user, ent.Comp.SetupDelay, new BipodSetupFinishedEvent(), ent.Owner, target: ent.Owner, used: ent.Owner) + { + BreakOnDamage = false, + BreakOnMove = true, + }; + // This is used to prevent the gun from shooting while setting up the bipod. + ent.Comp.BipodSetupTime = Timing.CurTime; + _doAfter.TryStartDoAfter(doAfterArgs); + } + + private void SetupBipod(Entity ent, ref BipodSetupFinishedEvent bipodEvent) + { + if (bipodEvent.Cancelled) // This method is called whether the DoAfter was successful - Hence the catch. + { + ent.Comp.BipodSetupTime = TimeSpan.Zero; // This allows them to shoot again when they cancel putting down the bipod. + return; + } + + var bipodUseComp = EnsureComp(bipodEvent.User); // Set a component on the user so we can track it for movement. + bipodUseComp.BipodOwnerUids.Add(ent.Owner); // Add it to the used Bipods. + + var gunName = Name(ent.Owner); + var bipodUser = Identity.Entity(bipodEvent.User, EntityManager); + // Send another popup that the bipod is successfully set up. + var msgUser = Loc.GetString("action-popup-bipod-finished-user", ("gunName", gunName)); + var msgOther = Loc.GetString("action-popup-bipod-finished-other", ("bipodUser", bipodUser), ("gunName", gunName)); + + Actions.SetToggled(ent.Comp.BipodToggleActionEntity, true); + PopupSystem.PopupPredicted(msgUser, msgOther, bipodEvent.User, bipodEvent.User); + + ent.Comp.IsSetup = true; // Activate the Bipod. + + RefreshModifiers(ent.Owner); // This will update the modifiers of the weapon, so the bipod is in effect. + Dirty(ent); + } + + private void PackUpBipod(Entity weapon, EntityUid user, IsUsingBipodComponent? userComp) + { + if (Timing.ApplyingState + || !Resolve(user, ref userComp)) // Component can be nullable, so we resolve. Less expensive than TryComp. + return; + + userComp.BipodOwnerUids.Remove(weapon); // Remove the bipod component from the list of used bipods. + if (userComp.BipodOwnerUids.Count == 0) // Remove the Component if no bipod is in use anymore. + RemComp(user); + + var gunName = Name(weapon); + var bipodUser = Identity.Entity(user, EntityManager); + // Show a popup that the bipod has been removed. + var msgUser = Loc.GetString("action-popup-bipod-disabling-user", ("gunName", gunName)); + var msgOther = Loc.GetString("action-popup-bipod-disabling-other", ("bipodUser", bipodUser), ("gunName", gunName)); + + Actions.SetToggled(weapon.Comp.BipodToggleActionEntity, false); // Set the action icon to red. + PopupSystem.PopupPredicted(msgUser, msgOther, user, user); + + weapon.Comp.IsSetup = false; // Deactivate the Bipod. + + RefreshModifiers(weapon.Owner); // This will update the modifiers of the weapon, so the bipod bonus is lost. + Dirty(weapon); + } + + private void CantSetupError(EntityUid user, string errorMessage) + { + PopupSystem.PopupClient(errorMessage, user, user); + } + + private void OnGunRefreshModifiers(Entity bonus, ref GunRefreshModifiersEvent args) + { + if (bonus.Comp.IsSetup) + { + args.MinAngle += bonus.Comp.MinAngle; + args.MaxAngle += bonus.Comp.MaxAngle; + args.AngleDecay += bonus.Comp.AngleDecay; + args.AngleIncrease += bonus.Comp.AngleIncrease; + args.FireRate += bonus.Comp.FireRateIncrease; + } + } + + private void OnShotAttempted(Entity ent, ref ShotAttemptedEvent args) + { + // This is true when the bipod is being set up - Preventing the gun from shooting. + if (Timing.CurTime < ent.Comp.BipodSetupTime + ent.Comp.SetupDelay) + args.Cancel(); + } +} + +/// +/// This event gets called when the Setup Doafter is done. +/// +[Serializable, NetSerializable] +public sealed partial class BipodSetupFinishedEvent : SimpleDoAfterEvent; diff --git a/Resources/Locale/en-US/_DV/actions/bipod.ftl b/Resources/Locale/en-US/_DV/actions/bipod.ftl new file mode 100644 index 0000000000..b305bcd779 --- /dev/null +++ b/Resources/Locale/en-US/_DV/actions/bipod.ftl @@ -0,0 +1,10 @@ +action-popup-bipod-user = You're setting up the bipod of your {$gunName}! +action-popup-bipod-disabling-user = You pack up the bipod of your {$gunName}! +action-popup-bipod-finished-user = You've set up the bipod of your {$gunName}! + +action-popup-bipod-other = {CAPITALIZE(THE($bipodUser))} is setting up the bipod of {POSS-ADJ($bipodUser)} {$gunName}! +action-popup-bipod-disabling-other = {CAPITALIZE(THE($bipodUser))} packed up the bipod of {POSS-ADJ($bipodUser)} {$gunName}! +action-popup-bipod-finished-other = {CAPITALIZE(THE($bipodUser))} has set up the bipod of {POSS-ADJ($bipodUser)} {$gunName}! + +action-popup-bipod-user-cant-setup = You tried to set up your bipod, but there was nothing to set up on. +action-popup-bipod-user-not-holding = You aren't holding the weapon with the bipod. diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 228a91f69c..fe9b56169f 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -465,6 +465,18 @@ - Sheet - RawMaterial - Ingot + # End DeltaV Additions + - type: BlueprintReceiver + whitelist: + tags: + - BlueprintAutolathe + - BlueprintSecurityTechfab + - type: ContainerContainer + containers: + machine_board: !type:Container + machine_parts: !type:Container + blueprint: !type:Container + # End DeltaV Additions - type: OreSiloClient - type: LatheAnnouncing channels: [Security] @@ -497,6 +509,17 @@ unlitRunningState: unlit-building # DeltaV - added animation sprite layers staticPacks: - SecurityAmmoStatic + # End DeltaV Additions + - type: BlueprintReceiver + whitelist: + tags: + - BlueprintAmmoTechfab + - type: ContainerContainer + containers: + machine_board: !type:Container + machine_parts: !type:Container + blueprint: !type:Container + # End DeltaV Additions - type: MaterialStorage whitelist: tags: diff --git a/Resources/Prototypes/_DV/Actions/types.yml b/Resources/Prototypes/_DV/Actions/types.yml index 13ef84575c..1dc20e75f5 100644 --- a/Resources/Prototypes/_DV/Actions/types.yml +++ b/Resources/Prototypes/_DV/Actions/types.yml @@ -66,3 +66,13 @@ useDelay: 30 - type: InstantAction event: !type:CoughItemActionEvent + +- type: entity + parent: BaseToggleAction + id: ActionToggleBipod + name: Set up your bipod + description: Increase the accuracy and fire rate of your firearm. + components: + - type: Action + icon: { sprite: _DV/Objects/Weapons/Guns/LMGs/NT-3.rsi, state: bipod-off } + iconOn: { sprite: _DV/Objects/Weapons/Guns/LMGs/NT-3.rsi, state: bipod-on } diff --git a/Resources/Prototypes/_DV/Catalog/Cargo/cargo_armory.yml b/Resources/Prototypes/_DV/Catalog/Cargo/cargo_armory.yml index 2b276fa434..8f18e7b8f5 100644 --- a/Resources/Prototypes/_DV/Catalog/Cargo/cargo_armory.yml +++ b/Resources/Prototypes/_DV/Catalog/Cargo/cargo_armory.yml @@ -69,3 +69,13 @@ cost: 18000 category: Armory group: market + +- type: cargoProduct + id: ArmoryNT3 + icon: + sprite: _DV/Objects/Weapons/Guns/LMGs/NT-3.rsi + state: icon + product: CrateNT3 + cost: 13000 + category: Armory + group: market diff --git a/Resources/Prototypes/_DV/Catalog/Fills/Crates/armory.yml b/Resources/Prototypes/_DV/Catalog/Fills/Crates/armory.yml index e275bba96c..1dc4aba466 100644 --- a/Resources/Prototypes/_DV/Catalog/Fills/Crates/armory.yml +++ b/Resources/Prototypes/_DV/Catalog/Fills/Crates/armory.yml @@ -68,3 +68,14 @@ contents: - id: WatchdogImplanter amount: 3 + +- type: entity + id: CrateNT3 + parent: CrateWeaponSecure + name: NT-3 crate + description: Contains the refurbished NT-3, along with two magazine boxes filled with .40 anti-material ammunition and a blueprint for the ammunition. + components: + - type: EntityTableContainerFill + containers: + entity_storage: !type:NestedSelector + tableId: NT3Table diff --git a/Resources/Prototypes/_DV/Entities/Markers/Spawners/Random/security.yml b/Resources/Prototypes/_DV/Entities/Markers/Spawners/Random/security.yml index a8129b67d6..8c971244d5 100644 --- a/Resources/Prototypes/_DV/Entities/Markers/Spawners/Random/security.yml +++ b/Resources/Prototypes/_DV/Entities/Markers/Spawners/Random/security.yml @@ -39,3 +39,13 @@ - id: GamblagatorCapacitor amount: !type:ConstantNumberSelector value: 4 + +- type: entityTable + id: NT3Table + table: !type:AllSelector + children: + - id: WeaponLightMachinegGunNT3 + - id: BlueprintMagazineBoxLMGAntiMateriel + - id: MagazineLMGAntiMaterielBox + amount: !type:ConstantNumberSelector + value: 2 diff --git a/Resources/Prototypes/_DV/Entities/Objects/Tools/blueprint.yml b/Resources/Prototypes/_DV/Entities/Objects/Tools/blueprint.yml new file mode 100644 index 0000000000..0ea4508ebb --- /dev/null +++ b/Resources/Prototypes/_DV/Entities/Objects/Tools/blueprint.yml @@ -0,0 +1,13 @@ +- type: entity + parent: BaseBlueprint + id: BlueprintMagazineBoxLMGAntiMateriel + name: ammuntion box blueprint (.40 anti-materiel) + description: A blueprint with a schematic of for .40 anti-materiel cartridges, used by the NT-3. It can be inserted into a Security Techfab. + components: + - type: Blueprint + providedRecipes: + - MagazineBoxLMGAntiMateriel + - type: Tag + tags: + - BlueprintSecurityTechfab + - BlueprintAmmoTechfab diff --git a/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimateriel.yml b/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimateriel.yml new file mode 100644 index 0000000000..2091f24118 --- /dev/null +++ b/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimateriel.yml @@ -0,0 +1,13 @@ +- type: entity + parent: MagazineBoxAntiMateriel + id: MagazineBoxLMGAntiMateriel + name: ammunition box (.40 anti-materiel) + description: A rigid steel box of .40 anti-materiel rounds. Intended to hold structure-piercing kinetic ammunition. + components: + - type: BallisticAmmoProvider + mayTransfer: true + whitelist: + tags: + - CartridgeLMGAntiMateriel + proto: CartridgeLMGAntiMateriel + capacity: 30 diff --git a/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/antimateriel.yml b/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/antimateriel.yml new file mode 100644 index 0000000000..86c7d5f6b4 --- /dev/null +++ b/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/antimateriel.yml @@ -0,0 +1,21 @@ +- type: entity + parent: [ BaseCartridge, BaseSecurityContraband ] + id: CartridgeLMGAntiMateriel + name: cartridge (.40 anti-materiel) + description: A expensive, heavy cartridge used by special LMGs. Structural-piercing kinetic ammunition is useful for when you don't care about what's between you and your target. + components: + - type: Tag + tags: + - Cartridge + - CartridgeLMGAntiMateriel + - type: CartridgeAmmo + proto: BulletLMGAntiMateriel + - type: Sprite + sprite: Objects/Weapons/Guns/Ammunition/Casings/ammo_casing.rsi + layers: + - state: base + map: ["enum.AmmoVisualLayers.Base"] + - type: Appearance + - type: SpentAmmoVisuals + - type: StaticPrice + price: 20 diff --git a/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Magazines/antimateriel.yml b/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Magazines/antimateriel.yml new file mode 100644 index 0000000000..a71809e198 --- /dev/null +++ b/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Magazines/antimateriel.yml @@ -0,0 +1,33 @@ +- type: entity + parent: [ BaseItem, BaseSecurityContraband ] + id: MagazineLMGAntiMaterielBox + name: "NT-3 magazine box (.40 anti-materiel)" + description: An ancient design of a box containing containing a 60-round belt of linked .40 anti-materiel rounds, used by refurbished light machine guns such as the NT-3. Intended to hold structure-piercing kinetic ammunition. + components: + - type: Tag + tags: + - MagazineLMGAntiMaterielBox + - type: BallisticAmmoProvider + mayTransfer: true + whitelist: + tags: + - CartridgeLMGAntiMateriel + proto: CartridgeLMGAntiMateriel + capacity: 60 + - type: Item + size: Small + - type: ContainerContainer + containers: + ballistic-ammo: !type:Container + - type: Sprite + sprite: _DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi + layers: + - state: base + map: ["enum.GunVisualLayers.Base"] + - state: mag-1 + map: ["enum.GunVisualLayers.Mag"] + - type: MagazineVisuals + magState: mag + steps: 6 + zeroVisible: false + - type: Appearance diff --git a/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/antimateriel.yml b/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/antimateriel.yml new file mode 100644 index 0000000000..de69db28ac --- /dev/null +++ b/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/antimateriel.yml @@ -0,0 +1,14 @@ +- type: entity + categories: [ HideSpawnMenu ] + parent: BaseBullet + id: BulletLMGAntiMateriel + name: bullet (.40 anti-materiel) + components: + - type: Projectile + damage: + types: + Piercing: 20 + Structural: 20 + penetrationThreshold: 200 # This is irrelevant - As long as it's above 0. + - type: PiercingProjectile + healthThreshold: 200 # Normal walls have a threshold of 200. diff --git a/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml b/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml new file mode 100644 index 0000000000..1f8958a8f4 --- /dev/null +++ b/Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml @@ -0,0 +1,80 @@ +- type: entity + name: NT-3 + parent: BaseItem # The base LightMachineGun had unwanted components. + id: WeaponLightMachinegGunNT3 + description: An ancient weapon from the old wars, refurbished and rebranded for NT's strongest stations. + components: + - type: Sprite + sprite: _DV/Objects/Weapons/Guns/LMGs/NT-3.rsi + layers: + - state: base + map: ["enum.GunVisualLayers.Base"] + - state: mag-3 + map: [ "enum.GunVisualLayers.Mag" ] + - type: MagazineVisuals + magState: mag + steps: 4 + zeroVisible: true + - type: Item + size: Ginormous + shape: + - 0,0,4,3 + - type: Clothing + sprite: _DV/Objects/Weapons/Guns/LMGs/NT-3.rsi + quickEquip: false + slots: + - Back + - type: ClothingSpeedModifier + sprintModifier: 0.9 + - type: Appearance + - type: Wieldable + unwieldOnUse: false + - type: GunRequiresWield + - type: Gun + minAngle: 12 + maxAngle: 30 + angleIncrease: 4 + angleDecay: 16 + fireRate: 4 + selectedMode: FullAuto + availableModes: + - FullAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/lmg.ogg + soundEmpty: + path: /Audio/Weapons/Guns/Empty/lmg_empty.ogg + - type: GunBipod + minAngle: -12 + maxAngle: -20 + angleDecay: 4 + fireRateIncrease: 3 + - type: ChamberMagazineAmmoProvider + soundRack: + path: /Audio/Weapons/Guns/Cock/lmg_cock.ogg + - type: AmmoCounter + - type: ItemSlots + slots: + gun_magazine: + name: Magazine + startingItem: MagazineLMGAntiMaterielBox + insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg + ejectSound: /Audio/Weapons/Guns/MagOut/batrifle_magout.ogg + priority: 2 + whitelist: + tags: + - MagazineLMGAntiMaterielBox + gun_chamber: + name: Chamber + startingItem: CartridgeLMGAntiMateriel + priority: 1 + whitelist: + tags: + - CartridgeLMGAntiMateriel + - type: ContainerContainer + containers: + gun_magazine: !type:ContainerSlot + gun_chamber: !type:ContainerSlot + - type: StaticPrice + price: 500 + - type: UseDelay + delay: 1 diff --git a/Resources/Prototypes/_DV/Recipes/Lathes/security.yml b/Resources/Prototypes/_DV/Recipes/Lathes/security.yml index 8ea60584f7..73a5e7be21 100644 --- a/Resources/Prototypes/_DV/Recipes/Lathes/security.yml +++ b/Resources/Prototypes/_DV/Recipes/Lathes/security.yml @@ -353,6 +353,16 @@ Gold: 500 Wood: 300 +# .40 Anti-materiel Ammo for the NT-3 + +- type: latheRecipe + id: MagazineBoxLMGAntiMateriel + result: MagazineBoxLMGAntiMateriel + completetime: 4 + materials: + Steel: 1000 + Uranium: 250 + - type: latheRecipe id: PyroLeftArm result: PyroLeftArm diff --git a/Resources/Prototypes/_DV/tags.yml b/Resources/Prototypes/_DV/tags.yml index 8583a15937..76c3681e1f 100644 --- a/Resources/Prototypes/_DV/tags.yml +++ b/Resources/Prototypes/_DV/tags.yml @@ -36,6 +36,12 @@ - type: Tag id: BeltSlotNotBelt #not a 'belt' +- type: Tag + id: BlueprintAmmoTechfab + +- type: Tag + id: BlueprintSecurityTechfab + - type: Tag id: BluespaceCrystal @@ -57,6 +63,9 @@ - type: Tag id: CartridgeLaser +- type: Tag + id: CartridgeLMGAntiMateriel + - type: Tag id: CartridgeSpecial # For the .38 special ammo and revolver @@ -114,6 +123,9 @@ - type: Tag id: MagazineLaser +- type: Tag + id: MagazineLMGAntiMaterielBox # For the NT-3 + - type: Tag id: MagazinePistolSpecial # For the .38 special ammo and pistol diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/base.png b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/base.png new file mode 100644 index 0000000000..1411189aa7 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/base.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/inhand-left.png b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/inhand-left.png new file mode 100644 index 0000000000..69c5d22f28 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/inhand-left.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/inhand-right.png b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/inhand-right.png new file mode 100644 index 0000000000..933a741907 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/inhand-right.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-1.png b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-1.png new file mode 100644 index 0000000000..d0a93ba46b Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-1.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-2.png b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-2.png new file mode 100644 index 0000000000..45ac19d2e3 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-2.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-3.png b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-3.png new file mode 100644 index 0000000000..0c494d5b7c Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-3.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-4.png b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-4.png new file mode 100644 index 0000000000..1a16e5f051 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-4.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-5.png b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-5.png new file mode 100644 index 0000000000..ade381e298 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/mag-5.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/meta.json b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/meta.json new file mode 100644 index 0000000000..c75c79711d --- /dev/null +++ b/Resources/Textures/_DV/Objects/Weapons/Guns/Ammunition/Magazine/LightRifle/light_rifle_small_box.rsi/meta.json @@ -0,0 +1,37 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Sprites made by SirWarock on Github", + "states": [ + { + "name": "base" + }, + { + "name": "mag-1" + }, + { + "name": "mag-2" + }, + { + "name": "mag-3" + }, + { + "name": "mag-4" + }, + { + "name": "mag-5" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/base.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/base.png new file mode 100644 index 0000000000..8312066903 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/base.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/bipod-off.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/bipod-off.png new file mode 100644 index 0000000000..0f2e246ca0 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/bipod-off.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/bipod-on.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/bipod-on.png new file mode 100644 index 0000000000..d49e045a0b Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/bipod-on.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/bolt-open.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/bolt-open.png new file mode 100644 index 0000000000..aa34e1ec2a Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/bolt-open.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/equipped-BACKPACK.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/equipped-BACKPACK.png new file mode 100644 index 0000000000..744f1a264d Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/equipped-BACKPACK.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/icon.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/icon.png new file mode 100644 index 0000000000..9529e3e2e5 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/icon.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/inhand-left.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/inhand-left.png new file mode 100644 index 0000000000..e63d063816 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/inhand-left.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/inhand-right.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/inhand-right.png new file mode 100644 index 0000000000..10031db3be Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/inhand-right.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-0.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-0.png new file mode 100644 index 0000000000..1a9cce4016 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-0.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-1.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-1.png new file mode 100644 index 0000000000..ba5af62e85 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-1.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-2.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-2.png new file mode 100644 index 0000000000..19cdf885d0 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-2.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-3.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-3.png new file mode 100644 index 0000000000..4c6bb164d4 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/mag-3.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/meta.json b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/meta.json new file mode 100644 index 0000000000..5f8f819791 --- /dev/null +++ b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/meta.json @@ -0,0 +1,58 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Sprites made by SirWarock on Github.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "base" + }, + { + "name": "bolt-open" + }, + { + "name": "mag-0" + }, + { + "name": "mag-1" + }, + { + "name": "mag-2" + }, + { + "name": "mag-3" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "wielded-inhand-left", + "directions": 4 + }, + { + "name": "wielded-inhand-right", + "directions": 4 + }, + { + "name": "equipped-BACKPACK", + "directions": 4 + }, + { + "name": "bipod-off" + }, + { + "name": "bipod-on" + } + ] +} diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/wielded-inhand-left.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/wielded-inhand-left.png new file mode 100644 index 0000000000..fb99015027 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/wielded-inhand-left.png differ diff --git a/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/wielded-inhand-right.png b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/wielded-inhand-right.png new file mode 100644 index 0000000000..e31c94c868 Binary files /dev/null and b/Resources/Textures/_DV/Objects/Weapons/Guns/LMGs/NT-3.rsi/wielded-inhand-right.png differ