//========================================================= // Retire - stop being active //========================================================= void CNPC_BaseTurret::Retire(void) { // make the turret level m_vecGoalAngles.x = 0; m_vecGoalAngles.y = m_flStartYaw; SetNextThink( gpGlobals->curtime + 0.1 ); StudioFrameAdvance( ); EyeOff( ); if (!MoveTurret()) { if (m_iSpin) { SpinDownCall(); } else if (GetSequence() != TURRET_ANIM_RETIRE) { SetTurretAnim(TURRET_ANIM_RETIRE); CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "Turret.Undeploy" ); m_OnDeactivate.FireOutput(this, this); } //else if (IsSequenceFinished()) else if( GetSequence() == TURRET_ANIM_RETIRE && GetCycle() <= 0.0 ) { m_iOn = 0; m_flLastSight = 0; //SetTurretAnim(TURRET_ANIM_NONE); Vector curmins, curmaxs; curmins = WorldAlignMins(); curmaxs = WorldAlignMaxs(); curmaxs.z = m_iRetractHeight; curmins.z = -m_iRetractHeight; SetCollisionBounds( curmins, curmaxs ); if (m_iAutoStart) { SetThink(&CNPC_BaseTurret::AutoSearchThink); SetNextThink( gpGlobals->curtime + 0.1 ); } else { SetThink( &CBaseEntity::SUB_DoNothing ); } } } else { SetTurretAnim(TURRET_ANIM_SPIN); } }
void CBaseTurret::Retire(void) { // make the turret level m_vecGoalAngles.x = 0; m_vecGoalAngles.y = m_flStartYaw; pev->nextthink = gpGlobals->time + 0.1; StudioFrameAdvance( ); EyeOff( ); if (!MoveTurret()) { if (m_iSpin) { SpinDownCall(); } else if (pev->sequence != TURRET_ANIM_RETIRE) { SetTurretAnim(TURRET_ANIM_RETIRE); EMIT_SOUND_DYN(ENT(pev), CHAN_BODY, "turret/tu_deploy.wav", TURRET_MACHINE_VOLUME, ATTN_NORM, 0, 120); SUB_UseTargets( this, USE_OFF, 0 ); } else if (m_fSequenceFinished) { m_iOn = 0; m_flLastSight = 0; SetTurretAnim(TURRET_ANIM_NONE); pev->maxs.z = m_iRetractHeight; pev->mins.z = -m_iRetractHeight; UTIL_SetSize(pev, pev->mins, pev->maxs); if (m_iAutoStart) { SetThink(&CBaseTurret::AutoSearchThink); pev->nextthink = gpGlobals->time + .1; } else SetThink(&CBaseTurret::SUB_DoNothing); } } else { SetTurretAnim(TURRET_ANIM_SPIN); } }
//========================================================= // Deploy - go active //========================================================= void CNPC_BaseTurret::Deploy(void) { SetNextThink( gpGlobals->curtime + 0.1 ); StudioFrameAdvance( ); if (GetSequence() != TURRET_ANIM_DEPLOY) { m_iOn = 1; SetTurretAnim(TURRET_ANIM_DEPLOY); CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "Turret.Deploy" ); m_OnActivate.FireOutput(this, this); } if (IsSequenceFinished()) { Vector curmins, curmaxs; curmins = WorldAlignMins(); curmaxs = WorldAlignMaxs(); curmaxs.z = m_iDeployHeight; curmins.z = -m_iDeployHeight; SetCollisionBounds( curmins, curmaxs ); m_vecCurAngles.x = 0; QAngle angles = GetAbsAngles(); if (m_iOrientation == TURRET_ORIENTATION_CEILING) { m_vecCurAngles.y = UTIL_AngleMod( angles.y + 180 ); } else { m_vecCurAngles.y = UTIL_AngleMod( angles.y ); } SetTurretAnim(TURRET_ANIM_SPIN); m_flPlaybackRate = 0; SetThink(&CNPC_BaseTurret::SearchThink); } m_flLastSight = gpGlobals->curtime + m_flMaxWait; }
// // This search function will sit with the turret deployed and look for a new target. // After a set amount of time, the barrel will spin down. After m_flMaxWait, the turret will // retact. // void CBaseTurret::SearchThink(void) { // ensure rethink SetTurretAnim(TURRET_ANIM_SPIN); StudioFrameAdvance( ); pev->nextthink = gpGlobals->time + 0.1; if (m_flSpinUpTime == 0 && m_flMaxSpin) m_flSpinUpTime = gpGlobals->time + m_flMaxSpin; Ping( ); // If we have a target and we're still healthy if (m_hEnemy != NULL) { if (!m_hEnemy->IsAlive() ) m_hEnemy = NULL;// Dead enemy forces a search for new one } // Acquire Target if (m_hEnemy == NULL) { Look(TURRET_RANGE); m_hEnemy = BestVisibleEnemy(); } // If we've found a target, spin up the barrel and start to attack if (m_hEnemy != NULL) { m_flLastSight = 0; m_flSpinUpTime = 0; SetThink(&CBaseTurret::ActiveThink); } else { // Are we out of time, do we need to retract? if (gpGlobals->time > m_flLastSight) { //Before we retrace, make sure that we are spun down. m_flLastSight = 0; m_flSpinUpTime = 0; SetThink(&CBaseTurret::Retire); } // should we stop the spin? else if ((m_flSpinUpTime) && (gpGlobals->time > m_flSpinUpTime)) { SpinDownCall(); } // generic hunt for new victims m_vecGoalAngles.y = (m_vecGoalAngles.y + 0.1 * m_fTurnRate); if (m_vecGoalAngles.y >= 360) m_vecGoalAngles.y -= 360; MoveTurret(); } }
//========================================================= // TurretDeath - I die as I have lived, beyond my means //========================================================= void CNPC_BaseTurret::TurretDeath(void) { StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.1 ); if (m_lifeState != LIFE_DEAD) { m_lifeState = LIFE_DEAD; CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "Turret.Die" ); StopSound( entindex(), "Turret.Spinup" ); if (m_iOrientation == TURRET_ORIENTATION_FLOOR) m_vecGoalAngles.x = -14; else m_vecGoalAngles.x = 90;//-90; SetTurretAnim(TURRET_ANIM_DIE); EyeOn( ); } EyeOff( ); if (m_flDamageTime + random->RandomFloat( 0, 2 ) > gpGlobals->curtime) { // lots of smoke Vector pos; CollisionProp()->RandomPointInBounds( vec3_origin, Vector( 1, 1, 1 ), &pos ); pos.z = CollisionProp()->GetCollisionOrigin().z; CBroadcastRecipientFilter filter; te->Smoke( filter, 0.0, &pos, g_sModelIndexSmoke, 2.5, 10 ); } if (m_flDamageTime + random->RandomFloat( 0, 5 ) > gpGlobals->curtime) { Vector vecSrc; CollisionProp()->RandomPointInBounds( vec3_origin, Vector( 1, 1, 1 ), &vecSrc ); g_pEffects->Sparks( vecSrc ); } if (IsSequenceFinished() && !MoveTurret() && m_flDamageTime + 5 < gpGlobals->curtime) { m_flPlaybackRate = 0; SetThink( NULL ); } }
void CBaseTurret::Deploy(void) { pev->nextthink = gpGlobals->time + 0.1; StudioFrameAdvance( ); if (pev->sequence != TURRET_ANIM_DEPLOY) { m_iOn = 1; SetTurretAnim(TURRET_ANIM_DEPLOY); EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_deploy.wav", TURRET_MACHINE_VOLUME, ATTN_NORM); SUB_UseTargets( this, USE_ON, 0 ); } if (m_fSequenceFinished) { pev->maxs.z = m_iDeployHeight; pev->mins.z = -m_iDeployHeight; UTIL_SetSize(pev, pev->mins, pev->maxs); m_vecCurAngles.x = 0; if (m_iOrientation == 1) { m_vecCurAngles.y = UTIL_AngleMod( pev->angles.y + 180 ); } else { m_vecCurAngles.y = UTIL_AngleMod( pev->angles.y ); } SetTurretAnim(TURRET_ANIM_SPIN); pev->framerate = 0; SetThink(&CBaseTurret::SearchThink); } m_flLastSight = gpGlobals->time + m_flMaxWait; }
void CTurret::SpinDownCall(void) { if (m_iSpin) { SetTurretAnim( TURRET_ANIM_SPIN ); if (pev->framerate == 1.0) { EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, "turret/tu_active2.wav", 0, 0, SND_STOP, 100); EMIT_SOUND(ENT(pev), CHAN_ITEM, "turret/tu_spindown.wav", TURRET_MACHINE_VOLUME, ATTN_NORM); } pev->framerate -= 0.02; if (pev->framerate <= 0) { pev->framerate = 0; m_iSpin = 0; } } }
void CNPC_Turret::SpinDownCall(void) { if (m_iSpin) { CPASAttenuationFilter filter( this ); SetTurretAnim(TURRET_ANIM_SPIN); if ( m_flPlaybackRate == 1.0) { StopSound( entindex(), "Turret.Spinup" ); EmitSound( filter, entindex(), "Turret.SpinDownCall" ); } m_flPlaybackRate -= 0.02; if (m_flPlaybackRate <= 0) { m_flPlaybackRate = 0; m_iSpin = 0; } } }
void CNPC_Turret::SpinUpCall(void) { StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.1 ); // Are we already spun up? If not start the two stage process. if (!m_iSpin) { SetTurretAnim(TURRET_ANIM_SPIN); // for the first pass, spin up the the barrel if (!m_iStartSpin) { SetNextThink( gpGlobals->curtime + 1.0 ); //spinup delay CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "Turret.SpinUpCall" ); m_iStartSpin = 1; m_flPlaybackRate = 0.1; } // after the barrel is spun up, turn on the hum else if (m_flPlaybackRate >= 1.0) { SetNextThink( gpGlobals->curtime + 0.1 );// retarget delay CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "Turret.Spinup" ); SetThink(&CNPC_BaseTurret::ActiveThink); m_iStartSpin = 0; m_iSpin = 1; } else { m_flPlaybackRate += 0.075; } } if (m_iSpin) { SetThink(&CNPC_BaseTurret::ActiveThink); } }
void CNPC_BaseTurret::Spawn() { Precache( ); SetNextThink( gpGlobals->curtime + 1 ); SetMoveType( MOVETYPE_FLY ); SetSequence( 0 ); SetCycle( 0 ); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_NOT_STANDABLE ); m_takedamage = DAMAGE_YES; AddFlag( FL_AIMTARGET ); AddFlag( FL_NPC ); SetUse( &CNPC_BaseTurret::TurretUse ); if (( m_spawnflags & SF_MONSTER_TURRET_AUTOACTIVATE ) && !( m_spawnflags & SF_MONSTER_TURRET_STARTINACTIVE )) { m_iAutoStart = true; } ResetSequenceInfo( ); SetBoneController(0, 0); SetBoneController(1, 0); m_flFieldOfView = VIEW_FIELD_FULL; m_bloodColor = DONT_BLEED; m_flDamageTime = 0; if ( GetSpawnFlags() & SF_MONSTER_TURRET_STARTINACTIVE ) { SetTurretAnim( TURRET_ANIM_RETIRE ); SetCycle( 0.0f ); m_flPlaybackRate = 0.0f; } }
void CTurret::SpinUpCall(void) { StudioFrameAdvance( ); pev->nextthink = gpGlobals->time + 0.1; // Are we already spun up? If not start the two stage process. if (!m_iSpin) { SetTurretAnim( TURRET_ANIM_SPIN ); // for the first pass, spin up the the barrel if (!m_iStartSpin) { pev->nextthink = gpGlobals->time + 1.0; // spinup delay EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_spinup.wav", TURRET_MACHINE_VOLUME, ATTN_NORM); m_iStartSpin = 1; pev->framerate = 0.1; } // after the barrel is spun up, turn on the hum else if (pev->framerate >= 1.0) { pev->nextthink = gpGlobals->time + 0.1; // retarget delay EMIT_SOUND(ENT(pev), CHAN_STATIC, "turret/tu_active2.wav", TURRET_MACHINE_VOLUME, ATTN_NORM); SetThink(&CTurret::ActiveThink); m_iStartSpin = 0; m_iSpin = 1; } else { pev->framerate += 0.075; } } if (m_iSpin) { SetThink(&CTurret::ActiveThink); } }
void CBaseTurret :: TurretDeath( void ) { BOOL iActive = FALSE; StudioFrameAdvance( ); pev->nextthink = gpGlobals->time + 0.1; if (pev->deadflag != DEAD_DEAD) { pev->deadflag = DEAD_DEAD; float flRndSound = RANDOM_FLOAT ( 0 , 1 ); if ( flRndSound <= 0.33 ) EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die.wav", 1.0, ATTN_NORM); else if ( flRndSound <= 0.66 ) EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die2.wav", 1.0, ATTN_NORM); else EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die3.wav", 1.0, ATTN_NORM); EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, "turret/tu_active2.wav", 0, 0, SND_STOP, 100); if (m_iOrientation == 0) m_vecGoalAngles.x = -15; else m_vecGoalAngles.x = -90; SetTurretAnim(TURRET_ANIM_DIE); EyeOn( ); } EyeOff( ); if (pev->dmgtime + RANDOM_FLOAT( 0, 2 ) > gpGlobals->time) { // lots of smoke MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); WRITE_BYTE( TE_SMOKE ); WRITE_COORD( RANDOM_FLOAT( pev->absmin.x, pev->absmax.x ) ); WRITE_COORD( RANDOM_FLOAT( pev->absmin.y, pev->absmax.y ) ); WRITE_COORD( pev->origin.z - m_iOrientation * 64 ); WRITE_SHORT( g_sModelIndexSmoke ); WRITE_BYTE( 25 ); // scale * 10 WRITE_BYTE( 10 - m_iOrientation * 5); // framerate MESSAGE_END(); } if (pev->dmgtime + RANDOM_FLOAT( 0, 5 ) > gpGlobals->time) { Vector vecSrc = Vector( RANDOM_FLOAT( pev->absmin.x, pev->absmax.x ), RANDOM_FLOAT( pev->absmin.y, pev->absmax.y ), 0 ); if (m_iOrientation == 0) vecSrc = vecSrc + Vector( 0, 0, RANDOM_FLOAT( pev->origin.z, pev->absmax.z ) ); else vecSrc = vecSrc + Vector( 0, 0, RANDOM_FLOAT( pev->absmin.z, pev->origin.z ) ); UTIL_Sparks( vecSrc ); } if (m_fSequenceFinished && !MoveTurret( ) && pev->dmgtime + 5 < gpGlobals->time) { pev->framerate = 0; SetThink( NULL ); } }
void CBaseTurret::ActiveThink(void) { int fAttack = 0; Vector vecDirToEnemy; pev->nextthink = gpGlobals->time + 0.1; StudioFrameAdvance( ); if ((!m_iOn) || (m_hEnemy == NULL)) { m_hEnemy = NULL; m_flLastSight = gpGlobals->time + m_flMaxWait; SetThink(&CBaseTurret::SearchThink); return; } // if it's dead, look for something new if ( !m_hEnemy->IsAlive() ) { if (!m_flLastSight) { m_flLastSight = gpGlobals->time + 0.5; // continue-shooting timeout } else { if (gpGlobals->time > m_flLastSight) { m_hEnemy = NULL; m_flLastSight = gpGlobals->time + m_flMaxWait; SetThink(&CBaseTurret::SearchThink); return; } } } Vector vecMid = pev->origin + pev->view_ofs; Vector vecMidEnemy = m_hEnemy->BodyTarget( vecMid ); // Look for our current enemy int fEnemyVisible = FBoxVisible(pev, m_hEnemy->pev, vecMidEnemy ); vecDirToEnemy = vecMidEnemy - vecMid; // calculate dir and dist to enemy float flDistToEnemy = vecDirToEnemy.Length(); Vector vec = UTIL_VecToAngles(vecMidEnemy - vecMid); // Current enmey is not visible. if (!fEnemyVisible || (flDistToEnemy > TURRET_RANGE)) { if (!m_flLastSight) m_flLastSight = gpGlobals->time + 0.5; else { // Should we look for a new target? if (gpGlobals->time > m_flLastSight) { m_hEnemy = NULL; m_flLastSight = gpGlobals->time + m_flMaxWait; SetThink(&CBaseTurret::SearchThink); return; } } fEnemyVisible = 0; } else { m_vecLastSight = vecMidEnemy; } UTIL_MakeAimVectors(m_vecCurAngles); /* ALERT( at_console, "%.0f %.0f : %.2f %.2f %.2f\n", m_vecCurAngles.x, m_vecCurAngles.y, gpGlobals->v_forward.x, gpGlobals->v_forward.y, gpGlobals->v_forward.z ); */ Vector vecLOS = vecDirToEnemy; //vecMid - m_vecLastSight; vecLOS = vecLOS.Normalize(); // Is the Gun looking at the target if (DotProduct(vecLOS, gpGlobals->v_forward) <= 0.866) // 30 degree slop fAttack = FALSE; else fAttack = TRUE; // fire the gun if (m_iSpin && ((fAttack) || (m_fBeserk))) { Vector vecSrc, vecAng; GetAttachment( 0, vecSrc, vecAng ); SetTurretAnim(TURRET_ANIM_FIRE); Shoot(vecSrc, gpGlobals->v_forward ); } else { SetTurretAnim(TURRET_ANIM_SPIN); } //move the gun if (m_fBeserk) { if (RANDOM_LONG(0,9) == 0) { m_vecGoalAngles.y = RANDOM_FLOAT(0,360); m_vecGoalAngles.x = RANDOM_FLOAT(0,90) - 90 * m_iOrientation; TakeDamage(pev,pev,1, DMG_GENERIC); // don't beserk forever return; } } else if (fEnemyVisible) { if (vec.y > 360) vec.y -= 360; if (vec.y < 0) vec.y += 360; //ALERT(at_console, "[%.2f]", vec.x); if (vec.x < -180) vec.x += 360; if (vec.x > 180) vec.x -= 360; // now all numbers should be in [1...360] // pin to turret limitations to [-90...15] if (m_iOrientation == 0) { if (vec.x > 90) vec.x = 90; else if (vec.x < m_iMinPitch) vec.x = m_iMinPitch; } else { if (vec.x < -90) vec.x = -90; else if (vec.x > -m_iMinPitch) vec.x = -m_iMinPitch; } // ALERT(at_console, "->[%.2f]\n", vec.x); m_vecGoalAngles.y = vec.y; m_vecGoalAngles.x = vec.x; } SpinUpCall(); MoveTurret(); }
void CSentry :: SentryDeath( void ) { BOOL iActive = FALSE; StudioFrameAdvance( ); pev->nextthink = gpGlobals->time + 0.1; if (pev->deadflag != DEAD_DEAD) { pev->deadflag = DEAD_DEAD; float flRndSound = RANDOM_FLOAT ( 0 , 1 ); if ( flRndSound <= 0.33 ) EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die.wav", 1.0, ATTN_NORM); else if ( flRndSound <= 0.66 ) EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die2.wav", 1.0, ATTN_NORM); else EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die3.wav", 1.0, ATTN_NORM); EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, "turret/tu_active2.wav", 0, 0, SND_STOP, 100); SetBoneController( 0, 0 ); SetBoneController( 1, 0 ); SetTurretAnim(TURRET_ANIM_DIE); pev->solid = SOLID_NOT; pev->angles.y = UTIL_AngleMod( pev->angles.y + RANDOM_LONG( 0, 2 ) * 120 ); EyeOn( ); } EyeOff( ); Vector vecSrc, vecAng; GetAttachment( 1, vecSrc, vecAng ); if (pev->dmgtime + RANDOM_FLOAT( 0, 2 ) > gpGlobals->time) { // lots of smoke MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); WRITE_BYTE( TE_SMOKE ); WRITE_COORD( vecSrc.x + RANDOM_FLOAT( -16, 16 ) ); WRITE_COORD( vecSrc.y + RANDOM_FLOAT( -16, 16 ) ); WRITE_COORD( vecSrc.z - 32 ); WRITE_SHORT( g_sModelIndexSmoke ); WRITE_BYTE( 15 ); // scale * 10 WRITE_BYTE( 8 ); // framerate MESSAGE_END(); } if (pev->dmgtime + RANDOM_FLOAT( 0, 8 ) > gpGlobals->time) { UTIL_Sparks( vecSrc ); } if (m_fSequenceFinished && pev->dmgtime + 5 < gpGlobals->time) { pev->framerate = 0; SetThink( NULL ); } }
//========================================================= // ActiveThink - //========================================================= void CNPC_BaseTurret::ActiveThink(void) { int fAttack = 0; SetNextThink( gpGlobals->curtime + 0.1 ); StudioFrameAdvance( ); if ( (!m_iOn) || (GetEnemy() == NULL) ) { SetEnemy( NULL ); m_flLastSight = gpGlobals->curtime + m_flMaxWait; SetThink(&CNPC_BaseTurret::SearchThink); return; } // if it's dead, look for something new if ( !GetEnemy()->IsAlive() ) { if (!m_flLastSight) { m_flLastSight = gpGlobals->curtime + 0.5; // continue-shooting timeout } else { if (gpGlobals->curtime > m_flLastSight) { SetEnemy( NULL ); m_flLastSight = gpGlobals->curtime + m_flMaxWait; SetThink(&CNPC_BaseTurret::SearchThink); return; } } } Vector vecMid = GetAbsOrigin() + GetViewOffset(); Vector vecMidEnemy = GetEnemy()->BodyTarget( vecMid, false ); // Look for our current enemy int fEnemyVisible = FBoxVisible(this, GetEnemy(), vecMidEnemy ); //We want to look at the enemy's eyes so we don't jitter Vector vecDirToEnemyEyes = vecMidEnemy - vecMid; float flDistToEnemy = vecDirToEnemyEyes.Length(); VectorNormalize( vecDirToEnemyEyes ); QAngle vecAnglesToEnemy; VectorAngles( vecDirToEnemyEyes, vecAnglesToEnemy ); // Current enmey is not visible. if (!fEnemyVisible || (flDistToEnemy > TURRET_RANGE)) { if (!m_flLastSight) m_flLastSight = gpGlobals->curtime + 0.5; else { // Should we look for a new target? if (gpGlobals->curtime > m_flLastSight) { SetEnemy( NULL ); m_flLastSight = gpGlobals->curtime + m_flMaxWait; SetThink(&CNPC_BaseTurret::SearchThink); return; } } fEnemyVisible = 0; } else { m_vecLastSight = vecMidEnemy; } //ALERT( at_console, "%.0f %.0f : %.2f %.2f %.2f\n", // m_vecCurAngles.x, m_vecCurAngles.y, // gpGlobals->v_forward.x, gpGlobals->v_forward.y, gpGlobals->v_forward.z ); Vector vecLOS = vecDirToEnemyEyes; //vecMid - m_vecLastSight; VectorNormalize( vecLOS ); Vector vecMuzzle, vecMuzzleDir; QAngle vecMuzzleAng; GetAttachment( 1, vecMuzzle, vecMuzzleAng ); AngleVectors( vecMuzzleAng, &vecMuzzleDir ); // Is the Gun looking at the target if (DotProduct(vecLOS, vecMuzzleDir) <= 0.866) // 30 degree slop fAttack = FALSE; else fAttack = TRUE; //forward // NDebugOverlay::Line(vecMuzzle, vecMid + ( vecMuzzleDir * 200 ), 255,0,0, false, 0.1); //LOS // NDebugOverlay::Line(vecMuzzle, vecMid + ( vecLOS * 200 ), 0,0,255, false, 0.1); // fire the gun if (m_iSpin && ((fAttack) || (m_fBeserk))) { Vector vecOrigin; QAngle vecAngles; GetAttachment( 1, vecOrigin, vecAngles ); Shoot(vecOrigin, vecMuzzleDir ); SetTurretAnim(TURRET_ANIM_FIRE); } else { SetTurretAnim(TURRET_ANIM_SPIN); } //move the gun if (m_fBeserk) { if (random->RandomInt(0,9) == 0) { m_vecGoalAngles.y = random->RandomFloat(0,360); m_vecGoalAngles.x = random->RandomFloat(0,90) - 90 * m_iOrientation; CTakeDamageInfo info; info.SetAttacker(this); info.SetInflictor(this); info.SetDamage( 1 ); info.SetDamageType( DMG_GENERIC ); TakeDamage( info ); // don't beserk forever return; } } else if (fEnemyVisible) { if (vecAnglesToEnemy.y > 360) vecAnglesToEnemy.y -= 360; if (vecAnglesToEnemy.y < 0) vecAnglesToEnemy.y += 360; //ALERT(at_console, "[%.2f]", vec.x); if (vecAnglesToEnemy.x < -180) vecAnglesToEnemy.x += 360; if (vecAnglesToEnemy.x > 180) vecAnglesToEnemy.x -= 360; // now all numbers should be in [1...360] // pin to turret limitations to [-90...14] if (m_iOrientation == TURRET_ORIENTATION_FLOOR) { if (vecAnglesToEnemy.x > 90) vecAnglesToEnemy.x = 90; else if (vecAnglesToEnemy.x < m_iMinPitch) vecAnglesToEnemy.x = m_iMinPitch; } else { if (vecAnglesToEnemy.x < -90) vecAnglesToEnemy.x = -90; else if (vecAnglesToEnemy.x > -m_iMinPitch) vecAnglesToEnemy.x = -m_iMinPitch; } //DevMsg( 1, "->[%.2f]\n", vec.x); m_vecGoalAngles.y = vecAnglesToEnemy.y; m_vecGoalAngles.x = vecAnglesToEnemy.x; } SpinUpCall(); MoveTurret(); }