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

📄 behavior.cpp

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

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

		follow.steeringforce += avoid.steeringforce;
		}

	self.Accelerate( follow.steeringforce );

	return true;
	}

void Flee::End
	(
	Actor &self
	)

	{
	avoid.End( self );
	follow.End( self );
	path = NULL;
	}

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

  OpenDoor Class Definition

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

CLASS_DECLARATION( Behavior, OpenDoor, NULL );

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

OpenDoor::OpenDoor()
	{
	usedir = false;
	}

void OpenDoor::SetArgs
	(
	Event *ev
	)

	{
	if ( ev->NumArgs() > 1 )
		{
		dir = ev->GetVector( 2 );
		//usedir = true;
		}
	}

void OpenDoor::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

   gi.printf( "\ntime: %f\n", time );
   gi.printf( "endtime: %f\n", endtime );
   gi.printf( "usedir: %d\n", usedir );
   gi.printf( "dir: ( %f, %f, %f )\n", dir.x, dir.y, dir.z );
	}

void OpenDoor::Begin
	(
	Actor &self
	)

	{
	Event		*e;
	trace_t	trace;
	Entity	*ent;
	Vector	pos;
	Vector	end;

	endtime = 0;

	pos = self.worldorigin + self.eyeposition;
	if ( usedir )
		{
		end = pos + dir;
		}
	else
		{
		end = pos + Vector( self.orientation[ 0 ] ) * 64;
		}

	trace = G_Trace( pos, vec_zero, vec_zero, end, &self, self.edict->clipmask, "OpenDoor 1" );

	ent = trace.ent->entity;
	if ( ent && ent->isSubclassOf( Door ) )
		{
		self.SetAnim( "idle" );

		time = level.time + 0.1;
		endtime = time + 1;

		e = new Event( EV_Use );
		e->AddEntity( &self );
		ent->ProcessEvent( e );
		}
	}

qboolean	OpenDoor::Evaluate
	(
	Actor &self
	)

	{
	trace_t	trace;
	Vector	pos;

	if ( level.time > endtime )
		{
		return false;
		}

	if ( time < level.time )
		{
		pos = self.worldorigin + self.eyeposition;
		trace = G_Trace( pos, self.mins, self.maxs, pos + Vector( self.orientation[ 0 ] ) * 32, &self, self.edict->clipmask, "OpenDoor 2" );
		if ( trace.fraction == 1 )
			{
			return false;
			}
		}

	return true;
	}

void OpenDoor::End
	(
	Actor &self
	)

	{
	}

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

  PlayAnim Class Definition

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

CLASS_DECLARATION( Behavior, PlayAnim, NULL );

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

void PlayAnim::SetArgs
	(
	Event *ev
	)

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

void PlayAnim::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

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

void PlayAnim::Begin
	(
	Actor &self
	)

	{
	if ( anim.length() )
		{
		if ( !self.SetAnim( anim, EV_Actor_FinishedBehavior ) )
         {
         //warning( "Begin", "%s does not exist for %s.", anim.c_str(), self.targetname.c_str() );
         self.PostEvent( EV_Actor_FinishedBehavior, 0 );
         }
		}
	}

qboolean	PlayAnim::Evaluate
	(
	Actor &self
	)

	{
	return true;
	}

void PlayAnim::End
	(
	Actor &self
	)

	{
	}

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

  Wander Class Definition

****************************************************************************/
/*
CLASS_DECLARATION( Behavior, Wander, NULL );

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

void Wander::SetArgs
	(
	Event *ev
	)

	{
	anim = ev->GetString( 2 );
   maxdistance = ev->GetFloat( 3 );
   maxdistance *= maxdistance;
	}

PathNode *Wander::FindWanderNode
	(
	Actor &self
	)

	{
	int i;
	PathNode	*bestnode;
	PathNode *node;
	FindCoverPath find;
	Path		*path;
	Vector	delta;
	float		dist;
	Vector	pos;
   int      count = 0;

	pos = self.worldorigin;
   bestnode = NULL;

   for ( i = 0; i < 5; i++ )
      {
      node = AI_GetNode( G_Random( ai_maxnode + 1 ) );
      
      if ( !node )
         continue;

      delta = node->worldorigin - pos;
      dist = delta * delta;
      if ( ( dist > 1024 ) && ( dist < maxdistance ) )
         {
         bestnode = node;
         break;
         }
      }
   
	if ( bestnode )
		{
		find.heuristic.self = &self;
		find.heuristic.setSize( self.size );
		find.heuristic.entnum = self.entnum;

		path = find.FindPath( self.worldorigin, bestnode->worldorigin );
		if ( path )
			{
			node = path->End();
			// Mark node as occupied for a short time
			node->occupiedTime = level.time + 1.5;
			node->entnum = self.entnum;
			chase.SetGoal( node );
			chase.SetPath( path );
			return node;
			}
      }
   return NULL;
	}

void Wander::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

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

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

void Wander::Begin
	(
	Actor &self
	)

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

	movegoal = NULL;
	state = 0;
	}

qboolean	Wander::Evaluate
	(
	Actor &self
	)

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

	switch( state )
		{
		case 0 :
			chase.Begin( self );
			movegoal = FindWanderNode( self );
			if ( !movegoal )
				{
				return false;
				}
			if ( anim.length() && ( anim != self.animname ) )
				{
				self.SetAnim( anim );
				}

			state = 1;
         
		case 1 :
			if ( chase.Evaluate( self ) )
				{
				return true;
				}

         // Look for another wander node
			state = 0;
			chase.End( self );
			return false;
			break;
		}
	return true;
	}

void Wander::End
	(
	Actor &self
	)

	{
	chase.End( self );
	}
*/

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

  FindCover Class Definition

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

