1 /*
2 ===========================================================================
3 
4 Return to Castle Wolfenstein multiplayer GPL Source Code
5 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Return to Castle Wolfenstein multiplayer GPL Source Code (“RTCW MP Source Code”).
8 
9 RTCW MP Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 RTCW MP Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with RTCW MP Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 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.
23 
24 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.
25 
26 ===========================================================================
27 */
28 
29 
30 /*****************************************************************************
31  * name:		be_interface.c
32  *
33  * desc:		bot library interface
34  *
35  *
36  *****************************************************************************/
37 
38 #include "../qcommon/q_shared.h"
39 #include "l_memory.h"
40 #include "l_log.h"
41 #include "l_libvar.h"
42 #include "l_script.h"
43 #include "l_precomp.h"
44 #include "l_struct.h"
45 #include "aasfile.h"
46 #include "botlib.h"
47 #include "be_aas.h"
48 #include "be_aas_funcs.h"
49 #include "be_aas_def.h"
50 #include "be_interface.h"
51 
52 #include "be_ea.h"
53 #include "be_ai_weight.h"
54 #include "be_ai_goal.h"
55 #include "be_ai_move.h"
56 #include "be_ai_weap.h"
57 #include "be_ai_chat.h"
58 #include "be_ai_char.h"
59 #include "be_ai_gen.h"
60 
61 //library globals in a structure
62 botlib_globals_t botlibglobals;
63 
64 botlib_export_t be_botlib_export;
65 botlib_import_t botimport;
66 //
67 int botDeveloper;
68 //qtrue if the library is setup
69 int botlibsetup = qfalse;
70 
71 //===========================================================================
72 //
73 // several functions used by the exported functions
74 //
75 //===========================================================================
76 
77 //===========================================================================
78 //
79 // Parameter:				-
80 // Returns:					-
81 // Changes Globals:		-
82 //===========================================================================
83 // Ridah, faster Win32 code
84 #ifdef _WIN32
85 #include <windows.h>
86 #endif
87 
Sys_MilliSeconds(void)88 int Sys_MilliSeconds( void ) {
89 // Ridah, faster Win32 code
90 #ifdef _WIN32
91 	int sys_curtime;
92 	static qboolean initialized = qfalse;
93 	static int sys_timeBase;
94 
95 	if ( !initialized ) {
96 		sys_timeBase = timeGetTime();
97 		initialized = qtrue;
98 	}
99 	sys_curtime = timeGetTime() - sys_timeBase;
100 
101 	return sys_curtime;
102 #else
103 	return clock() * 1000 / CLOCKS_PER_SEC;
104 #endif
105 } //end of the function Sys_MilliSeconds
106 //===========================================================================
107 //
108 // Parameter:				-
109 // Returns:					-
110 // Changes Globals:		-
111 //===========================================================================
ValidClientNumber(int num,char * str)112 qboolean ValidClientNumber( int num, char *str ) {
113 	if ( num < 0 || num > botlibglobals.maxclients ) {
114 		//weird: the disabled stuff results in a crash
115 		botimport.Print( PRT_ERROR, "%s: invalid client number %d, [0, %d]\n",
116 						 str, num, botlibglobals.maxclients );
117 		return qfalse;
118 	} //end if
119 	return qtrue;
120 } //end of the function BotValidateClientNumber
121 //===========================================================================
122 //
123 // Parameter:				-
124 // Returns:					-
125 // Changes Globals:		-
126 //===========================================================================
ValidEntityNumber(int num,char * str)127 qboolean ValidEntityNumber( int num, char *str ) {
128 	if ( num < 0 || num > botlibglobals.maxentities ) {
129 		botimport.Print( PRT_ERROR, "%s: invalid entity number %d, [0, %d]\n",
130 						 str, num, botlibglobals.maxentities );
131 		return qfalse;
132 	} //end if
133 	return qtrue;
134 } //end of the function BotValidateClientNumber
135 //===========================================================================
136 //
137 // Parameter:				-
138 // Returns:					-
139 // Changes Globals:		-
140 //===========================================================================
BotLibSetup(char * str)141 qboolean BotLibSetup( char *str ) {
142 //	return qtrue;
143 
144 	if ( !botlibglobals.botlibsetup ) {
145 		botimport.Print( PRT_ERROR, "%s: bot library used before being setup\n", str );
146 		return qfalse;
147 	} //end if
148 	return qtrue;
149 } //end of the function BotLibSetup
150 //===========================================================================
151 //
152 // Parameter:				-
153 // Returns:					-
154 // Changes Globals:		-
155 //===========================================================================
Export_BotLibSetup(void)156 int Export_BotLibSetup( void ) {
157 	int errnum;
158 
159 	botDeveloper = LibVarGetValue("bot_developer");
160  	memset( &botlibglobals, 0, sizeof(botlibglobals) );
161 	//initialize byte swapping (litte endian etc.)
162 //	Swap_Init();
163 
164 	if( botDeveloper )
165 	{
166 		Log_Open( "botlib.log" );
167 	}
168 
169 	botimport.Print( PRT_MESSAGE, "------- BotLib Initialization -------\n" );
170 	//
171 	botlibglobals.maxclients = (int) LibVarValue( "maxclients", "128" );
172 	botlibglobals.maxentities = (int) LibVarValue( "maxentities", "1024" );
173 
174 	errnum = AAS_Setup();           //be_aas_main.c
175 	if ( errnum != BLERR_NOERROR ) {
176 		return errnum;
177 	}
178 	errnum = EA_Setup();            //be_ea.c
179 	if ( errnum != BLERR_NOERROR ) {
180 		return errnum;
181 	}
182 //	errnum = BotSetupWeaponAI();	//be_ai_weap.c
183 //	if (errnum != BLERR_NOERROR)return errnum;
184 //	errnum = BotSetupGoalAI();		//be_ai_goal.c
185 //	if (errnum != BLERR_NOERROR) return errnum;
186 //	errnum = BotSetupChatAI();		//be_ai_chat.c
187 //	if (errnum != BLERR_NOERROR) return errnum;
188 //	errnum = BotSetupMoveAI();		//be_ai_move.c
189 //	if (errnum != BLERR_NOERROR) return errnum;
190 
191 	botlibsetup = qtrue;
192 	botlibglobals.botlibsetup = qtrue;
193 
194 	return BLERR_NOERROR;
195 } //end of the function Export_BotLibSetup
196 //===========================================================================
197 //
198 // Parameter:				-
199 // Returns:					-
200 // Changes Globals:		-
201 //===========================================================================
Export_BotLibShutdown(void)202 int Export_BotLibShutdown( void ) {
203 	static int recursive = 0;
204 
205 	if ( !BotLibSetup( "BotLibShutdown" ) ) {
206 		return BLERR_LIBRARYNOTSETUP;
207 	}
208 	//
209 	if ( recursive ) {
210 		return BLERR_NOERROR;
211 	}
212 	recursive = 1;
213 	// shutdown all AI subsystems
214 	BotShutdownChatAI();        //be_ai_chat.c
215 	BotShutdownMoveAI();        //be_ai_move.c
216 	BotShutdownGoalAI();        //be_ai_goal.c
217 	BotShutdownWeaponAI();      //be_ai_weap.c
218 	BotShutdownWeights();       //be_ai_weight.c
219 	BotShutdownCharacters();    //be_ai_char.c
220 	// shutdown AAS
221 	AAS_Shutdown();
222 	// shutdown bot elemantary actions
223 	EA_Shutdown();
224 	// free all libvars
225 	LibVarDeAllocAll();
226 	// remove all global defines from the pre compiler
227 	PC_RemoveAllGlobalDefines();
228 	// shut down library log file
229 	Log_Shutdown();
230 	//
231 	botlibsetup = qfalse;
232 	botlibglobals.botlibsetup = qfalse;
233 	recursive = 0;
234 	// print any files still open
235 	PC_CheckOpenSourceHandles();
236 	//
237 #ifdef _DEBUG
238 	Log_AlwaysOpen( "memory.log" );
239 	PrintMemoryLabels();
240 	Log_Shutdown();
241 #endif
242 	return BLERR_NOERROR;
243 } //end of the function Export_BotLibShutdown
244 //===========================================================================
245 //
246 // Parameter:				-
247 // Returns:					-
248 // Changes Globals:		-
249 //===========================================================================
Export_BotLibVarSet(const char * var_name,const char * value)250 int Export_BotLibVarSet( const char *var_name, const char *value ) {
251 	LibVarSet( var_name, value );
252 	return BLERR_NOERROR;
253 } //end of the function Export_BotLibVarSet
254 //===========================================================================
255 //
256 // Parameter:				-
257 // Returns:					-
258 // Changes Globals:		-
259 //===========================================================================
Export_BotLibVarGet(const char * var_name,char * value,int size)260 int Export_BotLibVarGet( const char *var_name, char *value, int size ) {
261 	char *varvalue;
262 
263 	varvalue = LibVarGetString( var_name );
264 	strncpy( value, varvalue, size - 1 );
265 	value[size - 1] = '\0';
266 	return BLERR_NOERROR;
267 } //end of the function Export_BotLibVarGet
268 //===========================================================================
269 //
270 // Parameter:				-
271 // Returns:					-
272 // Changes Globals:		-
273 //===========================================================================
Export_BotLibStartFrame(float time)274 int Export_BotLibStartFrame( float time ) {
275 	if ( !BotLibSetup( "BotStartFrame" ) ) {
276 		return BLERR_LIBRARYNOTSETUP;
277 	}
278 	return AAS_StartFrame( time );
279 } //end of the function Export_BotLibStartFrame
280 //===========================================================================
281 //
282 // Parameter:				-
283 // Returns:					-
284 // Changes Globals:		-
285 //===========================================================================
Export_BotLibLoadMap(const char * mapname)286 int Export_BotLibLoadMap( const char *mapname ) {
287 #ifdef DEBUG
288 	int starttime = Sys_MilliSeconds();
289 #endif
290 	int errnum;
291 
292 	if ( !BotLibSetup( "BotLoadMap" ) ) {
293 		return BLERR_LIBRARYNOTSETUP;
294 	}
295 	//
296 	botimport.Print( PRT_MESSAGE, "------------ Map Loading ------------\n" );
297 	//startup AAS for the current map, model and sound index
298 	errnum = AAS_LoadMap( mapname );
299 	if ( errnum != BLERR_NOERROR ) {
300 		return errnum;
301 	}
302 	//initialize the items in the level
303 	BotInitLevelItems();        //be_ai_goal.h
304 	BotSetBrushModelTypes();    //be_ai_move.h
305 	//
306 	botimport.Print( PRT_MESSAGE, "-------------------------------------\n" );
307 #ifdef DEBUG
308 	botimport.Print( PRT_MESSAGE, "map loaded in %d msec\n", Sys_MilliSeconds() - starttime );
309 #endif
310 	//
311 	return BLERR_NOERROR;
312 } //end of the function Export_BotLibLoadMap
313 //===========================================================================
314 //
315 // Parameter:				-
316 // Returns:					-
317 // Changes Globals:		-
318 //===========================================================================
Export_BotLibUpdateEntity(int ent,bot_entitystate_t * state)319 int Export_BotLibUpdateEntity( int ent, bot_entitystate_t *state ) {
320 	if ( !BotLibSetup( "BotUpdateEntity" ) ) {
321 		return BLERR_LIBRARYNOTSETUP;
322 	}
323 	if ( !ValidEntityNumber( ent, "BotUpdateEntity" ) ) {
324 		return BLERR_INVALIDENTITYNUMBER;
325 	}
326 
327 	return AAS_UpdateEntity( ent, state );
328 } //end of the function Export_BotLibUpdateEntity
329 //===========================================================================
330 //
331 // Parameter:				-
332 // Returns:					-
333 // Changes Globals:		-
334 //===========================================================================
335 void AAS_TestMovementPrediction( int entnum, vec3_t origin, vec3_t dir );
336 void ElevatorBottomCenter( aas_reachability_t *reach, vec3_t bottomcenter );
337 int BotGetReachabilityToGoal( vec3_t origin, int areanum, int entnum,
338 							  int lastgoalareanum, int lastareanum,
339 							  int *avoidreach, float *avoidreachtimes, int *avoidreachtries,
340 							  bot_goal_t *goal, int travelflags, int movetravelflags );
341 
342 int AAS_PointLight( vec3_t origin, int *red, int *green, int *blue );
343 
344 int AAS_TraceAreas( vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas );
345 
346 int AAS_Reachability_WeaponJump( int area1num, int area2num );
347 
348 int BotFuzzyPointReachabilityArea( vec3_t origin );
349 
350 float BotGapDistance( vec3_t origin, vec3_t hordir, int entnum );
351 
352 int AAS_NearestHideArea( int srcnum, vec3_t origin, int areanum, int enemynum, vec3_t enemyorigin, int enemyareanum, int travelflags );
353 
354 int AAS_FindAttackSpotWithinRange( int srcnum, int rangenum, int enemynum, float rangedist, int travelflags, float *outpos );
355 
356 void AAS_SetAASBlockingEntity( vec3_t absmin, vec3_t absmax, qboolean blocking );
357 
BotExportTest(int parm0,char * parm1,vec3_t parm2,vec3_t parm3)358 int BotExportTest( int parm0, char *parm1, vec3_t parm2, vec3_t parm3 ) {
359 
360 //	return AAS_PointLight(parm2, NULL, NULL, NULL);
361 
362 #ifdef DEBUG
363 	static int area = -1;
364 	static int line[2];
365 	int newarea, i, highlightarea, bot_testhidepos, hideposarea;
366 //	int reachnum;
367 	vec3_t eye, forward, right, end, origin;
368 //	vec3_t bottomcenter;
369 //	aas_trace_t trace;
370 //	aas_face_t *face;
371 //	aas_entity_t *ent;
372 //	bsp_trace_t bsptrace;
373 //	aas_reachability_t reach;
374 //	bot_goal_t goal;
375 
376 //	clock_t start_time, end_time;
377 	vec3_t mins = {-16, -16, -24};
378 	vec3_t maxs = {16, 16, 32};
379 //	int areas[10], numareas;
380 
381 
382 	//return 0;
383 
384 	if ( !( *aasworld ).loaded ) {
385 		return 0;
386 	}
387 	AAS_SetCurrentWorld( 0 );
388 
389 	for ( i = 0; i < 2; i++ ) if ( !line[i] ) {
390 			line[i] = botimport.DebugLineCreate();
391 		}
392 
393 //	AAS_ClearShownDebugLines();
394 	bot_testhidepos = LibVarGetValue( "bot_testhidepos" );
395 	if ( bot_testhidepos ) {
396 		VectorCopy( parm2, origin );
397 		newarea = BotFuzzyPointReachabilityArea( origin );
398 		if ( parm0 & 1 ) {
399 			botlibglobals.goalareanum = newarea;
400 			VectorCopy( origin, botlibglobals.goalorigin );
401 			botimport.Print( PRT_MESSAGE, "new enemy position %2.1f %2.1f %2.1f area %d\n",
402 							 origin[0], origin[1], origin[2], newarea );
403 		} //end if
404 		AAS_ClearShownPolygons();
405 		AAS_ClearShownDebugLines();
406 		hideposarea = AAS_NearestHideArea( 0, origin, AAS_PointAreaNum( origin ), 0,
407 										   botlibglobals.goalorigin, botlibglobals.goalareanum, TFL_DEFAULT );
408 
409 		//area we are currently in
410 		AAS_ShowAreaPolygons( newarea, 1, qtrue );
411 		//enemy position
412 		AAS_ShowAreaPolygons( botlibglobals.goalareanum, 2, qtrue );
413 		//area we should go hide
414 		AAS_ShowAreaPolygons( hideposarea, 4, qtrue );
415 		return 0;
416 	}
417 
418 	//if (AAS_AgainstLadder(parm2)) botimport.Print(PRT_MESSAGE, "against ladder\n");
419 	//BotOnGround(parm2, PRESENCE_NORMAL, 1, &newarea, &newarea);
420 	//botimport.Print(PRT_MESSAGE, "%f %f %f\n", parm2[0], parm2[1], parm2[2]);
421 	//*
422 	highlightarea = LibVarGetValue( "bot_highlightarea" );
423 	if ( highlightarea > 0 ) {
424 		newarea = highlightarea;
425 	} //end if
426 	else
427 	{
428 		VectorCopy( parm2, origin );
429 		origin[2] += 0.5;
430 		//newarea = AAS_PointAreaNum(origin);
431 		newarea = BotFuzzyPointReachabilityArea( origin );
432 	} //end else
433 
434 	botimport.Print( PRT_MESSAGE, "\rtravel time to goal (%d) = %d  ", botlibglobals.goalareanum,
435 					 AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT ) );
436 	//newarea = BotReachabilityArea(origin, qtrue);
437 	if ( newarea != area ) {
438 		botimport.Print( PRT_MESSAGE, "origin = %f, %f, %f\n", origin[0], origin[1], origin[2] );
439 		area = newarea;
440 		botimport.Print( PRT_MESSAGE, "new area %d, cluster %d, presence type %d\n",
441 						 area, AAS_AreaCluster( area ), AAS_PointPresenceType( origin ) );
442 		if ( ( *aasworld ).areasettings[area].areaflags & AREA_LIQUID ) {
443 			botimport.Print( PRT_MESSAGE, "liquid area\n" );
444 		} //end if
445 		botimport.Print( PRT_MESSAGE, "area contents: " );
446 		if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_WATER ) {
447 			botimport.Print( PRT_MESSAGE, "water " );
448 		} //end if
449 		if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_LAVA ) {
450 			botimport.Print( PRT_MESSAGE, "lava " );
451 		} //end if
452 		if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_SLIME ) {
453 //			botimport.Print(PRT_MESSAGE, "slime ");
454 			botimport.Print( PRT_MESSAGE, "slag " );
455 		} //end if
456 		if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_JUMPPAD ) {
457 			botimport.Print( PRT_MESSAGE, "jump pad " );
458 		} //end if
459 		if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_CLUSTERPORTAL ) {
460 			botimport.Print( PRT_MESSAGE, "cluster portal " );
461 		} //end if
462 		if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_DONOTENTER ) {
463 			botimport.Print( PRT_MESSAGE, "do not enter " );
464 		} //end if
465 		if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_DONOTENTER_LARGE ) {
466 			botimport.Print( PRT_MESSAGE, "do not enter large " );
467 		} //end if
468 		if ( !( *aasworld ).areasettings[area].contents ) {
469 			botimport.Print( PRT_MESSAGE, "empty " );
470 		} //end if
471 		if ( ( *aasworld ).areasettings[area].areaflags & AREA_DISABLED ) {
472 			botimport.Print( PRT_MESSAGE, "DISABLED" );
473 		} //end if
474 		botimport.Print( PRT_MESSAGE, "\n" );
475 		botimport.Print( PRT_MESSAGE, "travel time to goal (%d) = %d\n", botlibglobals.goalareanum,
476 						 AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT | TFL_ROCKETJUMP ) );
477 		/*
478 		VectorCopy(origin, end);
479 		end[2] += 5;
480 		numareas = AAS_TraceAreas(origin, end, areas, NULL, 10);
481 		AAS_TraceClientBBox(origin, end, PRESENCE_CROUCH, -1);
482 		botimport.Print(PRT_MESSAGE, "num areas = %d, area = %d\n", numareas, areas[0]);
483 		*/
484 		/*
485 		botlibglobals.goalareanum = newarea;
486 		VectorCopy(parm2, botlibglobals.goalorigin);
487 		botimport.Print(PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n",
488 								origin[0], origin[1], origin[2], newarea);
489 		*/
490 	} //end if
491 	  //*
492 	if ( parm0 & 1 ) {
493 		botlibglobals.goalareanum = newarea;
494 		VectorCopy( parm2, botlibglobals.goalorigin );
495 		botimport.Print( PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n",
496 						 origin[0], origin[1], origin[2], newarea );
497 	} //end if*/
498 //	if (parm0 & BUTTON_USE)
499 //	{
500 //		botlibglobals.runai = !botlibglobals.runai;
501 //		if (botlibglobals.runai) botimport.Print(PRT_MESSAGE, "started AI\n");
502 //		else botimport.Print(PRT_MESSAGE, "stopped AI\n");
503 	//* /
504 	/*
505 	goal.areanum = botlibglobals.goalareanum;
506 	reachnum = BotGetReachabilityToGoal(parm2, newarea, 1,
507 									ms.avoidreach, ms.avoidreachtimes,
508 									&goal, TFL_DEFAULT);
509 	if (!reachnum)
510 	{
511 		botimport.Print(PRT_MESSAGE, "goal not reachable\n");
512 	} //end if
513 	else
514 	{
515 		AAS_ReachabilityFromNum(reachnum, &reach);
516 		AAS_ClearShownDebugLines();
517 		AAS_ShowArea(area, qtrue);
518 		AAS_ShowArea(reach.areanum, qtrue);
519 		AAS_DrawCross(reach.start, 6, LINECOLOR_BLUE);
520 		AAS_DrawCross(reach.end, 6, LINECOLOR_RED);
521 		//
522 		if (reach.traveltype == TRAVEL_ELEVATOR)
523 		{
524 			ElevatorBottomCenter(&reach, bottomcenter);
525 			AAS_DrawCross(bottomcenter, 10, LINECOLOR_GREEN);
526 		} //end if
527 	} //end else*/
528 //		botimport.Print(PRT_MESSAGE, "travel time to goal = %d\n",
529 //					AAS_AreaTravelTimeToGoalArea(area, origin, botlibglobals.goalareanum, TFL_DEFAULT));
530 //		botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n");
531 //		AAS_Reachability_WeaponJump(703, 716);
532 //	} //end if*/
533 
534 /*	face = AAS_AreaGroundFace(newarea, parm2);
535 	if (face)
536 	{
537 		AAS_ShowFace(face - (*aasworld).faces);
538 	} //end if*/
539 	/*
540 	AAS_ClearShownDebugLines();
541 	AAS_ShowArea(newarea, parm0 & BUTTON_USE);
542 	AAS_ShowReachableAreas(area);
543 	*/
544 	AAS_ClearShownPolygons();
545 	AAS_ClearShownDebugLines();
546 	AAS_ShowAreaPolygons( newarea, 1, parm0 & 4 );
547 	if ( parm0 & 2 ) {
548 		AAS_ShowReachableAreas( area );
549 	} else
550 	{
551 		static int lastgoalareanum, lastareanum;
552 		static int avoidreach[MAX_AVOIDREACH];
553 		static float avoidreachtimes[MAX_AVOIDREACH];
554 		static int avoidreachtries[MAX_AVOIDREACH];
555 		int reachnum;
556 		bot_goal_t goal;
557 		aas_reachability_t reach;
558 
559 		goal.areanum = botlibglobals.goalareanum;
560 		VectorCopy( botlibglobals.goalorigin, goal.origin );
561 		reachnum = BotGetReachabilityToGoal( origin, newarea, -1,
562 											 lastgoalareanum, lastareanum,
563 											 avoidreach, avoidreachtimes, avoidreachtries,
564 											 &goal, TFL_DEFAULT | TFL_FUNCBOB, TFL_DEFAULT | TFL_FUNCBOB );
565 		AAS_ReachabilityFromNum( reachnum, &reach );
566 		AAS_ShowReachability( &reach );
567 	} //end else
568 	VectorClear( forward );
569 	//BotGapDistance(origin, forward, 0);
570 	/*
571 	if (parm0 & BUTTON_USE)
572 	{
573 		botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n");
574 		AAS_Reachability_WeaponJump(703, 716);
575 	} //end if*/
576 
577 	AngleVectors( parm3, forward, right, NULL );
578 	//get the eye 16 units to the right of the origin
579 	VectorMA( parm2, 8, right, eye );
580 	//get the eye 24 units up
581 	eye[2] += 24;
582 	//get the end point for the line to be traced
583 	VectorMA( eye, 800, forward, end );
584 
585 //	AAS_TestMovementPrediction(1, parm2, forward);
586 /*	//trace the line to find the hit point
587 	trace = AAS_TraceClientBBox(eye, end, PRESENCE_NORMAL, 1);
588 	if (!line[0]) line[0] = botimport.DebugLineCreate();
589 	botimport.DebugLineShow(line[0], eye, trace.endpos, LINECOLOR_BLUE);
590 	//
591 	AAS_ClearShownDebugLines();
592 	if (trace.ent)
593 	{
594 		ent = &(*aasworld).entities[trace.ent];
595 		AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
596 	} //end if*/
597 
598 /*
599 	start_time = clock();
600 	for (i = 0; i < 2000; i++)
601 	{
602 		AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
603 //		AAS_TraceClientBBox(eye, end, PRESENCE_NORMAL, 1);
604 	} //end for
605 	end_time = clock();
606 	botimport.Print(PRT_MESSAGE, "me %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC);
607 	start_time = clock();
608 	for (i = 0; i < 2000; i++)
609 	{
610 		AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
611 	} //end for
612 	end_time = clock();
613 	botimport.Print(PRT_MESSAGE, "id %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC);
614 */
615 
616 	/*
617 	AAS_ClearShownDebugLines();
618 	//bsptrace = AAS_Trace(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID);
619 	bsptrace = AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
620 	if (!line[0]) line[0] = botimport.DebugLineCreate();
621 	botimport.DebugLineShow(line[0], eye, bsptrace.endpos, LINECOLOR_YELLOW);
622 	if (bsptrace.fraction < 1.0)
623 	{
624 		face = AAS_TraceEndFace(&trace);
625 		if (face)
626 		{
627 			AAS_ShowFace(face - (*aasworld).faces);
628 		} //end if
629 		AAS_DrawPlaneCross(bsptrace.endpos,
630 									bsptrace.plane.normal,
631 									bsptrace.plane.dist + bsptrace.exp_dist,
632 									bsptrace.plane.type, LINECOLOR_GREEN);
633 		if (trace.ent)
634 		{
635 			ent = &(*aasworld).entities[trace.ent];
636 			AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
637 		} //end if
638 	} //end if*/
639 	/*/
640 	//bsptrace = AAS_Trace2(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID);
641 	bsptrace = AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
642 	botimport.DebugLineShow(line[1], eye, bsptrace.endpos, LINECOLOR_BLUE);
643 	if (bsptrace.fraction < 1.0)
644 	{
645 		AAS_DrawPlaneCross(bsptrace.endpos,
646 									bsptrace.plane.normal,
647 									bsptrace.plane.dist,// + bsptrace.exp_dist,
648 									bsptrace.plane.type, LINECOLOR_RED);
649 		if (bsptrace.ent)
650 		{
651 			ent = &(*aasworld).entities[bsptrace.ent];
652 			AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
653 		} //end if
654 	} //end if
655 	*/
656 #endif
657 	return 0;
658 } //end of the function BotExportTest
659 
660 
661 /*
662 ============
663 Init_AAS_Export
664 ============
665 */
Init_AAS_Export(aas_export_t * aas)666 static void Init_AAS_Export( aas_export_t *aas ) {
667 	//--------------------------------------------
668 	// be_aas_entity.c
669 	//--------------------------------------------
670 	aas->AAS_EntityInfo = AAS_EntityInfo;
671 	//--------------------------------------------
672 	// be_aas_main.c
673 	//--------------------------------------------
674 	aas->AAS_Initialized = AAS_Initialized;
675 	aas->AAS_PresenceTypeBoundingBox = AAS_PresenceTypeBoundingBox;
676 	aas->AAS_Time = AAS_Time;
677 	//--------------------------------------------
678 	// be_aas_sample.c
679 	//--------------------------------------------
680 	aas->AAS_PointAreaNum = AAS_PointAreaNum;
681 	aas->AAS_TraceAreas = AAS_TraceAreas;
682 	//--------------------------------------------
683 	// be_aas_bspq3.c
684 	//--------------------------------------------
685 	aas->AAS_PointContents = AAS_PointContents;
686 	aas->AAS_NextBSPEntity = AAS_NextBSPEntity;
687 	aas->AAS_ValueForBSPEpairKey = AAS_ValueForBSPEpairKey;
688 	aas->AAS_VectorForBSPEpairKey = AAS_VectorForBSPEpairKey;
689 	aas->AAS_FloatForBSPEpairKey = AAS_FloatForBSPEpairKey;
690 	aas->AAS_IntForBSPEpairKey = AAS_IntForBSPEpairKey;
691 	//--------------------------------------------
692 	// be_aas_reach.c
693 	//--------------------------------------------
694 	aas->AAS_AreaReachability = AAS_AreaReachability;
695 	//--------------------------------------------
696 	// be_aas_route.c
697 	//--------------------------------------------
698 	aas->AAS_AreaTravelTimeToGoalArea = AAS_AreaTravelTimeToGoalArea;
699 	//--------------------------------------------
700 	// be_aas_move.c
701 	//--------------------------------------------
702 	aas->AAS_Swimming = AAS_Swimming;
703 	aas->AAS_PredictClientMovement = AAS_PredictClientMovement;
704 
705 	// Ridah, route-tables
706 	//--------------------------------------------
707 	// be_aas_routetable.c
708 	//--------------------------------------------
709 	aas->AAS_RT_ShowRoute = AAS_RT_ShowRoute;
710 	aas->AAS_RT_GetHidePos = AAS_RT_GetHidePos;
711 	aas->AAS_FindAttackSpotWithinRange = AAS_FindAttackSpotWithinRange;
712 	aas->AAS_SetAASBlockingEntity = AAS_SetAASBlockingEntity;
713 	// done.
714 
715 	// Ridah, multiple AAS files
716 	aas->AAS_SetCurrentWorld = AAS_SetCurrentWorld;
717 	// done.
718 
719 }
720 
721 
722 /*
723 ============
724 Init_EA_Export
725 ============
726 */
Init_EA_Export(ea_export_t * ea)727 static void Init_EA_Export( ea_export_t *ea ) {
728 	//ClientCommand elementary actions
729 	ea->EA_Say = EA_Say;
730 	ea->EA_SayTeam = EA_SayTeam;
731 	ea->EA_UseItem = EA_UseItem;
732 	ea->EA_DropItem = EA_DropItem;
733 	ea->EA_UseInv = EA_UseInv;
734 	ea->EA_DropInv = EA_DropInv;
735 	ea->EA_Gesture = EA_Gesture;
736 	ea->EA_Command = EA_Command;
737 	ea->EA_SelectWeapon = EA_SelectWeapon;
738 	ea->EA_Talk = EA_Talk;
739 	ea->EA_Attack = EA_Attack;
740 	ea->EA_Reload = EA_Reload;
741 	ea->EA_Use = EA_Use;
742 	ea->EA_Respawn = EA_Respawn;
743 	ea->EA_Jump = EA_Jump;
744 	ea->EA_DelayedJump = EA_DelayedJump;
745 	ea->EA_Crouch = EA_Crouch;
746 	ea->EA_MoveUp = EA_MoveUp;
747 	ea->EA_MoveDown = EA_MoveDown;
748 	ea->EA_MoveForward = EA_MoveForward;
749 	ea->EA_MoveBack = EA_MoveBack;
750 	ea->EA_MoveLeft = EA_MoveLeft;
751 	ea->EA_MoveRight = EA_MoveRight;
752 	ea->EA_Move = EA_Move;
753 	ea->EA_View = EA_View;
754 	ea->EA_GetInput = EA_GetInput;
755 	ea->EA_EndRegular = EA_EndRegular;
756 	ea->EA_ResetInput = EA_ResetInput;
757 }
758 
759 
760 /*
761 ============
762 Init_AI_Export
763 ============
764 */
Init_AI_Export(ai_export_t * ai)765 static void Init_AI_Export( ai_export_t *ai ) {
766 	//-----------------------------------
767 	// be_ai_char.h
768 	//-----------------------------------
769 	ai->BotLoadCharacter = BotLoadCharacter;
770 	ai->BotFreeCharacter = BotFreeCharacter;
771 	ai->Characteristic_Float = Characteristic_Float;
772 	ai->Characteristic_BFloat = Characteristic_BFloat;
773 	ai->Characteristic_Integer = Characteristic_Integer;
774 	ai->Characteristic_BInteger = Characteristic_BInteger;
775 	ai->Characteristic_String = Characteristic_String;
776 	//-----------------------------------
777 	// be_ai_chat.h
778 	//-----------------------------------
779 	ai->BotAllocChatState = BotAllocChatState;
780 	ai->BotFreeChatState = BotFreeChatState;
781 	ai->BotQueueConsoleMessage = BotQueueConsoleMessage;
782 	ai->BotRemoveConsoleMessage = BotRemoveConsoleMessage;
783 	ai->BotNextConsoleMessage = BotNextConsoleMessage;
784 	ai->BotNumConsoleMessages = BotNumConsoleMessages;
785 	ai->BotInitialChat = BotInitialChat;
786 	ai->BotNumInitialChats = BotNumInitialChats;
787 	ai->BotReplyChat = BotReplyChat;
788 	ai->BotChatLength = BotChatLength;
789 	ai->BotEnterChat = BotEnterChat;
790 	ai->BotGetChatMessage = BotGetChatMessage;
791 	ai->StringContains = StringContains;
792 	ai->BotFindMatch = BotFindMatch;
793 	ai->BotMatchVariable = BotMatchVariable;
794 	ai->UnifyWhiteSpaces = UnifyWhiteSpaces;
795 	ai->BotReplaceSynonyms = BotReplaceSynonyms;
796 	ai->BotLoadChatFile = BotLoadChatFile;
797 	ai->BotSetChatGender = BotSetChatGender;
798 	ai->BotSetChatName = BotSetChatName;
799 	//-----------------------------------
800 	// be_ai_goal.h
801 	//-----------------------------------
802 	ai->BotResetGoalState = BotResetGoalState;
803 	ai->BotResetAvoidGoals = BotResetAvoidGoals;
804 	ai->BotRemoveFromAvoidGoals = BotRemoveFromAvoidGoals;
805 	ai->BotPushGoal = BotPushGoal;
806 	ai->BotPopGoal = BotPopGoal;
807 	ai->BotEmptyGoalStack = BotEmptyGoalStack;
808 	ai->BotDumpAvoidGoals = BotDumpAvoidGoals;
809 	ai->BotDumpGoalStack = BotDumpGoalStack;
810 	ai->BotGoalName = BotGoalName;
811 	ai->BotGetTopGoal = BotGetTopGoal;
812 	ai->BotGetSecondGoal = BotGetSecondGoal;
813 	ai->BotChooseLTGItem = BotChooseLTGItem;
814 	ai->BotChooseNBGItem = BotChooseNBGItem;
815 	ai->BotTouchingGoal = BotTouchingGoal;
816 	ai->BotItemGoalInVisButNotVisible = BotItemGoalInVisButNotVisible;
817 	ai->BotGetLevelItemGoal = BotGetLevelItemGoal;
818 	ai->BotGetNextCampSpotGoal = BotGetNextCampSpotGoal;
819 	ai->BotGetMapLocationGoal = BotGetMapLocationGoal;
820 	ai->BotAvoidGoalTime = BotAvoidGoalTime;
821 	ai->BotInitLevelItems = BotInitLevelItems;
822 	ai->BotUpdateEntityItems = BotUpdateEntityItems;
823 	ai->BotLoadItemWeights = BotLoadItemWeights;
824 	ai->BotFreeItemWeights = BotFreeItemWeights;
825 	ai->BotInterbreedGoalFuzzyLogic = BotInterbreedGoalFuzzyLogic;
826 	ai->BotSaveGoalFuzzyLogic = BotSaveGoalFuzzyLogic;
827 	ai->BotMutateGoalFuzzyLogic = BotMutateGoalFuzzyLogic;
828 	ai->BotAllocGoalState = BotAllocGoalState;
829 	ai->BotFreeGoalState = BotFreeGoalState;
830 	//-----------------------------------
831 	// be_ai_move.h
832 	//-----------------------------------
833 	ai->BotResetMoveState = BotResetMoveState;
834 	ai->BotMoveToGoal = BotMoveToGoal;
835 	ai->BotMoveInDirection = BotMoveInDirection;
836 	ai->BotResetAvoidReach = BotResetAvoidReach;
837 	ai->BotResetLastAvoidReach = BotResetLastAvoidReach;
838 	ai->BotReachabilityArea = BotReachabilityArea;
839 	ai->BotMovementViewTarget = BotMovementViewTarget;
840 	ai->BotPredictVisiblePosition = BotPredictVisiblePosition;
841 	ai->BotAllocMoveState = BotAllocMoveState;
842 	ai->BotFreeMoveState = BotFreeMoveState;
843 	ai->BotInitMoveState = BotInitMoveState;
844 	// Ridah
845 	ai->BotInitAvoidReach = BotInitAvoidReach;
846 	// done.
847 	//-----------------------------------
848 	// be_ai_weap.h
849 	//-----------------------------------
850 	ai->BotChooseBestFightWeapon = BotChooseBestFightWeapon;
851 	ai->BotGetWeaponInfo = BotGetWeaponInfo;
852 	ai->BotLoadWeaponWeights = BotLoadWeaponWeights;
853 	ai->BotAllocWeaponState = BotAllocWeaponState;
854 	ai->BotFreeWeaponState = BotFreeWeaponState;
855 	ai->BotResetWeaponState = BotResetWeaponState;
856 	//-----------------------------------
857 	// be_ai_gen.h
858 	//-----------------------------------
859 	ai->GeneticParentsAndChildSelection = GeneticParentsAndChildSelection;
860 }
861 
862 
863 /*
864 ============
865 GetBotLibAPI
866 ============
867 */
GetBotLibAPI(int apiVersion,botlib_import_t * import)868 botlib_export_t *GetBotLibAPI( int apiVersion, botlib_import_t *import ) {
869 	assert(import);
870 	botimport = *import;
871 	assert(botimport.Print);
872 
873 	memset( &be_botlib_export, 0, sizeof( be_botlib_export ) );
874 
875 	if ( apiVersion != BOTLIB_API_VERSION ) {
876 		botimport.Print( PRT_ERROR, "Mismatched BOTLIB_API_VERSION: expected %i, got %i\n", BOTLIB_API_VERSION, apiVersion );
877 		return NULL;
878 	}
879 
880 	Init_AAS_Export( &be_botlib_export.aas );
881 	Init_EA_Export( &be_botlib_export.ea );
882 	Init_AI_Export( &be_botlib_export.ai );
883 
884 	be_botlib_export.BotLibSetup = Export_BotLibSetup;
885 	be_botlib_export.BotLibShutdown = Export_BotLibShutdown;
886 	be_botlib_export.BotLibVarSet = Export_BotLibVarSet;
887 	be_botlib_export.BotLibVarGet = Export_BotLibVarGet;
888 	be_botlib_export.PC_AddGlobalDefine = PC_AddGlobalDefine;
889 	be_botlib_export.PC_LoadSourceHandle = PC_LoadSourceHandle;
890 	be_botlib_export.PC_FreeSourceHandle = PC_FreeSourceHandle;
891 	be_botlib_export.PC_ReadTokenHandle = PC_ReadTokenHandle;
892 	be_botlib_export.PC_SourceFileAndLine = PC_SourceFileAndLine;
893 
894 	be_botlib_export.BotLibStartFrame = Export_BotLibStartFrame;
895 	be_botlib_export.BotLibLoadMap = Export_BotLibLoadMap;
896 	be_botlib_export.BotLibUpdateEntity = Export_BotLibUpdateEntity;
897 	be_botlib_export.Test = BotExportTest;
898 
899 	return &be_botlib_export;
900 }
901