Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Fernito

Monsters "jump forward"

Recommended Posts

Sorry, as I'm not native English speaker, I really don't know how to put it, so I hope you guys can understand what I mean: why do some times mosters "jump forward" when killed, instead of backwards?

Share this post


Link to post

It's random.

The idea is so that monsters at the top of a flight of stairs or atop a balcony may have a chance of falling forward. Ever watched a movie where there's a shootout and people are falling from windows and stuff left and right when they're shot? (If not, watch more westerns.) That's kind of what this is meant to reproduce.

Share this post


Link to post

Just a guess, but it may be influenced by the exact place where the hitscan/projectile collision is detected by the engine. It may not always be in the closest place to the player. It may be a wrong statement for hitscans though, I don't know.

Share this post


Link to post

I don't know if you're asking just out of curiosity, but in case you want to avoid this behavior, there is a recent decorate flag for ZDoom that can disable this at specific projectiles; it is +NOFORWARDFALL.

Share this post


Link to post
scifista42 said:

Just a guess, but it may be influenced by the exact place where the hitscan/projectile collision is detected by the engine. It may not always be in the closest place to the player. It may be a wrong statement for hitscans though, I don't know.

No.

It is, as I said, random.

Full code:

//
// P_DamageMobj
// Damages both enemies and players
// "inflictor" is the thing that caused the damage
//  creature or missile, can be NULL (slime, etc)
// "source" is the thing to target after taking damage
//  creature or NULL
// Source and inflictor are the same for melee attacks.
// Source can be NULL for slime, barrel explosions
// and other environmental stuff.
//
void
P_DamageMobj
( mobj_t*	target,
  mobj_t*	inflictor,
  mobj_t*	source,
  int 		damage )
{
    unsigned	ang;
    int		saved;
    player_t*	player;
    fixed_t	thrust;
    int		temp;
	
    if ( !(target->flags & MF_SHOOTABLE) )
	return;	// shouldn't happen...
		
    if (target->health <= 0)
	return;

    if ( target->flags & MF_SKULLFLY )
    {
	target->momx = target->momy = target->momz = 0;
    }
	
    player = target->player;
    if (player && gameskill == sk_baby)
	damage >>= 1; 	// take half damage in trainer mode
		

    // Some close combat weapons should not
    // inflict thrust and push the victim out of reach,
    // thus kick away unless using the chainsaw.
    if (inflictor
	&& !(target->flags & MF_NOCLIP)
	&& (!source
	    || !source->player
	    || source->player->readyweapon != wp_chainsaw))
    {
	ang = R_PointToAngle2 ( inflictor->x,
				inflictor->y,
				target->x,
				target->y);
		
	thrust = damage*(FRACUNIT>>3)*100/target->info->mass;

	// make fall forwards sometimes
	if ( damage < 40
	     && damage > target->health
	     && target->z - inflictor->z > 64*FRACUNIT
	     && (P_Random ()&1) )
	{
	    ang += ANG180;
	    thrust *= 4;
	}
		
	ang >>= ANGLETOFINESHIFT;
	target->momx += FixedMul (thrust, finecosine[ang]);
	target->momy += FixedMul (thrust, finesine[ang]);
    }
    
    // player specific
    if (player)
    {
	// end of game hell hack
	if (target->subsector->sector->special == 11
	    && damage >= target->health)
	{
	    damage = target->health - 1;
	}
	

	// Below certain threshold,
	// ignore damage in GOD mode, or with INVUL power.
	if ( damage < 1000
	     && ( (player->cheats&CF_GODMODE)
		  || player->powers[pw_invulnerability] ) )
	{
	    return;
	}
	
	if (player->armortype)
	{
	    if (player->armortype == 1)
		saved = damage/3;
	    else
		saved = damage/2;
	    
	    if (player->armorpoints <= saved)
	    {
		// armor is used up
		saved = player->armorpoints;
		player->armortype = 0;
	    }
	    player->armorpoints -= saved;
	    damage -= saved;
	}
	player->health -= damage; 	// mirror mobj health here for Dave
	if (player->health < 0)
	    player->health = 0;
	
	player->attacker = source;
	player->damagecount += damage;	// add damage after armor / invuln

	if (player->damagecount > 100)
	    player->damagecount = 100;	// teleport stomp does 10k points...
	
	temp = damage < 100 ? damage : 100;

	if (player == &players[consoleplayer])
	    I_Tactile (40,10,40+temp*2);
    }
    
    // do the damage	
    target->health -= damage;	
    if (target->health <= 0)
    {
	P_KillMobj (source, target);
	return;
    }

    if ( (P_Random () < target->info->painchance)
	 && !(target->flags&MF_SKULLFLY) )
    {
	target->flags |= MF_JUSTHIT;	// fight back!
	
	P_SetMobjState (target, target->info->painstate);
    }
			
    target->reactiontime = 0;		// we're awake now...	

    if ( (!target->threshold || target->type == MT_VILE)
	 && source && source != target
	 && source->type != MT_VILE)
    {
	// if not intent on another player,
	// chase after this one
	target->target = source;
	target->threshold = BASETHRESHOLD;
	if (target->state == &states[target->info->spawnstate]
	    && target->info->seestate != S_NULL)
	    P_SetMobjState (target, target->info->seestate);
    }
			
}
Relevant excerpt:
	// make fall forwards sometimes
	if ( damage < 40
	     && damage > target->health
	     && target->z - inflictor->z > 64*FRACUNIT
	     && (P_Random ()&1) )
	{
	    ang += ANG180;
	    thrust *= 4;
	}
So, the requirements:
* Damage inflicted is less than 40 points
* Damage inflicted is enough to kill the monster
* Monster is at least 64 map units higher than shooter
* 50% chance

The effect is:
* Fall direction inverted (forward instead of backward)
* Momentum quadrupled (to make sure the monster does fall)

Share this post


Link to post

This happens a lot in Heretic E1M5 when killing the golems at the green doors with a hitscan weapon before raising the stairs. It looks really funny when chunks of flesh and blood fly to your face.

Share this post


Link to post

Great Gez, thanks a lot for the technical explanation. Now I can go and sleep in peace :)

@Darch: asking just out of curiosity :)

ASD said:

This happens a lot in Heretic E1M5 when killing the golems at the green doors with a hitscan weapon before raising the stairs. It looks really funny when chunks of flesh and blood fly to your face.


Yeah, you're right! This effect in Heretic seems to be "exacerbated".

Share this post


Link to post
Fernito said:

Yeah, you're right! This effect in Heretic seems to be "exacerbated".

And that's because Heretic increases the "thrust factor", so less damage inflicts more thrust. This is why monsters in the game on the whole move around a whole lot more when you shoot them. Also applies to the player equally.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×