Jump to content

A_Detonate and the Suicide Bomber


Gregor

Recommended Posts

I noticed while comparing Valiant and KDiKDiZD's suicide bombers that the former doesn't seem to behave as intended. See, KDiKDiZD (which is freaking awesome btw) increased the bombers radius to compensate for the fact that in vanilla you only have the A_Explode code pointer and can't adjust the blast radius and damage like @skillsaw

did in Valiant. In Valiant the explosions are done with A_Detonate, which according to the MBF reference sheet, should set the max damage and blast radius to the whatever value is set as damage of the entity. Now that's 96 in Valiant according to the DeHackEd patch. So the Suicide bomber shouldn't be able to do more than 96 damage at the most. It should actually be far less than that since u can never be at it origin inside the collision box. However, in the game the suicide bombers will do well over 100 damage and never less than 100. Basically just like a normal rocket. So something isn't working here, right? Or far more likely i don't understand something correctly (which is why i ask :=).

 

It's the same in Heartland, where the bomber's damage is set even lower to just 60. But again, they will end up doing more than that a lot of the time. At least they do less than a normal rocket, 76 is highest i got, and actually do less than 60 damage as well sometimes. But still, not what it says on the box. 

 

So does anybody know how A_Detonate actually works/calculate its damage? And why does it seemingly behave differently in Eternity??

Share this post


Link to post

Here's the original code in MBF:

//
// A_Detonate
// killough 8/9/98: same as A_Explode, except that the damage is variable
//

void A_Detonate(mobj_t *mo)
{
  P_RadiusAttack(mo, mo->target, mo->info->damage);
}

Which you can compare to the vanila A_Explode:

//
// A_Explode
//
void A_Explode (mobj_t* thingy)
{
    P_RadiusAttack ( thingy, thingy->target, 128 );
}

