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

📄 behavior.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 5 页
字号:

void FireOnSight::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

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

   gi.printf( "\naim:\n" );
   aim.ShowInfo( self );
   gi.printf( "\nmode : %d\n", mode );
   gi.printf( "anim : %s\n", anim.c_str() );
	}

void FireOnSight::Begin
	(
	Actor &self
	)

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

qboolean	FireOnSight::Evaluate
	(
	Actor &self
	)

	{
	if ( !self.currentEnemy || self.currentEnemy->deadflag || self.currentEnemy->health <= 0 )
		{
		return false;
		}

	switch( mode )
		{
		case 0 :
			// Start chasing
			self.SetAnim( anim );
			chase.Begin( self );
			mode = 1;

		case 1 :
			// Chasing
			if ( self.WeaponReady() && self.CanShoot( self.currentEnemy, false ) )
				{
				chase.End( self );
				self.SetAnim( "readyfire" );
				aim.Begin( self );
				mode = 2;
				break;
				}
			else 
				{
				self.Chatter( "snd_pursuit", 1 );
				}

			chase.SetTarget( self.currentEnemy );
			chase.Evaluate( self );
			break;

		case 2 :
			// Aiming
			aim.SetTarget( self.currentEnemy );
			aim.Evaluate( self );

			if ( self.WeaponReady() && self.CanShoot( self.currentEnemy, true ) )
				{
				self.Chatter( "snd_inmysights", 5 );
				self.SetAnim( "fire" );
				mode = 3;
				}
			else if ( !self.WeaponReady() || !self.CanShoot( self.currentEnemy, false ) )
				{
				aim.End( self );
				mode = 0;
				break;
				}
			break;

		case 3 :
			// Fire
			aim.SetTarget( self.currentEnemy );
			aim.Evaluate( self );
			if ( !self.CanShoot( self.currentEnemy, true ) )
				{
				self.SetAnim( "aim" );
				mode = 2;
				}
			else
				{
				self.Chatter( "snd_attacktaunt", 4 );
				}
			break;
		}

	return true;
	}

void FireOnSight::End
	(
	Actor &self
	)

	{
	chase.End( self );
	aim.End( self );
	}

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

  TurnTo Class Definition

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

CLASS_DECLARATION( Behavior, TurnTo, NULL );

ResponseDef TurnTo::Responses[] =
	{
		{ NULL, NULL }
	};

TurnTo::TurnTo()
	{
	dir = Vector( 1, 0, 0 );
	mode = 0;
	ent = NULL;
   yaw = 0;
	}

void TurnTo::SetDirection
	(
	float yaw
	)

	{
	Vector ang;

	ang = Vector( 0, yaw, 0 );
	this->yaw = anglemod( yaw );
	ang.AngleVectors( &dir, NULL, NULL );
	mode = 1;
	}

void TurnTo::SetTarget
	(
	Entity *ent
	)

	{
	this->ent = ent;
	mode = 2;
	}

void TurnTo::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

   gi.printf( "\nseek:\n" );
   seek.ShowInfo( self );

   if ( ent )
      {
      gi.printf( "\nent: #%d '%s'\n", ent->entnum, ent->targetname.c_str() );
      }
   else
      {
      gi.printf( "\nent: NULL\n" );
      }
   
   gi.printf( "dir: ( %f, %f, %f )\n", dir.x, dir.y, dir.z );
   gi.printf( "yaw: %f\n", yaw );
   gi.printf( "mode: %d\n", mode );
	}

void TurnTo::Begin
	(
	Actor &self
	)

	{
	seek.Begin( self );
	}

