View Single Post
Re: HPBBot/Bot#10/ZWC Bot: final fixes NED HELP!
Old
  (#3)
MIFUNE
Member
 
Status: Offline
Posts: 13
Join Date: Mar 2014
Big Grin Re: HPBBot/Bot#10/ZWC Bot: final fixes NED HELP! - 18-01-2017

Hereīs the full combat.cpp file (no secret is revealed, except the part to make bots shoot sentinels). Use it freely (but give me some credit!!, haha).

Code:
//===========================================================
//
//				Zion Warcry Bot Combat system.
//			Based on botman's Half-Life bot example
//
//				http://planethalflife.com/botman/
//
//  bot_combat.cpp (c) Botman all modifications (c) MIFUNE
//
//			10-11-12-13-14 Enero 2017
//===========================================================

#include "extdll.h"
#include "util.h"
#include "client.h"
#include "cbase.h"
#include "player.h"
#include "items.h"
#include "effects.h"
#include "weapons.h"
#include "soundent.h"
#include "gamerules.h"
#include "animation.h"

#include "bot.h"


extern int f_Observer;  // flag to indicate if player is in observer mode




ammo_check_t ammo_check[] = {

	{"ammo_9mmAR", "9mm",_9MM_MAX_CARRY},
	{"ammo_gaussclip", "uranium", URANIUM_MAX_CARRY},
    {"", 0, 0}};



//========================================================================================================================
//========================================================================================================================

CBaseEntity * CBot::BotFindEnemy( void )
{
   Vector vecEnd;
   static BOOL flag=TRUE;

   float nearestdistance = 10000;
  CBaseEntity *pNewEnemy = NULL;
   
   
//=================================================================================
// Modulo para que los Bots Disparen a los Centinelas
// Module to make the Bots shot to the sentinels
//=================================================================================

   	CBaseEntity* pEnt  = NULL;  
    

    if (  ( pEnt  = UTIL_FindEntityByClassname( pEnt , "monster_sentinel" ) )||( pEnt  = UTIL_FindEntityByClassname( pEnt , "monster_sentow"   ) ))
	           
	{ 
		 pBotEnemy = pEnt ; 
    

	// face the enemy
         Vector v_enemy = pBotEnemy->pev->origin; //- pev->origin; this part is commented trying to prevent headbanging
         Vector bot_angles = UTIL_VecToAngles( v_enemy );

         pev->ideal_yaw = bot_angles.y;

         // check for wrap around of angle...
         if (pev->ideal_yaw > 180)
            pev->ideal_yaw -= 360;
         if (pev->ideal_yaw < -180)
            pev->ideal_yaw += 360;

         return (pBotEnemy);
	  
	  // see if Bot can see the Monster...NEW

	      if (FInViewCone( &vecEnd ) && FVisible( vecEnd ))
		  {
			 float distance = (pEnt ->pev->origin - pev->origin).Length();
			 if (distance < nearestdistance)
         {
            nearestdistance = distance;
            pNewEnemy = pEnt ;
		    pBotUser = NULL;  
         }
      }
	
	}
	 	  
      
//=================================================================================
// Fin del Modulo para que los Bots Disparen a los Centinelas
// End of module.
//=================================================================================
	 
	if (pNewEnemy)
	
	{
	   	   
      // face the enemy
      Vector v_enemy = pNewEnemy->pev->origin;// Lo mismo de arriba, comento esto " - pev->origin; "
      Vector bot_angles = UTIL_VecToAngles( v_enemy );

      pev->ideal_yaw = bot_angles.y;

      // check for wrap around of angle...
      if (pev->ideal_yaw > 180)
         pev->ideal_yaw -= 360;
      if (pev->ideal_yaw < -180)
         pev->ideal_yaw += 360;

	  f_move_speed = -150.0;//freezes when see the enemy, then itīll shoot it
   }

   return (pNewEnemy);

//====================================================================================================================================
// Aņadido Final: parece que chuta 20-Junio-2007 Sin esto los Bots hacian que el juego se "colgase" si no "veian" a algun enemigo.
// Finall add: seems that it works 20-June-2007 Without this Bots make the game crash because they could not free-clear the pointer.
//====================================================================================================================================
   //Si no hay enemigo o está muerto eliminar el puntero.  
   //If thereīs no enemy or if itīs dead clear the pointer

	if (( !pNewEnemy) && (!pBotEnemy->IsAlive()))
	 { 
		 pBotEnemy = NULL; 
			 
	 }

}
  

Vector CBot::BotBodyTarget( CBaseEntity *pBotEnemy )
{
   Vector target;
   float f_distance;
   float f_scale;
   int d_x, d_y, d_z;

   f_distance = (pBotEnemy->pev->origin - pev->origin).Length();

   if (f_distance > 5000)
      f_scale = 1.0;
   else if (f_distance > 500)
      f_scale = f_distance / 1000.0;
   else
      f_scale = 0.1;

    target = pBotEnemy->Center() + pBotEnemy->pev->view_ofs * RANDOM_FLOAT( 0.0, 0.0 );
         d_x = 0;  // no offset
         d_y = 0;
         d_z = 0;

   target = target + Vector(d_x, d_y, d_z);

   return target;
}


void CBot::BotWeaponInventory( void )
{
   int i;

   // initialize the elements of the weapons arrays...
   for (i = 0; i < MAX_WEAPONS; i++)
   {
      weapon_ptr[i] = NULL;
      primary_ammo[i] = 0;
      secondary_ammo[i] = 0;
   }

   // find out which weapons the bot is carrying...
   for (i = 0; i < MAX_ITEM_TYPES; i++)
   {
      CBasePlayerItem *pItem = NULL;

      if (m_rgpPlayerItems[i])
      {
         pItem = m_rgpPlayerItems[i];
         while (pItem)
         {
            weapon_ptr[pItem->m_iId] = pItem;  // store pointer to item

            pItem = pItem->m_pNext;
         }
      }
   }

   // find out how much ammo of each type the bot is carrying...
   for (i = 0; i < MAX_AMMO_SLOTS; i++)
   {
      if (!CBasePlayerItem::AmmoInfoArray[i].pszName)
         continue;

	  if (strcmp("9mm", CBasePlayerItem::AmmoInfoArray[i].pszName) == 0)
      {
         primary_ammo[WEAPON_TWOHAND]	= m_rgAmmo[i];
		 primary_ammo[WEAPON_SHORYUKEN] = m_rgAmmo[i];
		 primary_ammo[WEAPON_SIEGE]		= m_rgAmmo[i];
		 primary_ammo[WEAPON_MJOLNIR]   = m_rgAmmo[i];
		 primary_ammo[WEAPON_SHREDDER]	= m_rgAmmo[i];
      }
	  else if (strcmp("uranium", CBasePlayerItem::AmmoInfoArray[i].pszName) == 0)
      {
         primary_ammo[WEAPON_FEMP]		= m_rgAmmo[i];
      }
   }

}

// specifing a weapon_choice allows you to choose the weapon the bot will
// use (assuming enough ammo exists for that weapon)
// BotFireWeapon will return TRUE if weapon was fired, FALSE otherwise
// primary is used to indicate whether you want primary or secondary fire
// if you have specified a weapon using weapon_choice

BOOL CBot::BotFireWeapon( Vector v_enemy_origin, int weapon_choice, BOOL primary )
{
   CBasePlayerItem *new_weapon;

   // is it time to check weapons inventory yet?
   if (f_weapon_inventory_time <= gpGlobals->time)
   {
      // check weapon and ammo inventory then update check time...
      BotWeaponInventory();

      f_weapon_inventory_time = gpGlobals->time + 1.0;
   }

   Vector v_enemy = v_enemy_origin - GetGunPosition( );

   float distance = v_enemy.Length();  // how far away is the enemy?



//===========================================================================================================
//								WEAPON URAKEN/CROWBAR
//===========================================================================================================

   // if bot is carrying the crowbar...
   if (pev->weapons & (1<<WEAPON_CROWBAR))
   {
      if (( (distance <= 78))) /*&&(weapon_choice == 0)|(weapon_choice == WEAPON_CROWBAR)))*/
      {
         new_weapon = weapon_ptr[WEAPON_CROWBAR];

         // check if the bot isn't already using this item.
		
         if (m_pActiveItem != new_weapon)
            SelectItem("weapon_crowbar");  // select the crowbar

         pev->button |= IN_ATTACK;  // use primary attack (whack! whack!)
 
         // set next time to "shoot"
         f_shoot_time = gpGlobals->time + 0.3;// + 
         return TRUE;
      }
   }



//===========================================================================================================
//							WEAPON APU GUNS// All derived from the MP5 Code.
//===========================================================================================================

//===========================================================================================================
//												TWOHAND
//===========================================================================================================
   
   if ((pev->weapons & (1<<WEAPON_TWOHAND))) 
   {
     

		if (( (distance <=  8000)&&(weapon_choice == 0)||((weapon_choice == WEAPON_TWOHAND))))
      
      {
         new_weapon = weapon_ptr[WEAPON_TWOHAND];

         // check if the bot has any ammo left for this weapon...
         if (primary_ammo[WEAPON_TWOHAND] > 0)
         {
            // check if the bot isn't already using this item...
            if (m_pActiveItem != new_weapon)
               SelectItem("weapon_twohand");  // select the Twohand
               
            pev->button |= IN_ATTACK;  // use primary attack (bang! bang!)
            pev->button |= IN_ATTACK2;  // use primary attack (bang! bang!)
           
            // set next time to shoot
            f_shoot_time = gpGlobals->time + 0.1;//
             

            return TRUE;
         }
		 if (primary_ammo[WEAPON_TWOHAND] <= 100)// A ver si hay suerte y les da por usar la RECARGA
		 {
			 	pev->button |= IN_RELOAD;  // use primary attack, BAZINGA!!!
		 }
      }

    }

//============================================================================================================
//                                      SHORYUKEN
//============================================================================================================
   
   if ((pev->weapons & (1<<WEAPON_SHORYUKEN)) && (pev->waterlevel != 3))
   {
     

	  if (( (distance <= 4000)&&(weapon_choice == 0)||((weapon_choice == WEAPON_SHORYUKEN))))
      
      {
         new_weapon = weapon_ptr[WEAPON_SHORYUKEN];

         // check if the bot has any ammo left for this weapon...
         if (primary_ammo[WEAPON_SHORYUKEN] > 0)
         {
            // check if the bot isn't already using this item...
            if (m_pActiveItem != new_weapon)
               SelectItem("weapon_shoryuken");  // select the Shoryuken

			pev->button |= IN_ATTACK;  // use primary attack (bang! bang!)
            pev->button |= IN_ATTACK2;  // use secondary attack (bang! bang!)
            
			// set next time to shoot
            f_shoot_time = gpGlobals->time + 0.1;
             

            return TRUE;
         }
		 if (primary_ammo[WEAPON_SHORYUKEN] <= 100)// A ver si hay suerte y les da por usar la RECARGA
			                                       // Cross fingers!, hope it reloads if ammo gets under 100
		 {
			 	pev->button |= IN_RELOAD;  // use primary attack, BAZINGA!!!
		 }
      }

   }


//=================================================================================================================
//											SHREDDER
//=================================================================================================================
   
   if ((pev->weapons & (1<<WEAPON_SHREDDER)))
   {
      
	  if (( (distance <= 2000)&&(weapon_choice == 0)||((weapon_choice == WEAPON_SHREDDER))))

      {
         new_weapon = weapon_ptr[WEAPON_SHREDDER];

         // check if the bot has any ammo left for this weapon...
         if (primary_ammo[WEAPON_SHREDDER] > 0)
         {
            // check if the bot isn't already using this item...
            if (m_pActiveItem != new_weapon)
               SelectItem("weapon_shredder");  // select the Shredder

			pev->button |= IN_ATTACK;  // use primary attack, BAZINGA!!!
            pev->button |= IN_ATTACK2;  // use secondary attack (bang! bang!)
 
            // set next time to shoot
            f_shoot_time = gpGlobals->time + 0.1;
               
            return TRUE;
         }

		 if (primary_ammo[WEAPON_SHREDDER] <= 100)// A ver si hay suerte y les da por usar la RECARGA
		 {
			 	pev->button |= IN_RELOAD;  // use primary attack, BAZINGA!!!
		 }
      }
  }

//===============================================================================================================
//											MJOLNIR
//===============================================================================================================
   
   if ((pev->weapons & (1<<WEAPON_MJOLNIR)))
   {
      if (( (distance <= 5000)&&(weapon_choice == 0)||((weapon_choice == WEAPON_MJOLNIR))))
      
      {
         new_weapon = weapon_ptr[WEAPON_MJOLNIR];

         // check if the bot has any ammo left for this weapon...
         if (primary_ammo[WEAPON_MJOLNIR] > 0)
         {
            // check if the bot isn't already using this item...
            if (m_pActiveItem != new_weapon)
               SelectItem("weapon_mjolnir");  // select the mjolnir
            
			pev->button |= IN_ATTACK;  // use primary attack, BAZINGA!!!
            pev->button |= IN_ATTACK2;  // use secondary attack (bang! bang!)
 
            // set next time to shoot
            f_shoot_time = gpGlobals->time + 0.1;// +
              
            return TRUE;
         }
		 if (primary_ammo[WEAPON_MJOLNIR] <= 100)// A ver si hay suerte y les da por usar la RECARGA
		 {
			 	pev->button |= IN_RELOAD;  // use primary attack, BAZINGA!!!
		 }
      }
   
   }

//=================================================================================================================
//													 SIEGE
//=================================================================================================================
   
   if ((pev->weapons & (1<<WEAPON_SIEGE)))
   {
      if (( (distance <=  9500)&&(weapon_choice == 0)||((weapon_choice == WEAPON_SIEGE))))
      
      {
         new_weapon = weapon_ptr[WEAPON_SIEGE];

         // check if the bot has any ammo left for this weapon...
         if (primary_ammo[WEAPON_SIEGE] > 0)
         {
            // check if the bot isn't already using this item...
            if (m_pActiveItem != new_weapon)
               SelectItem("weapon_siege");  // select the weapon_siege

            pev->button |= IN_ATTACK;  // use primary attack, BAZINGA!!!
            pev->button |= IN_ATTACK2;  // use secondary attack (bang! bang!)
 

            // set next time to shoot
            f_shoot_time = gpGlobals->time + 0.1;

            return TRUE;
         }
		 if (primary_ammo[WEAPON_SIEGE] <= 100)// A ver si hay suerte y les da por usar la RECARGA
		 {
			 	pev->button |= IN_RELOAD;  // use primary attack, BAZINGA!!!
		 }
      }

   }


//========================================================================================================================
//															FEMP
//========================================================================================================================

 if (pev->weapons & (1<<WEAPON_FEMP))
   {
      if (( (distance < 150)&&(weapon_choice == 0))||(weapon_choice == WEAPON_FEMP))
      {
         new_weapon = weapon_ptr[WEAPON_FEMP];

         // check if the bot has any ammo left for this weapon...
         if (primary_ammo[WEAPON_FEMP] > 0)
         {
            // check if the bot isn't already using this item...
            if (m_pActiveItem != new_weapon)
               SelectItem("weapon_femp");  
               pev->button |= IN_ATTACK;  // use primary attack, BAZINGA!!!
              // set next time to shoot
               f_shoot_time = gpGlobals->time + 10;
          }
	  }

	  if ( pev->health <= 30 )
		{
			// check if the bot isn't already using this item...
			if (m_pActiveItem != new_weapon)
               SelectItem("weapon_femp");  
               pev->button |= IN_ATTACK2;  // use the secondary attack to restore the engine
               // set next time to shoot
               f_shoot_time = gpGlobals->time + 30;
         }
            return TRUE;
        
	 }
   return FALSE;
}

//==========================================================================================================================
//
//==========================================================================================================================

void CBot::BotShootAtEnemy( void )
{
   

   // aim for the head and/or body
   
   Vector v_enemy = BotBodyTarget( pBotEnemy ) - GetGunPosition();

   pev->v_angle = UTIL_VecToAngles( v_enemy );
  
   pev->angles.x = pev->v_angle.x;//Esto es lo unico nuevo que he aņadido, de otro modo no apuntan arriba o abajo. 
   pev->angles.y = pev->v_angle.y;
   pev->angles.z = 0;

   pev->ideal_yaw = pev->v_angle.y;

   // check for wrap around of angle...
   
   if (pev->ideal_yaw > 180)
      pev->ideal_yaw -= 360;
   if (pev->ideal_yaw < -180)
      pev->ideal_yaw += 360;
   
   pev->v_angle.x = -pev->v_angle.x;  //adjust pitch to point gun 
  
   //=================================================
   //Limitador del angulo X (arriba-abajo)
   //Limiter for the X angle (up-down)
   //=================================================
   if (pev->v_angle.x >45) (pev->v_angle.x   =  45);
  // if (pev->v_angle.x <45) (pev->v_angle.x  +=  90); <----Commented!!!
   if (pev->v_angle.x < 0) (pev->v_angle.x   =   0);
  //==================================================

   // is it time to shoot yet?
   if (f_shoot_time <= gpGlobals->time)
   {
      // select the best weapon to use at this distance and fire...
      BotFireWeapon( pBotEnemy->pev->origin );

	  f_move_speed = -150.0;//No se mueve al disparar
   }                        //Freezes when shooting

	  v_enemy.z =  0;  // ignore z component (up & down)


}
Hope you can help me, any WORKING help will appear on credits.

Hereīs a video of the Bot in action...

http://www.moddb.com/mods/zion-warcr...ource#imagebox

Last edited by MIFUNE; 18-01-2017 at 18:54..
  
Reply With Quote