====== Custom Weaponry ====== You can create custom weaponry from deriving from one of the following classes: * Gun (Gun provides common useful methods such as ShootBullet that gun like weapons would find useful, it is derived from Weapon) * Melee (Melee has an Attack method, it is derived from Weapon) * Weapon (Weapon provides reload and ammo system and no more, it is derived from Carriable) * Carriable (Carriable provides nothing, its a bare bones thing that goes into your inventory and has a viewmodel) heres an example weapon you might find helpful using Editor; using Sandbox; using TerrorTown; [Library("ttt_weapon_overpowered"), HammerEntity] [Title("Overpowered Weapon"), Category("Weapons")] public class OverpoweredWeapon : Gun, ISecondaryWeapon, IRandomWeapon { public override string ViewModelPath => "weapons/rust_pistol/v_rust_pistol.vmdl"; public override string WorldModelPath => "weapons/rust_pistol/rust_pistol.vmdl"; public override float PrimaryAttackDelay => 0.000f; public override float PrimaryReloadDelay => 0.000f; public override int MaxPrimaryAmmo => 100000; public override AmmoType PrimaryAmmoType => AmmoType.Spare; public override float HeadshotMultiplier => 10.00f; public override bool Automatic => true; public override void PrimaryAttack() { PrimaryAmmo -= 1; ShootBullet(1000, 0.0f, 1000); PlaySound("rust_pistol.shoot"); (Owner as AnimatedEntity)?.SetAnimParameter("b_attack", true); ShootEffects(); } public override void ReloadPrimary() { base.ReloadPrimary(); } } if you would like to make a scope similar to the one on the m24, you can use this code snippet taken from the m24 public override void SecondaryAttack() { base.SecondaryAttack(); if ( Game.IsClient ) { if ( !Scoped ) { ScopeIn(); } else if ( Scoped ) { ScopeOut(); } } } ScopeOverlay ScopeOverlay; void ScopeIn() { Scoped = true; (Owner as Player).CameraController.SensitivityMultiplier = 25 / Game.Preferences.FieldOfView; (Owner as Player).CameraController.FOVMultiplier = 25 / Game.Preferences.FieldOfView; if ( Game.IsClient ) { ViewModelEntity.EnableDrawing = false; ScopeOverlay = new ScopeOverlay(); HUDRootPanel.Current.AddChild( ScopeOverlay ); PlaySound( "sniper.scope" ); } } void ScopeOut() { Scoped = false; (Owner as Player).CameraController.SensitivityMultiplier = 1; (Owner as Player).CameraController.FOVMultiplier = 1; if ( Game.IsClient ) { ViewModelEntity.EnableDrawing = true; ScopeOverlay?.Delete(); PlaySound( "sniper.scope" ); } } public override void OnActiveEnd() { ScopeOverlay?.Delete(); if ( Owner is Player player ) { player.CameraController.SensitivityMultiplier = 1; player.CameraController.FOVMultiplier = 1; } base.OnActiveEnd(); } Smoke Grenade Code using Editor; using Sandbox; namespace TerrorTown; [Library( "ttt_grenade_smoke" ), HammerEntity] [Title( "Smoke Grenade" ), Category( "Grenades" )] [EditorModel( "models/weapons/w_smokegrenade.vmdl" )] public class SmokeGrenade : Throwable, IGrenade, IRandomGrenade { public override string ViewModelPath => "models/weapons/v_smokegrenade.vmdl"; public override string WorldModelPath => "models/weapons/w_smokegrenade.vmdl"; public override void Throw() { if ( Game.IsServer ) { var Nade = new SmokeGrenadeThrown(); Nade.SetModel( WorldModelPath ); Nade.SetupPhysicsFromModel( PhysicsMotionType.Dynamic ); Nade.Position = Owner.AimRay.Position + (Owner.AimRay.Forward * 24) + (Vector3.Down * 5); Nade.PhysicsBody.Velocity = (Owner.AimRay.Forward * 900) + (Owner.AimRay.Forward.EulerAngles.ToRotation().Up * 80); Nade.PhysicsBody.Velocity += Owner.Velocity * 1f; Nade.PhysicsBody.AngularVelocity = Vector3.Random * 20; Nade.TimeOffset = TimeSinceClicked.Relative; } } } public class SmokeGrenadeThrown : BasePhysics { public float TimeOffset; public override void Spawn() { base.Spawn(); SetModel( "models/weapons/w_smokegrenade.vmdl" ); SetupPhysicsFromModel( PhysicsMotionType.Dynamic ); TimeSinceSpawned = 0; } TimeSince TimeSinceSpawned; Particles Particle; [GameEvent.Tick.Server] void tick() { if ( TimeSinceSpawned > (5 - TimeOffset) ) { if ( Particle == null ) { Particle = Particles.Create( "particles/smokegrenade.vpcf", this ); ParticleCleanupSystem.RegisterForCleanup( Particle ); } } if ( TimeSinceSpawned > (65 - TimeOffset) ) { Particle.Destroy(); } } }