Initial commit

This commit is contained in:
2026-03-15 14:54:49 +03:00
commit 64f8029c06
4027 changed files with 254888 additions and 0 deletions

View File

@@ -0,0 +1,252 @@
AddCSLuaFile()
SWEP.PrintName = "#weapon_fists"
SWEP.Author = "Kilburn, robotboy655, MaxOfS2D & Tenrys"
SWEP.Purpose = "Well we sure as hell didn't use guns! We would just wrestle Hunters to the ground with our bare hands! I used to kill ten, twenty a day, just using my fists."
SWEP.Slot = 0
SWEP.SlotPos = 4
SWEP.Spawnable = true
SWEP.ViewModel = Model( "models/weapons/c_arms.mdl" )
SWEP.WorldModel = ""
SWEP.ViewModelFOV = 54
SWEP.UseHands = true
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = true
SWEP.Primary.Ammo = ""
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = true
SWEP.Secondary.Ammo = ""
SWEP.DrawAmmo = false
SWEP.SwingSound = Sound( "WeaponFrag.Throw" ) -- Sound of the fists swinging
SWEP.HitSound = Sound( "Flesh.ImpactHard" ) -- Sound of the fists hitting an entity
SWEP.HitDistance = 48 -- Distance of the punch
SWEP.HitDelay = 0.2 -- Delay between the punch being thrown and hitting an object
SWEP.HitForceScale = 80 -- Scalar force of the punch
SWEP.SwingCooldown = 0.9 -- Cooldown between punches
SWEP.ComboCount = 2 -- Number of successive punches needed for a combo punch
SWEP.ComboResetTime = 0.1 -- Time between the next punch being available and the combo couner resetting
-- Bounds of the punch's hull trace
SWEP.HitSize = {
Min = Vector( -10, -10, -8 ),
Max = Vector( 10, 10, 8 )
}
SWEP.HitDamage = { 8, 12 } -- Normal punch damage
SWEP.ComboDamage = { 12, 24 } -- Combo punch damage
function SWEP:Initialize()
self:SetHoldType( "fist" )
end
function SWEP:SetupDataTables()
self:NetworkVar( "Float", 0, "NextMeleeAttack" )
self:NetworkVar( "Float", 1, "NextIdle" )
self:NetworkVar( "Int", 2, "Combo" )
end
function SWEP:UpdateNextIdle()
local vm = self:GetOwner():GetViewModel()
self:SetNextIdle( CurTime() + vm:SequenceDuration() / vm:GetPlaybackRate() )
end
function SWEP:PrimaryAttack( right )
local owner = self:GetOwner()
owner:SetAnimation( PLAYER_ATTACK1 )
local anim = "fists_left"
if ( right ) then anim = "fists_right" end
if ( self:GetCombo() >= self.ComboCount ) then
anim = "fists_uppercut"
end
local vm = owner:GetViewModel()
vm:SendViewModelMatchingSequence( vm:LookupSequence( anim ) )
self:EmitSound( self.SwingSound )
self:UpdateNextIdle()
self:SetNextMeleeAttack( CurTime() + self.HitDelay )
self:SetNextPrimaryFire( CurTime() + self.SwingCooldown )
self:SetNextSecondaryFire( CurTime() + self.SwingCooldown )
end
function SWEP:SecondaryAttack()
self:PrimaryAttack( true )
end
local phys_pushscale = GetConVar( "phys_pushscale" )
function SWEP:DealDamage()
local owner = self:GetOwner()
local anim = self:GetSequenceName(owner:GetViewModel():GetSequence())
owner:LagCompensation( true )
local tr = util.TraceLine( {
start = owner:GetShootPos(),
endpos = owner:GetShootPos() + owner:GetAimVector() * self.HitDistance,
filter = owner,
mask = MASK_SHOT_HULL
} )
if ( !IsValid( tr.Entity ) ) then
tr = util.TraceHull( {
start = owner:GetShootPos(),
endpos = owner:GetShootPos() + owner:GetAimVector() * self.HitDistance,
filter = owner,
mins = self.HitSize.Min,
maxs = self.HitSize.Max,
mask = MASK_SHOT_HULL
} )
end
-- We need the second part for single player because SWEP:Think is ran shared in SP
if ( tr.Hit and !( game.SinglePlayer() and CLIENT ) ) then
self:EmitSound( self.HitSound )
end
local hit = false
local scale = phys_pushscale:GetFloat()
if ( SERVER and IsValid( tr.Entity ) and ( tr.Entity:IsNPC() or tr.Entity:IsPlayer() or tr.Entity:Health() > 0 ) ) then
local dmginfo = DamageInfo()
local attacker = owner
if ( !IsValid( attacker ) ) then attacker = self end
dmginfo:SetAttacker( attacker )
dmginfo:SetInflictor( self )
dmginfo:SetWeapon( self )
local dmg = self.HitDamage
if ( anim == "fists_left" ) then
dmginfo:SetDamageForce( owner:GetRight() * 4912 * scale + owner:GetForward() * 9998 * scale ) -- Yes we need those specific numbers
elseif ( anim == "fists_right" ) then
dmginfo:SetDamageForce( owner:GetRight() * -4912 * scale + owner:GetForward() * 9989 * scale )
elseif ( anim == "fists_uppercut" ) then
dmginfo:SetDamageForce( owner:GetUp() * 5158 * scale + owner:GetForward() * 10012 * scale )
dmg = self.ComboDamage
end
dmginfo:SetDamage( istable( dmg ) and math.random( dmg[ 1 ], dmg[ 2 ] ) or dmg )
SuppressHostEvents( NULL ) -- Let the breakable gibs spawn in multiplayer on client
tr.Entity:TakeDamageInfo( dmginfo )
SuppressHostEvents( owner )
hit = true
end
if ( IsValid( tr.Entity ) ) then
local phys = tr.Entity:GetPhysicsObject()
if ( IsValid( phys ) ) then
phys:ApplyForceOffset( owner:GetAimVector() * self.HitForceScale * phys:GetMass() * scale, tr.HitPos )
end
end
if ( SERVER ) then
if ( hit and anim != "fists_uppercut" ) then
self:SetCombo( self:GetCombo() + 1 )
else
self:SetCombo( 0 )
end
end
owner:LagCompensation( false )
end
function SWEP:OnDrop()
self:Remove() -- You can't drop fists
end
local sv_deployspeed = GetConVar( "sv_defaultdeployspeed" )
function SWEP:Deploy()
local speed = sv_deployspeed:GetFloat()
local vm = self:GetOwner():GetViewModel()
vm:SendViewModelMatchingSequence( vm:LookupSequence( "fists_draw" ) )
vm:SetPlaybackRate( speed )
self:SetNextPrimaryFire( CurTime() + vm:SequenceDuration() / speed )
self:SetNextSecondaryFire( CurTime() + vm:SequenceDuration() / speed )
self:UpdateNextIdle()
if ( SERVER ) then
self:SetCombo( 0 )
end
return true
end
function SWEP:Holster()
self:SetNextMeleeAttack( 0 )
return true
end
function SWEP:Think()
local vm = self:GetOwner():GetViewModel()
local curtime = CurTime()
local idletime = self:GetNextIdle()
if ( idletime > 0 and curtime > idletime ) then
vm:SendViewModelMatchingSequence( vm:LookupSequence( "fists_idle_0" .. math.random( 1, 2 ) ) )
self:UpdateNextIdle()
end
local meleetime = self:GetNextMeleeAttack()
if ( meleetime > 0 and curtime > meleetime ) then
self:DealDamage()
self:SetNextMeleeAttack( 0 )
end
if ( SERVER and curtime > self:GetNextPrimaryFire() + self.ComboResetTime ) then
self:SetCombo( 0 )
end
end

