.:: Bots United ::.  
filebase forums discord server github wiki web
cubebot epodbot fritzbot gravebot grogbot hpbbot ivpbot jkbotti joebot
meanmod podbotmm racc rcbot realbot sandbot shrikebot soulfathermaps yapb

Go Back   .:: Bots United ::. > Developer's Farm > General Bot Coding
General Bot Coding See what a pain it is to get those little mechs shooting around

Reply
 
Thread Tools
Making entities follow the player
Old
  (#1)
Lazy
Member
 
Lazy's Avatar
 
Status: Offline
Posts: 236
Join Date: Jan 2004
Location: Toronto, Ontario, Canada
Default Making entities follow the player - 03-05-2004

The idea: Allow terrorists to move the hostages in CS.
The problem: I'm not good enough at math to fake the movement.

I have been able to move them around a bit, its very funny to see them slam into walls due to incorrect math.
I first thought of having the using player drop waypoints for the hostage to follow but I think thats overcomplicating the problem.

Any ideas would be helpful here.

Here is the source, just take into consideration that I have not had much time to work on it ( or anything else ) and alot of stuff is not finished or implemented yet ( or could be rewritten ).

Code:
  #include <extdll.h>
  #include <meta_api.h>
  #include "dll.h"
  
  // This prevents the user from "using"
  // every frame.
  bool g_bHasPressedUseAlready[ 32 ];
  
  // The next time the user ( index ) can
  // "press" the use key.
  float g_flNextUseCheckTime[ 32 ];
  
  // Returns true if the given player is on the
  // terrorist team.
  bool
  IsTerrorist( edict_t* pEdict ) {
     return true;
  }
  
  // "Borrowed" From util.cpp
  Vector 
  UTIL_VecToAngles( const Vector& vec ) {
  	float rgflVecOut[ 3 ];
  
  	VEC_TO_ANGLES( vec, rgflVecOut );
  
  	return Vector( rgflVecOut );
  }
  
  // "Borrowed" From util.cpp
  // Overloaded to add IGNORE_GLASS
  void 
 UTIL_TraceLine( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, IGNORE_GLASS ignoreGlass, edict_t *pentIgnore, TraceResult *ptr ) {
 	TRACE_LINE( vecStart, vecEnd, (igmon == ignore_monsters ? TRUE : FALSE) | (ignoreGlass?0x100:0), pentIgnore, ptr );
  }
  
  // Traces a line between an entity and a point to
  // determine if that point is visible to the given entity.
  BOOL
  IsVisible( edict_t* pStartEntity, const Vector& vecTarget ) {
     Vector vecStart = pStartEntity->v.origin + pStartEntity->v.view_ofs;
     TraceResult trTrace;
  
     UTIL_TraceLine( vecStart, vecTarget, ignore_monsters, ignore_glass, pStartEntity, &trTrace );
  
     if ( trTrace.flFraction != 1.0f )
  	  return FALSE;
     else
  	  return TRUE;
  
     return FALSE;
  }
  
  // Wrap the angles to make sure we don't overflow.
  void 
  WrapAngles( Vector& vecAngles ) {
     if ( vecAngles.x > 360 )
  	  vecAngles.x = 360;
     else if ( vecAngles.x < -180 )
  	  vecAngles.x = -180;
  
     if ( vecAngles.y > 360 )
  	  vecAngles.y = 360;
     else if ( vecAngles.y < -180 )
  	  vecAngles.y = -180;
  
     if ( vecAngles.z > 360 )
  	  vecAngles.z = 360;
     else if ( vecAngles.z < -180 )
  	  vecAngles.z = -180;
  }
  
  // Called every frame after physics have been applied.
  // Also called after the gamedll's version.
  void 
  PlayerPostThink_Post( edict_t* pEdict ) {
     // The player's entity index.
     int iPlayerIndex = ENTINDEX( pEdict );
  
     // Pointer to our hostage entity.
     edict_t* pHostage = NULL;
     
     // Do we have a valid hostage?
     // Added:
     // The hostage "movement" is done here to save
     // hooking another function.
     // Besides, the hostage is our bitch anyways for
     // the time being.
     if ( ! FNullEnt( pEdict->v.euser4 ) ) {
  	  pHostage = pEdict->v.euser4;
  
  	  // Release the hostage if either they are too far away,
  	  // out of sight,
  	  // the hostage is dead
  	  // or the player is dead.
  	  if ( ( pEdict->v.origin - pHostage->v.origin ).Length( ) > 1024.0f   || 
  		    !IsVisible( pHostage, pEdict->v.origin + pEdict->v.view_ofs )  ||
 			 pHostage->v.health == 0									 || 
  			 pEdict->v.health == 0 ) {
  		 // We are either too far away, out of sight or someone died.
  		 // Release the hostage.
  		 pEdict->v.euser4 = NULL;
  	 }
  	 else {
  		 // The hostage can see us and we aren't too far away.
  		 // Face our user.
 		 // Thanks to PMB for this angles stuff :)
 		 pHostage->v.angles = UTIL_VecToAngles( pEdict->v.oldorigin - ( pHostage->v.origin + pHostage->v.view_ofs ) );
  		 pHostage->v.angles.x = 0;
  	  }
     }
  
     RETURN_META( MRES_IGNORED );
  }
  
  // Called at the start of each video frame.
  void
  StartFrame_Post( void ) {
     // Will hold the origin to start the trace from.
     Vector vecStart = Vector( 0, 0, 0 );
  
     // The origin where the trace should end.
     Vector vecEnd = Vector( 0, 0, 0 );
  
     // Pointer to the current entity.
     edict_t* pCurrent = NULL;
  
     // Pointer to the entity the traceline
     // hit.
     edict_t* pHit = NULL;
  
     // Will hold the result of the trace used
     // to get the entity infront of the player.
     TraceResult trTrace;
  
     // Loop through all of the possible player spots.
     for ( int i = 1; i < 33; i++ ) {
  	  pCurrent = INDEXENT( i );
  
  	  // If this entity is null, we have reached the end
  	  // of the players.
  	  if ( FNullEnt( pCurrent ) )
  		 break;
  
  	  // Continue if the current player is not a terrorist.
  	  if ( ! IsTerrorist( pCurrent ) )
  		 continue;
  
  	  // Are we pressing the use key?
  	  if ( pCurrent->v.button & IN_USE ) {
  		 // Is it time to act upon it?
  		 if ( gpGlobals->time >= g_flNextUseCheckTime[ i - 1 ] ) {
  			// Set the next use check time to time + 0.5 
 			g_flNextUseCheckTime[ i - 1 ] = gpGlobals->time + 0.5;
  
 			// We have just pressed the use key, make sure we do not keep
  			// "using" every few frames.
  			if ( g_bHasPressedUseAlready[ i - 1 ] == false )
  			   g_bHasPressedUseAlready[ i - 1 ] = true;
  			else
  			   RETURN_META( MRES_IGNORED );
  
 			// If we already have a hostage and the use key was pressed
  			// means the player wants to release the hostage.
  			if ( ! FNullEnt( pCurrent->v.euser4 ) ) {
  			   pCurrent->v.euser4 = NULL;
  			   RETURN_META( MRES_IGNORED );
  			}
  
 			vecStart = pCurrent->v.origin + pCurrent->v.view_ofs;
  			vecEnd = vecStart + gpGlobals->v_forward * 72;
  
 			// Trace a line from the player's crosshair to 96 units infront.
 		 TRACE_LINE( vecStart, vecEnd, dont_ignore_monsters, pCurrent, &trTrace );
  			pHit = trTrace.pHit;
  
  			// Did we hit something? Was it a hostage?
 			if ( ! FNullEnt( pHit ) && FClassnameIs( pHit, "hostage_entity" ) ) {
  			   // euser4 Will now contain a pointer to the hostage
  			   // we wish to move.
  			   pCurrent->v.euser4 = pHit;
  			}
  		 }
  	  }
  	  else {
  		 // We are no longer pressing the use key.
  		 g_bHasPressedUseAlready[ i - 1 ] = false;
  	  }
     }
  
     RETURN_META( MRES_IGNORED );
  }
  
  // Called when an entity is spawning.
  int 
  DispatchSpawn_Post( edict_t* pEdict ) {
     // If the world is being spawned...
     if ( ! FNullEnt( pEdict ) ) {
  	  if ( FClassnameIs( pEdict, "worldspawn" ) ) {
  		 // Zero-out some global variables for use on this map
 		 memset( g_bHasPressedUseAlready, 0, sizeof( bool ) * 32 );	 
  		 memset( g_flNextUseCheckTime, 0, sizeof( float ) * 32 );
  	  }
  	  else if ( FClassnameIs( pEdict, "hostage_entity" ) ) {
  		 // Fix hostages hands not matching their skin color.
  		 if ( pEdict->v.body == 2 )
  			pEdict->v.skin = 1;
  	  }
     }
  
     RETURN_META_VALUE( MRES_IGNORED, 0 );
  }
  
  // Called when a player leaves the server.
  void
  ClientDisconnect_Post( edict_t* pEdict ) {
     // If the entity is valid reset their next use check
     // time and "has pressed already" stuff now.
     if ( ! FNullEnt( pEdict ) ) {
  	  g_bHasPressedUseAlready[ ENTINDEX( pEdict ) - 1 ] = false;
  	  g_flNextUseCheckTime[ ENTINDEX( pEdict ) - 1 ] = 0.0f;
     }
  
     RETURN_META( MRES_IGNORED );
  }
Edited to add in a comment I forgot to put in

Last edited by Lazy; 03-05-2004 at 12:28..
  
Reply With Quote
Re: Making entities follow the player
Old
  (#2)
Pierre-Marie Baty
Roi de France
 
Pierre-Marie Baty's Avatar
 
Status: Offline
Posts: 5,049
Join Date: Nov 2003
Location: 46°43'60N 0°43'0W 0.187A
Default Re: Making entities follow the player - 03-05-2004

I don't see what's so terribly wrong by making the hostage follow waypoints ? ???

Else you can do something more realistic, make your hostage fire a TraceHull (human_hull) towards your player and always head up towards the last hit point which reached the player (i.e, the vector location where your player was last visible for the hostage...)

I don't see the place where you put your hostage in movement ?
Setting the angles may not necessarily be enough. IMO a pfnWalkMove() call should be needed (it's the RunPlayerMove() for monsters...)



RACC home - Bots-United: beer, babies & bots (especially the latter)
"Learn to think by yourself, else others will do it for you."
  
Reply With Quote
Re: Making entities follow the player
Old
  (#3)
Lazy
Member
 
Lazy's Avatar
 
Status: Offline
Posts: 236
Join Date: Jan 2004
Location: Toronto, Ontario, Canada
Default Re: Making entities follow the player - 03-05-2004

Well, pfnWalkMove does not work but it appears random mathematical guessing does.
The hostages now follow their new user except for one bug...
They float.

Here is the new version of PlayerPostThink_Post...
Code:
 // Called every frame after physics have been applied.
 // Also called after the gamedll's version.
 void 
 PlayerPostThink_Post( edict_t* pEdict ) {
    // The player's entity index.
    int iPlayerIndex = ENTINDEX( pEdict );
 
    // Pointer to our hostage entity.
    edict_t* pHostage = NULL;
    
    // Do we have a valid hostage?
    // Added:
    // The hostage "movement" is done here to save
    // hooking another function.
    // Besides, the hostage is our bitch anyways for
    // the time being.
    if ( ! FNullEnt( pEdict->v.euser4 ) ) {
 	  pHostage = pEdict->v.euser4;
 
 	  // Release the hostage if either they are too far away,
 	  // out of sight,
 	  // the hostage is dead
 	  // or the player is dead.
 	  if ( ( pEdict->v.origin - pHostage->v.origin ).Length( ) > 1024.0f   || 
 		    !IsVisible( pHostage, pEdict->v.origin + pEdict->v.view_ofs )  ||
 			 pHostage->v.health == 0									   || 
 			 pEdict->v.health == 0 ) {
 		 // We are either too far away, out of sight or someone died.
 		 // Release the hostage.
 		 pEdict->v.euser4 = NULL;
 	 }
 	 else {
 		 // The hostage can see us and we aren't too far away.
 		 // Face our user.
 		 // Thanks to PMB for this angles stuff :)
 		 pHostage->v.angles = UTIL_VecToAngles( pEdict->v.origin - ( pHostage->v.origin + pHostage->v.view_ofs ) );
 		 pHostage->v.angles.x = 0;
 
 		 // Follow our user!
 		 pHostage->v.avelocity = pEdict->v.avelocity;
 		 pHostage->v.velocity = ( ( pEdict->v.origin - pHostage->v.origin ) - pEdict->v.velocity ) - gpGlobals->v_forward * 64;
 	  }
    }
 
    RETURN_META( MRES_IGNORED );
 }
Attached is a zipped demo of what the floating looks like.
Just unzip to your ( steam ) cstrike directory, go into CS and type "playdemo hostage.dem".
Attached Files
File Type: zip hostage.zip (189.0 KB, 423 views)
  
Reply With Quote
Re: Making entities follow the player
Old
  (#4)
Huntkillaz
Member
 
Huntkillaz's Avatar
 
Status: Offline
Posts: 594
Join Date: Mar 2004
Location: Middle Earth (New Zealand)
Default Re: Making entities follow the player - 03-05-2004

i haven't read this thread but thought i might mention:

note: pb needs a fix on to check wheather hossies are following or stuck somewhere...so that they dont run to rescue empty


●_•
  
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
vBulletin Skin developed by: vBStyles.com