void CalcEntitySpot ( const gentity_t *ent, const spot_t spot, vec3_t point ) { vec3_t forward, up, right; vec3_t start, end; trace_t tr; if ( !ent ) { return; } ViewHeightFix(ent); switch ( spot ) { case SPOT_ORIGIN: if(VectorCompare(ent->currentOrigin, vec3_origin)) {//brush VectorSubtract(ent->absmax, ent->absmin, point);//size VectorMA(ent->absmin, 0.5, point, point); } else { VectorCopy ( ent->currentOrigin, point ); } break; case SPOT_CHEST: case SPOT_HEAD: if ( ent->client && VectorLengthSquared( ent->client->renderInfo.eyePoint ) && (ent->client->ps.viewEntity <= 0 || ent->client->ps.viewEntity >= ENTITYNUM_WORLD) ) {//Actual tag_head eyespot! //FIXME: Stasis aliens may have a problem here... VectorCopy( ent->client->renderInfo.eyePoint, point ); if ( ent->client->NPC_class == CLASS_ATST ) {//adjust up some point[2] += 28;//magic number :) } if ( ent->NPC ) {//always aim from the center of my bbox, so we don't wiggle when we lean forward or backwards point[0] = ent->currentOrigin[0]; point[1] = ent->currentOrigin[1]; } else if ( !ent->s.number ) { SubtractLeanOfs( ent, point ); } } else { VectorCopy ( ent->currentOrigin, point ); if ( ent->client ) { point[2] += ent->client->ps.viewheight; } } if ( spot == SPOT_CHEST && ent->client ) { if ( ent->client->NPC_class != CLASS_ATST ) {//adjust up some point[2] -= ent->maxs[2]*0.2f; } } break; case SPOT_HEAD_LEAN: if ( ent->client && VectorLengthSquared( ent->client->renderInfo.eyePoint ) && (ent->client->ps.viewEntity <= 0 || ent->client->ps.viewEntity >= ENTITYNUM_WORLD) ) {//Actual tag_head eyespot! //FIXME: Stasis aliens may have a problem here... VectorCopy( ent->client->renderInfo.eyePoint, point ); if ( ent->client->NPC_class == CLASS_ATST ) {//adjust up some point[2] += 28;//magic number :) } if ( ent->NPC ) {//always aim from the center of my bbox, so we don't wiggle when we lean forward or backwards point[0] = ent->currentOrigin[0]; point[1] = ent->currentOrigin[1]; } else if ( !ent->s.number ) { SubtractLeanOfs( ent, point ); } //NOTE: automatically takes leaning into account! } else { VectorCopy ( ent->currentOrigin, point ); if ( ent->client ) { point[2] += ent->client->ps.viewheight; } //AddLeanOfs ( ent, point ); } break; //FIXME: implement... //case SPOT_CHEST: //Returns point 3/4 from tag_torso to tag_head? //break; case SPOT_LEGS: VectorCopy ( ent->currentOrigin, point ); point[2] += (ent->mins[2] * 0.5); break; case SPOT_WEAPON: if( ent->NPC && !VectorCompare( ent->NPC->shootAngles, vec3_origin ) && !VectorCompare( ent->NPC->shootAngles, ent->client->ps.viewangles )) { AngleVectors( ent->NPC->shootAngles, forward, right, up ); } else { AngleVectors( ent->client->ps.viewangles, forward, right, up ); } CalcMuzzlePoint( (gentity_t*)ent, forward, right, up, point, 0 ); //NOTE: automatically takes leaning into account! break; case SPOT_GROUND: // if entity is on the ground, just use it's absmin if ( ent->s.groundEntityNum != -1 ) { VectorCopy( ent->currentOrigin, point ); point[2] = ent->absmin[2]; break; } // if it is reasonably close to the ground, give the point underneath of it VectorCopy( ent->currentOrigin, start ); start[2] = ent->absmin[2]; VectorCopy( start, end ); end[2] -= 64; gi.trace( &tr, start, ent->mins, ent->maxs, end, ent->s.number, MASK_PLAYERSOLID, G2_NOCOLLIDE, 0 ); if ( tr.fraction < 1.0 ) { VectorCopy( tr.endpos, point); break; } // otherwise just use the origin VectorCopy( ent->currentOrigin, point ); break; default: VectorCopy ( ent->currentOrigin, point ); break; } }
//--------------------------------------------------------- void CalcMuzzlePoint( gentity_t *const ent, vec3_t wpFwd, vec3_t right, vec3_t wpUp, vec3_t muzzlePoint, float lead_in ) //--------------------------------------------------------- { vec3_t org; mdxaBone_t boltMatrix; if( !lead_in ) //&& ent->s.number != 0 {//Not players or melee if( ent->client ) { if ( ent->client->renderInfo.mPCalcTime >= level.time - FRAMETIME*2 ) {//Our muzz point was calced no more than 2 frames ago VectorCopy(ent->client->renderInfo.muzzlePoint, muzzlePoint); return; } } } VectorCopy( ent->currentOrigin, muzzlePoint ); switch( ent->s.weapon ) { case WP_BRYAR_PISTOL: ViewHeightFix(ent); muzzlePoint[2] += ent->client->ps.viewheight;//By eyes muzzlePoint[2] -= 16; VectorMA( muzzlePoint, 28, wpFwd, muzzlePoint ); VectorMA( muzzlePoint, 6, wpVright, muzzlePoint ); break; case WP_ROCKET_LAUNCHER: case WP_THERMAL: ViewHeightFix(ent); muzzlePoint[2] += ent->client->ps.viewheight;//By eyes muzzlePoint[2] -= 2; break; case WP_BLASTER: ViewHeightFix(ent); muzzlePoint[2] += ent->client->ps.viewheight;//By eyes muzzlePoint[2] -= 1; if ( ent->s.number == 0 ) VectorMA( muzzlePoint, 12, wpFwd, muzzlePoint ); // player, don't set this any lower otherwise the projectile will impact immediately when your back is to a wall else VectorMA( muzzlePoint, 2, wpFwd, muzzlePoint ); // NPC, don't set too far wpFwd otherwise the projectile can go through doors VectorMA( muzzlePoint, 1, wpVright, muzzlePoint ); break; case WP_SABER: if(ent->NPC!=NULL && (ent->client->ps.torsoAnim == TORSO_WEAPONREADY2 || ent->client->ps.torsoAnim == BOTH_ATTACK2))//Sniper pose { ViewHeightFix(ent); wpMuzzle[2] += ent->client->ps.viewheight;//By eyes } else { muzzlePoint[2] += 16; } VectorMA( muzzlePoint, 8, wpFwd, muzzlePoint ); VectorMA( muzzlePoint, 16, wpVright, muzzlePoint ); break; case WP_BOT_LASER: muzzlePoint[2] -= 16; // break; case WP_ATST_MAIN: if (ent->count > 0) { ent->count = 0; gi.G2API_GetBoltMatrix( ent->ghoul2, ent->playerModel, ent->handLBolt, &boltMatrix, ent->s.angles, ent->s.origin, (cg.time?cg.time:level.time), NULL, ent->s.modelScale ); } else { ent->count = 1; gi.G2API_GetBoltMatrix( ent->ghoul2, ent->playerModel, ent->handRBolt, &boltMatrix, ent->s.angles, ent->s.origin, (cg.time?cg.time:level.time), NULL, ent->s.modelScale ); } gi.G2API_GiveMeVectorFromMatrix( boltMatrix, ORIGIN, org ); VectorCopy(org,muzzlePoint); break; } AddLeanOfs(ent, muzzlePoint); }