Ejemplo n.º 1
0
bool Bot::LookupEnemy (void)
{
   // this function tries to find the best suitable enemy for the bot
   m_visibility = 0;

   // SyPB Pro P.1
   if (m_enemy != null && (GetTeam (GetEntity ()) == GetTeam (m_enemy) || Attack_Invisible(m_enemy)))
   {
   	   m_enemy = null;
   	   return false;
   }

   // SyPB Pro P.4
   if (GetEnemyEntity ())
   	   return true;

   // do not search for enemies while we're blinded, or shooting disabled by user
   if (m_blindTime > engine->GetTime () || sypb_noshots.GetBool ())
      return false;

   // do not check for new enemy too fast
   if (!FNullEnt (m_enemy) && m_enemyUpdateTime > engine->GetTime () && !(m_states & STATE_SUSPECTENEMY))
   {
      m_aimFlags |= AIM_ENEMY;
      return true;
   }
   edict_t *player, *newEnemy = null;

   float nearestDistance = m_viewDistance;
   int i, team = GetTeam (GetEntity ());

   // setup potentially visible set for this bot
   Vector potentialVisibility = EyePosition ();

   if (pev->flags & FL_DUCKING)
      potentialVisibility = potentialVisibility + (VEC_HULL_MIN - VEC_DUCK_HULL_MIN);

   uint8_t *pvs = ENGINE_SET_PVS (reinterpret_cast <float *> (&potentialVisibility));

   // clear suspected flag
   if (m_seeEnemyTime + 4.0f < engine->GetTime ())
      m_states &= ~STATE_SUSPECTENEMY;

   if (!FNullEnt (m_enemy))
   {
      player = m_enemy;

      // is player is alive
      if (IsAlive (player) && IsEnemyViewable (player))
         newEnemy = player;
   }

   // the old enemy is no longer visible or
   if (FNullEnt (newEnemy))
   {
      m_enemyUpdateTime = engine->GetTime () + 0.25f;

      // some shield stuff
      Array <edict_t *> enemies;

      // search the world for players...
      for (i = 0; i < engine->GetMaxClients (); i++)
      {
         if (!(g_clients[i].flags & CFLAG_USED) || !(g_clients[i].flags & CFLAG_ALIVE) || (g_clients[i].team == team) || (g_clients[i].ent == GetEntity ()))
            continue;

         player = g_clients[i].ent;

         // let the engine check if this player is potentially visible
         if (!ENGINE_CHECK_VISIBILITY (player, pvs))
            continue;

         // skip glowed players, in free for all mode, we can't hit them
         if (player->v.renderfx == kRenderFxGlowShell && GetGameMod() == 1)
            continue;

         // do some blind by smoke grenade
         if (IsBehindSmokeClouds (player) && m_blindRecognizeTime < engine->GetTime ())
            m_blindRecognizeTime = engine->GetTime () + engine->RandomFloat (2.0, 3.0f);

         if (player->v.button & (IN_ATTACK | IN_ATTACK2))
            m_blindRecognizeTime = engine->GetTime () - 0.1f;

         // see if bot can see the player...
         if (m_blindRecognizeTime < engine->GetTime () && IsEnemyViewable (player))
         {
            float distance = (player->v.origin - pev->origin).GetLength ();

            if (distance < nearestDistance)
            {
               enemies.Push (player);

               if (IsEnemyProtectedByShield (player))
                  continue;

               nearestDistance = distance;
               newEnemy = player;

               // aim VIP first on AS maps...
               if ((g_mapType & MAP_AS) && *(INFOKEY_VALUE (GET_INFOKEYBUFFER (player), "model")) == 'v')
                  break;
            }
         }
      }

      // if we got no enemies with no shield, and got enemies with target them
      if (enemies.GetElementNumber () != 0 && !IsValidPlayer (newEnemy))
         newEnemy = enemies[0];
   }

   if (IsValidPlayer (newEnemy))
   {
      g_botsCanPause = true;
      m_aimFlags |= AIM_ENEMY;

      if (newEnemy == m_enemy)
      {
         // if enemy is still visible and in field of view, keep it keep track of when we last saw an enemy
         m_seeEnemyTime = engine->GetTime ();

         // zero out reaction time
         m_actualReactionTime = 0.0f;
         m_lastEnemy = newEnemy;
         m_lastEnemyOrigin = newEnemy->v.origin;
         
         m_GetNewEnemyTimer =  engine->GetTime () + 0.8;

         return true;
      }
      else
      {
         if (m_seeEnemyTime + 3.0f < engine->GetTime () && (pev->weapons & (1 << WEAPON_C4) || HasHostage () || !FNullEnt (m_targetEntity)))
            RadioMessage (Radio_EnemySpotted);

         m_targetEntity = null; // stop following when we see an enemy...

         if (engine->RandomInt (0, 100) < m_skill)
            m_enemySurpriseTime = engine->GetTime () + (m_actualReactionTime / 3);
         else
            m_enemySurpriseTime = engine->GetTime () + m_actualReactionTime;

         // zero out reaction time
         m_actualReactionTime = 0.0f;
         m_enemy = newEnemy;
         m_lastEnemy = newEnemy;
         m_lastEnemyOrigin = newEnemy->v.origin;
         m_enemyReachableTimer = 0.0f;

         // keep track of when we last saw an enemy
         m_seeEnemyTime = engine->GetTime ();

         // now alarm all teammates who see this bot & don't have an actual enemy of the bots enemy should simulate human players seeing a teammate firing
         for (int j = 0; j < engine->GetMaxClients (); j++)
         {
            if (!(g_clients[j].flags & CFLAG_USED) || !(g_clients[j].flags & CFLAG_ALIVE) || g_clients[j].team != team || g_clients[j].ent == GetEntity ())
               continue;

            Bot *friendBot = g_botManager->GetBot (g_clients[j].ent);

            if (friendBot != null)
            {
               if (friendBot->m_seeEnemyTime + 2.0f < engine->GetTime () || FNullEnt (friendBot->m_lastEnemy))
               {
                  if (IsVisible (pev->origin, ENT (friendBot->pev)))
                  {
                     friendBot->m_lastEnemy = newEnemy;
                     friendBot->m_lastEnemyOrigin = m_lastEnemyOrigin;
                     friendBot->m_seeEnemyTime = engine->GetTime ();
                  }
               }
            }
         }
         m_GetNewEnemyTimer =  engine->GetTime () + 1.6;
         return true;
      }
   }
   else if (!FNullEnt (m_enemy))
   {
      newEnemy = m_enemy;
      m_lastEnemy = newEnemy;
      m_GetNewEnemyTimer =  engine->GetTime () + 0.8;

      if (!IsAlive (newEnemy))
      {
         m_enemy = null;

         // shoot at dying players if no new enemy to give some more human-like illusion
         if (m_seeEnemyTime + 0.1 > engine->GetTime ())
         {
            if (!UsesSniper ())
            {
               m_shootAtDeadTime = engine->GetTime () + 0.2f;
               m_actualReactionTime = 0.0f;
               m_states |= STATE_SUSPECTENEMY;

               return true;
            }
            return false;
         }
         else if (m_shootAtDeadTime > engine->GetTime ())
         {
            m_actualReactionTime = 0.0f;
            m_states |= STATE_SUSPECTENEMY;

            return true;
         }
         return false;
      }

      // if no enemy visible check if last one shoot able through wall
      if (sypb_thruwalls.GetBool () && engine->RandomInt (1, 100) < g_skillTab[m_skill / 20].seenShootThruProb)
      {
         if (IsShootableThruObstacle (newEnemy->v.origin))
         {
            m_seeEnemyTime = engine->GetTime () - 0.2f;

            m_states |= STATE_SUSPECTENEMY;
            m_aimFlags |= AIM_LASTENEMY;

            m_enemy = newEnemy;
            m_lastEnemy = newEnemy;
            m_lastEnemyOrigin = newEnemy->v.origin;

            return true;
         }
      }
   }

   // check if bots should reload...
   if ((m_aimFlags <= AIM_PREDICTENEMY && m_seeEnemyTime + 4.0f < engine->GetTime () &&  !(m_states & (STATE_SEEINGENEMY | STATE_HEARENEMY)) && FNullEnt (m_lastEnemy) && FNullEnt (m_enemy) && GetCurrentTask ()->taskID != TASK_DESTROYBREAKABLE && GetCurrentTask ()->taskID != TASK_PLANTBOMB && GetCurrentTask ()->taskID != TASK_DEFUSEBOMB) || g_roundEnded)
   {
      if (!m_reloadState)
         m_reloadState = RSTATE_PRIMARY;
   }

   // is the bot using a sniper rifle or a zoomable rifle?
   if ((UsesSniper () || UsesZoomableRifle ()) && m_zoomCheckTime + 1.0f < engine->GetTime ())
   {
      if (pev->fov < 90) // let the bot zoom out
         pev->button |= IN_ATTACK2;
      else
         m_zoomCheckTime = 0.0f;
   }
   return false;
}
Ejemplo n.º 2
0
Bot::Bot (edict_t *bot, int skill, int personality, int team, int member)
{
   // this function does core operation of creating bot, it's called by CreateBot (),
   // when bot setup completed, (this is a bot class constructor)

   char rejectReason[128];
   int clientIndex = ENTINDEX (bot);

   memset (this, 0, sizeof (Bot));

   pev = VARS (bot);

   if (bot->pvPrivateData != null)
      FREE_PRIVATE (bot);

   bot->pvPrivateData = null;
   bot->v.frags = 0;

   // create the player entity by calling MOD's player function
   BotControl::CallGameEntity (&bot->v);

   // set all info buffer keys for this bot
   char *buffer = GET_INFOKEYBUFFER (bot);

   SET_CLIENT_KEYVALUE (clientIndex, buffer, "model", "");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "rate", "3500.000000");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_updaterate", "20");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_lw", "1");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_lc", "1");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "tracker", "0");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_dlmax", "128");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "friends", "0");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "dm", "0");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "_ah", "0");

   if (yb_tagbots.GetBool ())
      SET_CLIENT_KEYVALUE (clientIndex, buffer, "*bot", "1");

   SET_CLIENT_KEYVALUE (clientIndex, buffer, "_vgui_menus", "0");

   memset (rejectReason, 0, sizeof (rejectReason)); // reset the reject reason template string
   MDLL_ClientConnect (bot, "fakeclient", FormatBuffer ("192.168.1.%d", ENTINDEX (bot) + 100), rejectReason);

   if (!IsNullString (rejectReason))
   {
      AddLogEntry (true, LOG_WARNING, "Server refused '%s' connection (%s)", STRING (bot->v.netname), rejectReason);
      ServerCommand ("kick \"%s\"", STRING (bot->v.netname)); // kick the bot player if the server refused it

      bot->v.flags |= FL_KILLME;
   }

   if (IsDedicatedServer () && engine->GetDeveloperLevel () > 0)
   {
      if (engine->GetDeveloperLevel () == 2)
      {
          ServerPrint ("Server requiring authentication");
          ServerPrint ("Client '%s' connected", STRING (bot->v.netname));
          ServerPrint ("Adr: 127.0.0.%d:27005", ENTINDEX (bot) + 100);
      }

      ServerPrint ("Verifying and uploading resources...");
      ServerPrint ("Custom resources total 0 bytes");
      ServerPrint ("  Decals:  0 bytes");
      ServerPrint ("----------------------");
      ServerPrint ("Resources to request: 0 bytes");
   }

   MDLL_ClientPutInServer (bot);

   bot->v.flags = 0;
   bot->v.flags |= FL_FAKECLIENT | FL_CLIENT; // set this player as fakeclient

   // initialize all the variables for this bot...
   m_notStarted = true;  // hasn't joined game yet

   m_startAction = CMENU_IDLE;
   m_moneyAmount = 0;
   m_logotypeIndex = engine->RandomInt (0, 5);


   // initialize msec value
   m_msecNum = m_msecDel = 0.0f;
   m_msecInterval = engine->GetTime ();
   m_msecVal = static_cast <uint8_t> (g_pGlobals->frametime * 1000.0f);
   m_msecBuiltin = engine->RandomInt (1, 4);

   // assign how talkative this bot will be
   m_sayTextBuffer.chatDelay = engine->RandomFloat (3.8f, 10.0f);
   m_sayTextBuffer.chatProbability = engine->RandomInt (1, 100);

   m_notKilled = false;
   m_skill = skill;
   m_weaponBurstMode = BURST_DISABLED;

   m_lastThinkTime = engine->GetTime ();
   m_frameInterval = engine->GetTime ();

   bot->v.idealpitch = bot->v.v_angle.x;
   bot->v.ideal_yaw = bot->v.v_angle.y;

   bot->v.yaw_speed = engine->RandomFloat (g_skillTab[m_skill / 20].minTurnSpeed, g_skillTab[m_skill / 20].maxTurnSpeed);
   bot->v.pitch_speed = engine->RandomFloat (g_skillTab[m_skill / 20].minTurnSpeed, g_skillTab[m_skill / 20].maxTurnSpeed);

   switch (personality)
   {
   case 1:
      m_personality = PERSONALITY_RUSHER;
      m_baseAgressionLevel = engine->RandomFloat (0.7f, 1.0f);
      m_baseFearLevel = engine->RandomFloat (0.0f, 0.4f);
      break;

   case 2:
      m_personality = PERSONALITY_CAREFUL;
      m_baseAgressionLevel = engine->RandomFloat (0.0f, 0.4f);
      m_baseFearLevel = engine->RandomFloat (0.7f, 1.0f);
      break;

   default:
      m_personality = PERSONALITY_NORMAL;
      m_baseAgressionLevel = engine->RandomFloat (0.4f, 0.7f);
      m_baseFearLevel = engine->RandomFloat (0.4f, 0.7f);
      break;
   }

   memset (&m_ammoInClip, 0, sizeof (m_ammoInClip));
   memset (&m_ammo, 0, sizeof (m_ammo));

   m_currentWeapon = 0; // current weapon is not assigned at start
   m_voicePitch = engine->RandomInt (166, 250) / 2; // assign voice pitch

   // copy them over to the temp level variables
   m_agressionLevel = m_baseAgressionLevel;
   m_fearLevel = m_baseFearLevel;
   m_nextEmotionUpdate = engine->GetTime () + 0.5f;

   // just to be sure
   m_actMessageIndex = 0;
   m_pushMessageIndex = 0;

   // assign team and class
   m_wantedTeam = team;
   m_wantedClass = member;

   NewRound ();
}
Ejemplo n.º 3
0
// SyPB Pro P.29 - new Look UP Enemy
bool Bot::LookupEnemy(void)
{
	m_visibility = 0;
	m_enemyOrigin = nullvec;

	if (m_blindTime > engine->GetTime() || sypb_noshots.GetBool())
		return false;

	if (!FNullEnt(m_lastEnemy))
	{
		if (IsNotAttackLab(m_lastEnemy) || !IsAlive(m_lastEnemy) || (GetTeam(m_lastEnemy) == GetTeam(GetEntity())))
		{
			m_lastEnemy = null;
			m_lastEnemyOrigin = nullvec;
		}
	}

	if (!FNullEnt(m_lastVictim))
	{
		if (!IsAlive(m_lastVictim) || (GetTeam(m_lastVictim) == GetTeam(GetEntity())))
			m_lastVictim = null;
	}

	m_states &= ~STATE_SUSPECTENEMY;

	int team = GetTeam(GetEntity()), i;
	edict_t *entity = null, *targetEntity = null;
	float enemy_distance = 9999.0f;

	// SyPB Pro P.30 - AMXX API
	if (m_blockCheckEnemyTime > engine->GetTime())
	{
		if (!FNullEnt(m_moveTargetEntityAPI))
		{
			if (GetTeam(GetEntity()) != GetTeam(m_moveTargetEntityAPI) && IsAlive(m_moveTargetEntityAPI))
				SetMoveTarget(m_moveTargetEntityAPI);
			else
			{
				// SyPB Pro P.32 - API Fixed
				SetMoveTarget(null);

				m_moveTargetEntityAPI = null;
			}
		}
		else if (!FNullEnt(m_enemyAPI))
		{
			if (GetTeam(GetEntity()) != GetTeam(m_enemyAPI) && IsAlive(m_enemyAPI))
			{
				m_targetEntity = null;
				m_enemy = m_enemyAPI;
				m_lastEnemy = m_enemy;
				m_lastEnemyOrigin = GetEntityOrigin(m_enemy);
				m_enemyReachableTimer = 0.0f;
				m_seeEnemyTime = engine->GetTime();

				if (!IsEnemyViewable(m_enemy, 1))
					m_enemyOrigin = GetEntityOrigin(m_enemy);

				return true;
			}
			else
				m_enemyAPI = null;
		}
		return false;
	}
	m_enemyAPI = null;
	m_moveTargetEntityAPI = null;

	if (!FNullEnt(m_enemy))
	{
		if (GetTeam(GetEntity()) == GetTeam(m_enemy) || IsNotAttackLab(m_enemy) || !IsAlive(m_enemy))
			return false;

		if (m_enemyUpdateTime > engine->GetTime() && !(m_states & STATE_SUSPECTENEMY))
		{
			m_aimFlags |= AIM_ENEMY;
			return true;
		}

		if (IsEnemyViewable(m_enemy, 1))
		{
			targetEntity = m_enemy;
			enemy_distance = GetEntityDistance(m_enemy);
		}
	}
	else if (!FNullEnt(m_moveTargetEntity))
	{
		if (GetTeam(GetEntity()) == GetTeam(m_moveTargetEntity) || !IsAlive(m_moveTargetEntity))
		{
			SetMoveTarget(null);
			return false;
		}

		targetEntity = m_moveTargetEntity;
		m_moveTargetOrigin = GetEntityOrigin(m_moveTargetEntity);
		enemy_distance = GetEntityDistance(m_moveTargetEntity);
	}
	
	// SyPB Pro P.34 - Zombie mode
	if (IsZombieBot(GetEntity()))
	{
		if (!FNullEnt(m_moveTargetEntity))
		{
			if (m_enemyUpdateTime > engine->GetTime())
				return false;
		}

		if (FNullEnt (m_enemy))
			m_enemyUpdateTime = engine->GetTime() + 0.15f;
	}


	for (i = 1; i <= engine->GetMaxClients(); i++)
	{
		entity = INDEXENT(i);

		if (FNullEnt(entity) || !IsAlive(entity) || GetTeam(entity) == team || entity == GetEntity())
			continue;

		if (IsBehindSmokeClouds(entity) && m_blindRecognizeTime < engine->GetTime())
			m_blindRecognizeTime = engine->GetTime() + engine->RandomFloat(2.0, 3.0f);

		if (m_blindRecognizeTime >= engine->GetTime())
			continue;

		float distance = GetEntityDistance(entity);
		if (distance >= enemy_distance)
			continue;

		if (IsEnemyProtectedByShield(entity))
			continue;

		if (IsEnemyViewable(entity))
		{
			enemy_distance = distance;
			targetEntity = entity;

			if ((g_mapType & MAP_AS) && *(INFOKEY_VALUE(GET_INFOKEYBUFFER(entity), "model")) == 'v')
				break;
		}
	}

	ITERATE_ARRAY(g_entityName, j)
	{
		if (g_entityAction[j] != 1 || (GetTeam(GetEntity()) == (g_entityTeam[j] - 1) && g_entityTeam[j] != 0))
			continue;

		while (!FNullEnt(entity = FIND_ENTITY_BY_CLASSNAME(entity, g_entityName[j])))
		{
			if (FNullEnt(entity) || entity == m_enemy)
				continue;

			float distance = GetEntityDistance(entity);
			if (distance >= enemy_distance)
				continue;

			if (IsBehindSmokeClouds(entity) && m_blindRecognizeTime < engine->GetTime())
				m_blindRecognizeTime = engine->GetTime() + engine->RandomFloat(2.0, 3.0f);

			// SyPB Pro P.30 - NPC Fixed
			if (IsEnemyViewable(entity))
			{
				enemy_distance = distance;
				targetEntity = entity;
			}
		}
	}


	if (!FNullEnt(targetEntity))  // Last Checking
	{
		enemy_distance = GetEntityDistance(targetEntity);
		if (GetTeam(targetEntity) == team || !IsEnemyViewable(targetEntity, 1))
			targetEntity = null;
	}

	if (!FNullEnt(m_enemy) && IsZombieBot(GetEntity()))
	{
		if (FNullEnt(targetEntity))  // Has not new enemy, and cannot see old enemy
		{
			g_botsCanPause = false;

			// SyPB Pro P.32 - Zombie Ai
			int botSrcIndex = g_waypoint->FindNearest(pev->origin);
			int targetSrcIndex = g_waypoint->FindNearest(GetEntityOrigin (m_enemy));
			int botStartIndex = *(g_waypoint->m_pathMatrix + (botSrcIndex * g_numWaypoints) + targetSrcIndex);
			if (!(botStartIndex < 0))
				ChangeWptIndex(botStartIndex);

			RemoveCertainTask(TASK_MOVETOTARGET);
			SetMoveTarget(m_enemy);
			return false;
		}
		// SyPB Pro P.30 - Zombie Ai
		else if (targetEntity != m_enemy)
		{
			float distance = GetEntityDistance(m_enemy);
			if (enemy_distance + 50.0f >= distance)
			{
				targetEntity = m_enemy;
				enemy_distance = distance;
			}
		}
	}

	if (!FNullEnt(targetEntity))
	{
		// SyPB Pro P.34 - Zombie Ai
		if (IsZombieBot(GetEntity()))
		{
			// SyPB Pro P.36 - Zombie Ai
			float distance = GetEntityDistance(targetEntity);

			enemy_distance = (GetEntityOrigin (targetEntity) - pev->origin).GetLength();
			bool moveTotarget = false;
			if (enemy_distance >= 150.0f)
			{
				moveTotarget = true;

				if (targetEntity == m_moveTargetEntity)
				{
					if (m_navNode == null || (m_navNode != null && m_navNode->next == null))
					{
						moveTotarget = false;

						// SyPB Pro P.37 - Zombie Ai
						m_enemyUpdateTime = engine->GetTime() + 4.0f;
					}
				}
			}
			else if (enemy_distance >= 80.0f && distance >= (enemy_distance * 2))
				moveTotarget = true;
			//else if (m_navNode != null && enemy_distance > 20.0f && distance >= 30.0f)//&& enemy_distance > 40.0f)
			else if (m_navNode != null && enemy_distance >= 20.0f)// && distance >= 30.0f)
			{
				PathNode *navid = &m_navNode[0];
				Path *path;

				while (navid != null)
				{
					path = g_waypoint->GetPath(navid->index);
					navid = navid->next;

					if (navid != null)
					{
						if (path->connectionFlags[navid->index] & PATHFLAG_JUMP)
						{
							moveTotarget = true;
							navid = null;
						}
					}
				}
			}

			if (moveTotarget)
			{
				// SyPB Pro P.35 - Fixed
				if (enemy_distance <= 80.0f)
				//if (moveTotarget <= 80.0f)
					pev->button |= IN_ATTACK;

				if (targetEntity != m_moveTargetEntity)
				{
					g_botsCanPause = false;

					// SyPB Pro P.32 - Zombie Ai
					int botSrcIndex = g_waypoint->FindNearest(pev->origin);
					int targetSrcIndex = g_waypoint->FindNearest(GetEntityOrigin (targetEntity));
					int botStartIndex = *(g_waypoint->m_pathMatrix + (botSrcIndex * g_numWaypoints) + targetSrcIndex);
					if (!(botStartIndex < 0))
						ChangeWptIndex(botStartIndex);

					SetMoveTarget(targetEntity);
				}

				return false;
			}

			// SyPB Pro P.37 - Zombie Ai
			if (m_enemyUpdateTime < engine->GetTime() + 3.0f)
				m_enemyUpdateTime = engine->GetTime() + 2.5f;
		}

		g_botsCanPause = true;
		m_aimFlags |= AIM_ENEMY;

		if (targetEntity == m_enemy)
		{
			m_seeEnemyTime = engine->GetTime();

			m_actualReactionTime = 0.0f;
			m_lastEnemy = targetEntity;
			m_lastEnemyOrigin = GetEntityOrigin(targetEntity);

			return true;
		}

		if (m_seeEnemyTime + 3.0f < engine->GetTime() && (pev->weapons & (1 << WEAPON_C4) || HasHostage() || !FNullEnt(m_targetEntity)))
			RadioMessage(Radio_EnemySpotted);

		m_targetEntity = null;

		if (engine->RandomInt(0, 100) < m_skill)
			m_enemySurpriseTime = engine->GetTime() + (m_actualReactionTime / 3);
		else
			m_enemySurpriseTime = engine->GetTime() + m_actualReactionTime;

		m_actualReactionTime = 0.0f;

		m_enemy = targetEntity;
		m_lastEnemy = m_enemy;
		m_lastEnemyOrigin = GetEntityOrigin(m_enemy);
		m_enemyReachableTimer = 0.0f;
		m_seeEnemyTime = engine->GetTime();


		if (!IsZombieBot(GetEntity()))
			m_enemyUpdateTime = engine->GetTime() + 0.6f;
		//m_enemyUpdateTime = (IsZombieBot(GetEntity()) ? engine->GetTime() + 2.5f : engine->GetTime() + 0.6f);

		return true;
	}

	if ((m_aimFlags <= AIM_PREDICTENEMY && m_seeEnemyTime + 4.0f < engine->GetTime() && !(m_states & (STATE_SEEINGENEMY | STATE_HEARENEMY)) && FNullEnt(m_lastEnemy) && FNullEnt(m_enemy) && GetCurrentTask()->taskID != TASK_DESTROYBREAKABLE && GetCurrentTask()->taskID != TASK_PLANTBOMB && GetCurrentTask()->taskID != TASK_DEFUSEBOMB) || g_roundEnded)
	{
		if (!m_reloadState)
			m_reloadState = RSTATE_PRIMARY;
	}

	if ((UsesSniper() || UsesZoomableRifle()) && m_zoomCheckTime + 1.0f < engine->GetTime())
	{
		if (pev->fov < 90)
			pev->button |= IN_ATTACK2;
		else
			m_zoomCheckTime = 0.0f;
	}

	return false;
}