quake2-action/a_doorkick.c
2018-11-13 00:25:08 -08:00

135 lines
3.9 KiB
C

/* a_doorkick.c
* Door kicking code by hal[9k]
* originally for AQ:Espionage (http://aqdt.fear.net/)
* email: hal9000@telefragged.com
* Assembled here by Homer (homer@fear.net)
*/
#include "g_local.h"
#define STATE_TOP 0
#define STATE_BOTTOM 1
#define STATE_UP 2
#define STATE_DOWN 3
#define DOOR_START_OPEN 1
#define DOOR_REVERSE 2
extern void door_use (edict_t *self, edict_t *other, edict_t *activator);
// needed for KickDoor
void VectorRotate(vec3_t in, vec3_t angles, vec3_t out)
{
float cv, sv, angle, tv;
VectorCopy(in, out);
angle = (-angles[PITCH]) * M_PI / 180;
cv = cos(angle);
sv = sin(angle);
tv = (out[0] * cv) - (out[2] * sv);
out[2] = (out[2] * cv) + (out[0] * sv);
out[0] = tv;
angle = (angles[YAW]) * M_PI / 180;
cv = cos(angle);
sv = sin(angle);
tv = (out[0] * cv) - (out[1] * sv);
out[1] = (out[1] * cv) + (out[0] * sv);
out[0] = tv;
angle = (angles[ROLL]) * M_PI / 180;
cv = cos(angle);
sv = sin(angle);
tv = (out[1] * cv) - (out[2] * sv);
out[2] = (out[2] * cv) + (out[1] * sv);
out[1] = tv;
}
int KickDoor( trace_t *tr_old, edict_t *ent, vec3_t forward )
{
trace_t tr;
vec3_t d_forward, right, end;
float d;
if ( !Q_strcasecmp( tr_old->ent->classname, "func_door_rotating" ) )
{
// Make that the door is closed
tr = *tr_old;
#if 1
if ( (!(tr.ent->spawnflags & DOOR_START_OPEN) &&
!(tr.ent->moveinfo.state == STATE_TOP)) ||
( (tr.ent->spawnflags & DOOR_START_OPEN) &&
!(tr.ent->moveinfo.state == STATE_BOTTOM)) )
#else
if ( (!(tr.ent->spawnflags & DOOR_START_OPEN) &&
((tr.ent->moveinfo.state == STATE_BOTTOM) ||
(tr.ent->moveinfo.state == STATE_DOWN))) ||
((tr.ent->spawnflags & DOOR_START_OPEN) &&
((tr.ent->moveinfo.state == STATE_TOP) ||
(tr.ent->moveinfo.state == STATE_UP))) )
#endif
{
//gi.dprintf( "Kicking a closed door\n" );
// Find out if we are on the "outside"
#if 0
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_RAILTRAIL);
gi.WritePosition (tr.ent->s.origin);
gi.WritePosition (tr.endpos);
gi.multicast (tr.ent->s.origin, MULTICAST_PHS);
#endif
VectorSubtract( tr.endpos, tr.ent->s.origin, d_forward );
forward[2] = 0;
d_forward[2] = 0;
VectorNormalize( forward );
VectorNormalize( d_forward );
VectorSet( right, 0, 90, 0 );
VectorRotate( d_forward, right, d_forward );
d = DotProduct( forward, d_forward );
if ( tr.ent->spawnflags & DOOR_REVERSE )
d = -d;
// d = sin( acos( d ) );
if ( d > 0.0 )
{
// gi.dprintf( "we think we are on the outside\n" );
//if ( tr.ent->spawnflags & DOOR_REVERSE )
// gi.dprintf( "but DOOR_REVERSE is set\n" );
// Only use the door if it's not already opening
if ( (!( tr.ent->spawnflags & DOOR_START_OPEN ) &&
!( tr.ent->moveinfo.state == STATE_UP )) ||
((tr.ent->spawnflags & DOOR_START_OPEN ) &&
(tr.ent->moveinfo.state == STATE_DOWN) ) )
door_use( tr.ent, ent, ent );
// Find out if someone else is on the other side
VectorMA( tr.endpos, 25, forward, end );
PRETRACE();
tr = gi.trace (tr.endpos, NULL, NULL, end, tr.ent, MASK_SHOT);
POSTTRACE();
if (!((tr.surface) && (tr.surface->flags & SURF_SKY)))
{
if (tr.fraction < 1.0)
{
if (tr.ent->client)
{
//gi.dprintf("we found a client on the other side\n");
*tr_old = tr;
return( 1 );
}
}
}
}
}
}
return( 0 );
}