View File

@@ -0,0 +1,115 @@
AddCSLuaFile()
SWEP.PrintName = "#weapon_flechettegun"
SWEP.Author = "garry"
SWEP.Purpose = "Shoot flechettes with primary attack."
SWEP.Slot = 1
SWEP.SlotPos = 2
SWEP.Spawnable = true
SWEP.ViewModel = Model( "models/weapons/c_smg1.mdl" )
SWEP.WorldModel = Model( "models/weapons/w_smg1.mdl" )
SWEP.ViewModelFOV = 54
SWEP.UseHands = true
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = true
SWEP.Primary.Ammo = "none"
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
SWEP.DrawAmmo = false
SWEP.AdminOnly = true
game.AddParticles( "particles/hunter_flechette.pcf" )
game.AddParticles( "particles/hunter_projectile.pcf" )
local ShootSound = Sound( "NPC_Hunter.FlechetteShoot" )
function SWEP:Initialize()
self:SetHoldType( "smg" )
end
function SWEP:Reload()
end
function SWEP:CanBePickedUpByNPCs()
return true
end
function SWEP:PrimaryAttack()
self:SetNextPrimaryFire( CurTime() + 0.1 )
self:EmitSound( ShootSound )
self:ShootEffects()
if ( CLIENT ) then return end
SuppressHostEvents( NULL ) -- Do not suppress the flechette effects
local ent = ents.Create( "hunter_flechette" )
if ( !IsValid( ent ) ) then return end
local owner = self:GetOwner()
local Forward = owner:GetAimVector()
ent:SetPos( owner:GetShootPos() + Forward * 32 )
ent:SetAngles( owner:EyeAngles() )
ent:SetOwner( owner )
ent:Spawn()
ent:Activate()
ent:SetVelocity( Forward * 2000 )
end
function SWEP:SecondaryAttack()
-- TODO: Reimplement the old rollermine secondary attack?
end
function SWEP:ShouldDropOnDie()
return false
end
function SWEP:GetNPCRestTimes()
-- Handles the time between bursts
-- Min rest time in seconds, max rest time in seconds
return 0.3, 0.6
end
function SWEP:GetNPCBurstSettings()
-- Handles the burst settings
-- Minimum amount of shots, maximum amount of shots, and the delay between each shot
-- The amount of shots can end up lower than specificed
return 1, 6, 0.1
end
function SWEP:GetNPCBulletSpread( proficiency )
-- Handles the bullet spread based on the given proficiency
-- return value is in degrees
return 1
end

