[Not a bug] Puff actors not spawning exactly at hitscan line termination

Bugs that have been investigated and resolved somehow.

Moderators: Developers, ZDoom.org Team

Puff actors not spawning exactly at hitscan line termination

Postby Xangi » Sun Oct 29, 2017 10:14 pm

Since I don't want to have to type it all out again, here's a discord capture.
Image
Essentially the source of this seems to be that the origin of a puff actor isn't necessarily in the same spot as the exact termination point of a hitscan ray, meaning that the "tracer" actors that can be spawned by A_FireBullets can end up going in wildly different directions than the hitscan attack when fired into a monster up close.
User avatar
Xangi
Recovering Shitpost Addict
 
Joined: 02 Nov 2012
Discord: Xangi#8619

Re: Puff actors not spawning exactly at hitscan line termina

Postby _mental_ » Mon Oct 30, 2017 3:15 am

Please post a runnable sample.
_mental_
 
 
 
Joined: 07 Aug 2011

Re: Puff actors not spawning exactly at hitscan line termina

Postby Graf Zahl » Mon Oct 30, 2017 3:19 am

This is intended behavior. The puff's z- coordinate is slightly randomized. This is not intended to be spawned at a possibly significant coordinate so you cannot use it for precise hit detection.
User avatar
Graf Zahl
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Puff actors not spawning exactly at hitscan line termina

Postby Nash » Mon Oct 30, 2017 3:39 am

There's an FBF_NORANDOMPUFFZ flag that can be used to disable that Z randomization.
User avatar
Nash
 
 
 
Joined: 27 Oct 2003
Location: Kuala Lumpur, Malaysia

Re: Puff actors not spawning exactly at hitscan line termina

Postby Xangi » Mon Oct 30, 2017 8:38 am

Thanks, I'll try that out and see if it helps. I was hoping this was something that could be remedied with an easy fix like that.
User avatar
Xangi
Recovering Shitpost Addict
 
Joined: 02 Nov 2012
Discord: Xangi#8619

Re: Puff actors not spawning exactly at hitscan line termina

Postby Xangi » Mon Oct 30, 2017 4:58 pm

Welp, turns out Nash's fix doesn't work, likely because the Blood actor isn't actually a puff and is therefore not subject to the flag he suggested, or some other reason.



Here is a weapon, use 'give TracerShotgun' and test it out.
https://mega.nz/#!u01zXZjD!6-A_XeC1TP_3 ... 0_kYg4oEl0

Steps to reproduce with near-100% chance:

1.) Use the freeze command
2.) summon a pinky demon
3.) center view and press directly against it
4.) Shoot until it dies
5.) Unfreeze time.

You should then see the trajectories of 20 (30 if you're extremely unlucky) tracers, many of which will be directed upwards at an angle far higher than the aim angle. This behavior is the result of an unsafe assumption being made in the tracer spawn code, which is that a vector from player(+offsets) -> puff is equivalent to, or at least close to, the hitscan line. Obviously it's not when you're extremely close to an enemy, as can be demonstrated here. No need to enable or disable autoaim, it works no matter what. In fact, you can predict the vectors by looking closely at the tracers and the blood actors, then mentally drawing a line that passes through both.

It would be possible to work around this if FBF_PUFFTARGET/FBF_PUFFMASTER/FBF_PUFFTRACER could return pointers to Blood actors (which would allow manual deletion of tracers after they pass their puff), or if it was reasonable to wrap firebullets in a loop which used explicit angles and separately spawned the tracers. Unfortunately one of those is impossible and the other would interfere with autoaim. If there's another workaround that doesn't kill performance, autoaim, or require tearing apart pre-existing weapons I'll be glad to use that.

EDIT: Okay so, firstly my assumption about the source of this issue is dead on, and I do think that maybe there should be a flag to use hitscan angle instead of puff direction if possible. Secondly there is a workaround which does basically just that (while preserving autoaim), and it's this:
Code: Select allExpand view
action void A_FireBulletsProperTracer(double anglex, double angley, int numbullets, int damage, int multiplier=3, string pufftype="PlayerPuff", double range=8192, string missile="", double spawnheight=0, double spawnofs_xy=0)
   {
      //Declare variables required
      let p = players[consoleplayer].mo;
      int zoffset = ((p.height/2)+p.AttackZOffset);
      double aimPitch, ax, ay;
      Vector3 aimVec;

      //Determine pitch including autoaim
      A_FireBullets(0, 0, 1, 0, "AutoAimPuff", FBF_NORANDOM|FBF_NORANDOMPUFFZ, 1);
      AutoAimPuff other = AutoAimPuff(ThinkerIterator.Create("AutoAimPuff").Next()); //We know one will exist because we just spawned it
      aimVec = (other.pos.x-p.pos.x, other.pos.y-p.pos.y, other.pos.z-(p.pos.z+zoffset)); //manually create vector to apply offset
      aimPitch = -asin(aimVec.z/aimVec.Length()); //hooray trig

      //fire bullets, in this case 10 with a 5x5 spread
      for(int i = 0; i < 10; i++)
      {
         ax = frandom(-anglex, anglex);
         ay = frandom(-angley, angley);
         A_FireBullets(ax, aimPitch+ay, -1, damage * random(1, multiplier), pufftype, FBF_EXPLICITANGLE|FBF_NOPITCH|FBF_NORANDOM, range);
         //spawn the tracers in the origin of the hitscan, and move them towards it
         p.A_SpawnProjectile (missile, zoffset+spawnheight, spawnofs_xy, p.angle+ax, CMF_AIMDIRECTION|CMF_ABSOLUTEANGLE, aimPitch+ay);
      }
   }

In ZScript we can use an incredibly short range dummy puff to get the aim pitch while also accounting for autoaim, then use that along with some other hackery to create the desired effect. There's also a way better way to do this if you don't want autoaim, which is to just use the player's pitch. So far I haven't encountered any issues with this, but it would probably be faster running native.
Last edited by Rachael on Mon Oct 30, 2017 6:43 pm, edited 1 time in total.
Reason: shrank image
User avatar
Xangi
Recovering Shitpost Addict
 
Joined: 02 Nov 2012
Discord: Xangi#8619


Return to Closed Bugs

Who is online

Users browsing this forum: No registered users and 1 guest