mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 13:23:46 +03:00
262 lines
6.3 KiB
Lua
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
|