⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 behavior.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 5 页
字号:
   gi.printf( "nextsearch: %f\n", nextsearch );
	}

void FindFlee::Begin
	(
	Actor &self
	)

	{
	if ( !anim.length() )
		{
		anim = "run";
		}

	movegoal = NULL;
	state = 0;
	}

qboolean	FindFlee::Evaluate
	(
	Actor &self
	)

	{
	if ( !movegoal )
		{
		state = 0;
		}

	switch( state )
		{
		case 0 :
         // Checking for flee node
			chase.Begin( self );
			movegoal = FindFleeNode( self );
			if ( !movegoal )
				{
            // Couldn't find any!
				return false;
				}

         // Found flee node, going to it
			if ( anim.length() && ( anim != self.animname ) )
				{
				self.SetAnim( anim );
				}

			state = 1;
			nextsearch = level.time + 1;

		case 1 :
			if ( chase.Evaluate( self ) )
				{
				if ( nextsearch < level.time )
					{
					state = 0;
					}
				return true;
				}

         // Reached cover
			if ( self.CanSeeEnemyFrom( self.worldorigin ) )
				{
				state = 0;
				}
         else
            {
            // standing
	   		self.SetAnim( "idle" );
		   	chase.End( self );
			   return false;
            }
			break;
		}

	return true;
	}

void FindFlee::End
	(
	Actor &self
	)

	{
	chase.End( self );
	}

/****************************************************************************

  FindEnemy Class Definition

****************************************************************************/

CLASS_DECLARATION( Behavior, FindEnemy, NULL );

ResponseDef FindEnemy::Responses[] =
	{
		{ &EV_Behavior_Args,			( Response )FindEnemy::SetArgs },
		{ NULL, NULL }
	};

void FindEnemy::SetArgs
	(
	Event *ev
	)

	{
	anim = ev->GetString( 2 );
	}

void FindEnemy::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

   gi.printf( "\nchase:\n" );
   chase.ShowInfo( self );

   gi.printf( "\nstate: %d\n", state );
   gi.printf( "nextsearch: %f\n", nextsearch );
   gi.printf( "anim: %s\n", anim.c_str() );
	}

void FindEnemy::Begin
	(
	Actor &self
	)

	{
	if ( !anim.length() )
		{
		anim = "run";
		}

	movegoal = NULL;
   lastSearchNode = NULL;
	state = 0;
	}

PathNode *FindEnemy::FindClosestSightNode
	(
	Actor &self
	)

	{
	int i;
	PathNode	*bestnode;
	float		bestdist;
	PathNode *node;
	Vector	delta;
	float		dist;
	Vector	pos;

   if ( self.currentEnemy )
      {
	   pos = self.currentEnemy->worldorigin;
      }
   else
      {
	   pos = self.worldorigin;
      }

	bestnode = NULL;
	bestdist = 999999999; // greater than ( 8192 * sqr(2) ) ^ 2 -- maximum squared distance
	for( i = 0; i <= ai_maxnode; i++ )
		{
		node = AI_GetNode( i );
		if ( node && ( ( node->occupiedTime <= level.time ) || ( node->entnum != self.entnum ) ) )
			{
			// get the distance squared (faster than getting real distance)
			delta = node->worldorigin - pos;
			dist = delta * delta;
			if ( ( dist < bestdist ) && self.CanSeeFrom( node->worldorigin, self.currentEnemy ) )
				{
				bestnode = node;
				bestdist = dist;
				}
			}
		}

	return bestnode;
	}

