//b_goal.cpp // leave this line at the top for all NPC_xxxx.cpp files... #include "g_headers.h" #include "b_local.h" #include "Q3_Interface.h" extern qboolean FlyingCreature( gentity_t *ent ); /* SetGoal */ void SetGoal( gentity_t *goal, float rating ) { NPCInfo->goalEntity = goal; // NPCInfo->goalEntityNeed = rating; NPCInfo->goalTime = level.time; if ( goal ) { // Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_INFO, "NPC_SetGoal: %s @ %s (%f)\n", goal->classname, vtos( goal->currentOrigin), rating ); } else { // Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_INFO, "NPC_SetGoal: NONE\n" ); } } /* NPC_SetGoal */ void NPC_SetGoal( gentity_t *goal, float rating ) { if ( goal == NPCInfo->goalEntity ) { return; } if ( !goal ) { // Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_ERROR, "NPC_SetGoal: NULL goal\n" ); return; } if ( goal->client ) { // Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_ERROR, "NPC_SetGoal: goal is a client\n" ); return; } if ( NPCInfo->goalEntity ) { // Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_INFO, "NPC_SetGoal: push %s\n", NPCInfo->goalEntity->classname ); NPCInfo->lastGoalEntity = NPCInfo->goalEntity; // NPCInfo->lastGoalEntityNeed = NPCInfo->goalEntityNeed; } SetGoal( goal, rating ); } /* NPC_ClearGoal */ void NPC_ClearGoal( void ) { gentity_t *goal; if ( !NPCInfo->lastGoalEntity ) { SetGoal( NULL, 0.0 ); return; } goal = NPCInfo->lastGoalEntity; NPCInfo->lastGoalEntity = NULL; if ( goal->inuse && !(goal->s.eFlags & EF_NODRAW) ) { // Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_INFO, "NPC_ClearGoal: pop %s\n", goal->classname ); SetGoal( goal, 0 );//, NPCInfo->lastGoalEntityNeed return; } SetGoal( NULL, 0.0 ); } /* ------------------------- G_BoundsOverlap ------------------------- */ qboolean G_BoundsOverlap(const vec3_t mins1, const vec3_t maxs1, const vec3_t mins2, const vec3_t maxs2) {//NOTE: flush up against counts as overlapping if(mins1[0]>maxs2[0]) return qfalse; if(mins1[1]>maxs2[1]) return qfalse; if(mins1[2]>maxs2[2]) return qfalse; if(maxs1[0]goalTime = level.time; //MCG - Begin NPCInfo->aiFlags &= ~NPCAI_MOVING; ucmd.forwardmove = 0; //Return that the goal was reached Q3_TaskIDComplete( NPC, TID_MOVE_NAV ); //MCG - End } /* ReachedGoal id removed checks against waypoints and is now checking surfaces */ qboolean ReachedGoal( gentity_t *goal ) { if ( NPCInfo->aiFlags & NPCAI_TOUCHED_GOAL ) { NPCInfo->aiFlags &= ~NPCAI_TOUCHED_GOAL; return qtrue; } return STEER::Reached(NPC, goal, NPCInfo->goalRadius, !!FlyingCreature(NPC)); } /* static gentity_t *UpdateGoal( void ) Id removed a lot of shit here... doesn't seem to handle waypoints independantly of goalentity In fact, doesn't seem to be any waypoint info on entities at all any more? MCG - Since goal is ALWAYS goalEntity, took out a lot of sending goal entity pointers around for no reason */ gentity_t *UpdateGoal( void ) { //FIXME: CREED should look at this // this func doesn't seem to be working correctly for the sand creature gentity_t *goal; if ( !NPCInfo->goalEntity ) { return NULL; } if ( !NPCInfo->goalEntity->inuse ) {//Somehow freed it, but didn't clear it NPC_ClearGoal(); return NULL; } goal = NPCInfo->goalEntity; if ( ReachedGoal( goal ) ) { NPC_ReachedGoal(); goal = NULL;//so they don't keep trying to move to it }//else if fail, need to tell script so? return goal; }