The variable name change is transparent (variable names are lost once it's machine code anyway), so the behavior is indeed identical to A_Explode except using the entity's damage value instead of hardcoded to 128.

Share this post


Link to post

The difference is probably that KDiKDiZD's suicide bomber only calls A_Explode at the start of its regular death state, not its xdeath, so that it avoids immediately causing a second explosion when it's killed by the first explosion.

 

# Monster: SUICIDE BOMBER (replaces Dead Lost Soul)
m = mobjinfo[MT_MISC65]
m.clear()
mobjinfo[MT_SPAWNSHOT].clear() # clear this to pin some frames
m.object_name = "Suicide Bomber (DeadLostSoul)"
m.doomednum = 3013
m.spawnhealth = 60
m.speed = 10
m.radius = 25 * FRACUNIT
m.height = 56 * FRACUNIT
m.reactiontime = 8
m.painchance = 5
m.mass = 100
m.flags = (MF_SOLID | MF_SHOOTABLE | MF_COUNTKILL)
m.seesound = sfx_posit2
m.painsound = sfx_popain
m.deathsound = sfx_barexp
m.update(states.parse("""
  Spawn: 
    BMBE AB 10 A_Look
    loop
  See:
    BMBE A 2 A_BabyMetal # oh you're a fan? name 3 of their albums
    BMBE AABBBCCCDDD 2 A_Chase
    loop
  Pain:
    BMBE A 6 A_Pain
    goto See
  Melee:
    # fall through into:
  Death:
    BMBE E 0 bright A_Explode
    # fall through into:
  XDeath:
    BMBE E 5 bright A_Scream
    BMBE F 5 bright
    BMBE G 5 A_Fall
    goto S_SPOS_XDIE4
"""))
"""We're using A_BabyMetal to play the suicide zombie's scream. Conveniently,
this pointer also has A_Chase baked into it, so we could shave off a frame.

The XDeath jumps past their explosion, so their explosion doesn't give them a
second explosion (insert Xzibit meme here)

They're supposed to play the explosion sound and the gib sound simultaneously,
but things in vanilla can only make one sound at a time, so I'm just using
the explosion sound only. CONSIDER: Making a new sound overlaying the two.
"""

 

Share this post


Link to post
Quote
33 minutes ago, Gez said:

Here's the original code in MBF:



//
// A_Detonate
// killough 8/9/98: same as A_Explode, except that the damage is variable
//

void A_Detonate(mobj_t *mo)
{
  P_RadiusAttack(mo, mo->target, mo->info->damage);
}

Which you can compare to the vanila A_Explode:



//
// A_Explode
//
void A_Explode (mobj_t* thingy)
{
    P_RadiusAttack ( thingy, thingy->target, 128 );
}

The variable name change is transparent (variable names are lost once it's machine code anyway), so the behavior is indeed identical to A_Explode except using the entity's damage value instead of hardcoded to 128.

 

Yes, but according to this, damage above 96 should be impossible. But yet it happens all the time. Just boot up Valiant, find a suicide bomber, make sure you have no armor equipped, and run into it. It will invariably do more than 96 damage. So the code notwithstanding, something makes it not do what the code is supposed to make it do.

Edited by Gregor

Share this post


Link to post
6 minutes ago, esselfortium said:

It's not impossible if its explosion is inadvertently triggering a second explosion.

Well, these are the suicide bomber's state from valiant opened in whacked. There are two detonate states. But it look like it's a duplicate frame. It has the same state number after all. Shouldn't that be ignored?

The same is also present in KDiKDiZD for the suicide bomber, just with a_explode.

 

1177487658_Screenshot(17).png.25461bebaedc138a9ff0844dac434140.png

Edited by Gregor

Share this post


Link to post
10 minutes ago, Gregor said:

Well, these are the suicide bomber's state from valiant opened in whacked. There are two detonate states. But it look like it's a duplicate frame. It has the same state number after all. Shouldn't that be ignored?

The same is also present in KDiKDiZD for the suicide bomber, just with a_explode.

 

1177487658_Screenshot(17).png.25461bebaedc138a9ff0844dac434140.png

The detonate state being shown twice for Valiant is its melee attack and its death. It doesn't have a separate xdeath defined to prevent the second explosion.

image.png

Share this post


Link to post
2 minutes ago, esselfortium said:

You're misunderstanding. It's the same state, yes, but there's nothing preventing the scenario I described. The second explosion is caused by the first explosion killing it and sending it to the first frame of its xdeath state, which is the same explosion it already did.

But the Valiant bomber, unlike the KDiKDiZD one, doesn't have an XDeath state. Only Spawn, Walk, Pain, Melee and Death. Do u mean, that the melee state (914) sends it to its death state (also 914)? But shouldn't that only be triggered when i shoot it myself?

 

2023167536_Screenshot(18).png.8dd05a828b3882657528c2e150a2b8e8.png

Share this post


Link to post

Okay, looking into this more I see I've explained it a bit wrong.

 

Because no xdeath is defined for it in Valiant, the self-detonation in its melee state sends it to the beginning of its standard death state, which calls detonate again.

 

When an xdeath is defined for it, the self-detonation in its melee state goes directly there instead of to its standard death, due to the amount of damage it's being dealt.

Share this post


Link to post
16 minutes ago, esselfortium said:

Okay, looking into this more I see I've explained it a bit wrong.

 

Because no xdeath is defined for it in Valiant, the self-detonation in its melee state sends it to the beginning of its standard death state, which calls detonate again.

 

When an xdeath is defined for it, the self-detonation in its melee state goes directly there instead of to its standard death, due to the amount of damage it's being dealt.

Aha. So it's an unintentional oversight? I mean, i definitely wouldn't expect this to happen. So whenever you build a custom monster that goes boom, you have to make sure that either its death state doesn't also have detonate or make sure to define a XDeath state that doesn't have detonate on it. Hmm. In that case, isn't KDiKDIZD bomber too weak in comparison? I assumed, the whole idea of widening its radius was to ensure that it doesn't do more damage than in Valiant/Heartland. But it looks like the Valiant one does quite a lot more if it actually does a double explosion.

Edited by Gregor

Share this post


Link to post

@esselfortium What is the duplicate frame for then? Why are there two 914s? You copied that for your mod as well, so i assume it serves some purpose.

 

EDIT: I think i get it now.

 

Edited by Gregor

Share this post


Link to post

It's not a duplicate frame. Whacked shows it twice because it's referenced both in Death and Melee state. If you replace every state on the Things screen with 914 and reapply the filter in States screen, you'll see a bunch of 914's.

Share this post


Link to post

Ok, so that explains why the suicide bombers does so much damage. It calls A_Detonate twice in a row instead of just once, doing 192 max damage instead of just 96. Only question remaining is whether this was intentional. 

 

But that is interesting that the bomber in KDiKDiZD actually does a lot less damage than in Valiant. So @esselfortium essential fixed it? Unless it was intentional design in the first place. skillsaw kept the same approach in Heartland after all. Even though he lowered the damage to 60, it must still do double explosion, since it still very much goes above that damage value.

Share this post


Link to post

Doesn't the whole thing about XDeath explosion avoidance means that if you gib them to begin with (dealing over 120 damage for example), then they will not explode at all?

Share this post


Link to post
3 minutes ago, Gez said:

Doesn't the whole thing about XDeath explosion avoidance means that if you gib them to begin with (dealing over 120 damage for example), then they will not explode at all?

Yes, though in practice that's most likely to happen when hitting them with a rocket explosion, so...

Share this post


Link to post

Could you explain that a bit more? A rocket could hit them and not make them explode? Never seen that one happen that's for sure.

Share this post


Link to post

I mean, there’s already an explosion happening there from the rocket, so the lack of a subsequent explosion from the bomber itself is less likely to be noticed. (They’ll still go through their standard death animation but not create additional splash damage.)

Share this post


Link to post
50 minutes ago, Gregor said:

Only question remaining is whether this was intentional.

It's a good question, because "fixing" it turned out to be pretty easy as I just tried. Have a separate melee state (not the same as death state first frame), and make it call MBF codepointer A_Die, which sends the suicide bomber to death state and makes it go boom once without breaking the "shoot" case.

Edited by Doomy__Doom

Share this post


Link to post
48 minutes ago, Gregor said:

Only question remaining is whether this was intentional. 

 

The double explosion behavior is not intentional, but the total amount of damage is. I balance based on the feel, not the numbers, so I tuned it until the result felt appropriate, without ever realizing that it triggered twice.

Share this post


Link to post

 

22 minutes ago, esselfortium said:

I mean, there’s already an explosion happening there from the rocket, so the lack of a subsequent explosion from the bomber itself is less likely to be noticed. (They’ll still go through their standard death animation but not create additional splash damage.)

You 're referring to your version of the suicide bomber, right?

Edited by Gregor

Share this post


Link to post

Is that yes definitive, or would you say there is another answer state that can be triggered?

 

Spoiler

I am just messing here in good jest.

 

Share this post


Link to post
1 minute ago, Redneckerz said:

Is that yes definitive, or would you say there is another answer state that can be triggered?

 

  Hide contents

I am just messing here in good jest.

 

Good one. Definitively. ;)

Share this post


Link to post

Actually i do have one more question. Just for the record: does A_Detonate change the blast radius or just the damage, or both?

Share this post


Link to post

A_Detonate causes an explosion with radius and damage both equal to the value of the calling Thing's missile damage property.

Share this post


Link to post

Sort of a tangent, but A_Detonate is limited in its usefulness because it reuses the same number for both values, since 128 damage is already a shitton and it's not possible to create a larger explosion without also cranking up the damage to ludicrous values.

 

Fortunately, if you've got access to A_Detonate you've probably also got MBF21's A_RadiusDamage (or some equivalent) available too, which lets you customize each value separately, as God and/or the Devil intended.

Share this post


Link to post
Guest
This topic is now closed to further replies.
×
×
  • Create New...