qboolean	TurnTo::Evaluate
	(
	Actor &self
	)

	{
	Vector delta;
	float ang;

	switch( mode )
		{
		case 1 :
			ang = angledist( yaw - self.angles.yaw() );
			if ( fabs( ang ) < 1 )
				{
				self.Accelerate( Vector( 0, ang, 0 ) );
				return false;
				}

			seek.SetTargetPosition( self.worldorigin + dir );
			seek.SetTargetVelocity( vec_zero );
			break;

		case 2 :
			if ( !ent )
				{
				return false;
				}

			delta = ent->worldorigin - self.worldorigin;
			yaw = delta.toYaw();
			//if ( self.angles.yaw() == yaw )
			//	{
			//	return false;
			//	}

			seek.SetTargetPosition( ent->worldorigin );
			seek.SetTargetVelocity( vec_zero );
			break;

		default :
			return false;
		}

	seek.SetPosition( self.worldorigin );
	seek.SetDir( self.movedir );
	seek.SetMaxSpeed( self.movespeed );
	seek.Evaluate( self );
	//seek.DrawForces();

	self.Accelerate( seek.steeringforce );

	return true;
	}

void TurnTo::End
	(
	Actor &self
	)

	{
	seek.End( self );
	}

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

  GotoPathNode Class Definition

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

CLASS_DECLARATION( Behavior, GotoPathNode, NULL );

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

GotoPathNode::GotoPathNode()
	{
	usevec = false;
	movegoal = NULL;
	goal = vec_zero;
	goalent = NULL;
	}

void GotoPathNode::SetArgs
	(
	Event *ev
	)

	{
	anim = ev->GetString( 2 );
	
	if ( ev->IsVectorAt( 3 ) )
		{
		goal = ev->GetVector( 3 );
		usevec = true;
		}
	else
		{
      usevec = false;
		movegoal = AI_FindNode( ev->GetString( 3 ) );
		if ( !movegoal )
			{
			goalent = ev->GetEntity( 3 );
			}
		}
	}

void GotoPathNode::SetGoal
	(
	PathNode *node
	)

	{
	usevec = false;
	movegoal = node;
	}

void GotoPathNode::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

   gi.printf( "\nturnto:\n" );
   turnto.ShowInfo( self );

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

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

   if ( goalent )
      {
      gi.printf( "\ngoalent: #%d '%s'\n", goalent->entnum, goalent->targetname.c_str() );
      }
   else
      {
      gi.printf( "\ngoalent: NULL\n" );
      }
   
   gi.printf( "goal: ( %f, %f, %f )\n", goal.x, goal.y, goal.z );
	}

void GotoPathNode::Begin
	(
	Actor &self
	)

	{
	state = 0;
	chase.Begin( self );
	turnto.Begin( self );
	if ( goalent )
		{
		chase.SetTarget( goalent );
		}
	else if ( movegoal )
      {
      chase.SetGoal( movegoal );
      }
   else
		{
		chase.SetGoalPos( goal );
		}

   // don't check for new paths as often
   chase.SetPathRate( 4 );

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

qboolean	GotoPathNode::Evaluate
	(
	Actor &self
	)

	{
	float yaw;

	if ( !usevec && !goalent && !movegoal )
		{
		return false;
		}

	switch( state )
		{
		case 0 :
			if ( chase.Evaluate( self ) )
				{
				break;
				}

			state = 1;
			self.SetAnim( "idle" );

			// cascade down to case 1
		case 1 :
			if ( !movegoal )
				{
				return false;
				}

			if ( movegoal->setangles )
				{
				yaw = movegoal->worldangles.yaw();
				turnto.SetDirection( yaw );
				if ( turnto.Evaluate( self ) )
					{
					break;
					}
				}

			if ( movegoal->animname == "" )
				{
            self.SetAnim( "idle" );
				return false;
				}

			self.SetAnim( movegoal->animname, EV_Actor_FinishedBehavior );
			state = 2;
			break;

		case 2 :
			break;
		}

	return true;
	}

void GotoPathNode::End
	(
	Actor &self
	)

	{
	chase.End( self );
	}

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

  Investigate Class Definition

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

CLASS_DECLARATION( Behavior, Investigate, NULL );

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

void Investigate::SetArgs
	(
	Event *ev
	)

	{
	Entity *ent;
	Actor *self;

	ent = ev->GetEntity( 1 );
	if ( ent && ent->isSubclassOf( Actor ) )
		{
		self = ( Actor * )ent;
		}

	anim = ev->GetString( 2 );
	goal = ev->GetVector( 3 );
	}

void Investigate::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

   gi.printf( "\nchase:\n" );
   chase.ShowInfo( self );
   gi.printf( "\nanim: %s\n", anim.c_str() );
   gi.printf( "curioustime: %f\n", curioustime );
   gi.printf( "goal: ( %f, %f, %f )\n", goal.x, goal.y, goal.z );
	}