qboolean	FindEnemy::Evaluate
	(
	Actor &self
	)

	{
	if ( !self.currentEnemy )
		{
		return false;
		}

	if ( nextsearch < level.time )
		{
      // check if we should search for the first time
      if ( !lastSearchNode )
         {
         //gi.dprintf( "%d: %s(%d) first time\n", level.framenum, self.targetname.c_str(), self.entnum );
         state = 0;
         }
      else
         {
         // search less often if we're far away
			nextsearch = self.DistanceTo( self.currentEnemy ) * ( 1.0 / 512.0 );
         if ( nextsearch < 1 )
            {
            nextsearch = 1;
            }
         nextsearch += level.time;

         // don't search again if our enemy hasn't moved very far
         if ( !self.currentEnemy->WithinDistance( lastSearchPos, 256 ) )
            {
            //gi.dprintf( "%d: %s(%d) searching again\n", level.framenum, self.targetname.c_str(), self.entnum );
            state = 0;
            }
         }
		}

	switch( state )
		{
		case 0 :
			// Searching for enemy
			chase.Begin( self );
         lastSearchPos = self.currentEnemy->worldorigin;
         movegoal = PathManager.NearestNode( lastSearchPos, &self );
         if ( !movegoal )
            {
            movegoal = PathManager.NearestNode( lastSearchPos, &self, false );
            }
         lastSearchNode = movegoal;
			if ( movegoal )
				{
				Path *path;
				FindEnemyPath find;
            PathNode *from;

				find.heuristic.self = &self;
				find.heuristic.setSize( self.size );
				find.heuristic.entnum = self.entnum;

            from = PathManager.NearestNode( self.worldorigin, &self );
            if ( ( from == movegoal ) && ( self.DistanceTo( from->worldorigin ) < 8 ) )
               {
               movegoal = NULL;
               from = NULL;
               }
            
            if ( from )
               {
               path = find.FindPath( from, movegoal );
				   if ( path )
					   {
					   chase.SetGoal( movegoal );
					   chase.SetPath( path );
					   }
               else
                  {
                  movegoal = NULL;
                  }
               }
				}

			if ( !movegoal )
				{
            if ( self.CanSee( self.currentEnemy ) || ( !self.currentEnemy->groundentity && !self.waterlevel ) )
               {
					chase.SetGoalPos( self.currentEnemy->worldorigin );
               }
            else
               {
				   // Couldn't find enemy
               // since we can't reach em
               // clear out enemy state
               //
	            self.ClearEnemies();
				   return false;
               }
				}

         // Found enemy, going to it
			if ( anim.length() && ( anim != self.animname ) )
				{
				self.SetAnim( anim );
				}

			state = 1;

		case 1 :
			if ( self.CanShoot( self.currentEnemy, false ) )
				{
				// Reached enemy
				chase.End( self );
				return false;
				}

			if ( !chase.Evaluate( self ) )
				{
            state = 0;
				nextsearch = 0;
				}
			break;
		}

	return true;
	}

void FindEnemy::End
	(
	Actor &self
	)

	{
	chase.End( self );
	}

/****************************************************************************

  Hide Class Definition

****************************************************************************/

CLASS_DECLARATION( Behavior, Hide, NULL );

ResponseDef Hide::Responses[] =
	{
		{ &EV_Behavior_Args,			( Response )Hide::SetArgs },
		{ NULL, NULL }
	};

void Hide::SetArgs
	(
	Event *ev
	)

	{
	anim = ev->GetString( 2 );
	}

void Hide::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

   gi.printf( "\nhide:\n" );
   hide.ShowInfo( self );

   gi.printf( "\nanim: %s\n", anim.c_str() );
   gi.printf( "state: %d\n", state );
   gi.printf( "checktime: %f\n", checktime );
	}

void Hide::Begin
	(
	Actor &self
	)

	{
	if ( !anim.length() )
		{
		anim = "run";
		}

	state = 0;
	}

qboolean	Hide::Evaluate
	(
	Actor &self
	)

	{
	switch( state )
		{
		// init run for cover
		case 0 :
			state = 1;
			hide.Begin( self );
			if ( hide.Evaluate( self ) && anim.length() )
		      {
		      self.SetAnim( anim );
		      }
         else
            {
				hide.End( self );
            self.SetAnim( "crouch_down" );
				state = 2;
				checktime = level.time + 1;
            }
         break;


		// running for cover
		case 1 :
			if ( !hide.Evaluate( self ) )
				{
				hide.End( self );
            self.SetAnim( "crouch_down" );
				state = 2;
				checktime = level.time + 1;
				}
			break;

		// wait for a bit
		case 2 :
			if ( checktime < level.time )
				{
				checktime = level.time + 0.5f;
				if ( self.CanSeeEnemyFrom( self.worldorigin ) )
					{
			      hide.Begin( self );
			      if ( hide.Evaluate( self ) && anim.length() )
		            {
		            self.SetAnim( anim );
   			      state = 1;
		            }
               else
                  {
				      hide.End( self );
      				checktime = level.time + 2;
                  }
					}
				}
			break;
		}

	return true;
	}

void Hide::End
	(
	Actor &self
	)

	{
	hide.End( self );
   self.SetAnim( "crouch_down" );
	}

/****************************************************************************

  FleeAndRemove Class Definition

****************************************************************************/

CLASS_DECLARATION( Behavior, FleeAndRemove, NULL );

