diff --git a/code/game/bg_pmove.c b/code/game/bg_pmove.c index df260874..c3b24bef 100644 --- a/code/game/bg_pmove.c +++ b/code/game/bg_pmove.c @@ -809,6 +809,8 @@ PM_DeadMove static void PM_DeadMove( void ) { float forward; + pm->ps->pm_flags |= PMF_NO_KNOCKBACK; + if ( !pml.walking ) { return; } diff --git a/code/game/bg_public.h b/code/game/bg_public.h index 0878102e..6c417d3b 100644 --- a/code/game/bg_public.h +++ b/code/game/bg_public.h @@ -142,6 +142,9 @@ typedef enum { #define PMF_FOLLOW 4096 // spectate following another player #define PMF_SCOREBOARD 8192 // spectate as a scoreboard #define PMF_INVULEXPAND 16384 // invulnerability sphere set to full size +#define PMF_NO_KNOCKBACK 32768 // this is basically the same as FL_NO_KNOCKBACK, + // except we apparently cannot set gentity_s::flags + // from inside of bg_pmove. Otherwise we wouldn't need this. #define PMF_ALL_TIMES (PMF_TIME_WATERJUMP|PMF_TIME_LAND|PMF_TIME_KNOCKBACK) diff --git a/code/game/g_combat.c b/code/game/g_combat.c index 5a88e713..e3d7a308 100644 --- a/code/game/g_combat.c +++ b/code/game/g_combat.c @@ -900,7 +900,10 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, if ( knockback > 200 ) { knockback = 200; } - if ( targ->flags & FL_NO_KNOCKBACK ) { + if ( + client && client->ps.pm_flags & PMF_NO_KNOCKBACK || + targ->flags & FL_NO_KNOCKBACK + ) { knockback = 0; } if ( dflags & DAMAGE_NO_KNOCKBACK ) { @@ -1064,8 +1067,26 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, } if ( targ->health <= 0 ) { - if ( client ) - targ->flags |= FL_NO_KNOCKBACK; + // In the original code we used to set `FL_NO_KNOCKBACK` here + // and not need `PMF_NO_KNOCKBACK` at all. + // However, that made it so that when fragging with the shotgun, + // the dead body does not gain momentum (knockback) + // from the pellets that come after the pellet + // that made the health go below 0. + // That resulted in the dead body not getting pushed + // as far as it should have been, and, most importantly, + // the gibs not getting enough momentum. See + // https://github.com/ec-/baseq3a/pull/53. + // + // Now we set the NO_KNOCKBACK flag inside of Pmove, + // which is ran after all the pellets of the shotgun shot + // have done their thing. + // + // This issiue is similar to + // https://github.com/ioquake/ioq3/issues/794. + // + // if ( client ) + // targ->flags |= FL_NO_KNOCKBACK; if (targ->health < -999) targ->health = -999;