bool MyTreeMap::RemoveKey(KEY key) {//分为以下情况 //1.无子树,直接删除 //2.有子树,以左子树最右的key或右子树最左的key作为子树的key SNode *p = (SNode*)GetNodePosition(key); if(!p) return false; if(!p->pLeft && !p->pRight) { delete p; return true; } //寻找左子树最右key SNode *pi; if(p->pLeft) { pi = p->pLeft; while(pi) { if(!pi->pRight) break; pi = pi->pRight; } } else { pi = p->pRight; while(pi) { if(!pi->pLeft) break; pi = pi->pLeft; } } //替换 p->Key = pi->Key; p->Val = pi->Val; delete pi; return true; }
//----------------------------- GetPath ------------------------------------ // // called by an agent after it has been notified that a search has terminated // successfully. The method extracts the path from m_pCurrentSearch, adds // additional edges appropriate to the search type and returns it as a list of // PathEdges. //----------------------------------------------------------------------------- CActor_PathPlanner::Path CActor_PathPlanner::GetPath() { assert( m_pCurrentSearch && "<CActor_PathPlanner::GetPathAsNodes>: no current search" ); Path path = m_pCurrentSearch->GetPathAsPathEdges(); int closest = GetClosestNodeToPosition( m_pOwner->Pos() ); path.push_front( PathEdge( m_pOwner->Pos(), GetNodePosition( closest ), NavGraphEdge::normal ) ); //if the bot requested a path to a location then an edge leading to the //destination must be added if ( m_pCurrentSearch->GetType() == Graph_SearchTimeSliced < EdgeType >::AStar ) { int idx = m_pOwner->World()->GetCellSpace()->PositionToIndex( m_vDestinationPos ); if ( invalid_node_index != m_pOwner->World()->GetNavGraph().GetNode( idx ).Index() ) { path.push_back( PathEdge( path.back().Destination(), m_vDestinationPos, NavGraphEdge::normal ) ); } } //smooth paths if required if ( script->GetBool( "SmoothPathsQuick" ) ) { SmoothPathEdgesQuick( path ); } if ( script->GetBool( "SmoothPathsPrecise" ) ) { SmoothPathEdgesPrecise( path ); } return path; }
//----------------------------- GetPath ------------------------------------ // // called by an agent after it has been notified that a search has terminated // successfully. The method extracts the path from m_pCurrentSearch, adds // additional edges appropriate to the search type and returns it as a list of // PathEdges. //----------------------------------------------------------------------------- Raven_PathPlanner::Path Raven_PathPlanner::GetPath() { assert (m_pCurrentSearch && "<Raven_PathPlanner::GetPathAsNodes>: no current search"); Path path = m_pCurrentSearch->GetPathAsPathEdges(); int closest = GetClosestNodeToPosition(m_pOwner->Pos()); path.push_front(PathEdge(m_pOwner->Pos(), GetNodePosition(closest), NavGraphEdge::normal)); //if the bot requested a path to a location then an edge leading to the //destination must be added if (m_pCurrentSearch->GetType() == Graph_SearchTimeSliced<EdgeType>::AStar) { path.push_back(PathEdge(path.back().Destination(), m_vDestinationPos, NavGraphEdge::normal)); } //smooth paths if required if (UserOptions->m_bSmoothPathsQuick) { SmoothPathEdgesQuick(path); } if (UserOptions->m_bSmoothPathsPrecise) { SmoothPathEdgesPrecise(path); } return path; }
bool CSimEntity::SolveAcoustics(double dfTime,double dfDT) { ACOUSTIC_NODE_LIST::iterator w; ACOUSTIC_SIGNAL_LIST::iterator q; // MOOSTrace("Solving Acoustics for %s\n", GetName().c_str()); for(w = m_AcousticNodes.begin();w!=m_AcousticNodes.end();w++) { //dereference the node CAcousticNode* pNode = *w; // MOOSTrace("\t Node %s\n", pNode->GetName().c_str()); pNode->SetEnvironment(m_pEnvironment); //and where it is now... Matrix X0; GetNodePosition(*pNode,0,X0); #ifdef SIM_ENTITY_VERBOSE MOOSTraceMatrix(X0,"X0"); #endif //MOOSTrace("%d acoustic signals in environment \n",m_pEnvironment->m_AcousticSignals.size()); for(q = m_pEnvironment->m_AcousticSignals.begin();q!=m_pEnvironment->m_AcousticSignals.end();q++) { //dereference it... CAcousticSignal & rSignal = *q; //is the node listening on this channel? if(pNode->Listening(rSignal.GetChannel())) { if(IsLocalSource(rSignal.GetSrcName())) { #ifdef SIM_ENTITY_VERBOSE MOOSTrace("%s is local to %s, Tx = %f Now = %f Age = %f - continue\n", rSignal.GetSrcName().c_str(), pNode->GetFullName().c_str(), rSignal.GetStartTime(),dfTime,rSignal.Age(dfTime)); #endif continue; } //so when approximately would the signal intercept the node? double dfT0 = rSignal.GetExpectedIntersectionTime(X0); #ifdef SIM_ENTITY_VERBOSE MOOSTrace("T = %f : Signal[%d] [Chan=%d] from %s will intersect %s in %f s\n", dfTime, rSignal.m_nID, rSignal.GetChannel(), rSignal.GetSrcName().c_str(), pNode->GetFullName().c_str(), dfT0-dfTime); #endif //is that close to us? ie within this epoch? if(dfT0>dfTime && dfT0<dfTime+dfDT) { //OK lets figure out where node would have been dfSmallDT //seconds ago...(we have already moved the host entity above) Matrix X1; GetNodePosition(*pNode,-dfDT,X1); // MOOSTraceMatrix(X1,"X1"); double dfT1 = rSignal.GetExpectedIntersectionTime(X1); //now need to find the intersection between the line joining points // (m_dfTimeNow,dfT0) and (m_dfTimeNow-dfSmallDT,dfT1) and the line // with gradient one ... double dfGrad = (dfT0-dfT1)/(dfTime-(dfTime-dfDT)); double dfC = dfT1+dfGrad*(-(dfTime-dfDT)); //intersection time is double dfTi = dfC/(1-dfGrad); /* MOOSTrace("ACoustic Hit @ %f timenow = %f\n", dfTi-m_pEnvironment->GetStartTime(), dfTime-m_pEnvironment->GetStartTime()); MOOSTrace("D = %f\n",(dfTi-rSignal.GetStartTime())*1498.0); */ pNode->OnAcousticHit(rSignal,dfTi); } } else { #ifdef SIM_ENTITY_VERBOSE MOOSTrace("%s is NOT listening for Signal[%d] from %s\n", pNode->GetFullName().c_str(), rSignal.m_nID, rSignal.GetSrcName().c_str()); #endif } } //this call lets the node go about its normal action such as //pinging when required pNode->Iterate(dfTime); } return true; }
qboolean CanJumpDown (edict_t *self, vec3_t neworg) { vec3_t start; edict_t *goal; trace_t tr; if (self->monsterinfo.jumpdn < 1) return false; // we can't jump down! // determine goal entity, if there is one if (self->movetarget && self->movetarget->inuse) goal = self->movetarget; else if (self->enemy && self->enemy->inuse) goal = self->enemy; else if (self->goalentity && self->goalentity->inuse) goal = self->goalentity; else return false; // trace down VectorCopy(neworg, start); start[2] -= 8192; tr = gi.trace(neworg, self->mins, self->maxs, start, self, MASK_MONSTERSOLID); // the landing position is less than 1 unit down, so it's not worth it //if (fabs(tr.endpos[2] - self->s.origin[2]) < STEPSIZE) //{ // gi.dprintf("can't jump down, not worth it\n"); // return false; //} // the landing position is hazardous, don't jump! if (!CheckHazards(self, tr.endpos)) { //gi.dprintf("can't jump down, hazard below\n"); return false; } // are we following a path? if (self->monsterinfo.numWaypoints && self->monsterinfo.nextWaypoint < self->monsterinfo.numWaypoints) { vec3_t v; // is the landing position closer to the next waypoint? GetNodePosition(self->monsterinfo.waypoint[self->monsterinfo.nextWaypoint], v); if (!LandCloserToGoal(self, v, tr.endpos)) { // is the landing position closer to the final waypoint? GetNodePosition(self->monsterinfo.waypoint[self->monsterinfo.numWaypoints-1], v); if (!LandCloserToGoal(self, v, tr.endpos)) { //gi.dprintf("can't jump down, landing position farther than current position\n"); return false; } } // the landing position is non-hazardous and closer to our final or next waypoint //gi.dprintf("jump down!\n"); return true; } // is the landing position closer to our goal entity? if (!LandCloserToGoal(self, goal->s.origin, tr.endpos)) return false; return true; }