From fffd90af154538bf3a091414250c037f7b8513ff Mon Sep 17 00:00:00 2001 From: BjossiAlfreds Date: Thu, 3 Oct 2019 15:46:14 +0000 Subject: [PATCH 1/3] Safely use plane normal in touch funcs --- src/g_newweap.c | 68 +++++++++++++---------------- src/g_sphere.c | 12 +++-- src/g_utils.c | 13 ++++++ src/g_weapon.c | 24 +++++++--- src/header/local.h | 1 + src/savegame/tables/gamefunc_decs.h | 2 +- 6 files changed, 71 insertions(+), 49 deletions(-) diff --git a/src/g_newweap.c b/src/g_newweap.c index 5920e0d..8b896af 100644 --- a/src/g_newweap.c +++ b/src/g_newweap.c @@ -45,8 +45,9 @@ void flechette_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { vec3_t dir; + vec3_t normal; - if (!self || !other || !plane) + if (!self || !other) { return; } @@ -67,15 +68,17 @@ flechette_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); } + get_normal_vector(plane, normal); + if (other->takedamage) { T_Damage(other, self, self->owner, self->velocity, self->s.origin, - plane->normal, self->dmg, self->dmg_radius, DAMAGE_NO_REG_ARMOR, + normal, self->dmg, self->dmg_radius, DAMAGE_NO_REG_ARMOR, MOD_ETF_RIFLE); } else { - VectorScale(plane->normal, 256, dir); + VectorScale(normal, 256, dir); gi.WriteByte(svc_temp_entity); gi.WriteByte(TE_FLECHETTE); @@ -367,12 +370,13 @@ prox_land(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { edict_t *field; vec3_t dir; + vec3_t normal; vec3_t forward, right, up; int movetype = MOVETYPE_NONE; int stick_ok = 0; vec3_t land_point; - if (!ent || !other || !plane) + if (!ent || !other) { return; } @@ -386,7 +390,9 @@ prox_land(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) return; } - VectorMA(ent->s.origin, -10.0, plane->normal, land_point); + get_normal_vector(plane, normal); + + VectorMA(ent->s.origin, -10.0, normal, land_point); if (gi.pointcontents(land_point) & (CONTENTS_SLIME | CONTENTS_LAVA)) { @@ -413,7 +419,7 @@ prox_land(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) float backoff, change; int i; - if ((other->movetype == MOVETYPE_PUSH) && (plane->normal[2] > 0.7)) + if ((other->movetype == MOVETYPE_PUSH) && (normal[2] > 0.7)) { stick_ok = 1; } @@ -422,11 +428,11 @@ prox_land(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) stick_ok = 0; } - backoff = DotProduct(ent->velocity, plane->normal) * 1.5; + backoff = DotProduct(ent->velocity, normal) * 1.5; for (i = 0; i < 3; i++) { - change = plane->normal[i] * backoff; + change = normal[i] * backoff; out[i] = ent->velocity[i] - change; if ((out[i] > -STOP_EPSILON) && (out[i] < STOP_EPSILON)) @@ -451,7 +457,7 @@ prox_land(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) } else /* no-stick. teflon time */ { - if (plane->normal[2] > 0.7) + if (normal[2] > 0.7) { Prox_Explode(ent); return; @@ -465,7 +471,7 @@ prox_land(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) return; } - vectoangles2(plane->normal, dir); + vectoangles2(normal, dir); AngleVectors(dir, forward, right, up); if (gi.pointcontents(ent->s.origin) & (CONTENTS_LAVA | CONTENTS_SLIME)) @@ -1230,13 +1236,16 @@ void tesla_lava(edict_t *ent, edict_t *other /* unused */, cplane_t *plane, csurface_t *surf /* unused */) { vec3_t land_point; + vec3_t normal; - if (!ent || !plane) + if (!ent) { return; } - VectorMA(ent->s.origin, -20.0, plane->normal, land_point); + get_normal_vector(plane, normal); + + VectorMA(ent->s.origin, -20.0, normal, land_point); if (gi.pointcontents(land_point) & (CONTENTS_SLIME | CONTENTS_LAVA)) { @@ -1500,14 +1509,7 @@ blaster2_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); } - if (plane) - { - VectorCopy(plane->normal, normal); - } - else - { - VectorCopy(vec3_origin, normal); - } + get_normal_vector(plane, normal); if (other->takedamage) { @@ -1719,24 +1721,13 @@ tracker_pain_daemon_spawn(edict_t *owner, edict_t *enemy, int damage) } void -tracker_explode(edict_t *self, cplane_t *plane) +tracker_explode(edict_t *self) { - vec3_t dir; - if (!self) { return; } - if (!plane) - { - VectorClear(dir); - } - else - { - VectorScale(plane->normal, 256, dir); - } - gi.WriteByte(svc_temp_entity); gi.WriteByte(TE_TRACKER_EXPLOSION); gi.WritePosition(self->s.origin); @@ -1749,6 +1740,7 @@ void tracker_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { float damagetime; + vec3_t normal; if (!self || !other || !plane) { @@ -1773,12 +1765,14 @@ tracker_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) if (other->takedamage) { + get_normal_vector(plane, normal); + if ((other->svflags & SVF_MONSTER) || other->client) { if (other->health > 0) /* knockback only for living creatures */ { T_Damage(other, self, self->owner, self->velocity, self->s.origin, - plane->normal, 0, (self->dmg * 3), TRACKER_IMPACT_FLAGS, + normal, 0, (self->dmg * 3), TRACKER_IMPACT_FLAGS, MOD_TRACKER); if (!(other->flags & (FL_FLY | FL_SWIM))) @@ -1793,18 +1787,18 @@ tracker_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) } else /* lots of damage (almost autogib) for dead bodies */ { - T_Damage(other, self, self->owner, self->velocity, self->s.origin, plane->normal, + T_Damage(other, self, self->owner, self->velocity, self->s.origin, normal, self->dmg * 4, (self->dmg * 3), TRACKER_IMPACT_FLAGS, MOD_TRACKER); } } else /* full damage in one shot for inanimate objects */ { - T_Damage(other, self, self->owner, self->velocity, self->s.origin, plane->normal, + T_Damage(other, self, self->owner, self->velocity, self->s.origin, normal, self->dmg, (self->dmg * 3), TRACKER_IMPACT_FLAGS, MOD_TRACKER); } } - tracker_explode(self, plane); + tracker_explode(self); } void @@ -1821,7 +1815,7 @@ tracker_fly(edict_t *self) if ((!self->enemy) || (!self->enemy->inuse) || (self->enemy->health < 1)) { - tracker_explode(self, NULL); + tracker_explode(self); return; } diff --git a/src/g_sphere.c b/src/g_sphere.c index dd3860e..d759bee 100644 --- a/src/g_sphere.c +++ b/src/g_sphere.c @@ -221,7 +221,9 @@ void sphere_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf, int mod) { - if (!self || !other || !plane) + vec3_t normal; + + if (!self || !other) { return; } @@ -259,8 +261,10 @@ sphere_touch(edict_t *self, edict_t *other, cplane_t *plane, if (other->takedamage) { + get_normal_vector(plane, normal); + T_Damage(other, self, self->owner, self->velocity, self->s.origin, - plane->normal, 10000, 1, DAMAGE_DESTROY_ARMOR, mod); + normal, 10000, 1, DAMAGE_DESTROY_ARMOR, mod); } else { @@ -274,7 +278,7 @@ void vengeance_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { - if (!self || !other || !plane) + if (!self || !other) { return; } @@ -294,7 +298,7 @@ hunter_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { edict_t *owner; - if (!self || !other || !plane || !surf) + if (!self || !other) { return; } diff --git a/src/g_utils.c b/src/g_utils.c index 61fdc57..1ff12ba 100644 --- a/src/g_utils.c +++ b/src/g_utils.c @@ -419,6 +419,19 @@ vtos(vec3_t v) return s; } +void +get_normal_vector(const cplane_t *p, vec3_t normal) +{ + if (p) + { + VectorCopy(p->normal, normal); + } + else + { + VectorCopy(vec3_origin, normal); + } +} + void G_SetMovedir(vec3_t angles, vec3_t movedir) { diff --git a/src/g_weapon.c b/src/g_weapon.c index 7af9a04..c2e74fd 100644 --- a/src/g_weapon.c +++ b/src/g_weapon.c @@ -346,8 +346,9 @@ void blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { int mod; + vec3_t normal; - if (!self || !other || !plane) + if (!self || !other) { return; } @@ -368,6 +369,8 @@ blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); } + get_normal_vector(plane, normal); + if (other->takedamage) { if (self->spawnflags & 1) @@ -379,7 +382,7 @@ blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) mod = MOD_BLASTER; } - T_Damage(other, self, self->owner, self->velocity, self->s.origin, plane->normal, + T_Damage(other, self, self->owner, self->velocity, self->s.origin, normal, self->dmg, 1, DAMAGE_ENERGY, mod); } else @@ -387,7 +390,7 @@ blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) gi.WriteByte(svc_temp_entity); gi.WriteByte(TE_BLASTER); gi.WritePosition(self->s.origin); - gi.WriteDir(plane->normal); + gi.WriteDir(normal); gi.multicast(self->s.origin, MULTICAST_PVS); } @@ -685,9 +688,10 @@ void rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { vec3_t origin; + vec3_t normal; int n; - if (!ent || !other || !plane) + if (!ent || !other) { return; } @@ -713,7 +717,9 @@ rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) if (other->takedamage) { - T_Damage(other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, + get_normal_vector(plane, normal); + + T_Damage(other, ent, ent->owner, ent->velocity, ent->s.origin, normal, ent->dmg, 0, 0, MOD_ROCKET); } else @@ -938,7 +944,9 @@ bfg_explode(edict_t *self) void bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { - if (!self || !other || !plane) + vec3_t normal; + + if (!self || !other) { return; } @@ -962,8 +970,10 @@ 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) { + get_normal_vector(plane, normal); + T_Damage(other, self, self->owner, self->velocity, self->s.origin, - plane->normal, 200, 0, 0, MOD_BFG_BLAST); + normal, 200, 0, 0, MOD_BFG_BLAST); } T_RadiusDamage(self, self->owner, 200, other, 100, MOD_BFG_BLAST); diff --git a/src/header/local.h b/src/header/local.h index 391397c..f48fff3 100644 --- a/src/header/local.h +++ b/src/header/local.h @@ -717,6 +717,7 @@ char *G_CopyString(char *in); float *tv(float x, float y, float z); char *vtos(vec3_t v); +void get_normal_vector(const cplane_t *p, vec3_t normal); float vectoyaw(vec3_t vec); void vectoangles(vec3_t vec, vec3_t angles); diff --git a/src/savegame/tables/gamefunc_decs.h b/src/savegame/tables/gamefunc_decs.h index 13dd16c..ae0511c 100644 --- a/src/savegame/tables/gamefunc_decs.h +++ b/src/savegame/tables/gamefunc_decs.h @@ -1000,7 +1000,7 @@ extern edict_t * SV_TestEntityPosition ( edict_t * ent ) ; extern void fire_tracker ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , edict_t * enemy ) ; extern void tracker_fly ( edict_t * self ) ; extern void tracker_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; -extern void tracker_explode ( edict_t * self , cplane_t * plane ) ; +extern void tracker_explode ( edict_t * self ) ; extern void tracker_pain_daemon_spawn ( edict_t * owner , edict_t * enemy , int damage ) ; extern void tracker_pain_daemon_think ( edict_t * self ) ; extern void fire_blaster2 ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , int effect , qboolean hyper ) ; From ab53f4d422b23c9080c138c5506da93b7082f8a7 Mon Sep 17 00:00:00 2001 From: BjossiAlfreds Date: Thu, 3 Oct 2019 16:04:54 +0000 Subject: [PATCH 2/3] Small fix to remove plane check from tracker_touch --- src/g_newweap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_newweap.c b/src/g_newweap.c index 8b896af..410aa9b 100644 --- a/src/g_newweap.c +++ b/src/g_newweap.c @@ -1742,7 +1742,7 @@ tracker_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) float damagetime; vec3_t normal; - if (!self || !other || !plane) + if (!self || !other) { return; } From 4c8d063a5583aa64a8e7e77aadbf8597d0e9a382 Mon Sep 17 00:00:00 2001 From: BjossiAlfreds Date: Thu, 3 Oct 2019 18:18:29 +0000 Subject: [PATCH 3/3] Added check for inuse to G_RunEntity that was missing but necessary --- src/g_phys.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/g_phys.c b/src/g_phys.c index bfaef61..915f542 100644 --- a/src/g_phys.c +++ b/src/g_phys.c @@ -1255,18 +1255,16 @@ G_RunEntity(edict_t *ent) gi.error("SV_Physics: bad movetype %i", (int)ent->movetype); } - if (saved_origin) + /* if we moved, check and fix origin if needed */ + /* also check inuse since entities are very often freed while thinking */ + if (saved_origin && ent->inuse && !VectorCompare(ent->s.origin, previous_origin)) { - /* if we moved, check and fix origin if needed */ - if (!VectorCompare(ent->s.origin, previous_origin)) - { - trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, - previous_origin, ent, MASK_MONSTERSOLID); + trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, + previous_origin, ent, MASK_MONSTERSOLID); - if (trace.allsolid || trace.startsolid) - { - VectorCopy(previous_origin, ent->s.origin); - } + if (trace.allsolid || trace.startsolid) + { + VectorCopy(previous_origin, ent->s.origin); } } }