/* ============ idAASFileLocal::PointReachableAreaNum ============ */ int idAASFileLocal::PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags, const int excludeTravelFlags ) const { int areaList[32], areaNum, i; idVec3 start, end, pointList[32]; aasTrace_t trace; idBounds bounds; float frac; start = origin; trace.areas = areaList; trace.points = pointList; trace.maxAreas = sizeof( areaList ) / sizeof( int ); trace.getOutOfSolid = true; areaNum = PointAreaNum( start ); if ( areaNum ) { if ( ( areas[areaNum].flags & areaFlags ) && ( ( areas[areaNum].travelFlags & excludeTravelFlags ) == 0 ) ) { return areaNum; } } else { // trace up end = start; end[2] += 32.0f; Trace( trace, start, end ); if ( trace.numAreas >= 1 ) { if ( ( areas[0].flags & areaFlags ) && ( ( areas[0].travelFlags & excludeTravelFlags ) == 0 ) ) { return areaList[0]; } start = pointList[0]; start[2] += 1.0f; } } // trace down end = start; end[2] -= 32.0f; Trace( trace, start, end ); if ( trace.lastAreaNum ) { if ( ( areas[trace.lastAreaNum].flags & areaFlags ) && ( ( areas[trace.lastAreaNum].travelFlags & excludeTravelFlags ) == 0 ) ) { return trace.lastAreaNum; } start = trace.endpos; } // expand bounds until an area is found for ( i = 1; i <= 12; i++ ) { frac = i * ( 1.0f / 12.0f ); bounds[0] = origin + searchBounds[0] * frac; bounds[1] = origin + searchBounds[1] * frac; areaNum = BoundsReachableAreaNum( bounds, areaFlags, excludeTravelFlags ); if ( areaNum && ( areas[areaNum].flags & areaFlags ) && ( ( areas[areaNum].travelFlags & excludeTravelFlags ) == 0 ) ) { return areaNum; } } return 0; }
/* ============ idAASLocal::ShowArea ============ */ void idAASLocal::ShowArea( const idVec3 &origin, int mode ) const { static int lastAreaNum; int areaNum; const aasArea_t *area; idVec3 org; org = origin; if ( mode == 1 ) { areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), AAS_AREA_REACHABLE_WALK, TravelFlagInvalidForTeam() ); PushPointIntoArea( areaNum, org ); } else { areaNum = PointAreaNum( origin ); } if ( aas_showTravelTime.GetInteger() ) { int travelTime; const aasReachability_t *reach; RouteToGoalArea( areaNum, org, aas_showTravelTime.GetInteger(), TFL_WALK|TFL_AIR, travelTime, &reach ); gameLocal.Printf( "\rtt = %4d", travelTime ); if ( reach ) { gameLocal.Printf( " to area %4d", reach->toAreaNum ); DrawArea( reach->toAreaNum ); } } if ( areaNum != lastAreaNum ) { area = &file->GetArea( areaNum ); gameLocal.Printf( "area %d:", areaNum ); if ( area->flags & AAS_AREA_LEDGE ) { gameLocal.Printf( " ledge" ); } if ( area->flags & AAS_AREA_CONTENTS_CLUSTERPORTAL ) { gameLocal.Printf( " clusterportal" ); } if ( area->flags & AAS_AREA_CONTENTS_OBSTACLE ) { gameLocal.Printf( " obstacle" ); } if ( area->flags & AAS_AREA_OUTSIDE ) { gameLocal.Printf( " outside" ); } if ( area->flags & AAS_AREA_HIGH_CEILING ) { gameLocal.Printf( " highceiling" ); } if ( area->travelFlags & ( TFL_INVALID | TFL_INVALID_GDF | TFL_INVALID_STROGG ) ) { gameLocal.Printf( " /" ); if ( area->travelFlags & TFL_INVALID ) { gameLocal.Printf( " invalid" ); } if ( area->travelFlags & TFL_INVALID_GDF ) { gameLocal.Printf( " invalidgdf" ); } if ( area->travelFlags & TFL_INVALID_STROGG ) { gameLocal.Printf( " invalidstrogg" ); } } gameLocal.Printf( "\n" ); lastAreaNum = areaNum; } if ( org != origin ) { idBounds bnds = file->GetSettings().boundingBox; bnds[ 1 ].z = bnds[ 0 ].z; gameRenderWorld->DebugBounds( colorYellow, bnds, org ); gameRenderWorld->DebugArrow( colorYellow, origin, org, 1 ); } DrawArea( areaNum ); }