I found this while comparing the behavior of A_FireBullets to that of the built-in attack functions (A_FirePistol, A_FireShotgun etc.). Eventually, both call LineAttack in their call chains, but there seems to be a difference in how the attack spread is calculated. A_FireBullets
multiplies the spread by a random2()-generated value and divides the result by 255. On the other hand, GunShot
(the function behind A_FirePistol, A_FireShotgun and A_FireCGun doing the actual attack) and A_FireShotgun2
do the same multiplication by random2(), but divide by 256 instead of 255.
Considering that random2() returns values between -255 and 255 (if I'm not mistaken), the actual spread for GunShot is thus ~5.603 instead of 5.625, and for A_FireShotgun2 it is ~11.206 instead of 11.25 (horizontal) and ~7.069 instead of 7.097 (vertical). On the other hand, A_FireBullets as well as A_CustomBulletAttack calculate the spread correctly. Unless random2() actually returns values between -256 and 256. Then it's A_FireBullets and A_CustomBulletAttack which should be fixed instead (but I think it's the other way around in this case, according to the source code and this comment from Gez
It actually seems that many built-in attack functions are affected by this, including but not limited to: Doom weapons (see above), Doom monsters (zombieman, shotgun guy, chaingun guy, Wolfenstein SS), Heretic weapons and Strife weapons. In all these cases, the actual attack spread is slightly lower than declared. Granted, this is in no way a critical issue, and it probably doesn't have much adverse effect to be noticed in-game (otherwise it would have already been reported long ago). But unless it was the original intention for real spread to be lower than the values used in the code - and that I highly doubt - this is a bug, since the code doesn't do exactly what it's supposed to do, and thus should be fixed.