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.
Monsters shooting at corpses
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!
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!
-
- Posts: 40
- Joined: Wed Jan 27, 2016 7:10 am
Re: Monsters shooting at corpses
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.
-
- Lead GZDoom+Raze Developer
- Posts: 49204
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: Monsters shooting at corpses
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.
It's just particularly noticable with corpses because they get reduced to a height of 16.
-
- Posts: 42
- Joined: Sun May 24, 2020 11:06 am
Re: Monsters shooting at corpses
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);
}
}
}