q3df.org | Wiki > Techniques > Groundboosting in the code
dfwc 2017

Wiki > Techniques > Groundboosting in the code    

Disclaimer

This is how I(<hk>) think the Groundboost works however I did not investigate any further. This is just how i pieced it together. I could be wrong here but I am at least very close. Please point out mistakes of any kind. I'll see to correct them.

Summary

  • The Bug lets you run on ground with no friction at all.
  • The more damage you take the longer you slide but only between 50 and 200 milliseconds(6 to 25 frames).
  • It should work with other players hitting you(teamtricking).
  • It should work with shooter(map object) hitting you.

How it works step by step

  • A player takes damage(from himself) by shooting at ground the ground or wall.
  • The player is pushed away relative to the damage he takes if the weapon has a knockback.
knockback = damage;
if ( knockback > 200 ) {
    knockback = 200;
}
if ( targ->flags & FL_NO_KNOCKBACK ) {
    knockback = 0;
}
if ( dflags & DAMAGE_NO_KNOCKBACK ) {
    knockback = 0;
}

g_combat.c in function G_Damage()

  • A flag is set which defines the player as being pushed around. The delay until the flag is cleared depends on the damage the player takes. It lasts at least 50 milliseconds but 200 milliseconds maximum (this will be your slidetime).
t = knockback * 2;
if ( t < 50 ) {
    t = 50;
}
if ( t > 200 ) {
    t = 200;
}
targ->client->ps.pm_time = t;
targ->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;

g_combat.c in function G_Damage()

  • Usually, when you are hit, you can't move very well because the knockback pushes you off the ground into the air. But you never left the ground so PM_WalkMove() applies instead of PM_AirMove(). You can walk on the ground with typical air acceleration. I guess that they removed the PMF_TIME_KNOCKBACK from this if() statement in CPM which would make the effect 10 times stronger than in VQ3. A while ago a programmer named "Setup" decompiled parts of the defrag QVM and determined the value for pm_accelerate to bi 15.0f
float pm_accelerate = 10.0f;
float pm_airaccelerate = 1.0f;

bg_pmove.c line 39

-float    pm_accelerate = 10.0f;
+float  pm_accelerate = 15.0f;

cpm.diff line 25 by setup

// when a player gets hit, they temporarily lose
// full control, which allows them to be moved a bit
if ( ( pml.groundTrace.surfaceFlags & SURF_SLICK )
    || pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) {
    accelerate = pm_airaccelerate;
} else {
    accelerate = pm_accelerate;
}

bg_pmove.c in function PM_WalkMove()

It's the same for Teleporterjumping. Here is the code snipped that set's the KNOCKBACK flag. Which eventually leads to a lack of ground friction.

// spit the player out
AngleVectors( angles, player->client->ps.velocity, NULL, NULL );
VectorScale( player->client->ps.velocity, 400, player->client->ps.velocity );
player->client->ps.pm_time = 160;   // hold time
player->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;

g_misc.c in function TeleportPlayer()

Here is the part where the PMF_TIME_KNOCKBACK leads to no friction at all. That's why you can accelerate like being on slicky ground. The section where friction is applied is skipped because the PMF_TIME_KNOCKBACK flag is set.

// apply ground friction
if ( pm->waterlevel <= 1 ) {
    if ( pml.walking && !(pml.groundTrace.surfaceFlags & SURF_SLICK) ) {
        // if getting knocked back, no friction
        if ( ! (pm->ps->pm_flags & PMF_TIME_KNOCKBACK) ) {
            control = speed < pm_stopspeed ? pm_stopspeed : speed;
            drop += control*pm_friction*pml.frametime;
        }
    }
}

bg_pmove.c in function PM_Friction()


thread in the forum

Written by <hk>

Text is available under the Creative Commons Attribution-ShareAlike License