08/05/2002-09/05/2002 @00:52:41 ^01:47:46
Freedoom; and more of Doom engine reprogramming
NERD STUFF ALERT! If you don't like this sort of thing DON'T READ THIS SECTION:-)
Went to Freedoom again and this time got hit number 11111 - even better than 11000? Probably!
While messing about with the golden gun cheat I've implemented in my Doom engine, I had it so that it was firing about 1000 plasma bullets in a big wall out in front of me. This was very funny but killed the frame rate for several seconds while the huge energy discharge dissipated. Yes all right I should have taken a screen shot. Sorry.
This was on top of the basic premise of a single bullet that kills anything. I've still got that implemented and it works really well after I fixed the "why do things fly towards me when I shoot them with a huge damage?" problem. I feel like explaining this. The convention in the source is that if you want to kill something outright you do a damage of 10000 points to it - this is what happens when you teleport on top of something, for example. But, when you shoot a monster, so there is a direction from which the damage has originated, the target gets a push in the opposite direction. To calculate the size of that push, we have (from p_inter.c, function P_DamageMobj)
thrust = damage * (FRACUNIT>>3) * 100 / target->info->mass;
FRACUNIT happens to be 2^16, so FRACUNIT>>3 i.e. FRACUNIT/8 is 2^13. The compiler does the multiplications before doing the final mass division and stores the intermediate result as a signed 32-bit integer (i.e. maximum 2^31) So to avoid an overflow:
2^31 > damage * (2^13) * 100 (threes and ones:-) )
i.e. damage must be less than 2621.44. Ordinarily, you wouldn't get a single damage this big (the maximum usually is 800, a possible value from a direct hit from a BFG) My original code read the amount of health of the monster you'd just shot and did a damage to it of that size, so when you shot a spiderdemon (health 3000) or cyberdemon (health 4000) you'd get this overflow and the corpse would fly towards you.
The solution was to "stagger" the damages. Loop, applying some large damage (say, 2000, which is still enormous, but less than 2621.44) to the target until it is dead. Plus, 2000 is big enough to impart such a large push to the smaller monsters that their mutilated corpses fly across the room at amazing speeds, which invariably results in hilarity.
PS P_DamageMobj is a fantastic function with all sorts of interesting stuff in it. One day I might write an update about the part of it that deals with how having armour affects damages done to the player: that is, the so-called "Damage Formula", and related results. Don't go away! It is really, really interesting!!!:-)