/*
============
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;
}
Example #2
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 );
}