/* 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 ); }