The rifle nade code is peculiar to say the least.
G_BounceMissile
...
// boom after 750 msecs
if( ent->s.weapon == WP_M7 || ent->s.weapon == WP_GPG40 ) {
ent->s.effect1Time = qtrue; // has bounced
if( (ent->nextthink - level.time) < 3250 ) {
G_ExplodeMissile( ent );
return;
}
}
...
The rifle nade starts out with a nextthink time of 4000 (meaning it will explode after 4 seconds no matter what)
So, if hits something, and has been alive for more than 3/4 of a sec, it will explode instantly (well, probably on the next server frame).
Otherwise, it bounces and does this:
...
if( ent->s.weapon == WP_M7 || ent->s.weapon == WP_GPG40 ) {
// explode one 750msecs after launchtime
ent->nextthink = level.time + (750 - (level.time + 4000 - ent->nextthink));
}
...
Note the expression above can be simplified (remember, addition is commutative, no need for all those parens):
ent->nextthink -= 3250;
:moo:!
If it bounces again after this, it will get back to the first case, which means it will always explode on the second impact. If bounces and doesn’t hit anything within 750ms of launch time (not bounce time), it will also explode. One wonders if this was the intended behavour. I kind of suspect one of those level.times was supposed to be something else…
Note, I’ve just skimmed that code, so it is quite possible that I’ve missed something. In particular G_RunMissile or G_MissileImpact might do something I haven’t taken into account.
edit:
Oh, all the above is ETmain. I don’t think it has changed in etpro, but perhaps one of the etpro team could confirm or deny.