Files
wnsrc/lua/weapons/weapon_fists.lua
lifestorm 9c918c46e5 Upload
2024-08-04 23:12:27 +03:00

262 lines
6.3 KiB
Lua

--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
AddCSLuaFile()
SWEP.PrintName = "#GMOD_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 )
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