Safely use plane normal in touch funcs

This commit is contained in:
BjossiAlfreds 2019-10-03 15:46:14 +00:00
parent 9eead824c7
commit fffd90af15
6 changed files with 71 additions and 49 deletions

View file

@ -45,8 +45,9 @@ void
flechette_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) flechette_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{ {
vec3_t dir; vec3_t dir;
vec3_t normal;
if (!self || !other || !plane) if (!self || !other)
{ {
return; 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); PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
} }
get_normal_vector(plane, normal);
if (other->takedamage) if (other->takedamage)
{ {
T_Damage(other, self, self->owner, self->velocity, self->s.origin, 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); MOD_ETF_RIFLE);
} }
else else
{ {
VectorScale(plane->normal, 256, dir); VectorScale(normal, 256, dir);
gi.WriteByte(svc_temp_entity); gi.WriteByte(svc_temp_entity);
gi.WriteByte(TE_FLECHETTE); 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; edict_t *field;
vec3_t dir; vec3_t dir;
vec3_t normal;
vec3_t forward, right, up; vec3_t forward, right, up;
int movetype = MOVETYPE_NONE; int movetype = MOVETYPE_NONE;
int stick_ok = 0; int stick_ok = 0;
vec3_t land_point; vec3_t land_point;
if (!ent || !other || !plane) if (!ent || !other)
{ {
return; return;
} }
@ -386,7 +390,9 @@ prox_land(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
return; 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)) 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; float backoff, change;
int i; int i;
if ((other->movetype == MOVETYPE_PUSH) && (plane->normal[2] > 0.7)) if ((other->movetype == MOVETYPE_PUSH) && (normal[2] > 0.7))
{ {
stick_ok = 1; stick_ok = 1;
} }
@ -422,11 +428,11 @@ prox_land(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
stick_ok = 0; stick_ok = 0;
} }
backoff = DotProduct(ent->velocity, plane->normal) * 1.5; backoff = DotProduct(ent->velocity, normal) * 1.5;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
change = plane->normal[i] * backoff; change = normal[i] * backoff;
out[i] = ent->velocity[i] - change; out[i] = ent->velocity[i] - change;
if ((out[i] > -STOP_EPSILON) && (out[i] < STOP_EPSILON)) 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 */ else /* no-stick. teflon time */
{ {
if (plane->normal[2] > 0.7) if (normal[2] > 0.7)
{ {
Prox_Explode(ent); Prox_Explode(ent);
return; return;
@ -465,7 +471,7 @@ prox_land(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
return; return;
} }
vectoangles2(plane->normal, dir); vectoangles2(normal, dir);
AngleVectors(dir, forward, right, up); AngleVectors(dir, forward, right, up);
if (gi.pointcontents(ent->s.origin) & (CONTENTS_LAVA | CONTENTS_SLIME)) 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 */) tesla_lava(edict_t *ent, edict_t *other /* unused */, cplane_t *plane, csurface_t *surf /* unused */)
{ {
vec3_t land_point; vec3_t land_point;
vec3_t normal;
if (!ent || !plane) if (!ent)
{ {
return; 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)) 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); PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
} }
if (plane) get_normal_vector(plane, normal);
{
VectorCopy(plane->normal, normal);
}
else
{
VectorCopy(vec3_origin, normal);
}
if (other->takedamage) if (other->takedamage)
{ {
@ -1719,24 +1721,13 @@ tracker_pain_daemon_spawn(edict_t *owner, edict_t *enemy, int damage)
} }
void void
tracker_explode(edict_t *self, cplane_t *plane) tracker_explode(edict_t *self)
{ {
vec3_t dir;
if (!self) if (!self)
{ {
return; return;
} }
if (!plane)
{
VectorClear(dir);
}
else
{
VectorScale(plane->normal, 256, dir);
}
gi.WriteByte(svc_temp_entity); gi.WriteByte(svc_temp_entity);
gi.WriteByte(TE_TRACKER_EXPLOSION); gi.WriteByte(TE_TRACKER_EXPLOSION);
gi.WritePosition(self->s.origin); gi.WritePosition(self->s.origin);
@ -1749,6 +1740,7 @@ void
tracker_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) tracker_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{ {
float damagetime; float damagetime;
vec3_t normal;
if (!self || !other || !plane) 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) if (other->takedamage)
{ {
get_normal_vector(plane, normal);
if ((other->svflags & SVF_MONSTER) || other->client) if ((other->svflags & SVF_MONSTER) || other->client)
{ {
if (other->health > 0) /* knockback only for living creatures */ if (other->health > 0) /* knockback only for living creatures */
{ {
T_Damage(other, self, self->owner, self->velocity, self->s.origin, 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); MOD_TRACKER);
if (!(other->flags & (FL_FLY | FL_SWIM))) 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 */ 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); self->dmg * 4, (self->dmg * 3), TRACKER_IMPACT_FLAGS, MOD_TRACKER);
} }
} }
else /* full damage in one shot for inanimate objects */ 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); self->dmg, (self->dmg * 3), TRACKER_IMPACT_FLAGS, MOD_TRACKER);
} }
} }
tracker_explode(self, plane); tracker_explode(self);
} }
void void
@ -1821,7 +1815,7 @@ tracker_fly(edict_t *self)
if ((!self->enemy) || (!self->enemy->inuse) || (self->enemy->health < 1)) if ((!self->enemy) || (!self->enemy->inuse) || (self->enemy->health < 1))
{ {
tracker_explode(self, NULL); tracker_explode(self);
return; return;
} }