ResponseDef FleeAndRemove::Responses[] =
	{
		{ &EV_Behavior_Args,			( Response )FleeAndRemove::SetArgs },
		{ NULL, NULL }
	};

void FleeAndRemove::SetArgs
	(
	Event *ev
	)

	{
	anim = ev->GetString( 2 );
	}

void FleeAndRemove::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

   gi.printf( "\nfindflee:\n" );
   flee.ShowInfo( self );

   gi.printf( "\nanim: %s\n", anim.c_str() );
   gi.printf( "state: %d\n", state );
   gi.printf( "checktime: %f\n", checktime );
	}

void FleeAndRemove::Begin
	(
	Actor &self
	)

	{
	if ( !anim.length() )
		{
		anim = "run";
		}

	state = 0;
	}

qboolean	FleeAndRemove::Evaluate
	(
	Actor &self
	)

	{
   if ( !self.currentEnemy )
      {
      return false;
      }

	switch( state )
		{
		// init run for cover
		case 0 :
			state = 1;

	      if ( anim.length() )
		      {
		      self.SetAnim( anim );
		      }

			flee.Begin( self );

         // if we fail on the first try, probably can't flee.
			if ( !flee.Evaluate( self ) )
            {
            flee.End( self );
            return false;
            }
         return true;
         
		// running for cover
		case 1 :
			if ( !flee.Evaluate( self ) )
				{
				flee.End( self );
				state = 2;
				checktime = 0;
            self.SetAnim( "crouch_down" );
				}
			break;

		// wait for a bit
		case 2 :
			if ( checktime < level.time )
				{
				checktime = level.time + 1;
				if ( self.CanSeeEnemyFrom( self.worldorigin ) )
					{
					state = 0;
					}
            else
               {
         		self.PostEvent( EV_Remove, 0 );
               }
				}
			break;
		}

	return true;
	}

void FleeAndRemove::End
	(
	Actor &self
	)

	{
	flee.End( self );
   self.SetAnim( "crouch_down" );
	}

/****************************************************************************

  AimAndShoot Class Definition

****************************************************************************/

CLASS_DECLARATION( Behavior, AimAndShoot, NULL );

ResponseDef AimAndShoot::Responses[] =
	{
		{ &EV_Behavior_Args,			( Response )AimAndShoot::SetArgs },
		{ &EV_Behavior_AnimDone,	( Response )AimAndShoot::AnimDone },
		{ NULL, NULL }
	};

AimAndShoot::AimAndShoot()
	{
	maxshots = 1;
	numshots = 0;
	}

void AimAndShoot::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

   gi.printf( "\naim:\n" );
   aim.ShowInfo( self );

   gi.printf( "\nmode: %d\n", mode );
   gi.printf( "maxshots: %d\n", maxshots );
   gi.printf( "numshots: %d\n", numshots );
   gi.printf( "animdone: %d\n", animdone );
	}

void AimAndShoot::Begin
	(
	Actor &self
	)

	{
   enemy_health = 0;
	mode = 0;
	animdone = false;

   readyfireanim = animprefix + "readyfire";
   if ( !self.HasAnim( readyfireanim.c_str() ) )
		{
      readyfireanim = "";
      }

   aimanim = animprefix + "aim";
   if ( !self.HasAnim( aimanim.c_str() ) )
		{
      aimanim = "";
      }

   fireanim = animprefix + "fire";
   if ( !self.HasAnim( fireanim.c_str() ) )
		{
      fireanim = "";
      }
   }

void AimAndShoot::SetMaxShots
	(
	int num
	)

	{
	maxshots = (num>>1) + G_Random( num );
	}

void AimAndShoot::SetArgs
	(
	Event *ev
	)

	{
	SetMaxShots( ev->GetInteger( 2 ) );
   if ( ev->NumArgs() > 2 )
      {
      animprefix = ev->GetString( 3 );
      }
	}

void AimAndShoot::AnimDone
	(
	Event *ev
	)

	{
	animdone = true;
	}

qboolean	AimAndShoot::Evaluate
	(
	Actor &self
	)

	{
	switch( mode )
		{
		case 0 :
         if ( !self.currentEnemy )
            {
            return false;
            }

			if ( !self.CanShoot( self.currentEnemy, false ) )
            {
            return false;
            }

         if ( readyfireanim.length() )
				{
				animdone = false;
				self.SetAnim( readyfireanim.c_str(), EV_Actor_NotifyBehavior );
				aim.Begin( self );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -