Monsters shooting at corpses

Is there something that doesn't work right in the latest GZDoom? Post about it here.

Moderator: GZDoom Developers

Forum rules
Please construct and post a simple demo whenever possible for all bug reports. Please provide links to everything.

If you can include a wad demonstrating the problem, please do so. Bug reports that include fully-constructed demos have a much better chance of being investigated in a timely manner than those that don't.

Please make a new topic for every bug. Don't combine multiple bugs into a single topic. Thanks!
rileymartin
Posts: 40
Joined: Wed Jan 27, 2016 7:10 am

Monsters shooting at corpses

Post by rileymartin »

I reported this a while back but it does not appear to have changed:

Monsters with volley attacks, such as the Mancubus or Cyberdemon, will aim down to shoot at the floor, where the monster corpse is, if their first shot killed the enemy - even if they're on the same elevation. This happens in (Strict) compatibility and is not vanilla behaviour. The monster is supposed to keep shooting straight over the corpse where the dead enemy's hitbox used to be and not correct their aim downwards mid-volley like that.
rileymartin
Posts: 40
Joined: Wed Jan 27, 2016 7:10 am

Re: Monsters shooting at corpses

Post by rileymartin »



Here is a rough video demonstration showing the difference. After the 18 second mark, you can see the GZ Cyber fire shots at the ground after killing Barons. Meanwhile, in the second half, the PR+ Cyber always shoots parallel to the ground after a kill.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49204
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Monsters shooting at corpses

Post by Graf Zahl »

This is a typical vanilla accuracy issue. The missile shooting function never checks the height of either shooter or target, it only checks their z position. Needless to say, if this gets changed back to this sloppy math it'd wreak havoc with all kinds of mods. ZDoom once changed this to aim at the target's center so that it works with smaller and larger targets than what the original code assumed would be valid.

It's just particularly noticable with corpses because they get reduced to a height of 16.
Warden
Posts: 42
Joined: Sun May 24, 2020 11:06 am

Re: Monsters shooting at corpses

Post by Warden »

This was bothering me now that you've pointed it out. Here's a Zscript fix for the Cyberdemon and Mancubus if you want to mod it yourself.

Code: Select all

class VNCyberdemon : Cyberdemon replaces Cyberdemon
{
    states {
    Missile:
    // restore vanilla Z aiming behavior for the Cyberdemon
		CYBR E 6 A_FaceTarget;
		CYBR F 12 A_VNCyberAttack;
		CYBR E 12 A_FaceTarget;
		CYBR F 12 A_VNCyberAttack;
		CYBR E 12 A_FaceTarget;
		CYBR F 12 A_VNCyberAttack;
		goto See;
    }
    
    void A_VNCyberAttack()
    {
        if (!target) return;
        A_FaceTarget();
        let missile = SpawnMissile(target, "Rocket");
        if (missile) {
            missile.Vel.Z = (target.Pos.Z - Pos.Z) / DistanceBySpeed(target, missile.speed);
        }
    }
}

class VNFatso : Fatso replaces Fatso
{
    states {
    Missile:
    // restore vanilla Z aiming behavior for the Mancubus
		FATT G 20 A_FatRaise;
		FATT H 10 BRIGHT A_VNFatAttack1;
		FATT IG 5 A_FaceTarget;
		FATT H 10 BRIGHT A_VNFatAttack2;
		FATT IG 5 A_FaceTarget;
		FATT H 10 BRIGHT A_VNFatAttack3;
		FATT IG 5 A_FaceTarget;
		goto See;
    }
    
    void A_VNFatAttack1()
    {
        if (!target) return;
        A_FaceTarget ();
        // Change direction  to ...
        Angle += FATSPREAD;
        let missile = SpawnMissile(target, "FatShot");
        if (missile) {
            missile.Vel.Z = (target.Pos.Z - Pos.Z) / DistanceBySpeed(target, missile.speed);
        }
        missile = SpawnMissile(target, "FatShot");
        if (missile) {
            missile.Angle += FATSPREAD;
            missile.VelFromAngle();
            missile.Vel.Z = (target.Pos.Z - Pos.Z) / DistanceBySpeed(target, missile.speed);
        }
    }    
    
    void A_VNFatAttack2()
    {
        if (!target) return;
        A_FaceTarget ();
        // Now here choose opposite deviation.
        Angle -= FATSPREAD;
        let missile = SpawnMissile(target, "FatShot");
        if (missile) {
            missile.Vel.Z = (target.Pos.Z - Pos.Z) / DistanceBySpeed(target, missile.speed);
        }
        missile = SpawnMissile(target, "FatShot");
        if (missile) {
            missile.Angle -= FATSPREAD;
            missile.VelFromAngle();
            missile.Vel.Z = (target.Pos.Z - Pos.Z) / DistanceBySpeed(target, missile.speed);
        }
    }    
    
    void A_VNFatAttack3()
    {
        if (!target) return;
        A_FaceTarget ();
        let missile = SpawnMissile(target, "FatShot");
        if (missile) {
            missile.Angle -= FATSPREAD/2;
            missile.VelFromAngle();
            missile.Vel.Z = (target.Pos.Z - Pos.Z) / DistanceBySpeed(target, missile.speed);
        }
        missile = SpawnMissile(target, "FatShot");
        if (missile) {
            missile.Angle += FATSPREAD/2;
            missile.VelFromAngle();
            missile.Vel.Z = (target.Pos.Z - Pos.Z) / DistanceBySpeed(target, missile.speed);
        }
    }
}

Return to “Bugs [GZDoom]”