Incendiary bullet chance?

I am designing a weapon which should occasionally - but not always - set its target on fire. How do I code the weapon so that each bullet has, say, a 15% chance of setting something ablaze?

I’m not exactle sure, but I would guess somthing like



<shooting function here>
RandomNumber = math.random(1,100)

if RandomNumber < 16 then

<inset burning bullet here>

else

<inset std. bullet here>

end
end


I’m very new with lua, but I think you get the idea.

Thanks very much, this helps. I will try it.

[editline]11:58PM[/editline]

Okay, I’ve put it in (after a fashion) and moved things around until I’ve boiled my error message down to:
<eof> expected near “else”

This is the code in question:

[lua]
//SWEP:PrimaryFire()\
function SWEP:PrimaryAttack()
RandomNumber = math.random(1,100)

	if RandomNumber &gt; 15 then

		local bullet = {}
			bullet.Num = self.Primary.NumberofShots
			bullet.Src = self.Owner:GetShootPos()
			bullet.Dir = self.Owner:GetAimVector()
			bullet.Spread = Vector( self.Primary.Spread * 0.1 , self.Primary.Spread * 0.1, 0)
			bullet.Tracer = 1
			bullet.Force = self.Primary.Force
			bullet.Damage = self.Primary.Damage
			bullet.AmmoType = self.Primary.Ammo
		if ( !self:CanPrimaryAttack() ) then return end
		local rnda = self.Primary.Recoil * -1
		local rndb = self.Primary.Recoil * math.random(-1, 1)
		self:ShootEffects()
		self.Owner:FireBullets( bullet )
		self.Weapon:EmitSound(Sound(self.Primary.Sound))
		self.Owner:ViewPunch( Angle( rnda,rndb,rnda ) )
		self:TakePrimaryAmmo(self.Primary.TakeAmmo)
		self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
		self.Weapon:SetNextSecondaryFire( CurTime() + self.Primary.Delay )
	end
end
	else

		local bullet = {}
			bullet.Num = self.Primary.NumberofShots
			bullet.Src = self.Owner:GetShootPos()
			bullet.Dir = self.Owner:GetAimVector()
			bullet.Spread = Vector( self.Primary.Spread * 0.1 , self.Primary.Spread * 0.1, 0)
			bullet.Tracer = 1
			bullet.Force = self.Primary.Force
			bullet.Damage = self.Primary.Damage
			bullet.AmmoType = self.Primary.Ammo
			bullet.Callback = function(attacker,tr,dmginfo)
	
				if tr.Entity:IsValid() then tr.Entity:Ignite(20,30) return end

		if ( !self:CanPrimaryAttack() ) then return end
		local rnda = self.Primary.Recoil * -1
		local rndb = self.Primary.Recoil * math.random(-1, 1)
		self:ShootEffects()
		self.Owner:FireBullets( bullet )
		self.Weapon:EmitSound(Sound(self.Primary.Sound))
		self.Owner:ViewPunch( Angle( rnda,rndb,rnda ) )
		self:TakePrimaryAmmo(self.Primary.TakeAmmo)
		self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
		self.Weapon:SetNextSecondaryFire( CurTime() + self.Primary.Delay )
	end

end
//SWEP:PrimaryFire()\
[/lua]

Any ideas?

Put it in lua tags so we can see the indentation, that looks horrendous.

[lua]function SWEP:PrimaryAttack()
RandomNumber = math.random(1,100)

if RandomNumber &gt; 15 then

	local bullet = {}
	bullet.Num = self.Primary.NumberofShots
	bullet.Src = self.Owner:GetShootPos()
	bullet.Dir = self.Owner:GetAimVector()
	bullet.Spread = Vector( self.Primary.Spread * 0.1 , self.Primary.Spread * 0.1, 0)
	bullet.Tracer = 1
	bullet.Force = self.Primary.Force
	bullet.Damage = self.Primary.Damage
	bullet.AmmoType = self.Primary.Ammo
	if ( !self:CanPrimaryAttack() ) then return end
	local rnda = self.Primary.Recoil * -1
	local rndb = self.Primary.Recoil * math.random(-1, 1)
	self:ShootEffects()
	self.Owner:FireBullets( bullet )
	self.Weapon:EmitSound(Sound(self.Primary.Sound))
	self.Owner:ViewPunch( Angle( rnda,rndb,rnda ) )
	self:TakePrimaryAmmo(self.Primary.TakeAmmo)
	self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
	self.Weapon:SetNextSecondaryFire( CurTime() + self.Primary.Delay )
	end
	end
