int BotExportTest( int parm0, char *parm1, vec3_t parm2, vec3_t parm3 ) { #if !defined RTCW_ET // return AAS_PointLight(parm2, NULL, NULL, NULL); #ifdef DEBUG static int area = -1; static int line[2]; #if defined RTCW_SP int newarea, i, highlightarea, bot_testhidepos, hideposarea, bot_testroutevispos; #elif defined RTCW_MP int newarea, i, highlightarea, bot_testhidepos, hideposarea; #endif // RTCW_XX // int reachnum; vec3_t eye, forward, right, end, origin; // vec3_t bottomcenter; // aas_trace_t trace; // aas_face_t *face; // aas_entity_t *ent; // bsp_trace_t bsptrace; // aas_reachability_t reach; // bot_goal_t goal; // clock_t start_time, end_time; vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; // int areas[10], numareas; //return 0; if ( !( *aasworld ).loaded ) { return 0; } AAS_SetCurrentWorld( 0 ); for ( i = 0; i < 2; i++ ) if ( !line[i] ) { line[i] = botimport.DebugLineCreate(); } // AAS_ClearShownDebugLines(); bot_testhidepos = LibVarGetValue( "bot_testhidepos" ); if ( bot_testhidepos ) { VectorCopy( parm2, origin ); newarea = BotFuzzyPointReachabilityArea( origin ); if ( parm0 & 1 ) { botlibglobals.goalareanum = newarea; VectorCopy( origin, botlibglobals.goalorigin ); botimport.Print( PRT_MESSAGE, "new enemy position %2.1f %2.1f %2.1f area %d\n", origin[0], origin[1], origin[2], newarea ); } //end if AAS_ClearShownPolygons(); AAS_ClearShownDebugLines(); #if defined RTCW_SP hideposarea = AAS_NearestHideArea( -1, origin, AAS_PointAreaNum( origin ), 0, #elif defined RTCW_MP hideposarea = AAS_NearestHideArea( 0, origin, AAS_PointAreaNum( origin ), 0, #endif // RTCW_XX botlibglobals.goalorigin, botlibglobals.goalareanum, TFL_DEFAULT ); #if defined RTCW_SP if ( bot_testhidepos > 1 ) { if ( hideposarea ) { botimport.Print( PRT_MESSAGE, "hidepos (%i) %2.1f %2.1f %2.1f\n", hideposarea, ( *aasworld ).areawaypoints[hideposarea][0], ( *aasworld ).areawaypoints[hideposarea][1], ( *aasworld ).areawaypoints[hideposarea][2] ); } else { botimport.Print( PRT_MESSAGE, "no hidepos found\n" ); } } #endif // RTCW_XX //area we are currently in AAS_ShowAreaPolygons( newarea, 1, qtrue ); //enemy position AAS_ShowAreaPolygons( botlibglobals.goalareanum, 2, qtrue ); //area we should go hide AAS_ShowAreaPolygons( hideposarea, 4, qtrue ); return 0; } #if defined RTCW_SP bot_testroutevispos = LibVarGetValue( "bot_testroutevispos" ); if ( bot_testroutevispos ) { VectorCopy( parm2, origin ); newarea = BotFuzzyPointReachabilityArea( origin ); if ( parm0 & 1 ) { botlibglobals.goalareanum = newarea; VectorCopy( origin, botlibglobals.goalorigin ); botimport.Print( PRT_MESSAGE, "new enemy position %2.1f %2.1f %2.1f area %d\n", origin[0], origin[1], origin[2], newarea ); } //end if AAS_ClearShownPolygons(); AAS_ClearShownDebugLines(); AAS_GetRouteFirstVisPos( botlibglobals.goalorigin, origin, TFL_DEFAULT, eye ); //area we are currently in AAS_ShowAreaPolygons( newarea, 1, qtrue ); //enemy position AAS_ShowAreaPolygons( botlibglobals.goalareanum, 2, qtrue ); //area that is visible in path from enemy pos hideposarea = BotFuzzyPointReachabilityArea( eye ); AAS_ShowAreaPolygons( hideposarea, 4, qtrue ); return 0; } #endif // RTCW_XX //if (AAS_AgainstLadder(parm2)) botimport.Print(PRT_MESSAGE, "against ladder\n"); //BotOnGround(parm2, PRESENCE_NORMAL, 1, &newarea, &newarea); //botimport.Print(PRT_MESSAGE, "%f %f %f\n", parm2[0], parm2[1], parm2[2]); //* highlightarea = LibVarGetValue( "bot_highlightarea" ); if ( highlightarea > 0 ) { newarea = highlightarea; } //end if else { VectorCopy( parm2, origin ); origin[2] += 0.5; //newarea = AAS_PointAreaNum(origin); newarea = BotFuzzyPointReachabilityArea( origin ); } //end else botimport.Print( PRT_MESSAGE, "\rtravel time to goal (%d) = %d ", botlibglobals.goalareanum, AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT ) ); //newarea = BotReachabilityArea(origin, qtrue); if ( newarea != area ) { botimport.Print( PRT_MESSAGE, "origin = %f, %f, %f\n", origin[0], origin[1], origin[2] ); area = newarea; botimport.Print( PRT_MESSAGE, "new area %d, cluster %d, presence type %d\n", area, AAS_AreaCluster( area ), AAS_PointPresenceType( origin ) ); if ( ( *aasworld ).areasettings[area].areaflags & AREA_LIQUID ) { botimport.Print( PRT_MESSAGE, "liquid area\n" ); } //end if botimport.Print( PRT_MESSAGE, "area contents: " ); if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_WATER ) { botimport.Print( PRT_MESSAGE, "water " ); } //end if if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_LAVA ) { botimport.Print( PRT_MESSAGE, "lava " ); } //end if if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_SLIME ) { // botimport.Print(PRT_MESSAGE, "slime "); botimport.Print( PRT_MESSAGE, "slag " ); } //end if if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_JUMPPAD ) { botimport.Print( PRT_MESSAGE, "jump pad " ); } //end if if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_CLUSTERPORTAL ) { botimport.Print( PRT_MESSAGE, "cluster portal " ); } //end if if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_DONOTENTER ) { botimport.Print( PRT_MESSAGE, "do not enter " ); } //end if if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_DONOTENTER_LARGE ) { botimport.Print( PRT_MESSAGE, "do not enter large " ); } //end if if ( !( *aasworld ).areasettings[area].contents ) { botimport.Print( PRT_MESSAGE, "empty " ); } //end if if ( ( *aasworld ).areasettings[area].areaflags & AREA_DISABLED ) { botimport.Print( PRT_MESSAGE, "DISABLED" ); } //end if botimport.Print( PRT_MESSAGE, "\n" ); botimport.Print( PRT_MESSAGE, "travel time to goal (%d) = %d\n", botlibglobals.goalareanum, AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT | TFL_ROCKETJUMP ) ); /* VectorCopy(origin, end); end[2] += 5; numareas = AAS_TraceAreas(origin, end, areas, NULL, 10); AAS_TraceClientBBox(origin, end, PRESENCE_CROUCH, -1); botimport.Print(PRT_MESSAGE, "num areas = %d, area = %d\n", numareas, areas[0]); */ /* botlibglobals.goalareanum = newarea; VectorCopy(parm2, botlibglobals.goalorigin); botimport.Print(PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n", origin[0], origin[1], origin[2], newarea); */ } //end if //* if ( parm0 & 1 ) { botlibglobals.goalareanum = newarea; VectorCopy( parm2, botlibglobals.goalorigin ); botimport.Print( PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n", origin[0], origin[1], origin[2], newarea ); } //end if*/ // if (parm0 & BUTTON_USE) // { // botlibglobals.runai = !botlibglobals.runai; // if (botlibglobals.runai) botimport.Print(PRT_MESSAGE, "started AI\n"); // else botimport.Print(PRT_MESSAGE, "stopped AI\n"); //* / /* goal.areanum = botlibglobals.goalareanum; reachnum = BotGetReachabilityToGoal(parm2, newarea, 1, ms.avoidreach, ms.avoidreachtimes, &goal, TFL_DEFAULT); if (!reachnum) { botimport.Print(PRT_MESSAGE, "goal not reachable\n"); } //end if else { AAS_ReachabilityFromNum(reachnum, &reach); AAS_ClearShownDebugLines(); AAS_ShowArea(area, qtrue); AAS_ShowArea(reach.areanum, qtrue); AAS_DrawCross(reach.start, 6, LINECOLOR_BLUE); AAS_DrawCross(reach.end, 6, LINECOLOR_RED); // if (reach.traveltype == TRAVEL_ELEVATOR) { ElevatorBottomCenter(&reach, bottomcenter); AAS_DrawCross(bottomcenter, 10, LINECOLOR_GREEN); } //end if } //end else*/ // botimport.Print(PRT_MESSAGE, "travel time to goal = %d\n", // AAS_AreaTravelTimeToGoalArea(area, origin, botlibglobals.goalareanum, TFL_DEFAULT)); // botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n"); // AAS_Reachability_WeaponJump(703, 716); // } //end if*/ /* face = AAS_AreaGroundFace(newarea, parm2); if (face) { AAS_ShowFace(face - (*aasworld).faces); } //end if*/ /* AAS_ClearShownDebugLines(); AAS_ShowArea(newarea, parm0 & BUTTON_USE); AAS_ShowReachableAreas(area); */ AAS_ClearShownPolygons(); AAS_ClearShownDebugLines(); AAS_ShowAreaPolygons( newarea, 1, parm0 & 4 ); if ( parm0 & 2 ) { AAS_ShowReachableAreas( area ); } else { static int lastgoalareanum, lastareanum; static int avoidreach[MAX_AVOIDREACH]; static float avoidreachtimes[MAX_AVOIDREACH]; static int avoidreachtries[MAX_AVOIDREACH]; int reachnum; bot_goal_t goal; aas_reachability_t reach; goal.areanum = botlibglobals.goalareanum; VectorCopy( botlibglobals.goalorigin, goal.origin ); reachnum = BotGetReachabilityToGoal( origin, newarea, -1, lastgoalareanum, lastareanum, avoidreach, avoidreachtimes, avoidreachtries, &goal, TFL_DEFAULT | TFL_FUNCBOB, TFL_DEFAULT | TFL_FUNCBOB ); AAS_ReachabilityFromNum( reachnum, &reach ); AAS_ShowReachability( &reach ); } //end else VectorClear( forward ); //BotGapDistance(origin, forward, 0); /* if (parm0 & BUTTON_USE) { botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n"); AAS_Reachability_WeaponJump(703, 716); } //end if*/ AngleVectors( parm3, forward, right, NULL ); //get the eye 16 units to the right of the origin VectorMA( parm2, 8, right, eye ); //get the eye 24 units up eye[2] += 24; //get the end point for the line to be traced VectorMA( eye, 800, forward, end ); // AAS_TestMovementPrediction(1, parm2, forward); /* //trace the line to find the hit point trace = AAS_TraceClientBBox(eye, end, PRESENCE_NORMAL, 1); if (!line[0]) line[0] = botimport.DebugLineCreate(); botimport.DebugLineShow(line[0], eye, trace.endpos, LINECOLOR_BLUE); // AAS_ClearShownDebugLines(); if (trace.ent) { ent = &(*aasworld).entities[trace.ent]; AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs); } //end if*/ /* start_time = clock(); for (i = 0; i < 2000; i++) { AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID); // AAS_TraceClientBBox(eye, end, PRESENCE_NORMAL, 1); } //end for end_time = clock(); botimport.Print(PRT_MESSAGE, "me %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC); start_time = clock(); for (i = 0; i < 2000; i++) { AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID); } //end for end_time = clock(); botimport.Print(PRT_MESSAGE, "id %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC); */ /* AAS_ClearShownDebugLines(); //bsptrace = AAS_Trace(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID); bsptrace = AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID); if (!line[0]) line[0] = botimport.DebugLineCreate(); botimport.DebugLineShow(line[0], eye, bsptrace.endpos, LINECOLOR_YELLOW); if (bsptrace.fraction < 1.0) { face = AAS_TraceEndFace(&trace); if (face) { AAS_ShowFace(face - (*aasworld).faces); } //end if AAS_DrawPlaneCross(bsptrace.endpos, bsptrace.plane.normal, bsptrace.plane.dist + bsptrace.exp_dist, bsptrace.plane.type, LINECOLOR_GREEN); if (trace.ent) { ent = &(*aasworld).entities[trace.ent]; AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs); } //end if } //end if*/ /*/ //bsptrace = AAS_Trace2(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID); bsptrace = AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID); botimport.DebugLineShow(line[1], eye, bsptrace.endpos, LINECOLOR_BLUE); if (bsptrace.fraction < 1.0) { AAS_DrawPlaneCross(bsptrace.endpos, bsptrace.plane.normal, bsptrace.plane.dist,// + bsptrace.exp_dist, bsptrace.plane.type, LINECOLOR_RED); if (bsptrace.ent) { ent = &(*aasworld).entities[bsptrace.ent]; AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs); } //end if } //end if */ #endif #else static int area = -1; static int line[2]; int newarea, i, highlightarea, bot_testhidepos, hideposarea, bot_debug; vec3_t forward, origin; // vec3_t mins = {-16, -16, -24}; // vec3_t maxs = {16, 16, 32}; if ( !aasworld->loaded ) { return 0; } AAS_SetCurrentWorld( 0 ); for ( i = 0; i < 2; i++ ) { if ( !line[i] ) { line[i] = botimport.DebugLineCreate(); } } // AAS_ClearShownDebugLines(); bot_testhidepos = LibVarGetValue( "bot_testhidepos" ); if ( bot_testhidepos ) { VectorCopy( parm2, origin ); newarea = BotFuzzyPointReachabilityArea( origin ); if ( parm0 & 1 ) { botlibglobals.goalareanum = newarea; VectorCopy( origin, botlibglobals.goalorigin ); botimport.Print( PRT_MESSAGE, "new enemy position %2.1f %2.1f %2.1f area %d\n", origin[0], origin[1], origin[2], newarea ); } //end if AAS_ClearShownPolygons(); AAS_ClearShownDebugLines(); hideposarea = AAS_NearestHideArea( 0, origin, AAS_PointAreaNum( origin ), 0, botlibglobals.goalorigin, botlibglobals.goalareanum, TFL_DEFAULT, 99999, NULL ); //area we are currently in AAS_ShowAreaPolygons( newarea, 1, qtrue ); //enemy position AAS_ShowAreaPolygons( botlibglobals.goalareanum, 2, qtrue ); //area we should go hide AAS_ShowAreaPolygons( hideposarea, 4, qtrue ); return 0; } highlightarea = LibVarGetValue( "bot_highlightarea" ); if ( highlightarea > 0 ) { newarea = highlightarea; } else { VectorCopy( parm2, origin ); //origin[2] += 0.5; newarea = BotFuzzyPointReachabilityArea( origin ); } //end else bot_debug = LibVarGetValue( "bot_debug" ); if ( bot_debug == 9 ) { aas_clientmove_t move; vec3_t dest; qboolean this_success; if ( parm0 & 1 ) { botlibglobals.goalareanum = newarea; VectorCopy( parm2, botlibglobals.goalorigin ); botimport.Print( PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n", origin[0], origin[1], origin[2], newarea ); } VectorCopy( parm2, origin ); VectorCopy( botlibglobals.goalorigin, dest ); // debug direct movement VectorSubtract( dest, origin, forward ); VectorNormalize( forward ); VectorScale( forward, 300, forward ); this_success = AAS_PredictClientMovement( &move, 0, origin, -1, qfalse, forward, dest, -1, 40, 0.05, SE_ENTERAREA | SE_HITGROUNDDAMAGE | SE_HITENT | SE_HITGROUNDAREA | SE_STUCK | SE_GAP, botlibglobals.goalareanum, qtrue ); if ( this_success ) { switch ( move.stopevent ) { case SE_ENTERAREA: case SE_HITENT: case SE_HITGROUNDAREA: break; default: this_success = qfalse; } } if ( this_success != botlibglobals.lastsuccess ) { botimport.Print( PRT_MESSAGE, "DirectMove: %s\n", this_success ? "SUCCESS" : "FAILURE" ); botlibglobals.lastsuccess = this_success; } return 0; } botimport.Print( PRT_MESSAGE, "\rtravel time to goal (%d) = %d ", botlibglobals.goalareanum, AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT ) ); if ( newarea != area ) { botimport.Print( PRT_MESSAGE, "origin = %f, %f, %f\n", origin[0], origin[1], origin[2] ); area = newarea; botimport.Print( PRT_MESSAGE, "new area %d, cluster %d, presence type %d\n", area, AAS_AreaCluster( area ), AAS_PointPresenceType( origin ) ); if ( aasworld->areasettings[area].areaflags & AREA_LIQUID ) { botimport.Print( PRT_MESSAGE, "liquid area\n" ); } //end if botimport.Print( PRT_MESSAGE, "area contents: " ); if ( aasworld->areasettings[area].contents & AREACONTENTS_MOVER ) { botimport.Print( PRT_MESSAGE, "mover " ); } //end if if ( aasworld->areasettings[area].contents & AREACONTENTS_WATER ) { botimport.Print( PRT_MESSAGE, "water " ); } //end if if ( aasworld->areasettings[area].contents & AREACONTENTS_LAVA ) { botimport.Print( PRT_MESSAGE, "lava " ); } //end if if ( aasworld->areasettings[area].contents & AREACONTENTS_SLIME ) { botimport.Print( PRT_MESSAGE, "slag " ); } //end if if ( aasworld->areasettings[area].contents & AREACONTENTS_JUMPPAD ) { botimport.Print( PRT_MESSAGE, "jump pad " ); } //end if if ( aasworld->areasettings[area].contents & AREACONTENTS_CLUSTERPORTAL ) { botimport.Print( PRT_MESSAGE, "cluster portal " ); } //end if if ( aasworld->areasettings[area].contents & AREACONTENTS_DONOTENTER ) { botimport.Print( PRT_MESSAGE, "do not enter " ); } //end if if ( aasworld->areasettings[area].contents & AREACONTENTS_DONOTENTER_LARGE ) { botimport.Print( PRT_MESSAGE, "do not enter large " ); } //end if if ( !aasworld->areasettings[area].contents ) { botimport.Print( PRT_MESSAGE, "empty " ); } //end if botimport.Print( PRT_MESSAGE, "\n" ); botimport.Print( PRT_MESSAGE, "area flags: " ); if ( aasworld->areasettings[area].areaflags & AREA_LADDER ) { botimport.Print( PRT_MESSAGE, "ladder " ); } if ( aasworld->areasettings[area].areaflags & AREA_GROUNDED ) { botimport.Print( PRT_MESSAGE, "grounded " ); } if ( aasworld->areasettings[area].areaflags & AREA_LIQUID ) { botimport.Print( PRT_MESSAGE, "liquid " ); } if ( aasworld->areasettings[area].areaflags & AREA_DISABLED ) { botimport.Print( PRT_MESSAGE, "DISABLED " ); } if ( aasworld->areasettings[area].areaflags & AREA_AVOID ) { botimport.Print( PRT_MESSAGE, "AVOID " ); } botimport.Print( PRT_MESSAGE, "\n" ); botimport.Print( PRT_MESSAGE, "travel time to goal (%d) = %d\n", botlibglobals.goalareanum, AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT | TFL_ROCKETJUMP ) ); } if ( parm0 & 1 ) { botlibglobals.goalareanum = newarea; VectorCopy( parm2, botlibglobals.goalorigin ); botimport.Print( PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n", origin[0], origin[1], origin[2], newarea ); } AAS_ClearShownPolygons(); AAS_ClearShownDebugLines(); if ( parm0 & 8 ) { int jk = 0; if ( parm0 & 16 ) { for ( ; jk < aasworld->numareas; jk++ ) { if ( !( aasworld->areasettings[jk].areaflags & AREA_DISABLED ) ) { AAS_ShowAreaPolygons( jk, 1, parm0 & 4 ); } } } else { for ( ; jk < aasworld->numareas; jk++ ) { AAS_ShowAreaPolygons( jk, 1, parm0 & 4 ); } } } else { AAS_ShowAreaPolygons( newarea, 1, parm0 & 4 ); } if ( parm0 & 2 ) { AAS_ShowReachableAreas( area ); } else { static int lastgoalareanum, lastareanum; static int avoidreach[MAX_AVOIDREACH]; static float avoidreachtimes[MAX_AVOIDREACH]; static int avoidreachtries[MAX_AVOIDREACH]; int reachnum; bot_goal_t goal; aas_reachability_t reach; static int lastreach; goal.areanum = botlibglobals.goalareanum; VectorCopy( botlibglobals.goalorigin, goal.origin ); reachnum = BotGetReachabilityToGoal( origin, newarea, -1, lastgoalareanum, lastareanum, avoidreach, avoidreachtimes, avoidreachtries, &goal, TFL_DEFAULT | TFL_FUNCBOB, TFL_DEFAULT ); AAS_ReachabilityFromNum( reachnum, &reach ); if ( lastreach != reachnum ) { botimport.Print( PRT_MESSAGE, "Travel Type: " ); AAS_PrintTravelType( reach.traveltype ); botimport.Print( PRT_MESSAGE, "\n" ); } lastreach = reachnum; AAS_ShowReachability( &reach ); } //end else VectorClear( forward ); #endif // RTCW_XX return 0; } //end of the function BotExportTest
qboolean AAS_RT_GetHidePos( vec3_t srcpos, int srcnum, int srcarea, vec3_t destpos, int destnum, int destarea, vec3_t returnPos ) { static int tfl = TFL_DEFAULT & ~( TFL_JUMPPAD | TFL_ROCKETJUMP | TFL_BFGJUMP | TFL_GRAPPLEHOOK | TFL_DOUBLEJUMP | TFL_RAMPJUMP | TFL_STRAFEJUMP | TFL_LAVA ); //----(SA) modified since slime is no longer deadly // static int tfl = TFL_DEFAULT & ~(TFL_JUMPPAD|TFL_ROCKETJUMP|TFL_BFGJUMP|TFL_GRAPPLEHOOK|TFL_DOUBLEJUMP|TFL_RAMPJUMP|TFL_STRAFEJUMP|TFL_SLIME|TFL_LAVA); #if 1 // use MrE's breadth first method int hideareanum; // int pretime; // disabled this so grenade hiding works //if (!srcarea || !destarea) // return qfalse; // pretime = -Sys_MilliSeconds(); hideareanum = AAS_NearestHideArea( srcnum, srcpos, srcarea, destnum, destpos, destarea, tfl ); if ( !hideareanum ) { // botimport.Print(PRT_MESSAGE, "Breadth First HidePos FAILED: %i ms\n", pretime + Sys_MilliSeconds()); return qfalse; } // we found a valid hiding area VectorCopy( ( *aasworld ).areawaypoints[hideareanum], returnPos ); // botimport.Print(PRT_MESSAGE, "Breadth First HidePos: %i ms\n", pretime + Sys_MilliSeconds()); return qtrue; #else // look around at random parent areas, if any of them have a center point // that isn't visible from "destpos", then return it's position in returnPos int i, j, pathArea, dir; unsigned short int destTravelTime; aas_rt_parent_t *srcParent, *travParent, *destParent; aas_rt_child_t *srcChild, *destChild, *travChild; aas_rt_route_t *route; vec3_t destVec; float destTravelDist; static float lastTime; static int frameCount, maxPerFrame = 2; int firstreach; aas_reachability_t *reachability, *reach; qboolean startVisible; unsigned short int bestTravelTime, thisTravelTime, elapsedTravelTime; #define MAX_HIDE_TRAVELTIME 1000 // 10 seconds is a very long way away unsigned char destVisLookup[MAX_PARENTS]; unsigned short int *destVisTrav; aas_rt_t *rt; const int MAX_CHECK_VISPARENTS = 100; int visparents_count, total_parents_checked; int thisParentIndex; int pretime; if ( !( rt = aasworld->routetable ) ) { // no route table present return qfalse; } /* if (lastTime > (AAS_Time() - 0.1)) { if (frameCount++ > maxPerFrame) { return qfalse; } } else { frameCount = 0; lastTime = AAS_Time(); } */ pretime = -Sys_MilliSeconds(); // is the src area grounded? if ( !( srcChild = AAS_RT_GetChild( srcarea ) ) ) { return qfalse; } // does it have a parent? // all valid areas have a parent // if (!srcChild->numParentLinks) { // return qfalse; // } // get the dest (enemy) area if ( !( destChild = AAS_RT_GetChild( destarea ) ) ) { return qfalse; } destParent = &rt->parents[ rt->parentLinks[destChild->startParentLinks].parent ]; // // populate the destVisAreas memset( destVisLookup, 0, sizeof( destVisLookup ) ); destVisTrav = rt->visibleParents + destParent->startVisibleParents; for ( i = 0; i < destParent->numVisibleParents; i++, destVisTrav++ ) { destVisLookup[*destVisTrav] = 1; } // // use the first parent to source the vis areas from srcParent = &rt->parents[ rt->parentLinks[srcChild->startParentLinks].parent ]; // // set the destTravelTime if ( route = AAS_RT_GetRoute( srcarea, srcpos, destarea ) ) { destTravelTime = route->travel_time; } else { destTravelTime = 0; } bestTravelTime = MAX_HIDE_TRAVELTIME; // ignore any routes longer than 10 seconds away // set the destVec VectorSubtract( destpos, srcpos, destVec ); destTravelDist = VectorNormalize( destVec ); // // randomize the direction we traverse the list, so the hiding spot isn't always the same if ( rand() % 2 ) { dir = 1; // forward } else { dir = -1; // reverse } // randomize the starting area if ( srcParent->numVisibleParents ) { i = rand() % srcParent->numVisibleParents; } else { // prevent divide by zero i = 0; } // // setup misc stuff reachability = ( *aasworld ).reachability; startVisible = botimport.AICast_VisibleFromPos( destpos, destnum, srcpos, srcnum, qfalse ); // // set the firstreach to prevent having to do an array and pointer lookup for each destination firstreach = ( *aasworld ).areasettings[srcarea].firstreachablearea; // // just check random parent areas, traversing the route until we find an area that can't be seen from the dest area for ( visparents_count = 0, total_parents_checked = 0; visparents_count < MAX_CHECK_VISPARENTS && total_parents_checked < rt->numParents; total_parents_checked++ ) { thisParentIndex = rand() % rt->numParents; travParent = &rt->parents[ thisParentIndex ]; // // never go to the enemy's areas if ( travParent->areanum == destarea ) { continue; } // // if it's visible from dest, ignore it if ( destVisLookup[thisParentIndex] ) { continue; } // visparents_count++; // they might be visible, check to see if the path to the area, takes us towards the // enemy we are trying to hide from { qboolean invalidRoute; vec3_t curPos, lastVec; #define GETHIDE_MAX_CHECK_PATHS 15 // invalidRoute = qfalse; // initialize the pathArea pathArea = srcarea; VectorCopy( srcpos, curPos ); // now evaluate the path for ( j = 0; j < GETHIDE_MAX_CHECK_PATHS; j++ ) { // get the reachability to the travParent if ( !( route = AAS_RT_GetRoute( pathArea, curPos, travParent->areanum ) ) ) { // we can't get to the travParent, so don't bother checking it invalidRoute = qtrue; break; } // set the pathArea reach = &reachability[route->reachable_index]; // how far have we travelled so far? elapsedTravelTime = AAS_AreaTravelTimeToGoalArea( pathArea, curPos, reach->areanum, tfl ); // add the travel to the center of the area elapsedTravelTime += AAS_AreaTravelTime( reach->areanum, reach->end, ( *aasworld ).areas[reach->areanum].center ); // have we gone too far already? if ( elapsedTravelTime > bestTravelTime ) { invalidRoute = qtrue; break; } else { thisTravelTime = route->travel_time; } // // if this travel would have us do something wierd if ( ( reach->traveltype == TRAVEL_WALKOFFLEDGE ) && ( reach->traveltime > 500 ) ) { invalidRoute = qtrue; break; } // pathArea = reach->areanum; VectorCopy( reach->end, curPos ); // // if this moves us into the enemies area, skip it if ( pathArea == destarea ) { invalidRoute = qtrue; break; } // if we are very close, don't get any closer under any circumstances { vec3_t vec; float dist; // VectorSubtract( destpos, reachability[firstreach + route->reachable_index].end, vec ); dist = VectorNormalize( vec ); // if ( destTravelTime < 400 ) { if ( dist < destTravelDist ) { invalidRoute = qtrue; break; } if ( DotProduct( destVec, vec ) < 0.2 ) { invalidRoute = qtrue; break; } } else { if ( dist < destTravelDist * 0.7 ) { invalidRoute = qtrue; break; } } // // check the directions to make sure we're not trying to run through them if ( j > 0 ) { if ( DotProduct( vec, lastVec ) < 0.2 ) { invalidRoute = qtrue; break; } } else if ( DotProduct( destVec, vec ) < 0.2 ) { invalidRoute = qtrue; break; } // VectorCopy( vec, lastVec ); } // // if this area isn't in the visible list for the enemy's area, it's a good hiding spot if ( !( travChild = AAS_RT_GetChild( pathArea ) ) ) { invalidRoute = qtrue; break; } if ( !destVisLookup[rt->parentLinks[travChild->startParentLinks].parent] ) { // success ? if ( !botimport.AICast_VisibleFromPos( destpos, destnum, ( *aasworld ).areas[pathArea].center, srcnum, qfalse ) ) { // SUCESS !! travParent = &rt->parents[rt->parentLinks[travChild->startParentLinks].parent]; break; } } else { // if we weren't visible when starting, make sure we don't move into their view if ( !startVisible ) { //botimport.AICast_VisibleFromPos( destpos, destnum, reachability[firstreach + route->reachable_index].end, srcnum, qfalse )) { invalidRoute = qtrue; break; } } // // if this is the travParent, then stop checking if ( pathArea == travParent->areanum ) { invalidRoute = qtrue; // we didn't find a hiding spot break; } } // end for areas in route // // if the route is invalid, skip this travParent if ( invalidRoute ) { continue; } } // // now last of all, check that this area is a safe hiding spot // if (botimport.AICast_VisibleFromPos( destpos, destnum, (*aasworld).areas[travParent->areanum].center, srcnum, qfalse )) { // continue; // } // // we've found a good hiding spot, so use it VectorCopy( ( *aasworld ).areas[travParent->areanum].center, returnPos ); bestTravelTime = elapsedTravelTime; // if ( thisTravelTime < 300 ) { botimport.Print( PRT_MESSAGE, "Fuzzy RT HidePos: %i ms\n", pretime + Sys_MilliSeconds() ); return qtrue; } } // // did we find something? if ( bestTravelTime < MAX_HIDE_TRAVELTIME ) { botimport.Print( PRT_MESSAGE, "Fuzzy RT HidePos: %i ms\n", pretime + Sys_MilliSeconds() ); return qtrue; } // // couldn't find anything botimport.Print( PRT_MESSAGE, "Fuzzy RT HidePos FAILED: %i ms\n", pretime + Sys_MilliSeconds() ); return qfalse; #endif }