static void DeadThink ( void ) { if ( !NPCInfo->timeOfDeath && NPC->client != NULL && NPCInfo != NULL ) { //haven't finished death anim yet and were NOT given a specific amount of time to wait before removal int legsAnim = (NPC->client->ps.legsAnim & ~ANIM_TOGGLEBIT); animation_t *animations = knownAnimFileSets[NPC->client->clientInfo.animFileIndex].animations; NPC->bounceCount = -1; // This is a cheap hack for optimizing the pointcontents check below if ( NPC->client->renderInfo.legsFrame == animations[legsAnim].firstFrame + (animations[legsAnim].numFrames - 1) ) { //reached the end of the death anim NPCInfo->timeOfDeath = level.time + BodyRemovalPadTime( NPC ); } } else { //death anim done (or were given a specific amount of time to wait before removal), wait the requisite amount of time them remove if ( level.time >= NPCInfo->timeOfDeath ) { if ( NPC->client->ps.eFlags & EF_NODRAW ) { NPC->e_ThinkFunc = thinkF_G_FreeEntity; NPC->nextthink = level.time + FRAMETIME; } else { // Start the body effect first, then delay 400ms before ditching the corpse NPC_RemoveBodyEffect(); NPC->e_ThinkFunc = thinkF_NPC_RemoveBody; if ( NPC->client->playerTeam == TEAM_FORGE ) NPC->nextthink = level.time + FRAMETIME * 8; else NPC->nextthink = level.time + FRAMETIME * 4; } return; } } // If the player is on the ground and the resting position contents haven't been set yet...(BounceCount tracks the contents) if ( NPC->bounceCount < 0 && NPC->s.groundEntityNum >= 0 ) { // if client is in a nodrop area, make him/her nodraw int contents = NPC->bounceCount = gi.pointcontents( NPC->currentOrigin, -1 ); if ( ( contents & CONTENTS_NODROP ) ) { NPC->client->ps.eFlags |= EF_NODRAW; } } // run the bot through the server like it was a real client ClientThink(NPC->s.number, &ucmd); VectorCopy(NPC->s.origin, NPC->s.origin2 ); }
/* ---------------------------------------- DeadThink ---------------------------------------- */ static void DeadThink ( void ) { trace_t trace; //HACKHACKHACKHACKHACK //We should really have a seperate G2 bounding box (seperate from the physics bbox) for G2 collisions only //FIXME: don't ever inflate back up? NPC->r.maxs.z = NPC->client->renderInfo.eyePoint.z - NPC->r.currentOrigin.z + 4; if ( NPC->r.maxs.z < -8 ) { NPC->r.maxs.z = -8; } if ( VectorCompare( &NPC->client->ps.velocity, &vec3_origin ) ) {//not flying through the air if ( NPC->r.mins.x > -32 ) { NPC->r.mins.x -= 1; trap->Trace (&trace, &NPC->r.currentOrigin, &NPC->r.mins, &NPC->r.maxs, &NPC->r.currentOrigin, NPC->s.number, NPC->clipmask, qfalse, 0, 0 ); if ( trace.allsolid ) { NPC->r.mins.x += 1; } } if ( NPC->r.maxs.x < 32 ) { NPC->r.maxs.x += 1; trap->Trace (&trace, &NPC->r.currentOrigin, &NPC->r.mins, &NPC->r.maxs, &NPC->r.currentOrigin, NPC->s.number, NPC->clipmask, qfalse, 0, 0 ); if ( trace.allsolid ) { NPC->r.maxs.x -= 1; } } if ( NPC->r.mins.y > -32 ) { NPC->r.mins.y -= 1; trap->Trace (&trace, &NPC->r.currentOrigin, &NPC->r.mins, &NPC->r.maxs, &NPC->r.currentOrigin, NPC->s.number, NPC->clipmask, qfalse, 0, 0 ); if ( trace.allsolid ) { NPC->r.mins.y += 1; } } if ( NPC->r.maxs.y < 32 ) { NPC->r.maxs.y += 1; trap->Trace (&trace, &NPC->r.currentOrigin, &NPC->r.mins, &NPC->r.maxs, &NPC->r.currentOrigin, NPC->s.number, NPC->clipmask, qfalse, 0, 0 ); if ( trace.allsolid ) { NPC->r.maxs.y -= 1; } } } //HACKHACKHACKHACKHACK //FIXME: tilt and fall off of ledges? //NPC_PostDeathThink(); /* if ( !NPCInfo->timeOfDeath && NPC->client != NULL && NPCInfo != NULL ) { //haven't finished death anim yet and were NOT given a specific amount of time to wait before removal int legsAnim = NPC->client->ps.legsAnim; animation_t *animations = knownAnimFileSets[NPC->client->clientInfo.animFileIndex].animations; NPC->bounceCount = -1; // This is a cheap hack for optimizing the pointcontents check below //ghoul doesn't tell us this anymore //if ( NPC->client->renderInfo.legsFrame == animations[legsAnim].firstFrame + (animations[legsAnim].numFrames - 1) ) { //reached the end of the death anim NPCInfo->timeOfDeath = level.time + BodyRemovalPadTime( NPC ); } } else */ { //death anim done (or were given a specific amount of time to wait before removal), wait the requisite amount of time them remove if ( level.time >= NPCInfo->timeOfDeath + BodyRemovalPadTime( NPC ) ) { if ( NPC->client->ps.eFlags & EF_NODRAW ) { if (!trap->ICARUS_IsRunning(NPC->s.number)) //if ( !NPC->taskManager || !NPC->taskManager->IsRunning() ) { NPC->think = G_FreeEntity; NPC->nextthink = level.time + FRAMETIME; } } else { class_t npc_class; // Start the body effect first, then delay 400ms before ditching the corpse NPC_RemoveBodyEffect(); //FIXME: keep it running through physics somehow? NPC->think = NPC_RemoveBody; NPC->nextthink = level.time + FRAMETIME; // if ( NPC->client->playerTeam == NPCTEAM_FORGE ) // NPCInfo->timeOfDeath = level.time + FRAMETIME * 8; // else if ( NPC->client->playerTeam == NPCTEAM_BOTS ) npc_class = NPC->client->NPC_class; // check for droids if ( npc_class == CLASS_SEEKER || npc_class == CLASS_REMOTE || npc_class == CLASS_PROBE || npc_class == CLASS_MOUSE || npc_class == CLASS_GONK || npc_class == CLASS_R2D2 || npc_class == CLASS_R5D2 || npc_class == CLASS_MARK2 || npc_class == CLASS_SENTRY )//npc_class == CLASS_PROTOCOL || { NPC->client->ps.eFlags |= EF_NODRAW; NPCInfo->timeOfDeath = level.time + FRAMETIME * 8; } else NPCInfo->timeOfDeath = level.time + FRAMETIME * 4; } return; } } // If the player is on the ground and the resting position contents haven't been set yet...(BounceCount tracks the contents) if ( NPC->bounceCount < 0 && NPC->s.groundEntityNum >= 0 ) { // if client is in a nodrop area, make him/her nodraw int contents = NPC->bounceCount = trap->PointContents( &NPC->r.currentOrigin, -1 ); if ( ( contents & CONTENTS_NODROP ) ) { NPC->client->ps.eFlags |= EF_NODRAW; } } CorpsePhysics( NPC ); }
/* ---------------------------------------- DeadThink ---------------------------------------- */ static void DeadThink ( void ) { trace_t trace; //HACKHACKHACKHACKHACK //We should really have a seperate G2 bounding box (seperate from the physics bbox) for G2 collisions only //FIXME: don't ever inflate back up? NPC->r.maxs[2] = NPC->client->renderInfo.eyePoint[2] - NPC->r.currentOrigin[2] + 4; if ( NPC->r.maxs[2] < -8 ) { NPC->r.maxs[2] = -8; } if ( VectorCompare( NPC->client->ps.velocity, vec3_origin ) ) {//not flying through the air if ( NPC->r.mins[0] > -32 ) { NPC->r.mins[0] -= 1; trap_Trace (&trace, NPC->r.currentOrigin, NPC->r.mins, NPC->r.maxs, NPC->r.currentOrigin, NPC->s.number, NPC->clipmask ); if ( trace.allsolid ) { NPC->r.mins[0] += 1; } } if ( NPC->r.maxs[0] < 32 ) { NPC->r.maxs[0] += 1; trap_Trace (&trace, NPC->r.currentOrigin, NPC->r.mins, NPC->r.maxs, NPC->r.currentOrigin, NPC->s.number, NPC->clipmask ); if ( trace.allsolid ) { NPC->r.maxs[0] -= 1; } } if ( NPC->r.mins[1] > -32 ) { NPC->r.mins[1] -= 1; trap_Trace (&trace, NPC->r.currentOrigin, NPC->r.mins, NPC->r.maxs, NPC->r.currentOrigin, NPC->s.number, NPC->clipmask ); if ( trace.allsolid ) { NPC->r.mins[1] += 1; } } if ( NPC->r.maxs[1] < 32 ) { NPC->r.maxs[1] += 1; trap_Trace (&trace, NPC->r.currentOrigin, NPC->r.mins, NPC->r.maxs, NPC->r.currentOrigin, NPC->s.number, NPC->clipmask ); if ( trace.allsolid ) { NPC->r.maxs[1] -= 1; } } } //HACKHACKHACKHACKHACK { //death anim done (or were given a specific amount of time to wait before removal), wait the requisite amount of time them remove if ( level.time >= NPCInfo->timeOfDeath + BodyRemovalPadTime( NPC ) ) { if ( NPC->client->ps.eFlags & EF_NODRAW ) { if (!trap_ICARUS_IsRunning(NPC->s.number)) { NPC->think = G_FreeEntity; NPC->nextthink = level.time + level.frameTime; } } else { class_t npc_class; // Start the body effect first, then delay 400ms before ditching the corpse NPC_RemoveBodyEffect(); //FIXME: keep it running through physics somehow? NPC->think = NPC_RemoveBody; NPC->nextthink = level.time + level.frameTime; npc_class = NPC->client->NPC_class; // check for droids if ( npc_class == CLASS_SEEKER || npc_class == CLASS_REMOTE || npc_class == CLASS_PROBE || npc_class == CLASS_MOUSE || npc_class == CLASS_GONK || npc_class == CLASS_R2D2 || npc_class == CLASS_R5D2 || npc_class == CLASS_MARK2 || npc_class == CLASS_SENTRY ) { NPC->client->ps.eFlags |= EF_NODRAW; NPCInfo->timeOfDeath = level.time + level.frameTime * 8; } else NPCInfo->timeOfDeath = level.time + level.frameTime * 4; } return; } } // If the player is on the ground and the resting position contents haven't been set yet...(BounceCount tracks the contents) if ( NPC->bounceCount < 0 && NPC->s.groundEntityNum >= 0 ) { // if client is in a nodrop area, make him/her nodraw int contents = NPC->bounceCount = trap_PointContents( NPC->r.currentOrigin, -1 ); if ( ( contents & CONTENTS_NODROP ) ) { NPC->client->ps.eFlags |= EF_NODRAW; } } CorpsePhysics( NPC ); }