mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-17 05:27:38 +03:00
More Gun Reworks: Manual Action Edition (#2165)
# Description This PR is yet another step on an ongoing set of refactors for guns. This restores the functionality for weapons to operate as "Manually Cycled", IE: Bolt Action or Pump Action. I've also fixed some older bugs related to firearms, such as manually loading cartridges not updating the ammo display, and manually cycling the gun not ejecting the cartridge. And even further, fixing instances where guns would fail to correctly eject cartridges using ejection force variables set by the gun itself. There's also some other small balancing changes to other guns that make use of the DamageModifier datafield added in my previous rework. Namely the Cobra and Mosin both use this datafield now. The .25 cartridge has had its damage reduced to 15 per shot(from 19), so that it is properly smaller than the .35 cartridge. This is largely to address issues of the FPA-90 and R25 rifles being kinda overpowered in their damage output. To keep this nerf from affecting the Cobra however, the Cobra has picked up an innate damage modifier that restores it to the original damage output. The Mosin's been rebalanced around its hunting rifle powerhouse aesthetic, it has a beefy damage modifier that brings it up to 42 damage per shot. This is acting as a fun tradeoff for it having only a 5 round internal magazine, and being changed to a bolt action weapon. It's still insanely cheap, to a point a traitor or a head revolutionary can afford 40 of them. This 42 damage calculation is specifically set such that you can consistently drop "wound into crit" unarmored crew in 2 shots (84+ HEAVY bleed will drop them consistently), while shooting security requires the full 5 rounds. The general gist of what these bolt action guns is that they'll typically have better characteristics for "Single source damage" than their non-bolt action counterparts. While for Shotguns, we can now make shotguns follow various common shotgun tropes that players expect from video games, such as the "Super shotgun" that obliterates anything at pointblank, or the "Street sweeper" that trades some of its accuracy for extra room coverage. Or the "hunting shotgun" that beats all of them at midrange. <details><summary><h1>Media</h1></summary> <p> https://github.com/user-attachments/assets/00ae2b34-f3f2-4fd9-adad-7147507a6c31 </p> </details> # Changelog 🆑 - add: Added "Bolt Action" or "Pump Action" gun options. - add: Added new sound fx for shotshells when landing on the ground or colliding with objects after being thrown. - tweak: Kammerer and Enforcer are now pump action shotguns, featuring a choke that gives them 50% tighter spreads in return for needing to be pumped (press Z) after each shot. - tweak: Mosin Nagant is now a proper bolt action rifle. The bolt must be worked manually (press Z) after each shot. The fun tradeoff is that it now hits like a truck with 42 damage a shot. - tweak: Bulldog shotgun now has a wide choke, it fires 33% more projectiles per shotshell, while also having a 50% wider spread. Cover the station hallways in lead. Pairs nicely with birdshot if you really want to sweep rooms. - tweak: R25 and FPA-90 both now deal 15 damage per shot, instead of 19. - fix: Fixed guns not correctly ejecting cartridges(they were instead dropping them at your feet). - fix: Fixed guns not updating the ammo counter UI when loaded manually. (cherry picked from commit a86362b8ad712678f1316e2cd55f5e888736f718)
This commit is contained in:
@@ -20,7 +20,7 @@ public sealed partial class GunSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates)
|
||||
protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates, GunComponent? gunComponent)
|
||||
{
|
||||
if (!Timing.IsFirstTimePredicted)
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Content.Server.Stack;
|
||||
using Content.Shared.Hands.EntitySystems; // WWDP
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Stacks;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
@@ -12,9 +12,11 @@ public sealed partial class GunSystem
|
||||
[Dependency] private readonly StackSystem _stack = default!; // WD EDIT
|
||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!; // WWDP
|
||||
|
||||
protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates)
|
||||
protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates, GunComponent? gunComponent)
|
||||
{
|
||||
EntityUid? ent = null;
|
||||
if (!Resolve(uid, ref gunComponent, false))
|
||||
return;
|
||||
|
||||
// TODO: Combine with TakeAmmo
|
||||
if (component.Entities.Count > 0)
|
||||
@@ -24,6 +26,7 @@ public sealed partial class GunSystem
|
||||
|
||||
Containers.Remove(existing, component.Container);
|
||||
EnsureShootable(existing);
|
||||
EjectCartridge(existing, gunComp: gunComponent);
|
||||
}
|
||||
else if (component.UnspawnedCount > 0)
|
||||
{
|
||||
@@ -33,7 +36,7 @@ public sealed partial class GunSystem
|
||||
}
|
||||
|
||||
if (ent != null)
|
||||
EjectCartridge(ent.Value);
|
||||
EjectCartridge(ent.Value, gunComp: gunComponent);
|
||||
|
||||
var cycledEvent = new GunCycledEvent();
|
||||
RaiseLocalEvent(uid, ref cycledEvent);
|
||||
|
||||
@@ -66,4 +66,16 @@ public sealed partial class BallisticAmmoProviderComponent : Component
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan FillDelay = TimeSpan.FromSeconds(0.5);
|
||||
|
||||
/// <summary>
|
||||
/// Is ammo ejected after each shot, or not.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool AutoCycle = true;
|
||||
|
||||
/// <summary>
|
||||
/// Is the gun ready to shoot; if AutoCycle is true then this will always stay true and not need to be manually done.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Cycled = true;
|
||||
}
|
||||
|
||||
@@ -351,7 +351,10 @@ public sealed partial class GunComponent : Component
|
||||
public float EjectionForce = 0.04f;
|
||||
|
||||
[DataField]
|
||||
public float EjectionSpeed = 5f;
|
||||
public float EjectionSpeed = 20f;
|
||||
|
||||
[DataField]
|
||||
public float EjectAngleOffset = 3.7f;
|
||||
|
||||
// WD EDIT START
|
||||
[DataField]
|
||||
|
||||
@@ -31,6 +31,7 @@ public abstract partial class SharedGunSystem
|
||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, GetAmmoCountEvent>(OnBallisticAmmoCount);
|
||||
|
||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, ExaminedEvent>(OnBallisticExamine);
|
||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, GetVerbsEvent<Verb>>(OnBallisticVerb);
|
||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, GetVerbsEvent<InteractionVerb>>(AddInteractionVerb); // WWDP
|
||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, GetVerbsEvent<AlternativeVerb>>(AddAlternativeVerb); // WWDP
|
||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, InteractUsingEvent>(OnBallisticInteractUsing);
|
||||
@@ -50,7 +51,9 @@ public abstract partial class SharedGunSystem
|
||||
|
||||
private void OnBallisticInteractUsing(EntityUid uid, BallisticAmmoProviderComponent component, InteractUsingEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
if (args.Handled
|
||||
|| _whitelistSystem.IsWhitelistFailOrNull(component.Whitelist, args.Used)
|
||||
|| GetBallisticShots(component) >= component.Capacity)
|
||||
return;
|
||||
|
||||
if (_whitelistSystem.IsWhitelistFailOrNull(component.Whitelist, args.Used))
|
||||
@@ -82,23 +85,20 @@ public abstract partial class SharedGunSystem
|
||||
// Not predicted so
|
||||
Audio.PlayPredicted(component.SoundInsert, uid, args.User);
|
||||
args.Handled = true;
|
||||
component.Cycled = true;
|
||||
UpdateAmmoCount(uid);
|
||||
UpdateBallisticAppearance(uid, component);
|
||||
Dirty(uid, component);
|
||||
}
|
||||
|
||||
private void OnBallisticAfterInteract(EntityUid uid, BallisticAmmoProviderComponent component, AfterInteractEvent args)
|
||||
{
|
||||
if (args.Handled ||
|
||||
!component.MayTransfer ||
|
||||
!Timing.IsFirstTimePredicted ||
|
||||
args.Target == null ||
|
||||
args.Used == args.Target ||
|
||||
Deleted(args.Target) ||
|
||||
!TryComp<BallisticAmmoProviderComponent>(args.Target, out var targetComponent) ||
|
||||
targetComponent.Whitelist == null)
|
||||
{
|
||||
if (args.Handled || !component.MayTransfer || !Timing.IsFirstTimePredicted
|
||||
|| args.Target is null || args.Used == args.Target
|
||||
|| Deleted(args.Target)
|
||||
|| !TryComp(args.Target, out BallisticAmmoProviderComponent? targetComponent)
|
||||
|| targetComponent.Whitelist is null)
|
||||
return;
|
||||
}
|
||||
|
||||
args.Handled = true;
|
||||
|
||||
@@ -115,9 +115,9 @@ public abstract partial class SharedGunSystem
|
||||
if (args.Handled || args.Cancelled) // WWDP
|
||||
return;
|
||||
|
||||
if (Deleted(args.Target) ||
|
||||
!TryComp<BallisticAmmoProviderComponent>(args.Target, out var target) ||
|
||||
target.Whitelist == null)
|
||||
if (Deleted(args.Target)
|
||||
|| !TryComp(args.Target, out BallisticAmmoProviderComponent? target)
|
||||
|| target.Whitelist is null)
|
||||
return;
|
||||
|
||||
if (target.Entities.Count + target.UnspawnedCount == target.Capacity)
|
||||
@@ -171,6 +171,7 @@ public abstract partial class SharedGunSystem
|
||||
// play sound to be cool
|
||||
Audio.PlayPredicted(component.SoundInsert, uid, args.User);
|
||||
SimulateInsertAmmo(ent.Value, args.Target.Value, Transform(args.Target.Value).Coordinates);
|
||||
component.Cycled = true; // Make sure when loading shells in shotguns, that the first round is chambered.
|
||||
}
|
||||
|
||||
if (IsClientSide(ent.Value))
|
||||
@@ -215,6 +216,19 @@ public abstract partial class SharedGunSystem
|
||||
}
|
||||
// WWDP edit end
|
||||
|
||||
private void OnBallisticVerb(EntityUid uid, BallisticAmmoProviderComponent component, GetVerbsEvent<Verb> args)
|
||||
{
|
||||
if (!args.CanAccess || !args.CanInteract || args.Hands == null || !component.Cycleable)
|
||||
return;
|
||||
|
||||
args.Verbs.Add(new Verb()
|
||||
{
|
||||
Text = Loc.GetString("gun-ballistic-cycle"),
|
||||
Disabled = GetBallisticShots(component) == 0,
|
||||
Act = () => ManualCycle(uid, component, TransformSystem.GetMapCoordinates(uid), args.User),
|
||||
});
|
||||
}
|
||||
|
||||
private void OnBallisticExamine(EntityUid uid, BallisticAmmoProviderComponent component, ExaminedEvent args)
|
||||
{
|
||||
if (!args.IsInDetailsRange)
|
||||
@@ -297,18 +311,18 @@ public abstract partial class SharedGunSystem
|
||||
return;
|
||||
|
||||
// Reset shotting for cycling
|
||||
if (Resolve(uid, ref gunComp, false) &&
|
||||
gunComp is { FireRateModified: > 0f } &&
|
||||
!Paused(uid))
|
||||
{
|
||||
if (Resolve(uid, ref gunComp, false)
|
||||
&& gunComp is { FireRateModified: > 0f }
|
||||
&& !Paused(uid))
|
||||
gunComp.NextFire = Timing.CurTime + TimeSpan.FromSeconds(1 / gunComp.FireRateModified);
|
||||
}
|
||||
|
||||
|
||||
Dirty(uid, component);
|
||||
Audio.PlayPredicted(component.SoundRack, uid, user);
|
||||
|
||||
var shots = GetBallisticShots(component);
|
||||
Cycle(uid, component, coordinates);
|
||||
component.Cycled = true;
|
||||
Cycle(uid, component, coordinates, gunComp);
|
||||
|
||||
var text = Loc.GetString(shots == 0 ? "gun-ballistic-cycled-empty" : "gun-ballistic-cycled");
|
||||
|
||||
@@ -319,7 +333,7 @@ public abstract partial class SharedGunSystem
|
||||
UpdateAmmoCount(uid);
|
||||
}
|
||||
|
||||
protected abstract void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates);
|
||||
protected abstract void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates, GunComponent? gunComponent = null);
|
||||
|
||||
private void OnBallisticInit(EntityUid uid, BallisticAmmoProviderComponent component, ComponentInit args)
|
||||
{
|
||||
@@ -341,15 +355,15 @@ public abstract partial class SharedGunSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected int GetBallisticShots(BallisticAmmoProviderComponent component)
|
||||
{
|
||||
return component.Entities.Count + component.UnspawnedCount;
|
||||
}
|
||||
protected int GetBallisticShots(BallisticAmmoProviderComponent component) => component.Entities.Count + component.UnspawnedCount;
|
||||
|
||||
private void OnBallisticTakeAmmo(EntityUid uid, BallisticAmmoProviderComponent component, TakeAmmoEvent args)
|
||||
{
|
||||
for (var i = 0; i < args.Shots; i++)
|
||||
{
|
||||
if (!component.Cycled)
|
||||
break;
|
||||
|
||||
EntityUid entity;
|
||||
|
||||
if (component.Entities.Count > 0)
|
||||
@@ -358,24 +372,24 @@ public abstract partial class SharedGunSystem
|
||||
|
||||
args.Ammo.Add((entity, EnsureShootable(entity)));
|
||||
|
||||
if (component.AutoCycle) // WD EDIT
|
||||
{
|
||||
component.Entities.RemoveAt(component.Entities.Count - 1);
|
||||
Containers.Remove(entity, component.Container);
|
||||
}
|
||||
// WWDP edit; support internal caseless ammo in hand-cycled guns
|
||||
else if (TryComp<CartridgeAmmoComponent>(entity, out var cartridge) && cartridge.DeleteOnSpawn)
|
||||
if (TryComp<CartridgeAmmoComponent>(entity, out var cartridge) && cartridge.DeleteOnSpawn)
|
||||
{
|
||||
component.Entities.RemoveAt(component.Entities.Count - 1);
|
||||
Containers.Remove(entity, component.Container);
|
||||
component.Racked = false;
|
||||
break;
|
||||
} // WWDP edit end
|
||||
else
|
||||
}
|
||||
// WWDP edit end
|
||||
|
||||
// if entity in container it can't be ejected, so shell will remain in gun and block next shoot
|
||||
if (!component.AutoCycle)
|
||||
{
|
||||
component.Racked = false; // WWDP
|
||||
break;
|
||||
}
|
||||
component.Entities.RemoveAt(component.Entities.Count - 1);
|
||||
Containers.Remove(entity, component.Container);
|
||||
}
|
||||
else if (component.UnspawnedCount > 0)
|
||||
{
|
||||
@@ -383,19 +397,22 @@ public abstract partial class SharedGunSystem
|
||||
entity = Spawn(component.Proto, args.Coordinates);
|
||||
args.Ammo.Add((entity, EnsureShootable(entity)));
|
||||
|
||||
// WD EDIT START
|
||||
if (!component.AutoCycle && TryComp<CartridgeAmmoComponent>(entity, out var cartridge))
|
||||
// Put it back in if it doesn't auto-cycle
|
||||
if (Timing.IsFirstTimePredicted && TryComp<CartridgeAmmoComponent>(entity, out var cartridge) && !component.AutoCycle) // WD EDIT
|
||||
{
|
||||
// WD EDIT START
|
||||
component.Racked = false;
|
||||
if (!cartridge.DeleteOnSpawn)
|
||||
{
|
||||
component.Entities.Add(entity);
|
||||
Containers.Insert(entity, component.Container);
|
||||
}
|
||||
break;
|
||||
if (cartridge.DeleteOnSpawn)
|
||||
break;
|
||||
// WD EDIT END
|
||||
|
||||
component.Entities.Add(entity);
|
||||
Containers.Insert(entity, component.Container);
|
||||
}
|
||||
// WD EDIT END
|
||||
}
|
||||
|
||||
if (!component.AutoCycle)
|
||||
component.Cycled = false;
|
||||
}
|
||||
|
||||
UpdateBallisticAppearance(uid, component);
|
||||
@@ -445,6 +462,4 @@ public abstract partial class SharedGunSystem
|
||||
/// DoAfter event for filling one ballistic ammo provider from another.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class AmmoFillDoAfterEvent : SimpleDoAfterEvent
|
||||
{
|
||||
}
|
||||
public sealed partial class AmmoFillDoAfterEvent : SimpleDoAfterEvent { }
|
||||
|
||||
@@ -540,10 +540,12 @@ public abstract partial class SharedGunSystem : EntitySystem
|
||||
{
|
||||
var throwingForce = 0.01f;
|
||||
var throwingSpeed = 5f;
|
||||
var ejectAngleOffset = 3.7f;
|
||||
if (gunComp is not null)
|
||||
{
|
||||
throwingForce = gunComp.EjectionForce;
|
||||
throwingSpeed = gunComp.EjectionSpeed;
|
||||
ejectAngleOffset = gunComp.EjectAngleOffset;
|
||||
}
|
||||
|
||||
// TODO: Sound limit version.
|
||||
@@ -555,15 +557,14 @@ public abstract partial class SharedGunSystem : EntitySystem
|
||||
|
||||
TransformSystem.SetLocalRotation(entity, Random.NextAngle(), xform);
|
||||
TransformSystem.SetCoordinates(entity, xform, coordinates);
|
||||
if (angle is null)
|
||||
angle = Random.NextAngle();
|
||||
|
||||
// decides direction the casing ejects and only when not cycling
|
||||
if (angle != null)
|
||||
{
|
||||
Angle ejectAngle = angle.Value;
|
||||
ejectAngle += 3.7f; // 212 degrees; casings should eject slightly to the right and behind of a gun
|
||||
ThrowingSystem.TryThrow(entity, ejectAngle.ToVec().Normalized() * throwingForce, throwingSpeed);
|
||||
}
|
||||
if (playSound && TryComp<CartridgeAmmoComponent>(entity, out var cartridge))
|
||||
Angle ejectAngle = angle.Value;
|
||||
ejectAngle += ejectAngleOffset; // 212 degrees; casings should eject slightly to the right and behind of a gun
|
||||
ThrowingSystem.TryThrow(entity, ejectAngle.ToVec().Normalized() * throwingForce, throwingSpeed);
|
||||
|
||||
if (playSound && TryComp(entity, out CartridgeAmmoComponent? cartridge))
|
||||
{
|
||||
Audio.PlayPvs(cartridge.EjectSound, entity, AudioParams.Default.WithVariation(SharedContentAudioSystem.DefaultVariation).WithVolume(-1f));
|
||||
}
|
||||
@@ -662,25 +663,14 @@ public abstract partial class SharedGunSystem : EntitySystem
|
||||
Dirty(projectile, targeted);
|
||||
}
|
||||
|
||||
public void SetFireRate(GunComponent component, float fireRate) // Goobstation
|
||||
{
|
||||
component.FireRate = fireRate;
|
||||
}
|
||||
public void SetFireRate(GunComponent component, float fireRate) => component.FireRate = fireRate;
|
||||
|
||||
public void SetUseKey(GunComponent component, bool useKey) // Goobstation
|
||||
{
|
||||
component.UseKey = useKey;
|
||||
}
|
||||
public void SetUseKey(GunComponent component, bool useKey) => component.UseKey = useKey;
|
||||
|
||||
public void SetSoundGunshot(GunComponent component, SoundSpecifier? sound) // Goobstation
|
||||
{
|
||||
component.SoundGunshot = sound;
|
||||
}
|
||||
public void SetSoundGunshot(GunComponent component, SoundSpecifier? sound) => component.SoundGunshot = sound;
|
||||
|
||||
public void SetClumsyProof(GunComponent component, bool clumsyProof) => component.ClumsyProof = clumsyProof;
|
||||
|
||||
public void SetClumsyProof(GunComponent component, bool clumsyProof) // Goobstation
|
||||
{
|
||||
component.ClumsyProof = clumsyProof;
|
||||
}
|
||||
protected abstract void CreateEffect(EntityUid gunUid, MuzzleFlashEvent message, EntityUid? user = null);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
- files:
|
||||
- "shotgun_shell1"
|
||||
- "shotgun_shell2"
|
||||
- "shotgun_shell3"
|
||||
license: "Custom"
|
||||
copyright: "Valve Software, Non-Commercial Steam Subscriber Agreement"
|
||||
source: "https://store.steampowered.com/app/220/HalfLife_2/"
|
||||
BIN
Resources/Audio/_EE/Weapons/Guns/Casings/shotgun_shell1.ogg
Normal file
BIN
Resources/Audio/_EE/Weapons/Guns/Casings/shotgun_shell1.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_EE/Weapons/Guns/Casings/shotgun_shell2.ogg
Normal file
BIN
Resources/Audio/_EE/Weapons/Guns/Casings/shotgun_shell2.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_EE/Weapons/Guns/Casings/shotgun_shell3.ogg
Normal file
BIN
Resources/Audio/_EE/Weapons/Guns/Casings/shotgun_shell3.ogg
Normal file
Binary file not shown.
@@ -3,6 +3,7 @@ gun-legality-salvage = This weapon is licensed for use in planetary expeditions.
|
||||
|
||||
# Weapon Modifiers
|
||||
gun-suppressed = This weapon comes with a built-in suppressor. It will be impossible to hear at a distance.
|
||||
gun-modifier-choke = This shotgun comes with a hunting choke. It has a 50% tighter spread when firing shotshells.
|
||||
|
||||
# Clothing Modifiers
|
||||
helmet-radio = This item includes a built-in radio, activate it to configure its settings.
|
||||
|
||||
@@ -438,7 +438,7 @@
|
||||
parent: ClothingBackpackDuffelSyndicateBundle
|
||||
id: ClothingBackpackDuffelSyndicateFilledFPA90
|
||||
name: FPA-90 bundle
|
||||
description: "A cheap integrally suppressed SMG. Comes bundled with three magazines."
|
||||
description: "A cheap integrally suppressed SMG. Magazines are sold separately."
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
|
||||
@@ -18,6 +18,16 @@
|
||||
map: [ "enum.AmmoVisualLayers.Base" ]
|
||||
- type: Appearance
|
||||
- type: SpentAmmoVisuals
|
||||
- type: EmitSoundOnLand
|
||||
sound:
|
||||
collection: ShellLand
|
||||
params:
|
||||
volume: -5
|
||||
- type: EmitSoundOnCollide
|
||||
sound:
|
||||
collection: ShellLand
|
||||
params:
|
||||
volume: -5
|
||||
|
||||
- type: entity
|
||||
id: ShellShotgunBeanbag
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
- type: Projectile
|
||||
damage:
|
||||
types:
|
||||
Piercing: 19
|
||||
Piercing: 15
|
||||
|
||||
- type: entity
|
||||
id: BulletCaselessRiflePractice
|
||||
@@ -30,7 +30,7 @@
|
||||
damage:
|
||||
types:
|
||||
Blunt: 3
|
||||
Heat: 16
|
||||
Heat: 12
|
||||
|
||||
- type: entity
|
||||
id: BulletCaselessRifleUranium
|
||||
@@ -41,8 +41,8 @@
|
||||
- type: Projectile
|
||||
damage:
|
||||
types:
|
||||
Radiation: 9
|
||||
Piercing: 10
|
||||
Radiation: 7
|
||||
Piercing: 8
|
||||
|
||||
- type: entity
|
||||
id: BulletCaselessRifleShrapnel
|
||||
@@ -53,7 +53,7 @@
|
||||
- type: Projectile
|
||||
damage:
|
||||
types:
|
||||
Piercing: 4.37
|
||||
Piercing: 3.75
|
||||
- type: Sprite
|
||||
scale: 0.5, 0.5
|
||||
|
||||
|
||||
@@ -10,8 +10,15 @@
|
||||
files:
|
||||
- "/Audio/Weapons/Guns/Casings/shotgun_fall.ogg"
|
||||
|
||||
- type: soundCollection
|
||||
id: ShellLand
|
||||
files:
|
||||
- "/Audio/_EE/Weapons/Guns/Casings/shotgun_shell1.ogg"
|
||||
- "/Audio/_EE/Weapons/Guns/Casings/shotgun_shell2.ogg"
|
||||
- "/Audio/_EE/Weapons/Guns/Casings/shotgun_shell3.ogg"
|
||||
|
||||
- type: soundCollection
|
||||
id: ToyFall
|
||||
files:
|
||||
- "/Audio/Items/Toys/ToyFall1.ogg"
|
||||
- "/Audio/Items/Toys/ToyFall2.ogg"
|
||||
- "/Audio/Items/Toys/ToyFall2.ogg"
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
tags:
|
||||
- Grenade
|
||||
capacity: 3
|
||||
autoCycle: false
|
||||
proto: GrenadeFrag
|
||||
soundInsert:
|
||||
path: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
- type: ChamberMagazineAmmoProvider
|
||||
boltClosed: null
|
||||
- type: Gun
|
||||
damageModifier: 1.25 # "Extra Robust" despite having an underpowered cartridge.
|
||||
fireRate: 4
|
||||
soundGunshot:
|
||||
path: /Audio/Weapons/Guns/Gunshots/silenced.ogg
|
||||
|
||||
@@ -284,7 +284,7 @@
|
||||
- 0,0,7,0
|
||||
sprite: Objects/Weapons/Guns/Shotguns/enforcer_inhands_64x.rsi
|
||||
- type: BallisticAmmoProvider
|
||||
autoCycle: true # WWDP semi-auto
|
||||
capacity: 7
|
||||
- type: Wieldable
|
||||
- type: MeleeWeapon
|
||||
attackRate: 1.4
|
||||
@@ -327,6 +327,12 @@
|
||||
- type: Wieldable
|
||||
- type: Gun
|
||||
shotgunSpreadMultiplier: 0.5
|
||||
- type: ExtendDescription
|
||||
descriptionList:
|
||||
- description: "gun-modifier-choke"
|
||||
fontSize: 12
|
||||
color: "#ff4f00"
|
||||
requireDetailRange: false
|
||||
|
||||
- type: entity
|
||||
name: sawn-off shotgun
|
||||
|
||||
Reference in New Issue
Block a user