mirror of
https://github.com/id-Software/RTCW-MP.git
synced 2026-03-21 01:21:19 +01:00
The Return to Castle Wolfenstein Multiplayer sources as originally released under the GPL license on August 12, 2010.
This commit is contained in:
271
src/botlib/be_aas_routealt.c
Normal file
271
src/botlib/be_aas_routealt.c
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein multiplayer GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein multiplayer GPL Source Code (RTCW MP Source Code).
|
||||
|
||||
RTCW MP Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
RTCW MP Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with RTCW MP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW MP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW MP Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* name: be_aas_routealt.c
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../game/q_shared.h"
|
||||
#include "l_utils.h"
|
||||
#include "l_memory.h"
|
||||
#include "l_log.h"
|
||||
#include "l_script.h"
|
||||
#include "l_precomp.h"
|
||||
#include "l_struct.h"
|
||||
#include "aasfile.h"
|
||||
#include "../game/botlib.h"
|
||||
#include "../game/be_aas.h"
|
||||
#include "be_aas_funcs.h"
|
||||
#include "be_interface.h"
|
||||
#include "be_aas_def.h"
|
||||
|
||||
//#define ENABLE_ALTROUTING
|
||||
|
||||
typedef struct midrangearea_s
|
||||
{
|
||||
int valid;
|
||||
unsigned short starttime;
|
||||
unsigned short goaltime;
|
||||
} midrangearea_t;
|
||||
|
||||
midrangearea_t *midrangeareas;
|
||||
int *clusterareas;
|
||||
int numclusterareas;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_AltRoutingFloodCluster_r( int areanum ) {
|
||||
int i, otherareanum;
|
||||
aas_area_t *area;
|
||||
aas_face_t *face;
|
||||
|
||||
//add the current area to the areas of the current cluster
|
||||
clusterareas[numclusterareas] = areanum;
|
||||
numclusterareas++;
|
||||
//remove the area from the mid range areas
|
||||
midrangeareas[areanum].valid = qfalse;
|
||||
//flood to other areas through the faces of this area
|
||||
area = &( *aasworld ).areas[areanum];
|
||||
for ( i = 0; i < area->numfaces; i++ )
|
||||
{
|
||||
face = &( *aasworld ).faces[abs( ( *aasworld ).faceindex[area->firstface + i] )];
|
||||
//get the area at the other side of the face
|
||||
if ( face->frontarea == areanum ) {
|
||||
otherareanum = face->backarea;
|
||||
} else { otherareanum = face->frontarea;}
|
||||
//if there is an area at the other side of this face
|
||||
if ( !otherareanum ) {
|
||||
continue;
|
||||
}
|
||||
//if the other area is not a midrange area
|
||||
if ( !midrangeareas[otherareanum].valid ) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
AAS_AltRoutingFloodCluster_r( otherareanum );
|
||||
} //end for
|
||||
} //end of the function AAS_AltRoutingFloodCluster_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_AlternativeRouteGoals( vec3_t start, vec3_t goal, int travelflags,
|
||||
aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
|
||||
int color ) {
|
||||
#ifndef ENABLE_ALTROUTING
|
||||
return 0;
|
||||
#else
|
||||
int i, j, startareanum, goalareanum, bestareanum;
|
||||
int numaltroutegoals, nummidrangeareas;
|
||||
int starttime, goaltime, goaltraveltime;
|
||||
float dist, bestdist;
|
||||
vec3_t mid, dir;
|
||||
#ifdef DEBUG
|
||||
int startmillisecs;
|
||||
|
||||
startmillisecs = Sys_MilliSeconds();
|
||||
#endif
|
||||
|
||||
startareanum = AAS_PointAreaNum( start );
|
||||
if ( !startareanum ) {
|
||||
return 0;
|
||||
}
|
||||
goalareanum = AAS_PointAreaNum( goal );
|
||||
if ( !goalareanum ) {
|
||||
return 0;
|
||||
}
|
||||
//travel time towards the goal area
|
||||
goaltraveltime = AAS_AreaTravelTimeToGoalArea( startareanum, start, goalareanum, travelflags );
|
||||
//clear the midrange areas
|
||||
memset( midrangeareas, 0, ( *aasworld ).numareas * sizeof( midrangearea_t ) );
|
||||
numaltroutegoals = 0;
|
||||
//
|
||||
nummidrangeareas = 0;
|
||||
//
|
||||
for ( i = 1; i < ( *aasworld ).numareas; i++ )
|
||||
{
|
||||
//
|
||||
if ( !( ( *aasworld ).areasettings[i].contents & AREACONTENTS_ROUTEPORTAL ) ) {
|
||||
continue;
|
||||
}
|
||||
//if the area has no reachabilities
|
||||
if ( !AAS_AreaReachability( i ) ) {
|
||||
continue;
|
||||
}
|
||||
//tavel time from the area to the start area
|
||||
starttime = AAS_AreaTravelTimeToGoalArea( startareanum, start, i, travelflags );
|
||||
if ( !starttime ) {
|
||||
continue;
|
||||
}
|
||||
//if the travel time from the start to the area is greater than the shortest goal travel time
|
||||
if ( starttime > 1.5 * goaltraveltime ) {
|
||||
continue;
|
||||
}
|
||||
//travel time from the area to the goal area
|
||||
goaltime = AAS_AreaTravelTimeToGoalArea( i, NULL, goalareanum, travelflags );
|
||||
if ( !goaltime ) {
|
||||
continue;
|
||||
}
|
||||
//if the travel time from the area to the goal is greater than the shortest goal travel time
|
||||
if ( goaltime > 1.5 * goaltraveltime ) {
|
||||
continue;
|
||||
}
|
||||
//this is a mid range area
|
||||
midrangeareas[i].valid = qtrue;
|
||||
midrangeareas[i].starttime = starttime;
|
||||
midrangeareas[i].goaltime = goaltime;
|
||||
Log_Write( "%d midrange area %d", nummidrangeareas, i );
|
||||
nummidrangeareas++;
|
||||
} //end for
|
||||
//
|
||||
for ( i = 1; i < ( *aasworld ).numareas; i++ )
|
||||
{
|
||||
if ( !midrangeareas[i].valid ) {
|
||||
continue;
|
||||
}
|
||||
//get the areas in one cluster
|
||||
numclusterareas = 0;
|
||||
AAS_AltRoutingFloodCluster_r( i );
|
||||
//now we've got a cluster with areas through which an alternative route could go
|
||||
//get the 'center' of the cluster
|
||||
VectorClear( mid );
|
||||
for ( j = 0; j < numclusterareas; j++ )
|
||||
{
|
||||
VectorAdd( mid, ( *aasworld ).areas[clusterareas[j]].center, mid );
|
||||
} //end for
|
||||
VectorScale( mid, 1.0 / numclusterareas, mid );
|
||||
//get the area closest to the center of the cluster
|
||||
bestdist = 999999;
|
||||
bestareanum = 0;
|
||||
for ( j = 0; j < numclusterareas; j++ )
|
||||
{
|
||||
VectorSubtract( mid, ( *aasworld ).areas[clusterareas[j]].center, dir );
|
||||
dist = VectorLength( dir );
|
||||
if ( dist < bestdist ) {
|
||||
bestdist = dist;
|
||||
bestareanum = clusterareas[j];
|
||||
} //end if
|
||||
} //end for
|
||||
//now we've got an area for an alternative route
|
||||
//FIXME: add alternative goal origin
|
||||
VectorCopy( ( *aasworld ).areas[bestareanum].center, altroutegoals[numaltroutegoals].origin );
|
||||
altroutegoals[numaltroutegoals].areanum = bestareanum;
|
||||
altroutegoals[numaltroutegoals].starttraveltime = midrangeareas[bestareanum].starttime;
|
||||
altroutegoals[numaltroutegoals].goaltraveltime = midrangeareas[bestareanum].goaltime;
|
||||
altroutegoals[numaltroutegoals].extratraveltime =
|
||||
( midrangeareas[bestareanum].starttime + midrangeareas[bestareanum].goaltime ) -
|
||||
goaltraveltime;
|
||||
numaltroutegoals++;
|
||||
//
|
||||
#ifdef DEBUG
|
||||
botimport.Print( PRT_MESSAGE, "alternative route goal area %d, numclusterareas = %d\n", bestareanum, numclusterareas );
|
||||
if ( color ) {
|
||||
AAS_DrawPermanentCross( ( *aasworld ).areas[bestareanum].center, 10, color );
|
||||
} //end if
|
||||
//AAS_ShowArea(bestarea, qtrue);
|
||||
#endif
|
||||
//don't return more than the maximum alternative route goals
|
||||
if ( numaltroutegoals >= maxaltroutegoals ) {
|
||||
break;
|
||||
}
|
||||
} //end for
|
||||
botimport.Print( PRT_MESSAGE, "%d alternative route goals\n", numaltroutegoals );
|
||||
#ifdef DEBUG
|
||||
botimport.Print( PRT_MESSAGE, "alternative route goals in %d msec\n", Sys_MilliSeconds() - startmillisecs );
|
||||
#endif
|
||||
return numaltroutegoals;
|
||||
#endif
|
||||
} //end of the function AAS_AlternativeRouteGoals
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_InitAlternativeRouting( void ) {
|
||||
#ifdef ENABLE_ALTROUTING
|
||||
if ( midrangeareas ) {
|
||||
FreeMemory( midrangeareas );
|
||||
}
|
||||
midrangeareas = (midrangearea_t *) GetMemory( ( *aasworld ).numareas * sizeof( midrangearea_t ) );
|
||||
if ( clusterareas ) {
|
||||
FreeMemory( clusterareas );
|
||||
}
|
||||
clusterareas = (int *) GetMemory( aasworld.numareas * sizeof( int ) );
|
||||
#endif
|
||||
} //end of the function AAS_InitAlternativeRouting
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShutdownAlternativeRouting( void ) {
|
||||
#ifdef ENABLE_ALTROUTING
|
||||
if ( midrangeareas ) {
|
||||
FreeMemory( midrangeareas );
|
||||
}
|
||||
midrangeareas = NULL;
|
||||
if ( clusterareas ) {
|
||||
FreeMemory( clusterareas );
|
||||
}
|
||||
clusterareas = NULL;
|
||||
numclusterareas = 0;
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user