Help with timer/HUD

Hey guys~
I’ve been editing my Murder server for a while now and perhaps making my own gamemode out of it on my private server. It’s quite a big project for someone who actually doesn’t quite know how to program in lua (I mostly program in Java, C#, or C++). Part of this gamemode is having the ability to revive someone who is dead via their dead body. I did have several ways of doing this and I wish I could show you what the code looked like but I narrowed it down to just tying to the “Hands” SWEP that is already in the gamemode. I copied all of the code from a TTT Defibrillator SWEP addon from https://github.com/willox/archive/blob/master/gmod-defibrillator-master/lua/weapons/weapon_ttt_defib.lua just to see if it would work, and if it did, I would change the whole thing entirely for this gamemode. The problem is, when I implemented the code into the “Hands” SWEP, the HUD seems to just completely ignore the timer and respawn the player immediately. I’ve been poking around the code for way too long to figure out what is actually happening. Can someone help me?

Here is my current code:



if SERVER then
	AddCSLuaFile()
else
	function SWEP:DrawWeaponSelection( x, y, w, h, alpha )
		-- draw.DrawText("Hands","Default",x + w * 0.44,y + h * 0.20,Color(0,50,200,alpha),1)
	end
end

local STATE_NONE, STATE_PROGRESS, STATE_ERROR = 0, 1, 2
local color_red = Color(255, 0, 0)

SWEP.Base = "weapon_mers_base"
SWEP.Slot = 0
SWEP.SlotPos = 1
SWEP.DrawCrosshair = false

SWEP.ViewModel	= "models/weapons/c_arms.mdl"
SWEP.WorldModel	= ""
SWEP.ViewModelFlip = false

SWEP.HoldType = "normal"
SWEP.SequenceDraw = "fists_draw"
SWEP.SequenceIdle = "fists_idle_01"

if CLIENT then
  surface.CreateFont("DefibText", {
    font = "Tahoma",
    size = 13,
    weight = 700,
    shadow = true
  })

  function SWEP:DrawHUD()
    local state = self:GetDefibState()
    local scrW, scrH = ScrW(), ScrH()
    local progress = 1
    local outlineCol, progressCol, progressText = color_white, color_white, ""

    if state == STATE_PROGRESS then
      local startTime, endTime = self:GetDefibStartTime(), self:GetDefibStartTime() + 5

      progress = math.TimeFraction(startTime, endTime, CurTime())

      if progress <= 0 then
        return
      end

      outlineCol = Color(0, 100, 0)
      progressCol = Color(0, 255, 0, (math.abs(math.sin(RealTime() * 3)) * 100) + 20)
      progressText = self:GetStateText() or "DEFIBRILLATING"
    elseif state == STATE_ERROR then
      outlineCol = color_red
      progressCol = Color(255, 0, 0, math.abs(math.sin(RealTime() * 15)) * 255)
      progressText = self:GetStateText() or ""
    else
      return
    end

    progress = math.Clamp(progress, 0, 1)

    surface.SetDrawColor(outlineCol)
    surface.DrawOutlinedRect(scrW / 2 - (200 / 2) - 1, scrH / 2 + 10 - 1, 202, 16)

    surface.SetDrawColor(progressCol)
    surface.DrawRect(scrW / 2  - (200 / 2), scrH / 2 + 10, 200 * progress, 14)

    surface.SetFont("DefibText")
    local textW, textH = surface.GetTextSize(progressText)

    surface.SetTextPos(scrW / 2 - 100 + 2, scrH / 2 - 20 + textH)
    surface.SetTextColor(color_white)
    surface.DrawText(progressText)
  end
end

function SWEP:SetupDataTables()
	self:NetworkVar("String", 0, "WeaponState")
	self:NetworkVar("Float", 0, "ReloadEnd")
	self:NetworkVar("Float", 1, "NextIdle")
	self:NetworkVar("Float", 2, "DrawEnd")
	self:NetworkVar("Int", 0, "DefibState")
  self:NetworkVar("Float", 1, "DefibStartTime")

  self:NetworkVar("String", 0, "StateText")
end

local taunts = {}

function addVoice(cat, soundFile, sex)
	if !taunts[cat] then
		taunts[cat] = {}
	end
	if !taunts[cat][sex] then
		taunts[cat][sex] = {}
	end
	local t = {}
	t.sound = soundFile
	t.sex = sex
	t.category = cat
	table.insert(taunts[cat][sex], t)
end

--Revive
addVoice("revive", "vo/npc/male01/health01.wav", "male")
addVoice("revive", "vo/npc/male01/health02.wav", "male")
addVoice("revive", "vo/npc/male01/health03.wav", "male")
addVoice("revive", "vo/npc/male01/health04.wav", "male")
addVoice("revive", "vo/npc/male01/health05.wav", "male")

addVoice("revive", "vo/npc/female01/health01.wav", "female")
addVoice("revive", "vo/npc/female01/health02.wav", "female")
addVoice("revive", "vo/npc/female01/health03.wav", "female")
addVoice("revive", "vo/npc/female01/health04.wav", "female")
addVoice("revive", "vo/npc/female01/health05.wav", "female")

SWEP.PrintName = translate and translate.hands or "Hands"
function SWEP:Initialize()
	self.PrintName = translate and translate.hands or "Hands"
	self.BaseClass.Initialize(self)
	self:SetDefibState(STATE_NONE)
  self:SetDefibStartTime(0)
end

local function addangle(ang,ang2)
	ang:RotateAroundAxis(ang:Up(),ang2.y) -- yaw
	ang:RotateAroundAxis(ang:Forward(),ang2.r) -- roll
	ang:RotateAroundAxis(ang:Right(),ang2.p) -- pitch
end

function SWEP:CalcViewModelView(vm, opos, oang, pos, ang)
	// iron sights
	local pos2 = Vector(-35, 0, 0)
	addangle(ang, Angle(-90, 0, 0))
	pos2:Rotate(ang)
	return pos + pos2, ang
end


local pickupWhiteList = {
	prop_ragdoll = true,
	prop_physics = true,
	prop_physics_multiplayer = true
}

if SERVER then
	function SWEP:CanPickup(ent)
		if ent:IsWeapon() || ent:IsPlayer() || ent:IsNPC() then return false end
		
		local class = ent:GetClass()
		if pickupWhiteList[class] then return true 
		
		elseif IsValid(target) and target:GetClass() == "prop_ragdoll" then
			return true
		end

		return false
	end
end

function SWEP:SecondaryAttack()
	if SERVER then
		--self:SetCarrying()
		local tr = self.Owner:GetEyeTraceNoCursor()

		if IsValid(tr.Entity) && self:CanPickup(tr.Entity) && (self.Owner:HasWeapon("weapon_mu_knife") || not self.Owner:GetMurderer()) then
			self:SetCarrying(tr.Entity, tr.PhysicsBone)
			self:ApplyForce()
		end
	end
end

function SWEP:ApplyForce()
	local target = self.Owner:GetAimVector() * 30 + self.Owner:GetShootPos()
	local phys = self.CarryEnt:GetPhysicsObjectNum(self.CarryBone)
	
	if IsValid(phys) then
		local vec = target - phys:GetPos()
		local len = vec:Length()
		if len > 40 then
			self:SetCarrying()
			return
		end

		vec:Normalize()
		
		local tvec = vec * len * 15
		local avec = tvec - phys:GetVelocity()
		avec = avec:GetNormal() * math.min(45, avec:Length())
		avec = avec / phys:GetMass() * 24
		
		phys:AddVelocity(avec)
	end
end

function SWEP:GetCarrying()
	return self.CarryEnt
end

function SWEP:SetCarrying(ent, bone)
	if IsValid(ent) then
		self.CarryEnt = ent
		self.CarryBone = bone
	else
		self.CarryEnt = nil
		self.CarryBone = nil
	end
	
	self.Owner:CalculateSpeed()
end

function SWEP:PrimaryAttack()
  if CLIENT then return end

  local tr = util.TraceLine({
    start = self.Owner:EyePos(),
    endpos = self.Owner:EyePos() + self.Owner:GetAimVector() * 80,
    filter = self.Owner
  })

  if IsValid(tr.Entity) and tr.Entity:GetClass() == "prop_ragdoll" then
    if not tr.Entity.uqid then
      self:FireError("FAILURE - SUBJECT BRAINDEAD")
      return
    end

    local ply = player.GetByUniqueID(tr.Entity.uqid)

    if IsValid(ply) then
      self:BeginDefib(ply, tr.Entity)
    else
      self:FireError("FAILURE - SUBJECT BRAINDEAD")
      return
    end
  else
    self:FireError("FAILURE - INVALID TARGET")
  end
end

function SWEP:BeginDefib(ply, ragdoll)
  local spawnPos = self:FindPosition(self.Owner)

  if not spawnPos then
    self:FireError("FAILURE - INSUFFICIENT ROOM")
    return
  end

  self:SetStateText("DEFIBRILLATING - "..string.upper(ply:Name()))
  self:SetDefibState(STATE_PROGRESS)
  self:SetDefibStartTime(CurTime())

  self.TargetPly = ply
  self.TargetRagdoll = ragdoll

  self:SetNextPrimaryFire(CurTime() + 6)
end

function SWEP:FireError(err)
  if err then
    self:SetStateText(err)
  else
    self:SetStateText("")
  end

  self:SetDefibState(STATE_ERROR)

  timer.Simple(1, function()
    if IsValid(self) then
      self:SetDefibState(STATE_NONE)
      self:SetStateText("")
    end
  end)

  self:SetNextPrimaryFire(CurTime() + 1.2)
end

function SWEP:FireSuccess()
  self:SetDefibState(STATE_NONE)
  self:SetNextPrimaryFire(CurTime() + 1)
  
  --hook.Call("UsedDefib", GAMEMODE, self.Owner)

  --self:Remove()
end

function SWEP:Think()
	self.BaseClass.Think(self)
	if IsValid(self.Owner) && self.Owner:KeyDown(IN_ATTACK2) then
		if IsValid(self.CarryEnt) then
			self:ApplyForce()
		end
	elseif self.CarryEnt then
		self:SetCarrying()
	else
		self.Owner:SetRunSpeed(200)
		self.Owner:SetWalkSpeed(200)
		self.Owner:SetCrouchedWalkSpeed(0.25)
		self.Owner:SetJumpPower(200)
	end
	
	if CLIENT then return end

  if self:GetDefibState() == STATE_PROGRESS then
    if not IsValid(self.Owner) then
      self:FireError()
      return
    end

    if not (IsValid(self.TargetPly) and IsValid(self.TargetRagdoll)) then
      self:FireError("ERROR - SUBJECT BRAINDEAD")
      return
    end

    local tr = util.TraceLine({
      start = self.Owner:EyePos(),
      endpos = self.Owner:EyePos() + self.Owner:GetAimVector() * 80,
      filter = self.Owner
    })

    if tr.Entity ~= self.TargetRagdoll then
      self:FireError("ERROR - TARGET LOST")
      return
    end

    if CurTime() >= self:GetDefibStartTime() + 5 then
      if self:HandleRespawn() then
        self:FireSuccess()
      else
        self:FireError("ERROR - INSUFFICIENT ROOM")
        return
      end
    end


    self:NextThink(CurTime())
    return true
  end
end

function SWEP:HandleRespawn()
  local ply, ragdoll = self.TargetPly, self.TargetRagdoll
  local spawnPos = self:FindPosition(self.Owner)
  
  print( self, type(self.Owner) )

  if not spawnPos then
    return false
  end

  ply:Spawn()
				ply:SetModel(ragdoll:GetModel())
				ply:SetPos(spawnPos)
				ply:SetEyeAngles(Angle(0, ragdoll:GetAngles().y, 0))
				ply:SetLootCollected(0)
				ply:Give("weapon_mu_hands")
				--self.Owner:SetLootCollected(self.Owner:GetLootCollected() - 6)
				ragdoll:Remove()
				
				local catRevive = "revive"
				local sexRevive = string.lower(ply.ModelSex or "male")
				local taunt = table.Random(taunts[catRevive][sexRevive])
				ply:EmitSound(taunt.sound, 100, 100)

  return true
end

local Positions = {}
for i=0,360,22.5 do table.insert( Positions, Vector(math.cos(i),math.sin(i),0) ) end -- Populate Around Player
table.insert(Positions, Vector(0, 0, 1)) -- Populate Above Player

function SWEP:FindPosition(ply)
  local size = Vector(32, 32, 72)
  
  local StartPos = ply:GetPos() + Vector(0, 0, size.z/2)
  
  local len = #Positions
  
  for i = 1, len do
    local v = Positions*
    local Pos = StartPos + v * size * 1.5
    
    local tr = {}
    tr.start = Pos
    tr.endpos = Pos
    tr.mins = size / 2 * -1
    tr.maxs = size / 2
    local trace = util.TraceHull(tr)
    
    if(not trace.Hit) then
      return Pos - Vector(0, 0, size.z/2)
    end
  end

  return false
end


[editline]24th October 2016[/editline]

Help on this would be so so soooo much appreciated, thanks~ :slight_smile:

I don’t mean to bump but can anyone help? :frowning: