Borderlands Corrosive Elemental Damage

Hi, im having some trouble implementing elemental damage like that seen in borderlands. Players and NPC’s can be corrodes by taking acid damage, which causes them to take more damage over time and be more succeptable to other damage. The error im getting is that at line 44, im trying to to an arithmetic to v.ele_corrode which i cant do apparently. Im not too familar with how to assign variables to entities. Whats the problem?




function MakeCorrosivePlayer( ent )
          ent.ele_corrode = 0
end
hook.Add("PlayerSpawn","MakeCorrosivePlayer",MakeCorrosivePlayer)
hook.Add("PlayerInitialSpawn","MakeCorrosivePlayer",MakeCorrosivePlayer)

function MakeCorrosiveNPC( ent )
     if ( ent:IsNPC() ) then
          ent.ele_corrode = 0
     end
end
hook.Add("OnEntityCreated","MakeCorrosiveNPC",MakeCorrosiveNPC)

function ScaleCorrosiveDamage( ent , hitgroup , dmginfo )
	
	if ( dmginfo:GetDamageType() == DMG_ACID ) then
	ent.ele_corrode = math.min(100,ent.ele_corrode+dmginfo:GetDamage())
	end
	dmginfo:ScaleDamage( 1+ent.ele_corrosive/33 )

end
hook.Add("ScaleNPCDamage","ScaleCorrosiveDamage",ScaleCorrosiveDamage)
hook.Add("ScalePlayerDamage","ScaleCorrosiveDamage",ScaleCorrosiveDamage)

function DoCorrosiveDamage()
	for _, v in pairs( ents.FindByClass( "npc*" ) ) do
		v:SetHealth(v:Health()-v.ele_corrode/10)
		v:SetColor(255-v.ele_corrode,255,255-v.ele_corrode,255)
		v.ele_corrode = math.max(0,v.ele_corrode-1)
		
		if ( v.ele_corrode>0 ) then
		local effectdata = EffectData()
		local vPoint = v:GetPhysicsObject():GetMassCenter()
		effectdata:SetStart( vPoint )
		effectdata:SetOrigin( vPoint )
		effectdata:SetScale( 1 )
		util.Effect( "effect_corrosive", effectdata )
		end
		
	end
	
	for _, v in pairs( ents.FindByClass( "player" ) ) do
		v:SetHealth(v:Health()-v.ele_corrode/10)
		v:SetColor(255-v.ele_corrode,255,255-v.ele_corrode,255) <-- screws up here at 255-v.ele_corrode
		v.ele_corrode = math.max(0,v.ele_corrode-1)
		
		if ( v.ele_corrode>0 ) then
		local effectdata = EffectData()
		local vPoint = v:GetPhysicsObject():GetMassCenter()
		effectdata:SetStart( vPoint )
		effectdata:SetOrigin( vPoint )
		effectdata:SetScale( 1 )
		util.Effect( "effect_corrosive", effectdata )
		end
		
	end
end

timer.Create("corrosive_effect",1,1,DoCorrosiveDamage)


The problem is probably that v.ele_corrode is nil (which means it hasn’t been set). There are entities with names starting with npc that aren’t actually NPCs. Inside the first for loop, at the start, try using:
[lua]
if not v:IsNPC() then continue end
[/lua]
or
[lua]
if v.ele_corrode == nil then continue end
[/lua]

Ok, im not getting any more errors, but i dont think its working either. Unless the antlion worker doesnt actually use DMG_ACID.

Print dmginfo:GetDamageType() just above the if statement, it’ll tell you what the damage type is.

It still says the value is nil. It ALWAYS says the value is nil. Am i not defining these variables right or something?

EDIT:

Nevermind, i think i may have seen the problem. Lemme get back to this with whether or not it works.

I fixed it so it works for a while, but then it stops working after some time. I don’t know whats wrong because it doesn’t give me an error message. I assume its something do do with an invalid entity, but im not sure. Also, the NPC’s take the damage fine and everything works for them, but me, the player, remains unaffected by the corrosion.

On a separate note, how could i make it so a swep has the damage type DMG_ACID? Currently every damage in the game is corrosive because i don’t have a weapon that does acid damage. I was thinking I could just include in the lua/autorun folder of a swep some code that uses ScaleNPC/PlayerDamage and if the inflictor is that weapon, it changes its damage type to DMG_ACID. Is there an easier way? Will scaling the damage there interfere with scaling the damage in THIS code?




function MakeCorrosivePlayer( ent )
	ent.ele_corrode = 0
end
hook.Add("PlayerSpawn","MakeCorrosivePlayer",MakeCorrosivePlayer)
hook.Add("PlayerInitialSpawn","MakeCorrosivePlayer",MakeCorrosivePlayer)

function MakeCorrosiveNPC( ent )
	if !ent:IsValid() then return end
    if ( ent:IsNPC() ) then
        ent.ele_corrode = 0
    end
end
hook.Add("OnEntityCreated","MakeCorrosiveNPC",MakeCorrosiveNPC)

function ScaleCorrosiveDamage( ent , hitgroup , dmginfo )
	
	if !ent:IsValid() then return end
	if ent.ele_corrode == nil then return end
	ent.ele_corrode = math.min(100,ent.ele_corrode+dmginfo:GetDamage())
	dmginfo:ScaleDamage( 1+ent.ele_corrode/50 )

end
hook.Add("ScaleNPCDamage","ScaleCorrosiveDamage",ScaleCorrosiveDamage)
hook.Add("ScalePlayerDamage","ScaleCorrosiveDamage",ScaleCorrosiveDamage)

function DoCorrosiveDamage()
	for _, v in pairs( ents.FindByClass( "npc*" ) ) do
		if !v:IsValid() then return end
		if !v:IsNPC() then return end
		if v.ele_corrode==nil then return end
		if v.ele_corrode>0 then
		v:TakeDamage(math.floor(v.ele_corrode/5),nil,nil)
		v:SetColor(255-v.ele_corrode*2,255,255-v.ele_corrode*2,255)
		v.ele_corrode = math.max(0,v.ele_corrode-2)
		end
		
	end
	
	for _, k in pairs( ents.FindByClass( "player" ) ) do
		if !k:IsValid() then return end
		if k.ele_corrode==nil then return end
		if k.ele_corrode>0 then
		k:TakeDamage(math.floor(k.ele_corrode/5),nil,nil)
		k:SetColor(255-k.ele_corrode*2,255,255-k.ele_corrode*2,255)
		k.ele_corrode = math.max(0,k.ele_corrode-2)
		end
	
	end
	
	timer.Start("corrosive_effect")
end

timer.Create("corrosive_effect",1,1,DoCorrosiveDamage)