Beispiel #1
0
bool Bot::IsShieldDrawn (void)
{
   // this function returns true, is the tactical shield is drawn

   if (!HasShield ())
      return false;

   return pev->weaponanim == 6 || pev->weaponanim == 7;
}
Beispiel #2
0
bool Bot::IsEnemyProtectedByShield (edict_t *enemy)
{
   // this function returns true, if enemy protected by the shield

   if (FNullEnt (enemy) || (HasShield () && IsShieldDrawn ()))
      return false;

   // check if enemy has shield and this shield is drawn
   if (strncmp (STRING (enemy->v.viewmodel), "models/shield/v_shield_", 23) == 0 && (enemy->v.weaponanim == 6 || enemy->v.weaponanim == 7))
   {
      if (::IsInViewCone (pev->origin, enemy))
         return true;
   }
   return false;
}
Beispiel #3
0
// SyPB Pro P.32 - Knife Attack Ai
bool Bot::KnifeAttack(edict_t *entity)
{
	float distance = (pev->origin - GetEntityOrigin(entity)).GetLength();

	float kad1 = (m_knifeDistance1API <= 0) ? 64.0f : m_knifeDistance1API;; // Knife Attack Distance (API)
	float kad2 = (m_knifeDistance2API <= 0) ? 64.0f : m_knifeDistance2API;

	if (distance < kad1 || distance < kad2)
	{
		float distanceSkipZ = (pev->origin - GetEntityOrigin(entity)).GetLength2D();
		//if (distanceSkipZ < distance && pev->origin.z > GetEntityOrigin(entity).z)
		// pev->button |= IN_DUCK;


		// SyPB Pro P.35 - Knife Attack Change
		if (pev->origin.z > GetEntityOrigin(entity).z && distanceSkipZ < 64.0f)
			pev->button |= IN_DUCK;
		else if (pev->origin.z + 150.0f < GetEntityOrigin(entity).z && distanceSkipZ < 300.0f && distanceSkipZ > 64.0f)
			pev->button |= IN_JUMP;

		if (IsZombieBot(GetEntity()))
		{
			if (distance < kad1)
				pev->button |= IN_ATTACK;
			else
				pev->button |= IN_ATTACK2;
		}
		else
		{
			if (distance > kad1)
				pev->button |= IN_ATTACK2;
			else if (distance > kad2)
				pev->button |= IN_ATTACK;
			else if (engine->RandomInt(1, 100) < 30 || HasShield())
				pev->button |= IN_ATTACK;
			else
				pev->button |= IN_ATTACK2;
		}

		return true;
	}

	return false;
}
Beispiel #4
0
void Bot::FireWeapon (void)
{
   // this function will return true if weapon was fired, false otherwise
   float distance = (m_lookAt - EyePosition ()).GetLength (); // how far away is the enemy?

   // if using grenade stop this
   if (m_isUsingGrenade)
   {
      m_shootTime = engine->GetTime () + 0.1f;
      return;
   }

   // or if friend in line of fire, stop this too but do not update shoot time
   if (!FNullEnt (m_enemy) && IsFriendInLineOfFire (distance))
      return;

   FireDelay *delay = &g_fireDelay[0];
   WeaponSelect *selectTab = &g_weaponSelect[0];

   edict_t *enemy = m_enemy;

   int selectId = WEAPON_KNIFE, selectIndex = 0, chosenWeaponIndex = 0;
   int weapons = pev->weapons;

   // if jason mode use knife only
   if (sypb_knifemode.GetBool ())
      goto WeaponSelectEnd;

   // use knife if near and good skill (l33t dude!)
   if (m_skill > 80 && !FNullEnt (enemy) && distance < 80.0f && pev->health > 80 && pev->health >= enemy->v.health && !IsGroupOfEnemies (pev->origin) && !::IsInViewCone (pev->origin, enemy))
      goto WeaponSelectEnd;

   // loop through all the weapons until terminator is found...
   while (selectTab[selectIndex].id)
   {
      // is the bot carrying this weapon?
      if (weapons & (1 << selectTab[selectIndex].id))
      {
         // is enough ammo available to fire AND check is better to use pistol in our current situation...
         if ((m_ammoInClip[selectTab[selectIndex].id] > 0) && !IsWeaponBadInDistance (selectIndex, distance))
            chosenWeaponIndex = selectIndex;
      }
      selectIndex++;
   }
   selectId = selectTab[chosenWeaponIndex].id;

   // if no available weapon...
   if (chosenWeaponIndex == 0)
   {
      selectIndex = 0;

      // loop through all the weapons until terminator is found...
      while (selectTab[selectIndex].id)
      {
         int id = selectTab[selectIndex].id;

         // is the bot carrying this weapon?
         if (weapons & (1 << id))
         {
            if (g_weaponDefs[id].ammo1 != -1 && m_ammo[g_weaponDefs[id].ammo1] >= selectTab[selectIndex].minPrimaryAmmo)
            {
               // available ammo found, reload weapon
               if (m_reloadState == RSTATE_NONE || m_reloadCheckTime > engine->GetTime () || GetCurrentTask ()->taskID != TASK_ESCAPEFROMBOMB)
               {
                  m_isReloading = true;
                  m_reloadState = RSTATE_PRIMARY;
                  m_reloadCheckTime = engine->GetTime ();
                  m_fearLevel = 1.0f; // SyPB Pro P.7

                  RadioMessage (Radio_NeedBackup);
               }
               return;
            }
         }
         selectIndex++;
      }
      selectId = WEAPON_KNIFE; // no available ammo, use knife!
   }

WeaponSelectEnd:
   // we want to fire weapon, don't reload now
   if (!m_isReloading)
   {
      m_reloadState = RSTATE_NONE;
      m_reloadCheckTime = engine->GetTime () + 3.0f;
   }

   // select this weapon if it isn't already selected
   if (m_currentWeapon != selectId)
   {
      SelectWeaponByName (g_weaponDefs[selectId].className);

      // reset burst fire variables
      m_firePause = 0.0f;
      m_timeLastFired = 0.0f;
      m_burstShotsFired = 0;

      return;
   }

   if (delay[chosenWeaponIndex].weaponIndex != selectId)
      return;

   if (selectTab[chosenWeaponIndex].id != selectId)
   {
      chosenWeaponIndex = 0;

      // loop through all the weapons until terminator is found...
      while (selectTab[chosenWeaponIndex].id)
      {
         if (selectTab[chosenWeaponIndex].id == selectId)
            break;

         chosenWeaponIndex++;
      }
   }

   // if we're have a glock or famas vary burst fire mode
   CheckBurstMode (distance);

   if (HasShield () && m_shieldCheckTime < engine->GetTime () && GetCurrentTask ()->taskID != TASK_CAMP) // better shield gun usage
   {
      if ((distance > 550) && !IsShieldDrawn ())
         pev->button |= IN_ATTACK2; // draw the shield
      else if (IsShieldDrawn () || (!FNullEnt (m_enemy) && (m_enemy->v.button & IN_RELOAD)))
         pev->button |= IN_ATTACK2; // draw out the shield

      m_shieldCheckTime = engine->GetTime () + 1.0f;
   }

   if (UsesSniper () && m_zoomCheckTime < engine->GetTime ()) // is the bot holding a sniper rifle?
   {
      if (distance > 1500 && pev->fov >= 40) // should the bot switch to the long-range zoom?
         pev->button |= IN_ATTACK2;

      else if (distance > 150 && pev->fov >= 90) // else should the bot switch to the close-range zoom ?
         pev->button |= IN_ATTACK2;

      else if (distance <= 150 && pev->fov < 90) // else should the bot restore the normal view ?
         pev->button |= IN_ATTACK2;

      m_zoomCheckTime = engine->GetTime ();

      if (!FNullEnt (m_enemy) && (pev->velocity.x != 0 || pev->velocity.y != 0 || pev->velocity.z != 0) && (pev->basevelocity.x != 0 || pev->basevelocity.y != 0 || pev->basevelocity.z != 0))
      {
         m_moveSpeed = 0.0f;
         m_strafeSpeed = 0.0f;
         m_navTimeset = engine->GetTime ();
      }
   }
   else if (UsesZoomableRifle () && m_zoomCheckTime < engine->GetTime () && m_skill < 90) // else is the bot holding a zoomable rifle?
   {
      if (distance > 800 && pev->fov >= 90) // should the bot switch to zoomed mode?
         pev->button |= IN_ATTACK2;

      else if (distance <= 800 && pev->fov < 90) // else should the bot restore the normal view?
         pev->button |= IN_ATTACK2;

      m_zoomCheckTime = engine->GetTime ();
   }

   const float baseDelay = delay[chosenWeaponIndex].primaryBaseDelay;
   const float minDelay = delay[chosenWeaponIndex].primaryMinDelay[abs ((m_skill / 20) - 5)];
   const float maxDelay = delay[chosenWeaponIndex].primaryMaxDelay[abs ((m_skill / 20) - 5)];

   // need to care for burst fire?
   if (distance < 256.0f || m_blindTime > engine->GetTime ())
   {
      if (selectId == WEAPON_KNIFE)
      {
         if (distance < 64.0f)
         {
            if (engine->RandomInt (1, 100) < 30 || HasShield ())
               pev->button |= IN_ATTACK; // use primary attack
            else
               pev->button |= IN_ATTACK2; // use secondary attack
         }
      }
      else
      {
         if (selectTab[chosenWeaponIndex].primaryFireHold) // if automatic weapon, just press attack
            pev->button |= IN_ATTACK;
         else // if not, toggle buttons
         {
            if ((pev->oldbuttons & IN_ATTACK) == 0)
               pev->button |= IN_ATTACK;
         }
      }

      if (pev->button & IN_ATTACK)
         m_shootTime = engine->GetTime ();
   }
   else
   {
      if (DoFirePause (distance, &delay[chosenWeaponIndex]))
         return;

      // don't attack with knife over long distance
      if (selectId == WEAPON_KNIFE)
         return;

      if (selectTab[chosenWeaponIndex].primaryFireHold)
      {
         m_shootTime = engine->GetTime ();
         m_zoomCheckTime = engine->GetTime ();

         pev->button |= IN_ATTACK;  // use primary attack
      }
      else
      {
         pev->button |= IN_ATTACK;  // use primary attack

         m_shootTime = engine->GetTime () + baseDelay + engine->RandomFloat (minDelay, maxDelay);
         m_zoomCheckTime = engine->GetTime ();
      }
   }
}
Beispiel #5
0
// returns true if buying is completed, false if not
bool CBotCS::BuyStuff()
{
   int iId;
   CServerCS *pServerCS = dynamic_cast<CServerCS *>(g_pServer);

   switch (m_iBuyCount)
   {
   case 0: // if bot is rich, buy armor+helmet; else buy armor
      if (m_iAccount > RandomLong(3000, 5000)) {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying armor + helmet");
         g_General.FakeClientCommand(this, "buy;menuselect 8;menuselect 2");
      } else {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying armor");
         g_General.FakeClientCommand(this, "buy;menuselect 8;menuselect 1");
      }
      break;

   case 1: // if bot doesn't have a primary weapon, buy one
      if (HasPrimary() || HasShield())
      {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): already have a primary weapon; exiting");
         break; // don't proceed if we already have one
      }

      // TODO: emotion
      // select a primary weapon
      iId = g_pBuyMgrCS->ChooseWeapon(RandomLong(0, 100)/*FIXME*/, m_iAccount, GetTeam());
      if (iId != 0) {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): Buying weapon: %s", g_General.GetWeaponName(iId));
         cs_weapontable_s *pWeapon = get_weapon(iId);
         assert(pWeapon);
         if (pServerCS->GetCSVersion() == CS_VERSION_STEAM)
            g_General.FakeClientCommand(this, pWeapon->szBuyCmd16);
         else
            g_General.FakeClientCommand(this, pWeapon->szBuyCmd15);
      } else {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): no primary weapon is selected");
      }
      break;

   case 2: // if bot doesn't have a secondary weapon, buy one
      if (GetWeapons() & ((1 << CS_WEAPON_P228) | (1 << CS_WEAPON_DEAGLE) |
         (1 << CS_WEAPON_FIVESEVEN) | (1 << CS_WEAPON_ELITE)))
      {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): already have a secondary weapon; exiting");
         break; // don't proceed if we already have a good secondary weapon
      }

      // TODO: emotion
      // select a primary weapon
      iId = g_pBuyMgrCS->ChooseWeapon(RandomLong(0, 100)/*FIXME*/, m_iAccount, GetTeam(), 1);
      if (iId != 0) {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): Buying weapon: %s", g_General.GetWeaponName(iId));
         if (HasShield() && iId == CS_WEAPON_ELITE)
            break; // if we have a shield, we can't buy the dual elites
         cs_weapontable_s *pWeapon = get_weapon(iId);
         assert(pWeapon);
         if (pServerCS->GetCSVersion() == CS_VERSION_STEAM)
            g_General.FakeClientCommand(this, pWeapon->szBuyCmd16);
         else
            g_General.FakeClientCommand(this, pWeapon->szBuyCmd15);
      } else {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): no secondary weapon is selected");
      }
      break;

   case 3: // buy enough ammo
      DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying ammo");
      g_General.FakeClientCommand(this, "buy;menuselect 6"); // prim. ammo
      g_General.FakeClientCommand(this, "buy;menuselect 7"); // sec. ammo
      break;

   case 4: // buy grenades, defusers, etc.
      // if bot is CT, randomly buy the defuser
      if (GetTeam() == CS_TEAM_CT &&
         RandomLong(1, 100) < 33 && m_iAccount > 200)
      {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying defuser");
         if (pServerCS->GetCSVersion() == CS_VERSION_STEAM)
            g_General.FakeClientCommand(this, "defuser"); // use alias in CS 1.6
         else
            g_General.FakeClientCommand(this, "buyequip;menuselect 6");
      }

      if (RandomLong(1, 100) < 75 && m_iAccount >= 300 &&
         !(GetWeapons() & CS_WEAPON_HEGRENADE))
      {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying HE Grenade");
         // Buy a HE Grenade
         g_General.FakeClientCommand(this, "buyequip");
         g_General.FakeClientCommand(this, "menuselect 4");
      }

      if (RandomLong(1, 100) < 50 && m_iAccount >= 200 &&
         !(GetWeapons() & CS_WEAPON_FLASHBANG))
      {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying Concussion Grenade");
         // Buy a Concussion Grenade, i.e., 'FlashBang'
         g_General.FakeClientCommand(this, "buyequip");
         g_General.FakeClientCommand(this, "menuselect 3");
      }

      if (RandomLong(1, 100) < 30 && m_iAccount >= 300 &&
         !(GetWeapons() & CS_WEAPON_SMOKEGRENADE))
      {
         DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying Smoke Grenade");
         // Buy a Smoke Grenade
         g_General.FakeClientCommand(this, "buyequip");
         g_General.FakeClientCommand(this, "menuselect 5");
      }

      break;

   case 5: // buying finished
      return true; // no more buying
      break;

   default:
      CGeneral::TerminateOnError("CBotCS::BuyStuff(): m_iBuyCount error");
      break;
   }

   m_iBuyCount++; // add the buying counter
   return false;
}