Players are sharing local variables and timers used in my SWEP
4 replies, posted
My earthshaker works great, however there are several problems due to the fact that it seems that players are somehow sharing variables and timers in my SWEP code. As in, one player will fire. Then during the 2 second delay that follows before the weapon's supposed to go off, another player will fire. The second player will then somehow [i]inherit[/i] the first player's attack, and when the first player's timer goes off the effect gets emitted from the second player. Also, there are problems with people's effects ending too soon or too late. Sometimes people cant even fire because other people are in the process of doing so. I'm thinking the ending too soon bug is something to do with the variable cur, but that's a local variable in the SWEP code! I thought any code inside the SWEP code was run specific to the player/weapon, hence self.Owner. I'm at a loss of what to do.
Here's the complete code for the weapon.
[lua]local cur = 0
local prevpos = Vector()
local parts = {}
local forward = Vector()
local up = Vector()
if (SERVER) then
AddCSLuaFile( "shared.lua" )
SWEP.Weight= 5
SWEP.AutoSwitchTo= false
SWEP.AutoSwitchFrom= false
end
if ( CLIENT ) then
SWEP.PrintName= "Earth Shaker"
SWEP.Slot= 4
SWEP.SlotPos= 1
SWEP.DrawAmmo= false
SWEP.DrawCrosshair= false
end
SWEP.Author= "shoffing"
SWEP.Contact= ""
SWEP.Purpose= "Makes the earth tremble."
SWEP.Instructions= "Primary to tremble the earth."
SWEP.Category= "Ants"
SWEP.Base= "weapon_base"
SWEP.HoldType= "pistol"
SWEP.Spawnable= true
SWEP.AdminSpawnable= true
SWEP.ViewModel= "models/weapons/v_pistol.mdl"
SWEP.WorldModel= "models/weapons/w_pistol.mdl"
SWEP.Primary.ClipSize= 1
SWEP.Primary.DefaultClip= 1
SWEP.Primary.Automatic= false
SWEP.Primary.Delay = 5
SWEP.Primary.Ammo= "none"
SWEP.Secondary.ClipSize= -1
SWEP.Secondary.DefaultClip= -1
SWEP.Secondary.Automatic= false
SWEP.Secondary.Ammo= "none"
--[[-------------------------------------------------------
Initialize
---------------------------------------------------------]]
function SWEP:Initialize()
if SERVER then self:SetWeaponHoldType( self.HoldType ) end
end
function SWEP:Precache()
end
--[[-------------------------------------------------------
Reload
---------------------------------------------------------]]
function SWEP:Reload()
end
--[[-------------------------------------------------------
Think
---------------------------------------------------------]]
function SWEP:Think()
end
--[[-------------------------------------------------------
PrimaryAttack
---------------------------------------------------------]]
function SWEP:PrimaryAttack()
local ply = self.Owner
if ply:GetNWBool("CanFire") then
ply:SetNWBool("CanFire", false)
local PartSys = ents.Create( "info_particle_system" )
PartSys:SetPos(ply:GetShootPos())
PartSys:SetAngles((ply:GetAimVector()*Vector(1,1,0)):Angle() )
PartSys:SetKeyValue( "effect_name", "striderbuster_attach" )
PartSys:SetKeyValue( "start_active", "1" )
PartSys:Spawn()
PartSys:Activate()
PartSys:SetParent(ply)
SafeRemoveEntityDelayed(PartSys, 5)
WorldSound("weapons/strider_buster/Strider_Buster_stick1.wav", ply:GetShootPos(), 100, 100)
timer.Create( "start"..ply:SteamID(), 1.5, 1, startshake )
end
end
function startshake()
forward = Angle(0,ply:GetAimVector():Angle().yaw,0):Forward()
local tr_et = util.QuickTrace( ply:GetShootPos(), forward*32, player.GetAll() )
if !tr_et.Hit then
WorldSound("ambient/levels/labs/electric_explosion1.wav",ply:GetShootPos(), 100, 160)
up = forward:Angle():Up()
prevpos = ply:GetPos()+Vector(0,0,16)+forward*32
timer.Create("shake"..ply:SteamID(), 0.1, 40, shake)
//print("=====")
else
WorldSound("buttons/combine_button_locked.wav",ply:GetShootPos(), 100, 160)
ply:SetNWBool("CanFire", true)
end
end
function shake()
if !ply:GetNWBool("CanFire") then
cur = cur+1
if(cur < 40) then
local myTeam = ply:Team()
local otherTeam = 0
if myTeam == 1 then
otherTeam = 2
elseif myTeam == 2 then
otherTeam = 1
end
local tr_forward = util.QuickTrace( prevpos, forward*32, player.GetAll() )
if tr_forward.Hit then
//print("Trace forward hit.")
tr_up = util.QuickTrace( tr_forward.HitPos + tr_forward.HitNormal*16, up*32, player.GetAll() )
if !tr_up.Hit then
//print("==Trace up not hit.")
forward, up = up, forward*-1
prevpos = tr_forward.HitPos + up*32
//do particle shit
if string.Explode(".", tostring(cur/2))[2] != nil then
ParticleEffect("rock_impact_stalactite", tr_forward.HitPos, forward)
ParticleEffect("rock_splinter_stalactite", tr_forward.HitPos, forward)
end
WorldSound( "ambient/explosions/explode_4.wav", tr_forward.HitPos, 10, 60 + cur*2 )
local dPos = tr_forward.HitPos
local dTrace = tr_forward
local inRange = ents.FindInSphere( dPos, 75 )
for _,b in pairs(inRange) do
if b:IsPlayer() then
if b:Team() == otherTeam then
b:TakeDamage( math.random(20,25), ply, ply:GetActiveWeapon() )
end
elseif b:GetNWInt( "team" ) == otherTeam then
b:TakeDamage( math.random(20,25), ply, ply:GetActiveWeapon() )
end
end
else
//print("Trace up hit.")
cur = 0
ply:SetNWBool("CanFire",true)
//print("=====")
timer.Stop("shake"..ply:SteamID())
end
else
//print("==Trace forward not hit.")
local tr_down = util.QuickTrace( tr_forward.HitPos, up*-64, player.GetAll() )
if !tr_down.Hit then
//print("==Trace down not hit.")
local tr_back = util.QuickTrace( tr_down.HitPos, forward*-32, player.GetAll() )
if tr_back.Hit then
//print("Trace back hit.")
forward, up = up*-1, forward
prevpos = tr_back.HitPos + up*16
//do particle shit
if string.Explode(".", tostring(cur/2))[2] != nil then
ParticleEffect("rock_impact_stalactite", tr_back.HitPos, forward)
ParticleEffect("rock_splinter_stalactite", tr_back.HitPos, forward)
end
WorldSound( "ambient/explosions/explode_4.wav", tr_forward.HitPos, 10, 60 + cur*2 )
local dPos = tr_back.HitPos
local dTrace = tr_back
local inRange = ents.FindInSphere( dPos, 75 )
for _,b in pairs(inRange) do
if b:IsPlayer() then
if b:Team() == otherTeam then
b:TakeDamage( math.random(20,25), ply, ply:GetActiveWeapon() )
end
elseif b:GetNWInt( "team" ) == otherTeam then
b:TakeDamage( math.random(20,25), ply, ply:GetActiveWeapon() )
end
end
else
//print("==Trace back not hit.")
cur = 0
ply:SetNWBool("CanFire",true)
//print("=====")
timer.Stop("shake"..ply:SteamID())
end
else
//print("Trace down hit.")
prevpos = tr_down.HitPos + up*16
//do particle shit
if string.Explode(".", tostring(cur/2))[2] != nil then
ParticleEffect("rock_impact_stalactite", tr_down.HitPos, forward)
ParticleEffect("rock_splinter_stalactite", tr_down.HitPos, forward)
end
WorldSound( "ambient/explosions/explode_4.wav", tr_forward.HitPos, 10, 60 + cur*2 )
local dPos = tr_down.HitPos
local dTrace = tr_down
local inRange = ents.FindInSphere( dPos, 75 )
for _,b in pairs(inRange) do
if b:IsPlayer() then
if b:Team() == otherTeam then
b:TakeDamage( math.random(20,25), ply, ply:GetActiveWeapon() )
end
elseif b:GetNWInt( "team" ) == otherTeam then
b:TakeDamage( math.random(20,25), ply, ply:GetActiveWeapon() )
end
end
end
end
debugoverlay.Line(prevpos, prevpos + forward*32, 10, Color(255,0,0))
debugoverlay.Cross(prevpos, 5, 10, Color(255, 255, 0))
else
cur = 0
ply:SetNWBool("CanFire", true)
timer.Stop("shake"..ply:SteamID())
end
end
end
--
Rather than just making local variables, it's good coding practice as well as a potential fix to make them variables on the SWEP table itself. i.e. SWEP.prevpos and whatnot. You can access these variables using self.prevpos and the likes.
Ohey entoros, and ok.
[editline]10:41PM[/editline]
That doesn't work. I get
Timer Error: ...memodes\ants\entities\weapons\earthshaker\shared.lua:102: attempt to index global 'self' (a nil value) because the 2 functions startshake and shake aren't associated with the weapon apparently.
Rather than just making them functions in space, you have to make them functions on the object. i.e.
[lua]function SWEP:shake()[/lua]
And then in your code, you can call the shake function from another SWEP function by doing
[lua]self:shake()[/lua]
still getting same error.
Sorry, you need to Log In to post a reply to this thread.