else

	local bullet = {}
	bullet.Num = self.Primary.NumberofShots
	bullet.Src = self.Owner:GetShootPos()
	bullet.Dir = self.Owner:GetAimVector()
	bullet.Spread = Vector( self.Primary.Spread * 0.1 , self.Primary.Spread * 0.1, 0)
	bullet.Tracer = 1
	bullet.Force = self.Primary.Force
	bullet.Damage = self.Primary.Damage
	bullet.AmmoType = self.Primary.Ammo
	bullet.Callback = function(attacker,tr,dmginfo)

	if tr.Entity:IsValid() then tr.Entity:Ignite(20,30) return end

	if ( !self:CanPrimaryAttack() ) then return end
	local rnda = self.Primary.Recoil * -1
	local rndb = self.Primary.Recoil * math.random(-1, 1)
	self:ShootEffects()
	self.Owner:FireBullets( bullet )
	self.Weapon:EmitSound(Sound(self.Primary.Sound))
	self.Owner:ViewPunch( Angle( rnda,rndb,rnda ) )
	self:TakePrimaryAmmo(self.Primary.TakeAmmo)
	self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
	self.Weapon:SetNextSecondaryFire( CurTime() + self.Primary.Delay )
end

end[/lua]

:barf:

[editline]02:18PM[/editline]

This is what happens when you try to edit a SWEP generated from a SWEP Creator.

I know, I’m sorry about the appearance - I’m afraid I’m more familiar even with lua than I am with internet text. I tried to put it in the tags, but it really wasn’t cooperating, so I decided to deal with the actual problem first and the user malfunction second.

Is that better?

[editline]09:29AM[/editline]

Also, quite the contrary - I have had plenty of success making my own SWEPs with the creator; I use it as a jumping-off point, and to set up a workable structure. What you see above is extremely heavily modified.

[editline]09:33AM[/editline]

So, philosophical and grammatical woes aside, how do I fix my gun?

There is an awful lot wrong with that code, so much in fact that I don’t think that I have the motivation to fix it for you. However, I will say that you have ends where there shouldn’t be ends and no ends where there should be ends.

Also, It isn’t such a great idea to use code generated by a SWEP Creator as a base for your modifications, if you are using MakeR’s SWEP Creator (which I think you are), then the output code is incredibly messy and somewhat random, making it difficult to read and (therefore) modify.

You are correct in surmising that I am using this particular SWEP creator, and it is new information to me that it is so messy - although, being somewhat inexperienced, I am still in that stage where it all looks rather the same to me.

I am relatively confident that if I had a clue as to where my ends ought to go I could puzzle it out from there. As I said, all I am getting from the game is that there should be one near ‘else’. This doesn’t tell me a whole lot.

MakeR’s SWEP Creator produces incredibly messy code (I should know, I made it :smile:).

I will have a go at sorting your code out shortly.

Thanks very much - I appreciate it.

Here, taken from my incendiary weapon for a gamemode I’m working on. Change as you see fit.

The “AIShootBullet” function is called in the SWEP:PrimaryFire() of the swep_base.

[lua]local function IgnitionCallback(bouncenum, attacker, tr, dmginfo)
local ed = EffectData()
ed:SetOrigin(tr.HitPos)
ed:SetNormal(tr.HitNormal)
if tr.HitEntity then
ed:SetEntity(tr.Entity)
end
util.Effect(“fireshot”,ed)

if tr.Entity then
	if tr.Entity:IsPlayer() and tr.Entity:Team() == TEAM_ALIEN then
		tr.Entity:Ignite(math.random(1,5),0)
	end
	if tr.Entity:IsNPC() then
		tr.Entity:Ignite(math.random(1,5),0)
	end
end

end

function SWEP:AIShootBullet(dmg, numbul, cone)
local bullet = {}
bullet.Num = numbul
bullet.Src = self.Owner:GetShootPos()
bullet.Dir = self.Owner:GetAimVector()
bullet.Spread = Vector(cone, cone, 0)
bullet.Tracer = 1
bullet.Force = dmg * 0.5
bullet.Damage = dmg
if math.random(1,6)==1 then
bullet.Callback = function(a, b, c) IgnitionCallback(0, a, b, c) end
end

self.Owner:FireBullets(bullet)

self:SendWeaponAnim(ACT_VM_PRIMARYATTACK)
self.Owner:MuzzleFlash()
self.Owner:SetAnimation(PLAYER_ATTACK1)

end[/lua]

There you go, no need for me to go through it. :smile:

Again, this is all greatly appreciated, but you are overestimating my knowledge of lua code. Everything I’ve learned has been by fiddling with things - trial and error. I have little to no understanding of the overall structure of it. I am sure the above segment of code would be really very helpful; I just have no idea where to put it.

I thank you all; your tremendous patience is not lost on me.

[editline]11:59AM[/editline]

Frankly, I still prefer your help. To make a metaphor of the whole thing, I’m a guy who just knows maybe what a couple of the trees look like, and I need help from someone who knows his way around the forest. If this is left in my hands I will end up standing there wondering what to do with it.

[lua]
local function IgnitionCallback(bouncenum, attacker, tr, dmginfo) // This function gets called when the bullet hits.
local ed = EffectData() // Creating an effect.
ed:SetOrigin(tr.HitPos) // Setting where the effect originates
ed:SetNormal(tr.HitNormal) // Setting the effect’s normal
if tr.HitEntity then
ed:SetEntity(tr.Entity)
end
util.Effect(“fireshot”,ed) // Creating an effect with the effect data.

