diff --git a/src/game/g_combat.c b/src/game/g_combat.c index 887d859d..0593f597 100644 --- a/src/game/g_combat.c +++ b/src/game/g_combat.c @@ -501,6 +501,24 @@ M_ReactToDamage(edict_t *targ, edict_t *attacker) } } +static void +apply_knockback(edict_t *targ, vec3_t dir, float knockback, float scale) +{ + vec3_t kvel; + float mass; + + if (!knockback) + { + return; + } + + mass = (targ->mass < 50) ? 50.0f : (float)targ->mass; + + VectorNormalize2 (dir, kvel); + VectorScale (kvel, scale * (knockback / mass), kvel); + VectorAdd (targ->velocity, kvel, targ->velocity); +} + void T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal, int damage, @@ -567,8 +585,6 @@ T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, te_sparks = TE_SPARKS; } - VectorNormalize(dir); - /* bonus damage for suprising a monster */ if (!(dflags & DAMAGE_RADIUS) && (targ->svflags & SVF_MONSTER) && (attacker->client) && (!targ->enemy) && (targ->health > 0)) @@ -582,37 +598,14 @@ T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, } /* figure momentum add */ - if (!(dflags & DAMAGE_NO_KNOCKBACK)) + if (!(dflags & DAMAGE_NO_KNOCKBACK) && + (targ->movetype != MOVETYPE_NONE) && + (targ->movetype != MOVETYPE_BOUNCE) && + (targ->movetype != MOVETYPE_PUSH) && + (targ->movetype != MOVETYPE_STOP)) { - if ((knockback) && (targ->movetype != MOVETYPE_NONE) && - (targ->movetype != MOVETYPE_BOUNCE) && - (targ->movetype != MOVETYPE_PUSH) && - (targ->movetype != MOVETYPE_STOP)) - { - vec3_t kvel; - float mass; - - if (targ->mass < 50) - { - mass = 50; - } - else - { - mass = targ->mass; - } - - if (targ->client && (attacker == targ)) - { - /* This allows rocket jumps */ - VectorScale(dir, 1600.0 * (float)knockback / mass, kvel); - } - else - { - VectorScale(dir, 500.0 * (float)knockback / mass, kvel); - } - - VectorAdd(targ->velocity, kvel, targ->velocity); - } + apply_knockback (targ, dir, knockback, + ((client && attacker == targ) ? 1600.0f : 500.0f)); } take = damage; diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c index 22c2a52a..e49e6e17 100644 --- a/src/game/g_weapon.c +++ b/src/game/g_weapon.c @@ -1042,26 +1042,28 @@ bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) /* core explosion - prevents firing it into the wall/floor */ if (other->takedamage) { - if (plane) - { - T_Damage(other, self, self->owner, self->velocity, self->s.origin, - plane->normal, 200, 0, 0, MOD_BFG_BLAST); - } - else - { - T_Damage(other, self, self->owner, self->velocity, self->s.origin, - vec3_origin, 200, 0, 0, MOD_BFG_BLAST); - } + T_Damage(other, self, self->owner, self->velocity, self->s.origin, + (plane) ? plane->normal : vec3_origin, + 200, 0, 0, MOD_BFG_BLAST); } T_RadiusDamage(self, self->owner, 200, other, 100, MOD_BFG_BLAST); gi.sound(self, CHAN_VOICE, gi.soundindex( "weapons/bfg__x1b.wav"), 1, ATTN_NORM, 0); + self->solid = SOLID_NOT; self->touch = NULL; - VectorMA(self->s.origin, -1 * FRAMETIME, self->velocity, self->s.origin); + + /* move it back a bit from walls so the effects aren't cut off */ + if (!other->takedamage) + { + VectorNormalize(self->velocity); + VectorMA(self->s.origin, -40.0f, self->velocity, self->s.origin); + } + VectorClear(self->velocity); + self->s.modelindex = gi.modelindex("sprites/s_bfg3.sp2"); self->s.frame = 0; self->s.sound = 0; @@ -1070,6 +1072,8 @@ bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) self->nextthink = level.time + FRAMETIME; self->enemy = other; + gi.linkentity(self); + gi.WriteByte(svc_temp_entity); gi.WriteByte(TE_BFG_BIGEXPLOSION); gi.WritePosition(self->s.origin);