Exemple #1
0
///////////////////////////////////////////////////////////////////////
// Set bot to move to it's movetarget. (following node path)
///////////////////////////////////////////////////////////////////////
void ACEMV_MoveToGoal(edict_t *self, usercmd_t *ucmd)
{
	// If a rocket or grenade is around deal with it
	// Simple, but effective (could be rewritten to be more accurate)
	if(strcmp(self->movetarget->classname,"rocket")==0 ||
	   strcmp(self->movetarget->classname,"grenade")==0)
	{
		VectorSubtract (self->movetarget->s.origin, self->s.origin, self->move_vector);
		ACEMV_ChangeBotAngle(self);
		if(debug_mode)
			debug_printf("%s: Oh crap a rocket!\n",self->client->pers.netname);
		
		// strafe left/right
		if(rand()%1 && ACEMV_CanMove(self, MOVE_LEFT))
				ucmd->sidemove = -400;
		else if(ACEMV_CanMove(self, MOVE_RIGHT))
				ucmd->sidemove = 400;
		return;

	}
	else
	{
		// Set bot's movement direction
		VectorSubtract (self->movetarget->s.origin, self->s.origin, self->move_vector);
		ACEMV_ChangeBotAngle(self);
		ucmd->forwardmove = 400;
		return;
	}
}
// Set bot to move to it's moveTarget. (following node path)
void ACEMV_MoveToGoal(gentity_t * self)
{
	// if a rocket or grenade is around deal with it
	// simple, but effective (could be rewritten to be more accurate)
	if((strcmp(self->bs.moveTarget->classname, "rocket") == 0 || strcmp(self->bs.moveTarget->classname, "grenade") == 0))
	{
		VectorSubtract(self->bs.moveTarget->s.origin, self->client->ps.origin, self->bs.moveVector);
		ACEMV_ChangeBotAngle(self);

		if(ace_debug.integer)
			trap_SendServerCommand(-1, va("print \"%s: Oh crap a rocket!\n\"", self->client->pers.netname));

		//trap_SendServerCommand(-1, va("%s \"%s%c%c%s\"", mode == SAY_TEAM ? "tchat" : "chat", name, Q_COLOR_ESCAPE, color, message));

		// strafe left/right
		if(rand() % 1 && ACEMV_CanMove(self, MOVE_LEFT))
		{
			self->client->pers.cmd.rightmove = -127;
		}
		else if(ACEMV_CanMove(self, MOVE_RIGHT))
		{
			self->client->pers.cmd.rightmove = 127;
		}
		return;

	}
	else
	{
		// set bot's movement direction
		VectorSubtract(self->bs.moveTarget->s.origin, self->client->ps.origin, self->bs.moveVector);
		ACEMV_ChangeBotAngle(self);

		if(ACEMV_CanMove(self, MOVE_FORWARD))
			self->client->pers.cmd.forwardmove = 127;
		return;
	}
}
Exemple #3
0
///////////////////////////////////////////////////////////////////////
// Main movement code. (following node path)
///////////////////////////////////////////////////////////////////////
void ACEMV_Move(edict_t *self, usercmd_t *ucmd)
{
	vec3_t dist;
	int current_node_type=-1;
	int next_node_type=-1;
	int i;
		
	// Get current and next node back from nav code.
	if(!ACEND_FollowPath(self))
	{
		self->state = STATE_WANDER;
		self->wander_timeout = level.time + 1.0;
		return;
	}

	current_node_type = nodes[self->current_node].type;
	next_node_type = nodes[self->next_node].type;
		
	///////////////////////////
	// Move To Goal
	///////////////////////////
	if (self->movetarget)
		ACEMV_MoveToGoal(self,ucmd);

	////////////////////////////////////////////////////////
	// Platforms
	///////////////////////////////////////////////////////
	if(current_node_type != NODE_PLATFORM && next_node_type == NODE_PLATFORM)
	{
		// check to see if lift is down?
		for(i=0;i<num_items;i++)
			if(item_table[i].node == self->next_node)
				if(item_table[i].ent->moveinfo.state != STATE_BOTTOM)
				    return; // Wait for elevator
	}
	if(current_node_type == NODE_PLATFORM && next_node_type == NODE_PLATFORM)
	{
		// Move to the center
		self->move_vector[2] = 0; // kill z movement	
		if(VectorLength(self->move_vector) > 10)
			ucmd->forwardmove = 200; // walk to center
				
		ACEMV_ChangeBotAngle(self);
		
		return; // No move, riding elevator
	}

	////////////////////////////////////////////////////////
	// Jumpto Nodes
	///////////////////////////////////////////////////////
	if(next_node_type == NODE_JUMP || 
	  (current_node_type == NODE_JUMP && next_node_type != NODE_ITEM && nodes[self->next_node].origin[2] > self->s.origin[2]))
	{
		// Set up a jump move
		ucmd->forwardmove = 300;
                ucmd->upmove = 300;

		ACEMV_ChangeBotAngle(self);

		VectorCopy(self->move_vector,dist);
		VectorScale(dist,440,self->velocity);

		return;
	}
	
	////////////////////////////////////////////////////////
	// Ladder Nodes
	///////////////////////////////////////////////////////
	if(next_node_type == NODE_LADDER && nodes[self->next_node].origin[2] > self->s.origin[2])
	{
		// Otherwise move as fast as we can
		ucmd->forwardmove = 300; 
		self->velocity[2] = 320;
		
		ACEMV_ChangeBotAngle(self);
		
		return;

	}
	// If getting off the ladder
	if(current_node_type == NODE_LADDER && next_node_type != NODE_LADDER &&
	   nodes[self->next_node].origin[2] > self->s.origin[2])
	{
		ucmd->forwardmove = 300; 
		ucmd->upmove = 200;
		self->velocity[2] = 200;
		ACEMV_ChangeBotAngle(self);
		return;
	}

	////////////////////////////////////////////////////////
	// Water Nodes
	///////////////////////////////////////////////////////
	if(current_node_type == NODE_WATER)
	{
		// We need to be pointed up/down
		ACEMV_ChangeBotAngle(self);

		// If the next node is not in the water, then move up to get out.
		if(next_node_type != NODE_WATER && !(gi.pointcontents(nodes[self->next_node].origin) & MASK_WATER)) // Exit water
			ucmd->upmove = 300;
		
		ucmd->forwardmove = 300;
		return;

	}
	
	// Falling off ledge?
	if(!self->groundentity)
	{
		ACEMV_ChangeBotAngle(self);

		self->velocity[0] = self->move_vector[0] * 360;
		self->velocity[1] = self->move_vector[1] * 360;
	
		return;
	}
		
	// Check to see if stuck, and if so try to free us
	// Also handles crouching
 	if(VectorLength(self->velocity) < 37)
	{
		// Keep a random factor just in case....
		if(random() > 0.1 && ACEMV_SpecialMove(self, ucmd))
			return;
		
		self->s.angles[YAW] += random() * 180 - 90; 

		ucmd->forwardmove = 300;
		
		return;
	}

	// Otherwise move as fast as we can
	ucmd->forwardmove = 300; 

	ACEMV_ChangeBotAngle(self);
	
}
// Wandering code (based on old ACE movement code)
void ACEMV_Wander(gentity_t * self)
{
	vec3_t          tmp;

	// do not move
	if(self->bs.next_move_time > level.time)
		return;

	// Special check for elevators, stand still until the ride comes to a complete stop.
	/*
	 * FIXME
	 if(self->groundentity != NULL && self->groundentity->use == Use_Plat)
	 if(self->groundentity->moveinfo.state == STATE_UP || self->groundentity->moveinfo.state == STATE_DOWN) // only move when platform not
	 {
	 self->velocity[0] = 0;
	 self->velocity[1] = 0;
	 self->velocity[2] = 0;
	 self->next_move_time = level.time + 500;
	 return;
	 }

	 */

	// touched jumppad last Frame?
	if(self->s.groundEntityNum == ENTITYNUM_NONE)
	{
		if(VectorLength(self->client->ps.velocity) > 120)
		{
			VectorNormalize2(self->client->ps.velocity, tmp);

			if(AngleBetweenVectors(self->bs.moveVector, tmp) >= 120)
			{
				// we might have been knocked back by someone or something ..
				if(!self->bs.moveTarget)
				{
					VectorCopy(tmp, self->bs.moveVector);
					ACEMV_ChangeBotAngle(self);
				}
			}
		}

		//ACEMV_ChangeBotAngle(self);
		//self->client->ps.velocity[0] = self->bs.moveVector[0] * 360;
		//self->client->ps.velocity[1] = self->bs.moveVector[1] * 360;
		//return;
	}

	// is there a target to move to
	if(self->bs.moveTarget)
	{
		ACEMV_MoveToGoal(self);
	}

	// swimming?
	VectorCopy(self->client->ps.origin, tmp);
	tmp[2] += 24;

	if(trap_PointContents(tmp, self->s.number) & MASK_WATER)
	{
		// if drowning and no node, move up
		if(self->client->airOutTime > 0)
		{
			self->client->pers.cmd.upmove = 1;
			self->bs.viewAngles[PITCH] = -45;
		}
		else
			self->client->pers.cmd.upmove = 15;

		self->client->pers.cmd.forwardmove = 100;
	}
	else
	{
		//self->client->airOutTime = 0;    // probably shound not be messing with this, but
	}

	// lava?
	tmp[2] -= 48;
	if(trap_PointContents(tmp, self->s.number) & (CONTENTS_LAVA | CONTENTS_SLIME))
	{
		//  safe_bprintf(PRINT_MEDIUM,"lava jump\n");
		self->bs.viewAngles[YAW] += random() * 360 - 180;
		self->client->pers.cmd.forwardmove = 127;
		self->client->pers.cmd.upmove = 127;
		return;
	}

	// check for special movement if we have a normal move (have to test)
	if(VectorLength(self->client->ps.velocity) < 37)
	{
		//if(random() > 0.1 && ACEMV_SpecialMove(self))
		//  return; //removed this because when wandering, the last thing you want is bots jumping
		//over things and going off ledges.  It's better for them to just bounce around the map.

		self->bs.viewAngles[YAW] += random() * 180 - 90;

		if(ACEMV_CanMove(self, MOVE_FORWARD))
			self->client->pers.cmd.forwardmove = 127;
		else if(ACEMV_CanMove(self, MOVE_BACK))
			self->client->pers.cmd.forwardmove = -127;

		// if there is ground continue otherwise wait for next move
		if( /*!M_CheckBottom || */ self->s.groundEntityNum != ENTITYNUM_NONE)
		{
			if(ACEMV_CanMove(self, MOVE_FORWARD))
				self->client->pers.cmd.forwardmove = 127;
		}

		return;
	}

	if(ACEMV_CheckEyes(self))
		return;

	if(ACEMV_CanMove(self, MOVE_FORWARD))
		self->client->pers.cmd.forwardmove = 127;
}
// Main movement code. (following node path)
void ACEMV_Move(gentity_t * self)
{
	int             currentNodeType = -1;
	int             nextNodeType = -1;

	// get current and next node back from nav code.
	if(!ACEND_FollowPath(self))
	{
		self->bs.state = STATE_WANDER;
		self->bs.wander_timeout = level.time + 1000;

		// center view
		//self->bs.viewAngles[PITCH] = 0;   //-self->client->ps.delta_angles[PITCH];
		return;
	}

	currentNodeType = nodes[self->bs.currentNode].type;
	nextNodeType = nodes[self->bs.nextNode].type;

	// move to a selected goal, if any
	if(self->bs.moveTarget)
	{
		ACEMV_MoveToGoal(self);
	}

	// grapple
	/*
	   if(nextNodeType == NODE_GRAPPLE)
	   {
	   ACEMV_ChangeBotAngle(self);
	   ACEIT_ChangeWeapon(self, FindItem("grapple"));
	   self->client->pers.cmd.buttons = BUTTON_ATTACK;
	   return;
	   }
	   // Reset the grapple if hangin on a graple node
	   if(currentNodeType == NODE_GRAPPLE)
	   {
	   CTFPlayerResetGrapple(self);
	   return;
	   }
	 */

#if 0
	// check for platforms
	if(currentNodeType != NODE_PLATFORM && nextNodeType == NODE_PLATFORM)
	{
		// check to see if lift is down?
		for(i = 0; i < num_items; i++)
			if(item_table[i].node == self->bs.nextNode)
				if(item_table[i].ent->moverState != MOVER_POS1)
					return;		// Wait for elevator
	}
#endif

	if(currentNodeType == NODE_PLATFORM && nextNodeType == NODE_PLATFORM)
	{
		// move to the center
		self->bs.moveVector[2] = 0;	// kill z movement

		if(VectorLength(self->bs.moveVector) > 10)
			self->client->pers.cmd.forwardmove = 200;	// walk to center

		ACEMV_ChangeBotAngle(self);

		return;					// No move, riding elevator
	}

	// jumpto nodes
	if(nextNodeType == NODE_JUMP ||
	   (currentNodeType == NODE_JUMP && nextNodeType != NODE_ITEM &&
		nodes[self->bs.nextNode].origin[2] > self->client->ps.origin[2]))
	{
		// set up a jump move
		if(ACEMV_CanMove(self, MOVE_FORWARD))
			self->client->pers.cmd.forwardmove = 127;

		self->client->pers.cmd.upmove = 127;

		ACEMV_ChangeBotAngle(self);

		//VectorCopy(self->bs.moveVector, dist);
		//VectorScale(dist, 127, self->client->ps.velocity);
		return;
	}


	// ladder nodes
	/*
	   if(nextNodeType == NODE_LADDER && nodes[self->nextNode].origin[2] > self->s.origin[2])
	   {
	   // Otherwise move as fast as we can
	   self->client->pers.cmd.forwardmove = 400;
	   self->velocity[2] = 320;

	   ACEMV_ChangeBotAngle(self);

	   return;

	   }
	   // If getting off the ladder
	   if(currentNodeType == NODE_LADDER && nextNodeType != NODE_LADDER && nodes[self->nextNode].origin[2] > self->s.origin[2])
	   {
	   self->client->pers.cmd.forwardmove = 400;
	   self->client->pers.cmd.upmove = 200;
	   self->velocity[2] = 200;
	   ACEMV_ChangeBotAngle(self);
	   return;
	   }
	 */

	// water nodes
	if(currentNodeType == NODE_WATER)
	{
		// we need to be pointed up/down
		ACEMV_ChangeBotAngle(self);

		// ff the next node is not in the water, then move up to get out.
		if(nextNodeType != NODE_WATER && !(trap_PointContents(nodes[self->bs.nextNode].origin, self->s.number) & MASK_WATER))
		{
			// exit water
			self->client->pers.cmd.upmove = 127;
		}

		self->client->pers.cmd.forwardmove = 100;
		return;

	}

	// falling off ledge?
	if(self->s.groundEntityNum == ENTITYNUM_NONE)
	{
		ACEMV_ChangeBotAngle(self);

		//self->client->ps.velocity[0] = self->bs.moveVector[0] * 360;
		//self->client->ps.velocity[1] = self->bs.moveVector[1] * 360;
		return;
	}

	// check to see if stuck, and if so try to free us
	// also handles crouching
	if(VectorLength(self->client->ps.velocity) < 37)
	{
		// keep a random factor just in case....
		if(random() > 0.1 && ACEMV_SpecialMove(self))
			return;

		self->bs.viewAngles[YAW] += random() * 180 - 90;

		if(ACEMV_CanMove(self, MOVE_FORWARD))
			self->client->pers.cmd.forwardmove = 127;
		else if(ACEMV_CanMove(self, MOVE_BACK))
			self->client->pers.cmd.forwardmove = -127;
		return;
	}

	// otherwise move as fast as we can
	if(ACEMV_CanMove(self, MOVE_FORWARD))
		self->client->pers.cmd.forwardmove = 127;

	ACEMV_ChangeBotAngle(self);
}