View File

@@ -0,0 +1,268 @@
AddCSLuaFile()
SWEP.PrintName = "#weapon_medkit"
SWEP.Author = "robotboy655, MaxOfS2D, code_gs"
SWEP.Purpose = "Heal other people with primary attack, heal yourself with secondary attack."
SWEP.Slot = 5
SWEP.SlotPos = 3
SWEP.Spawnable = true
SWEP.ViewModel = Model( "models/weapons/c_medkit.mdl" )
SWEP.WorldModel = Model( "models/weapons/w_medkit.mdl" )
SWEP.ViewModelFOV = 54
SWEP.UseHands = true
SWEP.Primary.ClipSize = 100
SWEP.Primary.DefaultClip = SWEP.Primary.ClipSize
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = ""
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = ""
SWEP.HoldType = "slam"
SWEP.HealSound = Sound( "HealthKit.Touch" )
SWEP.DenySound = Sound( "WallHealth.Deny" )
SWEP.HealCooldown = 0.5 -- Time between successful heals
SWEP.DenyCooldown = 1 -- Time between unsuccessful heals
SWEP.HealAmount = 20 -- Maximum heal amount per use
SWEP.HealRange = 64 -- Range in units at which healing works
SWEP.AmmoRegenRate = 1 -- Number of seconds before each ammo regen
SWEP.AmmoRegenAmount = 2 -- Amount of ammo refilled every AmmoRegenRate seconds
function SWEP:Initialize()
self:SetHoldType( self.HoldType )
-- Prevent large ammo jumps on-creation
-- if DefaultClip < ClipSize
self:SetLastAmmoRegen( CurTime() )
if ( CLIENT ) then
self.AmmoDisplay = {
Draw = true,
PrimaryClip = 0
}
end
end
function SWEP:Deploy()
-- Regen what we've gained since we've holstered
-- and realign the timer
self:Regen( false )
return true
end
function SWEP:SetupDataTables()
self:NetworkVar( "Float", 0, "LastAmmoRegen" )
self:NetworkVar( "Float", 1, "NextIdle" )
end
function SWEP:PrimaryAttack()
local owner = self:GetOwner()
local dolagcomp = SERVER and owner:IsPlayer()
if ( dolagcomp ) then
owner:LagCompensation( true )
end
local startpos = owner:GetShootPos()
local tr = util.TraceLine( {
start = startpos,
endpos = startpos + owner:GetAimVector() * self.HealRange,
filter = owner
} )
if ( dolagcomp ) then
owner:LagCompensation( false )
end
self:DoHeal( tr.Entity )
end
function SWEP:SecondaryAttack()
self:DoHeal( self:GetOwner() )
end
function SWEP:Reload()
end
local DAMAGE_YES = 2
-- Basic black/whitelist function
-- Checking if the entity's health is below its max is done in SWEP:DoHeal
function SWEP:CanHeal( ent )
-- ent may be NULL here, but these functions return false for it
if ( ent:IsPlayer() or ent:IsNPC() ) then
local takedamage = ent:GetInternalVariable( "m_takedamage" )
-- Don't heal turrets and helicopters
return takedamage == nil or takedamage == DAMAGE_YES
end
return false
end
function SWEP:DoHeal( ent )
local amount = self.HealAmount
if ( !self:CanHeal( ent ) ) then self:HealFail( ent ) return false end
local health, maxhealth = ent:Health(), ent:GetMaxHealth()
if ( health >= maxhealth ) then self:HealFail( ent ) return false end
-- Check regen right before we access the clip
-- to make sure we're up to date
self:Regen( true )
local healamount = self.HealAmount
-- No support for "damage kits"
if ( healamount > 0 ) then
healamount = math.min( maxhealth - health, healamount )
local ammo = self:Clip1()
if ( ammo < healamount ) then self:HealFail( ent ) return false end
-- Heal ent
self:SetClip1( ammo - healamount )
ent:SetHealth( health + healamount )
else
healamount = 0
end
self:HealSuccess( ent, healamount )
return true
end
function SWEP:HealSuccess( ent, healamount )
-- Do effects
self:EmitSound( self.HealSound )
self:SendWeaponAnim( ACT_VM_PRIMARYATTACK )
local owner = self:GetOwner()
if ( owner:IsValid() ) then
owner:SetAnimation( PLAYER_ATTACK1 )
end
local curtime = CurTime()
-- Reset regen time
self:SetLastAmmoRegen( curtime )
-- Set next idle time
local endtime = curtime + self:SequenceDuration()
self:SetNextIdle( endtime )
-- Set next firing time
endtime = endtime + self.HealCooldown
self:SetNextPrimaryFire( endtime )
self:SetNextSecondaryFire( endtime )
end
function SWEP:HealFail( ent )
-- Do effects
self:EmitSound( self.DenySound )
-- Setup next firing time
local endtime = CurTime() + self.DenyCooldown
self:SetNextPrimaryFire( endtime )
self:SetNextSecondaryFire( endtime )
end
function SWEP:Think()
-- Try ammo regen
-- but keep it aligned to the last action time
self:Regen( true )
-- Do idle anim
self:Idle()
end
function SWEP:Regen( keepaligned )
local curtime = CurTime()
local lastregen = self:GetLastAmmoRegen()
local timepassed = curtime - lastregen
local regenrate = self.AmmoRegenRate
-- Not ready to regenerate
if ( timepassed < regenrate ) then return false end
local ammo = self:Clip1()
local maxammo = self.Primary.ClipSize
-- Already at/over max ammo
if ( ammo >= maxammo ) then return false end
if ( regenrate > 0 ) then
self:SetClip1( math.min( ammo + math.floor( timepassed / regenrate ) * self.AmmoRegenAmount, maxammo ) )
-- If we are setting the last regen time from the Think function,
-- keep it aligned with the last action time to prevent late Thinks from
-- creating hiccups in the rate
self:SetLastAmmoRegen( keepaligned == true and curtime + timepassed % regenrate or curtime )
else
self:SetClip1( maxammo )
self:SetLastAmmoRegen( curtime )
end
return true
end
function SWEP:Idle()
-- Update idle anim
local curtime = CurTime()
if ( curtime < self:GetNextIdle() ) then return false end
self:SendWeaponAnim( ACT_VM_IDLE )
self:SetNextIdle( curtime + self:SequenceDuration() )
return true
end
-- The following code does not need to exist on the server, so bail
if ( SERVER ) then return end
function SWEP:CustomAmmoDisplay()
local display = self.AmmoDisplay
display.PrimaryClip = self:Clip1()
return display
end

