View Single Post
Re: Show off your finest piece of code!
Old
  (#4)
Rick
Council Member
 
Rick's Avatar
 
Status: Offline
Posts: 690
Join Date: Dec 2003
Location: Holland
Default Re: Show off your finest piece of code! - 29-12-2004

Cube bot, main think function:

Code:
     void CBot::Think()
     {
     	 if (intermission)
     		  return;
     			 
     	 // Bot is dead?
     	 if (m_pMyEnt->state == CS_DEAD)
     	 {
     		  if(lastmillis-m_pMyEnt->lastaction<1200)
     		  {
     			   m_pMyEnt->move = 0;
     			   moveplayer(m_pMyEnt, 1, false);
     		  }
     		  else if (!m_arena)
     			   Spawn();
     	 
     		  return;
     	 }
 							 
     	 CheckItems();
     	 CheckQuad(curtime);
     	 
     	 // Basic AI
     	 if (!BotManager.IdleBots())
     	 {			   
     		  // Default bots will run forward
     		  m_pMyEnt->move = 1;
     		
     		  // Default bots won't strafe
     		  m_pMyEnt->strafe = 0;
     		
     		  if (!BotManager.BotsShoot() && m_pMyEnt->enemy)
     			   m_pMyEnt->enemy = NULL;
     			 
     		  // Find enemy
     		  if (BotManager.BotsShoot() && FindEnemy())
     		  {
     			   // Shoot at enemy
     			   ShootEnemy();
     		  }
     
     		  // Navigate		
     		  HomeThroughMap();
     	 }
     	 else
     		  m_pMyEnt->move = 0;
     				  
     	 // Aim to ideal yaw and pitch
     	 AimToIdeal();
     	 
     	 // Store current location, to see if the bot is stuck
     	 m_vPrevOrigin = m_pMyEnt->o;
     		
     	 // Move the bot
     	 moveplayer(m_pMyEnt, 1, false);
     	 
     	 // Update bot info on all clients
     	 SendBotInfo();
     }
My favourite template (esf & cube bot)

Code:
    template <class C> class TMultiChoice 
    {
    	struct SMultiChoice
    	{
    		int MinVal;
    		int MaxVal;
    		C Choice;
    		SMultiChoice(void) : MinVal(0), MaxVal(0){};
    	};
    
    	int TotalVal;
    	TLinkedList<SMultiChoice*> *pChoiceList;
    
    public:
    	TMultiChoice(void) : TotalVal(0) // Constructor
    	{
    			 pChoiceList = new TLinkedList<SMultiChoice*>;
    	};
    	
    	~TMultiChoice(void) // Destructor
    	{
    		while(pChoiceList->Empty() == false)
    		{
    			SMultiChoice *pEntry = pChoiceList->Pop();
    			if (pEntry)
    				delete pEntry;
    			else
    				break;
    		}
    		delete pChoiceList;
    		pChoiceList = NULL;
    	}
    
    	void Insert(C Choice, short Percent = 50)
    	{
    		if (Percent == 0)
    			return;
    
    		SMultiChoice *pChoiceEntry = new SMultiChoice;
    		
    		pChoiceEntry->MinVal = TotalVal;
    		pChoiceEntry->MaxVal = TotalVal + Percent;
    		pChoiceEntry->Choice = Choice;
    
    		pChoiceList->AddNode(pChoiceEntry);
    
    		TotalVal += Percent;
    	};
    
    	bool FindSelection(SMultiChoice *MS, int Choice)
    	{
    		if ((Choice >= MS->MinVal) && (Choice < MS->MaxVal))
    		{
    			return true;
    		}
    		return false;
    	}
    
    	void ClearChoices(void)
    	{
    		TotalVal = 0;
    		while(pChoiceList->Empty() == false)
    			delete pChoiceList->Pop();
    	}
    
    	bool GetSelection(C &Var)
    	{
    		int Choice = RandomLong(0, (TotalVal - 1));
    		TLinkedList<SMultiChoice*>::node_s *pNode = pChoiceList->GetFirst();
    
    		while(pNode)
    		{
 			if ((Choice >= pNode->Entry->MinVal) && (Choice < pNode->Entry->MaxVal))
    			{
 				Var = pNode->Entry->Choice;
    				return true;
    			}
    			pNode = pNode->next;
    		}
    
    		return false;
    	}
    };
Used if there are things to select, like weapons, where each choice has a different score. For example:

Code:
   TMultiChoice WeaponChoices;
    
    WeaponChoices.Insert(GUN_FIST, 20);
    WeaponChoices.Insert(GUN_RIFLE, 50); // Higher chance for rifle

Here something new in the cube bot: used when bots have an enemy and still want an item(ammo etc). They will strafe to it but keep aiming(and shooting) at their enemy.

Code:
   			   vec v = { m_pTargetEnt->x, m_pTargetEnt->y,
 						 S(m_pTargetEnt->x, m_pTargetEnt->y)->floor+m_pMyEnt->eyeheight };
   			   vec v2, forward, right, up, cross;
   			   float flDot;
   
  			 AnglesToVectors(GetViewAngles(), forward, right, up);
   
   			   v2 = v;
   			   vsub(v2, m_pMyEnt->o);
   			   v2.z = 0.0f; // Make 2D
   			   v2 = Normalize(v2);
   			   forward.z = 0; // Make 2D
   		  
   			   flDot = dotprod(v2 , forward);
   			   cross = CrossProduct(v2, forward);
   			   
   			   bool IsLeft = (cross.z < -0.1f);
   			   bool IsRight = (cross.z > 0.1f);
   			   bool IsBehind = (flDot < 0.1f);
   			   bool IsInFront = (flDot > 0.1f);
   			   
   			   particle_trail(1, 500, m_pMyEnt->o, v);
   
   			   EDirection eMoveDir = FORWARD;
 											 
 			 if (IsInFront && !IsLeft && !IsRight) // ent is straight forward
   			   {
   				    eMoveDir = FORWARD;
 				 m_pMyEnt->move = m_iMoveDir = 1; // move forward
 				 m_pMyEnt->strafe = m_iStrafeDir = 0; // Don't strafe
 			 }												 
 			 else if (IsBehind && !IsLeft && !IsRight) // Ent is straight behind bot
   			   {
   				    eMoveDir = BACKWARD;
 				 m_pMyEnt->move = m_iMoveDir = -1; // Move backward
 				 m_pMyEnt->strafe = m_iStrafeDir = 0; // Don't strafe
   			   }
 			 else if (!IsBehind && !IsInFront && IsLeft) // Ent is straight left
   			   {
   				    eMoveDir = LEFT;
 				 m_pMyEnt->move = m_iMoveDir = 0; // don't move back or forward
 				 m_pMyEnt->strafe = m_iStrafeDir = -1; // Strafe left
   			   }
 			 else if (!IsBehind && !IsInFront && IsRight) // Ent is straight right
   			   {
   				    eMoveDir = RIGHT;
 				 m_pMyEnt->move = m_iMoveDir = 0; // don't move back or forward
 				 m_pMyEnt->strafe = m_iStrafeDir = 1; // Strafe right
 			 }			 
 			 else if (IsInFront && IsLeft) // Ent is forward-left
   			   {
   				    eMoveDir = FORWARD_LEFT;
 				 m_pMyEnt->move = m_iMoveDir = 1; // Move forward
 				 m_pMyEnt->strafe = m_iStrafeDir = -1; // Strafe left
   			   }
 			 else if (IsInFront && IsRight) // Ent is forward-right
   			   {
   				    eMoveDir = FORWARD_RIGHT;
 				 m_pMyEnt->move = m_iMoveDir = 1; // Move forward
 				 m_pMyEnt->strafe = m_iStrafeDir = 1; // Strafe right
 			 }			 
 			 else if (IsBehind && IsLeft) // ent is backward-left
   			   {
   				    eMoveDir = BACKWARD_LEFT;
 				 m_pMyEnt->move = m_iMoveDir = -1; // Move backward
 				 m_pMyEnt->strafe = m_iStrafeDir = -1; // Strafe left
   			   }
 			 else if (IsBehind && IsRight) // ent is backward-right
   			   {
   				    eMoveDir = BACKWARD_RIGHT;
 				 m_pMyEnt->move = m_iMoveDir = -1; // Move backward
 				 m_pMyEnt->strafe = m_iStrafeDir = 1; // Strafe right
   			   }
   			   
  			 m_iCombatNavTime = lastmillis + RandomLong(125, 250);
   			   
   			   // Check if bot needs to jump
   			   vec from = m_pMyEnt->o;
   			   from.z -= 1.0f;
   			   if (!IsVisible(from, eMoveDir, 3.0f, false))
  				 m_pMyEnt->jumpnext = true;

Aiming in cube bot(maths obviously not by me )
Code:
  void CBot::AimToVec(const vec &o)
  {
  	 m_pMyEnt->targetpitch = atan2(o.z-m_pMyEnt->o.z, GetDistance(o))*180/PI;
  	 m_pMyEnt->targetyaw = -(float)atan2(o.x - m_pMyEnt->o.x, o.y -
 										 m_pMyEnt->o.y)/PI*180+180;
  }
Handy for rocketlaunchers:

Code:
  // Prediction:
  // - pos: Current position
  // - vel: Current velocity
  // - Time: In seconds, predict how far it is after Time seconds
  vec PredictPos(vec pos, vec vel, float Time)
  {
  	 float flVelLength = sqrt(vel.x*vel.x + vel.y*vel.y + vel.z*vel.z);
  	
  	 if (flVelLength <= 1.0)
  		  return pos; // don't bother with low velocities...
  
  	 float speed = flVelLength * Time;
  	 float flTemp = 1/flVelLength;
  	 vec vecNormalize;
  	 
  	 vecNormalize.x = vel.x * flTemp;
  	 vecNormalize.y = vel.y * flTemp;
  	 vecNormalize.z = vel.z * flTemp;
  	 
  	 vec v_src = pos;
  	 vmul(vecNormalize, speed);
  	 vec v_end = v_src;
  	 vadd(v_end, vecNormalize);
  	 
  	 return v_end;
  }
A* Function, was pretty happy when it was done:
Code:
  // return true when done calculating
  bool CBot::AStar()
  {
  	 if (!m_pCurrentGoalWaypoint || !m_pCurrentWaypoint)
  	 {
  		  m_bCalculatingAStarPath = false;
  		  return true;
  	 }
  
  	 // Ideas by PMB :
  	 // * Make locals static to speed up a bit
  	 // * MaxCycles per frame and make it fps dependent
  
  	 static int iMaxCycles;
  	 static int iCurrentCycles;
  	 static float newg;
  	 static waypoint_s *n, *n2;
  	 static TLinkedList<waypoint_s *>::node_s *pPath = NULL;
  
  	 iMaxCycles = 10 * BotManager.m_iFrameTime;
  	 iCurrentCycles = 0;
  
  	 if (!m_bCalculatingAStarPath)
  	 {
  		  m_pCurrentWaypoint->g = 0.0f;
 		 m_pCurrentWaypoint->f = m_pCurrentWaypoint->g + GetDistance(m_pCurrentGoalWaypoint->v_origin);
  		  m_pCurrentWaypoint->pParent = NULL;
  		  m_AStarOpenList.Clear();
  		  m_AStarClosedList.DeleteAllNodes();
  		  m_AStarOpenList.AddEntry(m_pCurrentWaypoint, m_pCurrentWaypoint->f);
  		  
  		  m_AStarNodeList.DeleteAllNodes();
  	 }
  
  	 while(!m_AStarOpenList.Empty())
  	 {
  		  if (iCurrentCycles >= iMaxCycles)
  		  {
  			   m_bCalculatingAStarPath = true;
  			   return false;
  		  }
  
  		  n = m_AStarOpenList.Pop();
  
  		  // Done with calculating
  		  if (n == m_pCurrentGoalWaypoint)
  		  {
  			   while(n)
  			   {
 				 m_AStarNodeList.PushNode(n);
  				    n = n->pParent;
  			   }
  
  			   m_AStarOpenList.Clear();
  			   m_AStarClosedList.DeleteAllNodes();
  
  			   m_bCalculatingAStarPath = false;
  			   return true;
  		  }
  
  		  pPath = n->ConnectedWPs.GetFirst();
  		  while(pPath)
  		  {
  			   n2 = pPath->Entry;
  
  			   newg = AStarCost(n, n2);
  
  			   if ((n2->g <= newg) &&
 				 ((m_AStarClosedList.IsInList(n2) || m_AStarOpenList.IsInList(n2, n2->f))))
  			   {
  				    pPath = pPath->next;
 					continue;
  			   }
  			   
  			   n2->pParent = n;
  			   n2->g = newg;
 			 n2->f = n2->g + GetDistance(n2->v_origin, m_pCurrentGoalWaypoint->v_origin);
  
  			   m_AStarClosedList.DeleteEntry(n2);
  
  			   if (!m_AStarOpenList.IsInList(n2, n2->f))
  			   {
 				 m_AStarOpenList.AddEntry(n2, n2->f);
  			   }
  			   pPath = pPath->next;
  		  }
  		  
  		  m_AStarClosedList.PushNode(n);
  		  iCurrentCycles++;
  	 }
  
  	 // Failed making path
  	 conoutf("Path failed");
  	 m_AStarOpenList.Clear();
  	 m_AStarClosedList.DeleteAllNodes();	 
  	 m_bCalculatingAStarPath = false;
  	 return true;
  }
And I saw this from a n00b somewhere at a forum
Code:
  int blah=0;
  blah++;
  blah++;
  blah++;
  blah++;

As usual most code is inspired by PMB, he has some nice ideas *hugs*
  
Reply With Quote