void VEH_TurretObeyPassengerControl( Vehicle_t *pVeh, gentity_t *parent, int turretNum ) { turretStats_t *turretStats = &pVeh->m_pVehicleInfo->turret[turretNum]; gentity_t *passenger = (gentity_t *)pVeh->m_ppPassengers[turretStats->passengerNum - 1]; if ( passenger && passenger->client && passenger->health > 0 ) {//a valid, living passenger client vehWeaponInfo_t *vehWeapon = &g_vehWeaponInfo[turretStats->iWeapon]; int curMuzzle = pVeh->turretStatus[turretNum].nextMuzzle; vector3 aimAngles; VectorCopy( &passenger->client->ps.viewangles, &aimAngles ); VEH_TurretAim( pVeh, parent, NULL, turretStats, vehWeapon, turretNum, curMuzzle, &aimAngles ); if ( (passenger->client->pers.cmd.buttons&(BUTTON_ATTACK | BUTTON_ALT_ATTACK)) ) {//he's pressing an attack button, so fire! VEH_TurretCheckFire( pVeh, parent, turretStats, vehWeapon, turretNum, curMuzzle ); } } }
void VEH_TurretThink( Vehicle_t *pVeh, gentity_t *parent, int turretNum ) //----------------------------------------------------- { qboolean doAim = qfalse; float enemyDist, rangeSq; vec3_t enemyDir; turretStats_t *turretStats = &pVeh->m_pVehicleInfo->turret[turretNum]; vehWeaponInfo_t *vehWeapon = NULL; gentity_t *turretEnemy = NULL; int curMuzzle = 0;//? if ( !turretStats || !turretStats->iAmmoMax ) {//not a valid turret return; } if ( turretStats->passengerNum && pVeh->m_iNumPassengers >= turretStats->passengerNum ) {//the passenger that has control of this turret is on the ship VEH_TurretObeyPassengerControl( pVeh, parent, turretNum ); return; } else if ( !turretStats->bAI )//try AI {//this turret does not think on its own. return; } vehWeapon = &g_vehWeaponInfo[turretStats->iWeapon]; rangeSq = (turretStats->fAIRange*turretStats->fAIRange); curMuzzle = pVeh->turretStatus[turretNum].nextMuzzle; if ( pVeh->turretStatus[turretNum].enemyEntNum < ENTITYNUM_WORLD ) { turretEnemy = &g_entities[pVeh->turretStatus[turretNum].enemyEntNum]; if ( turretEnemy->health < 0 || !turretEnemy->inuse || turretEnemy == ((gentity_t*)pVeh->m_pPilot)//enemy became my pilot///? || turretEnemy == parent || turretEnemy->r.ownerNum == parent->s.number // a passenger? || ( turretEnemy->client && turretEnemy->client->sess.sessionTeam == TEAM_SPECTATOR ) || ( turretEnemy->client && turretEnemy->client->tempSpectate >= level.time ) ) {//don't keep going after spectators, pilot, self, dead people, etc. turretEnemy = NULL; pVeh->turretStatus[turretNum].enemyEntNum = ENTITYNUM_NONE; } } if ( pVeh->turretStatus[turretNum].enemyHoldTime < level.time ) { if ( VEH_TurretFindEnemies( pVeh, parent, turretStats, turretNum, curMuzzle ) ) { turretEnemy = &g_entities[pVeh->turretStatus[turretNum].enemyEntNum]; doAim = qtrue; } else if ( parent->enemy && parent->enemy->s.number < ENTITYNUM_WORLD ) { turretEnemy = parent->enemy; doAim = qtrue; } if ( turretEnemy ) {//found one if ( turretEnemy->client ) {//hold on to clients for a min of 3 seconds pVeh->turretStatus[turretNum].enemyHoldTime = level.time + 3000; } else {//hold less pVeh->turretStatus[turretNum].enemyHoldTime = level.time + 500; } } } if ( turretEnemy != NULL ) { if ( turretEnemy->health > 0 ) { // enemy is alive WP_CalcVehMuzzle( parent, curMuzzle ); VectorSubtract( turretEnemy->r.currentOrigin, pVeh->m_vMuzzlePos[curMuzzle], enemyDir ); enemyDist = VectorLengthSquared( enemyDir ); if ( enemyDist < rangeSq ) { // was in valid radius if ( trap_InPVS( pVeh->m_vMuzzlePos[curMuzzle], turretEnemy->r.currentOrigin ) ) { // Every now and again, check to see if we can even trace to the enemy trace_t tr; vec3_t start, end; VectorCopy( pVeh->m_vMuzzlePos[curMuzzle], start ); VectorCopy( turretEnemy->r.currentOrigin, end ); trap_Trace( &tr, start, NULL, NULL, end, parent->s.number, MASK_SHOT ); if ( tr.entityNum == turretEnemy->s.number || (!tr.allsolid && !tr.startsolid ) ) { doAim = qtrue; // Can see our enemy } } } } } if ( doAim ) { vec3_t aimAngles; if ( VEH_TurretAim( pVeh, parent, turretEnemy, turretStats, vehWeapon, turretNum, curMuzzle, aimAngles ) ) { VEH_TurretCheckFire( pVeh, parent, /*turretEnemy,*/ turretStats, vehWeapon, turretNum, curMuzzle ); } } }