View File

@@ -0,0 +1,275 @@
AddCSLuaFile()
SWEP.PrintName = "Аптечка"
SWEP.Author = "robotboy655, MaxOfS2D, code_gs"
SWEP.Purpose = "Heal other people with primary attack, heal yourself with secondary attack."
SWEP.Slot = 5
SWEP.SlotPos = 3
SWEP.Spawnable = true
SWEP.ViewModel = Model( "models/weapons/c_medkit.mdl" )
SWEP.WorldModel = Model( "models/weapons/w_medkit.mdl" )
SWEP.ViewModelFOV = 54
SWEP.UseHands = true
SWEP.Primary.ClipSize = 100
SWEP.Primary.DefaultClip = SWEP.Primary.ClipSize
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = ""
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = ""
SWEP.HoldType = "slam"
SWEP.HealSound = Sound( "HealthKit.Touch" )
SWEP.DenySound = Sound( "WallHealth.Deny" )
SWEP.HealCooldown = 0.5 -- Time between successful heals
SWEP.DenyCooldown = 1 -- Time between unsuccessful heals
SWEP.HealAmount = 20 -- Maximum heal amount per use
SWEP.HealRange = 64 -- Range in units at which healing works
SWEP.AmmoRegenRate = 1 -- Number of seconds before each ammo regen
SWEP.AmmoRegenAmount = 2 -- Amount of ammo refilled every AmmoRegenRate seconds
function SWEP:Initialize()
self:SetHoldType( self.HoldType )
-- Prevent large ammo jumps on-creation
-- if DefaultClip < ClipSize
self:SetLastAmmoRegen( CurTime() )
if ( CLIENT ) then
self.AmmoDisplay = {
Draw = true,
PrimaryClip = 0
}
end
end
function SWEP:Deploy()
-- Regen what we've gained since we've holstered
-- and realign the timer
self:Regen( false )
return true
end
function SWEP:SetupDataTables()
self:NetworkVar( "Float", 0, "LastAmmoRegen" )
self:NetworkVar( "Float", 1, "NextIdle" )
end
function SWEP:PrimaryAttack()
local owner = self:GetOwner()
local dolagcomp = SERVER and owner:IsPlayer()
if ( dolagcomp ) then
owner:LagCompensation( true )
end
local startpos = owner:GetShootPos()
local tr = util.TraceLine( {
start = startpos,
endpos = startpos + owner:GetAimVector() * self.HealRange,
filter = owner
} )
if ( dolagcomp ) then
owner:LagCompensation( false )
end
self:DoHeal( tr.Entity )
end
function SWEP:SecondaryAttack()
self:DoHeal( self:GetOwner() )
end
function SWEP:Reload()
end
local DAMAGE_YES = 2
-- Basic black/whitelist function
-- Checking if the entity's health is below its max is done in SWEP:DoHeal
function SWEP:CanHeal( ent )
-- ent may be NULL here, but these functions return false for it
if ( ent:IsPlayer() or ent:IsNPC() ) then
local takedamage = ent:GetInternalVariable( "m_takedamage" )
-- Don't heal turrets and helicopters
return takedamage == nil or takedamage == DAMAGE_YES
end
return false
end
function SWEP:DoHeal( ent )
local amount = self.HealAmount
if ( !self:CanHeal( ent ) ) then self:HealFail( ent ) return false end
local health, maxhealth = ent:Health(), ent:GetMaxHealth()
if ( health >= maxhealth ) then self:HealFail( ent ) return false end
-- Check regen right before we access the clip
-- to make sure we're up to date
self:Regen( true )
local healamount = self.HealAmount
-- No support for "damage kits"
if ( healamount > 0 ) then
healamount = math.min( maxhealth - health, healamount )
local ammo = self:Clip1()
if ( ammo < healamount ) then self:HealFail( ent ) return false end
-- Heal ent
self:SetClip1( ammo - healamount )
ent:SetHealth( health + healamount )
else
healamount = 0
end
self:HealSuccess( ent, healamount )
return true
end
local ix_heal_payment = 2
function SWEP:HealSuccess( ent, healamount )
-- Do effects
self:EmitSound( self.HealSound )
self:SendWeaponAnim( ACT_VM_PRIMARYATTACK )
local owner = self:GetOwner()
if ( owner:IsValid() ) then
owner:SetAnimation( PLAYER_ATTACK1 )
if owner:GetCharacter() and ent != owner then
owner:GetCharacter():GiveMoney(ix_heal_payment)
owner:NotifyLocalized("healed_ply",ix.currency.Get(ix_heal_payment))
end
end
local curtime = CurTime()
-- Reset regen time
self:SetLastAmmoRegen( curtime )
-- Set next idle time
local endtime = curtime + self:SequenceDuration()
self:SetNextIdle( endtime )
-- Set next firing time
endtime = endtime + self.HealCooldown
self:SetNextPrimaryFire( endtime )
self:SetNextSecondaryFire( endtime )
end
function SWEP:HealFail( ent )
-- Do effects
self:EmitSound( self.DenySound )
-- Setup next firing time
local endtime = CurTime() + self.DenyCooldown
self:SetNextPrimaryFire( endtime )
self:SetNextSecondaryFire( endtime )
end
function SWEP:Think()
-- Try ammo regen
-- but keep it aligned to the last action time
self:Regen( true )
-- Do idle anim
self:Idle()
end
function SWEP:Regen( keepaligned )
local curtime = CurTime()
local lastregen = self:GetLastAmmoRegen()
local timepassed = curtime - lastregen
local regenrate = self.AmmoRegenRate
-- Not ready to regenerate
if ( timepassed < regenrate ) then return false end
local ammo = self:Clip1()
local maxammo = self.Primary.ClipSize
-- Already at/over max ammo
if ( ammo >= maxammo ) then return false end
if ( regenrate > 0 ) then
self:SetClip1( math.min( ammo + math.floor( timepassed / regenrate ) * self.AmmoRegenAmount, maxammo ) )
-- If we are setting the last regen time from the Think function,
-- keep it aligned with the last action time to prevent late Thinks from
-- creating hiccups in the rate
self:SetLastAmmoRegen( keepaligned == true and curtime + timepassed % regenrate or curtime )
else
self:SetClip1( maxammo )
self:SetLastAmmoRegen( curtime )
end
return true
end
function SWEP:Idle()
-- Update idle anim
local curtime = CurTime()
if ( curtime < self:GetNextIdle() ) then return false end
self:SendWeaponAnim( ACT_VM_IDLE )
self:SetNextIdle( curtime + self:SequenceDuration() )
return true
end
-- The following code does not need to exist on the server, so bail
if ( SERVER ) then return end
function SWEP:CustomAmmoDisplay()
local display = self.AmmoDisplay
display.PrimaryClip = self:Clip1()
return display
end