if tr.Entity then // If the bullet hit an entity
	if tr.Entity:IsPlayer() or tr.Entity:IsNPC() then // If the entity is a player or an NPC
		tr.Entity:Ignite(math.random(1,5),0) // Ignite the player/NPC
	end
end

end

function SWEP:AIShootBullet(dmg, numbul, cone)
local bullet = {} // Creating the bullet table.
bullet.Num = numbul // Setting the amount of bullets fired.
bullet.Src = self.Owner:GetShootPos() // Telling the bullet where it comes from
bullet.Dir = self.Owner:GetAimVector() // Telling the bullet where it is headed,
bullet.Spread = Vector(cone, cone, 0) // Setting the spread
bullet.Tracer = 1
bullet.Force = dmg * 0.5 // Setting the force of the bullet impact
bullet.Damage = dmg // Setting the bullet damage.
if math.random(1,6) == 1 then // If the random value is 1 then
bullet.Callback = function(a, b, c) IgnitionCallback(0, a, b, c) end // Set the callback of the bullet to the above function so the function gets called when the bulet hits
end

self.Owner:FireBullets(bullet) // Shoot the bullet.

self:SendWeaponAnim(ACT_VM_PRIMARYATTACK) // Show the shooting animation.
self.Owner:MuzzleFlash() // Show the muzleflash
self.Owner:SetAnimation(PLAYER_ATTACK1) // Show the third person animation.

end[/lua]

Read the comments i placed.

[lua]local function IgnitionCallback(att, tr, dmginfo)
if ValidEntity(tr.Entity) then
tr.Entity:Ignite(math.random(5,10),0)
end
end

function SWEP:PrimaryAttack()
local bullet = {}
bullet.Num = self.Primary.NumberofShots
bullet.Src = self.Owner:GetShootPos()
bullet.Dir = self.Owner:GetAimVector()
bullet.Spread = Vector(self.Primary.Spread * 0.1 , self.Primary.Spread * 0.1, 0)
bullet.Tracer = 1
bullet.Force = self.Primary.Force
bullet.Damage = self.Primary.Damage
bullet.AmmoType = self.Primary.Ammo
if math.random(100) <= 15 then
bullet.Callback = IgnitionCallback
end
self.Owner:FireBullets(bullet)

self:ShootEffects()
self.Weapon:EmitSound(Sound(self.Primary.Sound))  
self.Owner:ViewPunch(Angle(rnda,rndb,rnda))  

self:TakePrimaryAmmo(self.Primary.TakeAmmo)  
self.Weapon:SetNextPrimaryFire(CurTime() + self.Primary.Delay)  

end[/lua]

Add this to your weapon code, replacing (or merging with) your primary attack function. If it doesn’t work or you need any more help, feel free to ask me in a PM.

What if the weapon shoots more than one shot, like a shotgun? Don’t callbacks not work when there is more then one bullet?

No it works. It only doesn’t work as expected when a gun shoots more than one bullet (like a shotgun) and you fire bullets in the callback. If you do this all other callbacks for the bullets from that shot won’t get called.

You could of course do…


function FireBullets(ent, attacker, inflictor, amount, dmginfo)
local FireMath = math.random(0,100)
if ent:IsNPC() and attacker:IsPlayer() then
if FireMath <= 15 then
ent:Ignite(10)
end
end
end
hook.Add("EntityTakeDamage", "Gasoline4Ever", FireBullets)

You could also add a table of weapons for this to act upon or just a Var to check… Kinda like.


function FireBullets(ent, attacker, inflictor, amount, dmginfo)
local FireMath = math.random(0,100)
if ent:IsNPC() and attacker:IsPlayer() and attacker:GetActiveWeapon().HasFireBullets then
if FireMath <= 15 then
ent:Ignite(10)
end
end
end
hook.Add("EntityTakeDamage", "Gasoline4Ever", FireBullets)

But im sorry, im usually used to making coop gamemodes so… I guess you would want this…


function FireBullets(ent, attacker, inflictor, amount, dmginfo)
local FireMath = math.random(0,100)
if ent:IsValid() and attacker:IsPlayer() and attacker:GetActiveWeapon().HasFireBullets then
if FireMath <= 15 then
ent:Ignite(10)
end
end
end
hook.Add("EntityTakeDamage", "Gasoline4Ever", FireBullets)

Excellent! It works beautifully, excepting the minor error where the necessity to reload is overridden and the gun simply draws from the main ammo pool.

Still, I’m quite pleased with it.

[editline]04:12PM[/editline]

If this one would - in theory - work with a shotgun-style weapon, I may be using this too. I’m putting together a pack of these weapons.

Don’t make a pack of weapons when you can barely code Lua.

[editline]11:30PM[/editline]

Not trying to be a dick or anything, but if its poorly made or something you’re going to get a load of PM’s/emails ranting about it being bad.