View file

@ -221,7 +221,9 @@ void
sphere_touch(edict_t *self, edict_t *other, cplane_t *plane, sphere_touch(edict_t *self, edict_t *other, cplane_t *plane,
csurface_t *surf, int mod) csurface_t *surf, int mod)
{ {
if (!self || !other || !plane) vec3_t normal;
if (!self || !other)
{ {
return; return;
} }
@ -259,8 +261,10 @@ sphere_touch(edict_t *self, edict_t *other, cplane_t *plane,
if (other->takedamage) if (other->takedamage)
{ {
get_normal_vector(plane, normal);
T_Damage(other, self, self->owner, self->velocity, self->s.origin, 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 else
{ {
@ -274,7 +278,7 @@ void
vengeance_touch(edict_t *self, edict_t *other, cplane_t *plane, vengeance_touch(edict_t *self, edict_t *other, cplane_t *plane,
csurface_t *surf) csurface_t *surf)
{ {
if (!self || !other || !plane) if (!self || !other)
{ {
return; return;
} }
@ -294,7 +298,7 @@ hunter_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{ {
edict_t *owner; edict_t *owner;
if (!self || !other || !plane || !surf) if (!self || !other)
{ {
return; return;
} }

View file

@ -419,6 +419,19 @@ vtos(vec3_t v)
return s; 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 void
G_SetMovedir(vec3_t angles, vec3_t movedir) G_SetMovedir(vec3_t angles, vec3_t movedir)
{ {

View file

@ -346,8 +346,9 @@ void
blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{ {
int mod; int mod;
vec3_t normal;
if (!self || !other || !plane) if (!self || !other)
{ {
return; 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); PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
} }
get_normal_vector(plane, normal);
if (other->takedamage) if (other->takedamage)
{ {
if (self->spawnflags & 1) 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; 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); self->dmg, 1, DAMAGE_ENERGY, mod);
} }
else 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(svc_temp_entity);
gi.WriteByte(TE_BLASTER); gi.WriteByte(TE_BLASTER);
gi.WritePosition(self->s.origin); gi.WritePosition(self->s.origin);
gi.WriteDir(plane->normal); gi.WriteDir(normal);
gi.multicast(self->s.origin, MULTICAST_PVS); 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) rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{ {
vec3_t origin; vec3_t origin;
vec3_t normal;
int n; int n;
if (!ent || !other || !plane) if (!ent || !other)
{ {
return; return;
} }
@ -713,7 +717,9 @@ rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
if (other->takedamage) 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); ent->dmg, 0, 0, MOD_ROCKET);
} }
else else
@ -938,7 +944,9 @@ bfg_explode(edict_t *self)
void void
bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) 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; 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 */ /* core explosion - prevents firing it into the wall/floor */
if (other->takedamage) if (other->takedamage)
{ {
get_normal_vector(plane, normal);
T_Damage(other, self, self->owner, self->velocity, self->s.origin, 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); T_RadiusDamage(self, self->owner, 200, other, 100, MOD_BFG_BLAST);

View file

@ -717,6 +717,7 @@ char *G_CopyString(char *in);
float *tv(float x, float y, float z); float *tv(float x, float y, float z);
char *vtos(vec3_t v); char *vtos(vec3_t v);
void get_normal_vector(const cplane_t *p, vec3_t normal);
float vectoyaw(vec3_t vec); float vectoyaw(vec3_t vec);
void vectoangles(vec3_t vec, vec3_t angles); void vectoangles(vec3_t vec, vec3_t angles);

View file

@ -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 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_fly ( edict_t * self ) ;
extern void tracker_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; 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_spawn ( edict_t * owner , edict_t * enemy , int damage ) ;
extern void tracker_pain_daemon_think ( edict_t * self ) ; 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 ) ; extern void fire_blaster2 ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , int effect , qboolean hyper ) ;