// Turns on showing of the path, set goal to -1 to // shut off. (utility function) void ACEND_ShowPath(gentity_t * self, int goalNode) { int currentNode; currentNode = ACEND_FindClosestReachableNode(self, NODE_DENSITY, NODE_ALL); if(currentNode == INVALID) { trap_SendServerCommand(self - g_entities, "print \"no closest reachable node!\n\""); return; } ACEND_DrawPath(currentNode, goalNode); }
void ACEND_SetGoal(gentity_t * self, int goalNode) { int node; self->bs.goalNode = goalNode; node = ACEND_FindClosestReachableNode(self, NODE_DENSITY * 3, NODE_ALL); if(node == INVALID) return; if(ace_debug.integer) trap_SendServerCommand(-1, va("print \"%s: new start node selected %d\n\"", self->client->pers.netname, node)); self->bs.currentNode = node; self->bs.nextNode = self->bs.currentNode; // make sure we get to the nearest node first self->bs.node_timeout = 0; if(ace_showPath.integer) { // draw path to LR goal ACEND_DrawPath(self->bs.currentNode, self->bs.goalNode); } }
/////////////////////////////////////////////////////////////////////// // 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 }
// 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 }