Merge pull request #52 from BjossiAlfreds/plane

Safely use plane normal in rest of touch functions
This commit is contained in:
Yamagi 2019-10-07 18:58:42 +02:00 committed by GitHub
commit 6196f3fb9a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 60 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);
@ -371,12 +374,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;
} }
@ -390,7 +394,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))
{ {
@ -417,7 +423,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;
} }
@ -426,11 +432,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))
@ -455,7 +461,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;
@ -469,7 +475,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))
@ -1249,13 +1255,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))
{ {
@ -1519,14 +1528,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)
{ {
@ -1738,24 +1740,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);
@ -1768,8 +1759,9 @@ 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)
{ {
return; return;
} }
@ -1792,12 +1784,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)))
@ -1812,18 +1806,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
@ -1840,7 +1834,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

@ -1255,18 +1255,16 @@ G_RunEntity(edict_t *ent)
gi.error("SV_Physics: bad movetype %i", (int)ent->movetype); 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 */ trace = gi.trace(ent->s.origin, ent->mins, ent->maxs,
if (!VectorCompare(ent->s.origin, previous_origin)) 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) if (trace.allsolid || trace.startsolid)
{ {
VectorCopy(previous_origin, ent->s.origin); VectorCopy(previous_origin, ent->s.origin);
}
} }
} }
} }

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 ) ;