mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
279 lines
5.9 KiB
Lua
279 lines
5.9 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_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
|