Files
wnsrc/lua/weapons/weapon_medkit.lua
lifestorm 94063e4369 Upload
2024-08-04 22:55:00 +03:00

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