Beispiel #1
0
///////////////////////////////////////////////////////////////////////
// Check for adding ladder nodes
///////////////////////////////////////////////////////////////////////
qboolean ACEND_CheckForLadder(edict_t *self)
{
	int closest_node;

	// If there is a ladder and we are moving up, see if we should add a ladder node
	if (gi.pointcontents(self->s.origin) & CONTENTS_LADDER && self->velocity[2] > 0)
	{
		//debug_printf("contents: %x\n",tr.contents);

		closest_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_LADDER); 
		if(closest_node == -1)
		{
			closest_node = ACEND_AddNode(self,NODE_LADDER);
	
			// Now add link
		    ACEND_UpdateNodeEdge(self->last_node,closest_node);	   
			
			// Set current to last
			self->last_node = closest_node;
		}
		else
		{
			ACEND_UpdateNodeEdge(self->last_node,closest_node);	   
			self->last_node = closest_node; // set visited to last
		}
		return true;
	}
	return false;
}
Beispiel #2
0
///////////////////////////////////////////////////////////////////////
// Capture when the grappling hook has been fired for mapping purposes.
///////////////////////////////////////////////////////////////////////
void ACEND_GrapFired(edict_t *self)
{
	int closest_node;
	
	if(!self->owner)
		return; // should not be here
	
	// Check to see if the grapple is in pull mode
	if(self->owner->client->ctf_grapplestate == CTF_GRAPPLE_STATE_PULL)
	{
		// Look for the closest node of type grapple
		closest_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_GRAPPLE);
		if(closest_node == -1 ) // we need to drop a node
		{	
			closest_node = ACEND_AddNode(self,NODE_GRAPPLE);
			 
			// Add an edge
			ACEND_UpdateNodeEdge(self->owner->last_node,closest_node);
		
			self->owner->last_node = closest_node;
		}
		else
			self->owner->last_node = closest_node; // zero out so other nodes will not be linked
	}
}
Beispiel #3
0
///////////////////////////////////////////////////////////////////////
// Special command processor
///////////////////////////////////////////////////////////////////////
qboolean ACECM_Commands(edict_t *ent)
{
    char *cmd;
    int  node;

    cmd = gi.argv(0);

    if ((Q_strcasecmp(cmd, "addnode") == 0) && debug_mode)
    {
        ent->last_node = ACEND_AddNode(ent, atoi(gi.argv(1)));
    }

    else if ((Q_strcasecmp(cmd, "removelink") == 0) && debug_mode)
    {
        ACEND_RemoveNodeEdge(ent, atoi(gi.argv(1)), atoi(gi.argv(2)));
    }

    else if ((Q_strcasecmp(cmd, "addlink") == 0) && debug_mode)
    {
        ACEND_UpdateNodeEdge(atoi(gi.argv(1)), atoi(gi.argv(2)));
    }

    else if ((Q_strcasecmp(cmd, "showpath") == 0) && debug_mode)
    {
        ACEND_ShowPath(ent, atoi(gi.argv(1)));
    }

    else if ((Q_strcasecmp(cmd, "findnode") == 0) && debug_mode)
    {
        node = ACEND_FindClosestReachableNode(ent, NODE_DENSITY, NODE_ALL);
        safe_bprintf(PRINT_MEDIUM, "node: %d type: %d x: %f y: %f z %f\n", node, nodes[node].type, nodes[node].origin[0], nodes[node].origin[1], nodes[node].origin[2]);
    }

    else if ((Q_strcasecmp(cmd, "movenode") == 0) && debug_mode)
    {
        node = atoi(gi.argv(1));
        nodes[node].origin[0] = atof(gi.argv(2));
        nodes[node].origin[1] = atof(gi.argv(3));
        nodes[node].origin[2] = atof(gi.argv(4));
        safe_bprintf(PRINT_MEDIUM, "node: %d moved to x: %f y: %f z %f\n", node, nodes[node].origin[0], nodes[node].origin[1], nodes[node].origin[2]);
    }

    else
    {
        return false;
    }

    return true;
}
Beispiel #4
0
///////////////////////////////////////////////////////////////////////
// Add a node of type ?
///////////////////////////////////////////////////////////////////////
int ACEND_AddNode(edict_t *self, int type)
{
	vec3_t v1,v2;
	
	// Block if we exceed maximum
	if (numnodes + 1 > MAX_NODES)
		return false;
	
	// Set location
	VectorCopy(self->s.origin,nodes[numnodes].origin);

	// Set type
	nodes[numnodes].type = type;

	/////////////////////////////////////////////////////
	// ITEMS
	// Move the z location up just a bit.
	if(type == NODE_ITEM)
	{
		nodes[numnodes].origin[2] += 16;
		numitemnodes++;
	}

	// Teleporters
	if(type == NODE_TELEPORTER)
	{
		// Up 32
		nodes[numnodes].origin[2] += 32;
	}

	if(type == NODE_LADDER)
	{
		nodes[numnodes].type = NODE_LADDER;
				
		if(debug_mode)
		{
			debug_printf("Node added %d type: Ladder\n",numnodes);
			ACEND_ShowNode(numnodes);
		}
		
		numnodes++;
		return numnodes-1; // return the node added

	}

	// For platforms drop two nodes one at top, one at bottom
	if(type == NODE_PLATFORM)
	{
		VectorCopy(self->maxs,v1);
		VectorCopy(self->mins,v2);
		
		// To get the center
		nodes[numnodes].origin[0] = (v1[0] - v2[0]) / 2 + v2[0];
		nodes[numnodes].origin[1] = (v1[1] - v2[1]) / 2 + v2[1];
		nodes[numnodes].origin[2] = self->maxs[2];
			
		if(debug_mode)	
			ACEND_ShowNode(numnodes);
		
		numnodes++;

		nodes[numnodes].origin[0] = nodes[numnodes-1].origin[0];
		nodes[numnodes].origin[1] = nodes[numnodes-1].origin[1];
		nodes[numnodes].origin[2] = self->mins[2]+64;
		
		nodes[numnodes].type = NODE_PLATFORM;

		// Add a link
		ACEND_UpdateNodeEdge(numnodes,numnodes-1);			
		
		if(debug_mode)
		{
			debug_printf("Node added %d type: Platform\n",numnodes);
			ACEND_ShowNode(numnodes);
		}

		numnodes++;

		return numnodes -1;
	}
		
	if(debug_mode)
	{
		if(nodes[numnodes].type == NODE_MOVE)
			debug_printf("Node added %d type: Move\n",numnodes);
		else if(nodes[numnodes].type == NODE_TELEPORTER)
			debug_printf("Node added %d type: Teleporter\n",numnodes);
		else if(nodes[numnodes].type == NODE_ITEM)
			debug_printf("Node added %d type: Item\n",numnodes);
		else if(nodes[numnodes].type == NODE_WATER)
			debug_printf("Node added %d type: Water\n",numnodes);
		else if(nodes[numnodes].type == NODE_GRAPPLE)
			debug_printf("Node added %d type: Grapple\n",numnodes);

		ACEND_ShowNode(numnodes);
	}
		
	numnodes++;
	
	return numnodes-1; // return the node added
}
Beispiel #5
0
///////////////////////////////////////////////////////////////////////
// This routine is called to hook in the pathing code and sets
// the current node if valid.
///////////////////////////////////////////////////////////////////////
void ACEND_PathMap(edict_t *self)
{
	int closest_node;
	static float last_update=0; // start off low
	vec3_t v;

	if(level.time < last_update)
		return;

	last_update = level.time + 0.15; // slow down updates a bit

	// Special node drawing code for debugging
    if(show_path_to != -1)
		ACEND_DrawPath();
	
	////////////////////////////////////////////////////////
	// Special check for ladder nodes
	///////////////////////////////////////////////////////
	if(ACEND_CheckForLadder(self)) // check for ladder nodes
		return;

	// Not on ground, and not in the water, so bail
    if(!self->groundentity && !self->waterlevel)
		return;

	////////////////////////////////////////////////////////
	// Lava/Slime
	////////////////////////////////////////////////////////
	VectorCopy(self->s.origin,v);
	v[2] -= 18;
	if(gi.pointcontents(v) & (CONTENTS_LAVA|CONTENTS_SLIME))
		return; // no nodes in slime
	
    ////////////////////////////////////////////////////////
	// Jumping
	///////////////////////////////////////////////////////
	if(self->is_jumping)
	{
	   // See if there is a closeby jump landing node (prevent adding too many)
		closest_node = ACEND_FindClosestReachableNode(self, 64, NODE_JUMP);

		if(closest_node == INVALID)
			closest_node = ACEND_AddNode(self,NODE_JUMP);
		
		// Now add link
		if(self->last_node != -1)
			ACEND_UpdateNodeEdge(self->last_node, closest_node);	   

		self->is_jumping = false;
		return;
	}

	////////////////////////////////////////////////////////////
	// Grapple
	// Do not add nodes during grapple, added elsewhere manually
	////////////////////////////////////////////////////////////
	if(ctf->value && self->client->ctf_grapplestate == CTF_GRAPPLE_STATE_PULL)
		return;
	 
	// Iterate through all nodes to make sure far enough apart
	closest_node = ACEND_FindClosestReachableNode(self, NODE_DENSITY, NODE_ALL);

	////////////////////////////////////////////////////////
	// Special Check for Platforms
	////////////////////////////////////////////////////////
	if(self->groundentity && self->groundentity->use == Use_Plat)
	{
		if(closest_node == INVALID)
			return; // Do not want to do anything here.

		// Here we want to add links
		if(closest_node != self->last_node && self->last_node != INVALID)
			ACEND_UpdateNodeEdge(self->last_node,closest_node);	   

		self->last_node = closest_node; // set visited to last
		return;
	}
	 
	 ////////////////////////////////////////////////////////
	 // Add Nodes as needed
	 ////////////////////////////////////////////////////////
	 if(closest_node == INVALID)
	 {
		// Add nodes in the water as needed
		if(self->waterlevel)
			closest_node = ACEND_AddNode(self,NODE_WATER);
		else
		    closest_node = ACEND_AddNode(self,NODE_MOVE);
		
		// Now add link
		if(self->last_node != -1)
			ACEND_UpdateNodeEdge(self->last_node, closest_node);	   
			
	 }
	 else if(closest_node != self->last_node && self->last_node != INVALID)
	 	ACEND_UpdateNodeEdge(self->last_node,closest_node);	   
	
	 self->last_node = closest_node; // set visited to last
	
}
Beispiel #6
0
// This routine is called to hook in the pathing code and sets
// the current node if valid.
void ACEND_PathMap(gentity_t * self)
{
	int             closestNode;
	static float    lastUpdate = 0;	// start off low
	vec3_t          v;
	//qboolean        isJumping;
	//int             i;

#if 0
	if(level.time < lastUpdate)
		return;
#endif

	lastUpdate = level.time + 150;	// slow down updates a bit

#if 0
	if(self->r.svFlags & SVF_BOT)
		return;
#endif

	// don't add links when you went into a trap
	if(self->health <= 0)
		return;

#if 1
	if(self->s.groundEntityNum == ENTITYNUM_NONE && !(self->r.svFlags & SVF_BOT))
	{
#if 0
		isJumping = qfalse;
		for(i = 0; i < self->client->ps.eventSequence; i++)
		{
			if(self->client->ps.events[i] == EV_JUMP)
				isJumping = qtrue;
		}

		if(isJumping)
#else
		if((self->client->ps.pm_flags & PMF_JUMP_HELD))
#endif
		{
			if(ace_debug.integer)
				trap_SendServerCommand(-1, va("print \"%s: jumping\n\"", self->client->pers.netname));

			// see if there is a closeby jump landing node (prevent adding too many)
			closestNode = ACEND_FindClosestReachableNode(self, 64, NODE_JUMP);

			if(closestNode == INVALID)
				closestNode = ACEND_AddNode(self, NODE_JUMP);

			// now add link
			if(self->bs.lastNode != INVALID)
				ACEND_UpdateNodeEdge(self->bs.lastNode, closestNode);

			self->bs.isJumping = qfalse;
			return;
		}
	}
#endif

	// not on ground, and not in the water, so bail
	if(self->s.groundEntityNum == ENTITYNUM_NONE)
	{
		/*
		   if(self->bs.lastNode != INVALID)
		   {
		   // we might have been pushed by a jump pad
		   if(nodes[self->bs.lastNode].type != NODE_JUMPPAD)
		   return;
		   }
		   else if(!self->waterlevel)
		   {
		   return;
		   }
		 */
	}


	// lava / slime
	VectorCopy(self->client->ps.origin, v);
	v[2] -= 18;

	if(trap_PointContents(self->client->ps.origin, -1) & (CONTENTS_LAVA | CONTENTS_SLIME))
		return;					// no nodes in slime

	// Grapple
	// Do not add nodes during grapple, added elsewhere manually

	/*
	   if(ctf->value && self->client->ctf_grapplestate == CTF_GRAPPLE_STATE_PULL)
	   return;
	 */

	// iterate through all nodes to make sure far enough apart
	closestNode = ACEND_FindClosestReachableNode(self, NODE_DENSITY, NODE_ALL);


	// Special Check for Platforms
	/* FIXME
	   if(self->groundentity && self->groundentity->use == Use_Plat)
	   {
	   if(closestNode == INVALID)
	   return;              // Do not want to do anything here.

	   // Here we want to add links
	   if(closestNode != self->lastNode && self->lastNode != INVALID)
	   ACEND_UpdateNodeEdge(self->lastNode, closestNode);

	   self->lastNode = closestNode;    // set visited to last
	   return;
	   }
	 */


	if(closestNode != INVALID)
	{
		// add automatically some links between nodes

		if(closestNode != self->bs.lastNode && self->bs.lastNode != INVALID)
		{
			ACEND_UpdateNodeEdge(self->bs.lastNode, closestNode);
			if(ace_showLinks.integer)
				ACEND_DrawPath(self->bs.lastNode, closestNode);
		}

		self->bs.lastNode = closestNode;	// set visited to last
	}
#if 1
	else if(closestNode == INVALID && self->s.groundEntityNum != ENTITYNUM_NONE)
	{
		// add nodes in the water as needed
		if(self->waterlevel)
			closestNode = ACEND_AddNode(self, NODE_WATER);
		else
			closestNode = ACEND_AddNode(self, NODE_MOVE);

		// now add link
		if(self->bs.lastNode != INVALID)
		{
			ACEND_UpdateNodeEdge(self->bs.lastNode, closestNode);

			if(ace_showLinks.integer)
				ACEND_DrawPath(self->bs.lastNode, closestNode);
		}

		self->bs.lastNode = closestNode;	// set visited to last
	}
#endif
}