Bullet ricochets?

How do I get bullets to ricochet?

Make your own bullets as physics objects and do your own physics update for it.

I would be more inclined to do something like this:

[lua]local oldFireBullets = _R.Entity.FireBullets;

local ricochets = {};
function _R.Entity:FireBullets( bullet )
bullet.Ricochet = bullet.Ricochet or 0;
if bullet.Ricochet < 3 then
bullet.Callback = function(attacker, tr, dmginfo)
table.insert(ricochets, {trace = tr, origbullet = bullet});
oldFireBullets(self, bullet);
for _, ric in ipairs(ricochets) do
if ric.trace.Hit then
local norm = ric.trace.Normal;
local ang = norm:Angle();
ang:RotateAroundAxis(ric.trace.HitNormal, 180);
local dir = ang:Forward()*-1;
local bullet = {
Src = ric.trace.HitPos,
Dir = dir;
Force = ric.origbullet.Force;
Spread = 0,
Attacker = ric.origbullet.Attacker;
Num = 1;
Damage = ric.origbullet.Damage,
Tracer = ric.origbullet.Tracer,
TracerName = ric.origbullet.TracerName,
Ricochet = ric.origbullet.Ricochet + 1;
table.remove(ricochets, _);
oldFireBullets(self, bullet);

I personally kept having issues with FireBullets (about a year or so ago) where the bullets would just fire off at one random position (which no one could seem to figure out why D:) so I started just making my own bullets so I could do whatever I wanted without issue. :c

It would be nice for your snippet to have a more realistic effect to make the ricochet depend on distance of the bullet travelled and its current velocity (maybe even the type of surface such as a player, world or water.)

A ricochet is unpredictable and that seems like it would be pretty simple to guess how to make bullets in that code fire seeming as you just rotate the angle by a fixed number of degrees and negate the direction it is going. I was kind of hoping the OP was going to try doing something more fantastic.

Bullets in source are just traces, they don’t have velocity.

Rotating the angle by 180 around the hit normal produces a ricochet where it’s angle of incidence is the same as the angle of reflection (like light bouncing off a mirror), I’m pretty sure this is the effect the OP wants.

Was just my opinion that a more realistic effect would be desired over that which would look contrived (by which I mean artificial/un natural.) And you could still roughly self calculate the speed depending on the distance from the firing entity and how long it took artificially (if you knew what kind of speed the particular gun fired bullets at) but that isn’t too important. It was a suggestion just to help the OP if he wanted something a little more interesting.

A bullet ricochet is just not as perfect as a beam of light and how it reflects off a mirror but this is all I can be bothered to now say about it. I am sure he would be happy with it but I just like to give out extra options sometimes that people may not have considered. We will just have to agree to disagree and move on lol. This is just spamming up the poor guys/girls topic and I doubt either of us care enough to take it to PM’s. That and I haven’t slept for over a day so I need some sleep now really. So good night. :smiley:


The hl2 crossbow ricochets at wide angles, worth starting there?

That’s not coded in Lua though.

awesome, that works great. how would I increase the number of ricochets?

Change 3 here: if bullet.Ricochet < 3 then to how many times you would like it to ricochet.

My bullets seam to only ricochet once, regardless to what I change that number to.

Oh, I made a mistake in the code, change line 31 from this:
[lua]oldFireBullets(self, bullet)[/lua]
to this:
[lua]return self:FireBullets(bullet)[/lua]

now I get a stack overflow.

Sorry, I edited my post above, it should be:
[lua]return self:FireBullets(bullet)[/lua]

still only ricochets once. do you think I might be doing something wrong? :confused:

Yes, It works perfectly fine for me, where are you putting that code?

to save the embarrassment… where should I put it?

also, Ive noticed that its affecting my other sweps. Is there a way to avoid that?

Well, I made it to affect all SWEPS that use FireBullets, you can easily change that by renaming the function to something else, put it in your SWEP base or SWEP code and call it instead of FireBullets.

thanks a bunch. works now.