CLASS_DECLARATION( Behavior, FindCover, NULL );

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

void FindCover::SetArgs
	(
	Event *ev
	)

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

PathNode *FindCover::FindCoverNode
	(
	Actor &self
	)

	{
	int i;
	PathNode	*bestnode;
	float		bestdist;
	PathNode	*desperatebestnode;
	float		desperatebestdist;
	PathNode *node;
	FindCoverPath find;
	Path		*path;
	Vector	delta;
	float		dist;
	Vector	pos;

	pos = self.worldorigin;

	bestnode = NULL;
	bestdist = 999999999; // greater than ( 8192 * sqr(2) ) ^ 2 -- maximum squared distance
	desperatebestnode = NULL;
	desperatebestdist = 999999999; // greater than ( 8192 * sqr(2) ) ^ 2 -- maximum squared distance
	for( i = 0; i <= ai_maxnode; i++ )
		{
		node = AI_GetNode( i );
		if ( node && ( node->nodeflags & ( AI_DUCK | AI_COVER ) ) &&
			( ( 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.CanSeeEnemyFrom( node->worldorigin ) ||//) )//||
				( ( node->nodeflags & AI_DUCK ) && !self.CanSeeEnemyFrom( node->worldorigin - Vector( 0, 0, 32 ) ) ) ) )
				{
				bestnode = node;
				bestdist = dist;
				}
			else if ( ( dist < desperatebestdist ) && ( desperatebestdist > ( 64 * 64 ) ) )
				{
				desperatebestnode = node;
				desperatebestdist = dist;
				}
			}
		}

	if ( !bestnode )
		{
		bestnode = desperatebestnode;
		}

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

		path = find.FindPath( self.worldorigin, bestnode->worldorigin );
		if ( path )
			{
			node = path->End();

			// Mark node as occupied for a short time
			node->occupiedTime = level.time + 1.5;
			node->entnum = self.entnum;

			chase.SetGoal( node );
			chase.SetPath( path );

			return node;
			}
		}

	return NULL;
	}

void FindCover::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

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

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

void FindCover::Begin
	(
	Actor &self
	)

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

	movegoal = NULL;
	state = 0;
	}

qboolean	FindCover::Evaluate
	(
	Actor &self
	)

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

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

			// Found cover, 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;
				}

			if ( movegoal->nodeflags & AI_DUCK )
				{
            // ducking
				self.SetAnim( "crouch_down" );
				}
			else
				{
            // standing
				self.SetAnim( "idle" );
				}

			chase.End( self );
			return false;
			break;
		}

	return true;
	}

void FindCover::End
	(
	Actor &self
	)

	{
	chase.End( self );
	}

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

  FindFlee Class Definition

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

CLASS_DECLARATION( Behavior, FindFlee, NULL );

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

void FindFlee::SetArgs
	(
	Event *ev
	)

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

PathNode *FindFlee::FindFleeNode
	(
	Actor &self
	)

	{
	int i;
	PathNode	*bestnode;
	float		bestdist;
	PathNode	*desperatebestnode;
	float		desperatebestdist;
	PathNode *node;
	FindFleePath find;
	Path		*path;
	Vector	delta;
	float		dist;
	Vector	pos;

	pos = self.worldorigin;

	bestnode = NULL;
	bestdist = 999999999; // greater than ( 8192 * sqr(2) ) ^ 2 -- maximum squared distance
	desperatebestnode = NULL;
	desperatebestdist = 999999999; // greater than ( 8192 * sqr(2) ) ^ 2 -- maximum squared distance
	for( i = 0; i <= ai_maxnode; i++ )
		{
		node = AI_GetNode( i );
		if ( node && ( node->nodeflags & AI_FLEE ) &&
			( ( 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.CanSeeEnemyFrom( node->worldorigin ) )
				{
				bestnode = node;
				bestdist = dist;
				}
			else if ( ( dist < desperatebestdist ) && ( desperatebestdist > ( 64 * 64 ) ) )
				{
				desperatebestnode = node;
				desperatebestdist = dist;
				}
			}
		}

	if ( !bestnode )
		{
		bestnode = desperatebestnode;
		}

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

		path = find.FindPath( self.worldorigin, bestnode->worldorigin );
		if ( path )
			{
			node = path->End();

			// Mark node as occupied for a short time
			node->occupiedTime = level.time + 1.5;
			node->entnum = self.entnum;

			chase.SetGoal( node );
			chase.SetPath( path );

			return node;
			}
		}

	return NULL;
	}

void FindFlee::ShowInfo
	(
	Actor &self
	)

	{
   Behavior::ShowInfo( self );

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

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

⌨️ 快捷键说明

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