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