void Investigate::Begin
	(
	Actor &self
	)

	{
   //
   // we are only interested for about 10 seconds, if we can't get there, lets go back to what we were doing
   //
   curioustime = level.time + 10;
	self.Chatter( "snd_investigate", 10 );
	chase.Begin( self );
	chase.SetGoalPos( goal );

	// Don't allow guys to change their anim if we're already close enough to the goal
	if ( !Done( self ) && anim.length() )
		{
		self.SetAnim( anim );
		}
	}

qboolean Investigate::Done
	(
	Actor &self
	)

	{
	Vector delta;
	float xydist;

   if ( curioustime < level.time )
      {
      return true;
      }

	if ( self.CanSeeEnemyFrom( self.worldorigin ) )
		{
		return true;
		}

   if ( self.lastmove == STEPMOVE_STUCK )
      {
      return true;
      }
	delta = goal - self.worldorigin;
   // 
   // get rid of Z variance
   //
   delta[ 2 ] = 0;
   xydist = delta.length();
	if ( xydist < 100 )
		{
		return true;
		}

	return false;
	}

qboolean	Investigate::Evaluate
	(
	Actor &self
	)

	{
	if ( Done( self ) || !chase.Evaluate( self ) )
		{
		return false;
		}

	return true;
	}

void Investigate::End
	(
	Actor &self
	)

	{
	chase.End( self );
	}

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

  Flee Class Definition

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

CLASS_DECLARATION( Behavior, Flee, NULL );

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

void Flee::SetArgs
	(
	Event *ev
	)

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

void Flee::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

   gi.printf( "\nfollow:\n" );
   follow.ShowInfo( self );

   if ( path )
      {
      gi.printf( "\npath : ( %f, %f, %f ) to ( %f, %f, %f )\n", 
         path->Start()->worldorigin.x, path->Start()->worldorigin.y, path->Start()->worldorigin.z, 
         path->End()->worldorigin.x, path->End()->worldorigin.y, path->End()->worldorigin.z );
      }
   else
      {
      gi.printf( "\npath : NULL\n" );
      }

   gi.printf( "\navoid:\n" );
   avoid.ShowInfo( self );

   gi.printf( "\navoidtime: %f\n", avoidtime );
   gi.printf( "anim: %s\n", anim.c_str() );
	}

void Flee::Begin
	(
	Actor &self
	)

	{
	follow.Begin( self );
   avoid.AvoidWalls( false );
	avoid.Begin( self );
	avoidtime = 0;

	path = NULL;

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

qboolean	Flee::Evaluate
	(
	Actor &self
	)

	{
	PathNode *node;
	int i;

	self.Chatter( "snd_panic", 3 );

	if ( path && follow.DoneWithPath( self ) )
		{
		path = NULL;

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

	if ( !path )
		{
		for( i = 0; i < 5; i++ )
			{
			node = AI_GetNode( ( int )G_Random( ai_maxnode + 1 ) );
			if ( node )
				{
				break;
				}
			}

		if ( node )
			{
			path = follow.SetPath( self, self.worldorigin, node->worldorigin );
			}
		else
			{
			return false;
			}
		}

	follow.SetPosition( self.worldorigin );
	follow.SetDir( self.movedir );
	follow.SetMaxSpeed( self.movespeed );
	follow.Evaluate( self );

	if ( avoidtime < level.time )
		{
		avoidtime = level.time + 0.4;

⌨️ 快捷键说明

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