• Incendiary bullet chance?
    21 replies, posted
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 [code] <shooting function here> RandomNumber = math.random(1,100) if RandomNumber < 16 then <inset burning bullet here> else <inset std. bullet here> end end [/code] 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 > 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 > 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] [QUOTE=NullPoint;19427231]There you go, no need for me to go through it. :smile:[/QUOTE] 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?
[QUOTE=CowThing;19431711]What if the weapon shoots more than one shot, like a shotgun? Don't callbacks not work when there is more then one bullet?[/QUOTE] 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... [code]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)[/code] You could also add a table of weapons for this to act upon or just a Var to check... Kinda like. [code]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)[/code] But im sorry, im usually used to making coop gamemodes so.. I guess you would want this.. [code]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)[/code]
[QUOTE=NullPoint;19431522][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.[/QUOTE] 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] [QUOTE=Wizey!;19433030]You could of course do... [code]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)[/code] You could also add a table of weapons for this to act upon or just a Var to check... Kinda like. [code]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)[/code] But im sorry, im usually used to making coop gamemodes so.. I guess you would want this.. [code]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)[/code][/QUOTE] 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.
Correction: Don't make a pack of weapons when you can barely code Lua AND are prepared to settle for something less finished than what you have in mind. Since I'm not prepared to settle, I don't think there will be a problem. Believe me, nothing irks me more than poor-quality downloads and I'm not about to add to the problem.
Okay, just trying to add a mini-filter to the Gmod crap pipe :P
Sorry, you need to Log In to post a reply to this thread.