1 /*
2 ===========================================================================
3
4 Return to Castle Wolfenstein single player 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 single player GPL Source Code (RTCW SP Source Code).
8
9 RTCW SP 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 SP 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 SP Source Code. If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the RTCW SP 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 SP 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", "2048" );
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 ) {
190 return errnum;
191 }
192
193 botlibsetup = qtrue;
194 botlibglobals.botlibsetup = qtrue;
195
196 return BLERR_NOERROR;
197 } //end of the function Export_BotLibSetup
198 //===========================================================================
199 //
200 // Parameter: -
201 // Returns: -
202 // Changes Globals: -
203 //===========================================================================
Export_BotLibShutdown(void)204 int Export_BotLibShutdown( void ) {
205 static int recursive = 0;
206
207 if ( !BotLibSetup( "BotLibShutdown" ) ) {
208 return BLERR_LIBRARYNOTSETUP;
209 }
210 //
211 if ( recursive ) {
212 return BLERR_NOERROR;
213 }
214 recursive = 1;
215 // shutdown all AI subsystems
216 BotShutdownChatAI(); //be_ai_chat.c
217 BotShutdownMoveAI(); //be_ai_move.c
218 BotShutdownGoalAI(); //be_ai_goal.c
219 BotShutdownWeaponAI(); //be_ai_weap.c
220 BotShutdownWeights(); //be_ai_weight.c
221 BotShutdownCharacters(); //be_ai_char.c
222 // shutdown AAS
223 AAS_Shutdown();
224 // shutdown bot elemantary actions
225 EA_Shutdown();
226 // free all libvars
227 LibVarDeAllocAll();
228 // remove all global defines from the pre compiler
229 PC_RemoveAllGlobalDefines();
230 // shut down library log file
231 Log_Shutdown();
232 //
233 botlibsetup = qfalse;
234 botlibglobals.botlibsetup = qfalse;
235 recursive = 0;
236 // print any files still open
237 PC_CheckOpenSourceHandles();
238 //
239 #ifdef _DEBUG
240 Log_AlwaysOpen( "memory.log" );
241 PrintMemoryLabels();
242 Log_Shutdown();
243 #endif
244 return BLERR_NOERROR;
245 } //end of the function Export_BotLibShutdown
246 //===========================================================================
247 //
248 // Parameter: -
249 // Returns: -
250 // Changes Globals: -
251 //===========================================================================
Export_BotLibVarSet(const char * var_name,const char * value)252 int Export_BotLibVarSet( const char *var_name, const char *value ) {
253 LibVarSet( var_name, value );
254 return BLERR_NOERROR;
255 } //end of the function Export_BotLibVarSet
256 //===========================================================================
257 //
258 // Parameter: -
259 // Returns: -
260 // Changes Globals: -
261 //===========================================================================
Export_BotLibVarGet(const char * var_name,char * value,int size)262 int Export_BotLibVarGet( const char *var_name, char *value, int size ) {
263 char *varvalue;
264
265 varvalue = LibVarGetString( var_name );
266 strncpy( value, varvalue, size - 1 );
267 value[size - 1] = '\0';
268 return BLERR_NOERROR;
269 } //end of the function Export_BotLibVarGet
270 //===========================================================================
271 //
272 // Parameter: -
273 // Returns: -
274 // Changes Globals: -
275 //===========================================================================
Export_BotLibStartFrame(float time)276 int Export_BotLibStartFrame( float time ) {
277 if ( !BotLibSetup( "BotStartFrame" ) ) {
278 return BLERR_LIBRARYNOTSETUP;
279 }
280 return AAS_StartFrame( time );
281 } //end of the function Export_BotLibStartFrame
282 //===========================================================================
283 //
284 // Parameter: -
285 // Returns: -
286 // Changes Globals: -
287 //===========================================================================
Export_BotLibLoadMap(const char * mapname)288 int Export_BotLibLoadMap( const char *mapname ) {
289 #ifdef DEBUG
290 int starttime = Sys_MilliSeconds();
291 #endif
292 int errnum;
293
294 if ( !BotLibSetup( "BotLoadMap" ) ) {
295 return BLERR_LIBRARYNOTSETUP;
296 }
297 //
298 botimport.Print( PRT_MESSAGE, "------------ Map Loading ------------\n" );
299 //startup AAS for the current map, model and sound index
300 errnum = AAS_LoadMap( mapname );
301 if ( errnum != BLERR_NOERROR ) {
302 return errnum;
303 }
304 //initialize the items in the level
305 BotInitLevelItems(); //be_ai_goal.h
306 BotSetBrushModelTypes(); //be_ai_move.h
307 //
308 botimport.Print( PRT_MESSAGE, "-------------------------------------\n" );
309 #ifdef DEBUG
310 botimport.Print( PRT_MESSAGE, "map loaded in %d msec\n", Sys_MilliSeconds() - starttime );
311 #endif
312 //
313 return BLERR_NOERROR;
314 } //end of the function Export_BotLibLoadMap
315 //===========================================================================
316 //
317 // Parameter: -
318 // Returns: -
319 // Changes Globals: -
320 //===========================================================================
Export_BotLibUpdateEntity(int ent,bot_entitystate_t * state)321 int Export_BotLibUpdateEntity( int ent, bot_entitystate_t *state ) {
322 if ( !BotLibSetup( "BotUpdateEntity" ) ) {
323 return BLERR_LIBRARYNOTSETUP;
324 }
325 if ( !ValidEntityNumber( ent, "BotUpdateEntity" ) ) {
326 return BLERR_INVALIDENTITYNUMBER;
327 }
328
329 return AAS_UpdateEntity( ent, state );
330 } //end of the function Export_BotLibUpdateEntity
331 //===========================================================================
332 //
333 // Parameter: -
334 // Returns: -
335 // Changes Globals: -
336 //===========================================================================
337 void AAS_TestMovementPrediction( int entnum, vec3_t origin, vec3_t dir );
338 void ElevatorBottomCenter( aas_reachability_t *reach, vec3_t bottomcenter );
339 int BotGetReachabilityToGoal( vec3_t origin, int areanum, int entnum,
340 int lastgoalareanum, int lastareanum,
341 int *avoidreach, float *avoidreachtimes, int *avoidreachtries,
342 bot_goal_t *goal, int travelflags );
343
344 int AAS_PointLight( vec3_t origin, int *red, int *green, int *blue );
345
346 int AAS_TraceAreas( vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas );
347
348 int AAS_Reachability_WeaponJump( int area1num, int area2num );
349
350 int BotFuzzyPointReachabilityArea( vec3_t origin );
351
352 float BotGapDistance( vec3_t origin, vec3_t hordir, int entnum );
353
354 int AAS_NearestHideArea( int srcnum, vec3_t origin, int areanum, int enemynum, vec3_t enemyorigin, int enemyareanum, int travelflags );
355
356 int AAS_FindAttackSpotWithinRange( int srcnum, int rangenum, int enemynum, float rangedist, int travelflags, float *outpos );
357
358 qboolean AAS_GetRouteFirstVisPos( vec3_t srcpos, vec3_t destpos, int travelflags, vec3_t retpos );
359
360 void AAS_SetAASBlockingEntity( vec3_t absmin, vec3_t absmax, qboolean blocking );
361
BotExportTest(int parm0,char * parm1,vec3_t parm2,vec3_t parm3)362 int BotExportTest( int parm0, char *parm1, vec3_t parm2, vec3_t parm3 ) {
363
364 // return AAS_PointLight(parm2, NULL, NULL, NULL);
365
366 #ifdef DEBUG
367 static int area = -1;
368 static int line[2];
369 int newarea, i, highlightarea, bot_testhidepos, hideposarea, bot_testroutevispos;
370 // int reachnum;
371 vec3_t eye, forward, right, end, origin;
372 // vec3_t bottomcenter;
373 // aas_trace_t trace;
374 // aas_face_t *face;
375 // aas_entity_t *ent;
376 // bsp_trace_t bsptrace;
377 // aas_reachability_t reach;
378 // bot_goal_t goal;
379
380 // clock_t start_time, end_time;
381 vec3_t mins = {-16, -16, -24};
382 vec3_t maxs = {16, 16, 32};
383 // int areas[10], numareas;
384
385
386 //return 0;
387
388 if ( !( *aasworld ).loaded ) {
389 return 0;
390 }
391 AAS_SetCurrentWorld( 0 );
392
393 for ( i = 0; i < 2; i++ ) if ( !line[i] ) {
394 line[i] = botimport.DebugLineCreate();
395 }
396
397 // AAS_ClearShownDebugLines();
398 bot_testhidepos = LibVarGetValue( "bot_testhidepos" );
399 if ( bot_testhidepos ) {
400 VectorCopy( parm2, origin );
401 newarea = BotFuzzyPointReachabilityArea( origin );
402 if ( parm0 & 1 ) {
403 botlibglobals.goalareanum = newarea;
404 VectorCopy( origin, botlibglobals.goalorigin );
405 botimport.Print( PRT_MESSAGE, "new enemy position %2.1f %2.1f %2.1f area %d\n",
406 origin[0], origin[1], origin[2], newarea );
407 } //end if
408 AAS_ClearShownPolygons();
409 AAS_ClearShownDebugLines();
410 hideposarea = AAS_NearestHideArea( -1, origin, AAS_PointAreaNum( origin ), 0,
411 botlibglobals.goalorigin, botlibglobals.goalareanum, TFL_DEFAULT );
412
413 if ( bot_testhidepos > 1 ) {
414 if ( hideposarea ) {
415 botimport.Print( PRT_MESSAGE, "hidepos (%i) %2.1f %2.1f %2.1f\n",
416 hideposarea,
417 ( *aasworld ).areawaypoints[hideposarea][0],
418 ( *aasworld ).areawaypoints[hideposarea][1],
419 ( *aasworld ).areawaypoints[hideposarea][2] );
420 } else {
421 botimport.Print( PRT_MESSAGE, "no hidepos found\n" );
422 }
423 }
424
425 //area we are currently in
426 AAS_ShowAreaPolygons( newarea, 1, qtrue );
427 //enemy position
428 AAS_ShowAreaPolygons( botlibglobals.goalareanum, 2, qtrue );
429 //area we should go hide
430 AAS_ShowAreaPolygons( hideposarea, 4, qtrue );
431 return 0;
432 }
433
434 bot_testroutevispos = LibVarGetValue( "bot_testroutevispos" );
435 if ( bot_testroutevispos ) {
436 VectorCopy( parm2, origin );
437 newarea = BotFuzzyPointReachabilityArea( origin );
438 if ( parm0 & 1 ) {
439 botlibglobals.goalareanum = newarea;
440 VectorCopy( origin, botlibglobals.goalorigin );
441 botimport.Print( PRT_MESSAGE, "new enemy position %2.1f %2.1f %2.1f area %d\n",
442 origin[0], origin[1], origin[2], newarea );
443 } //end if
444 AAS_ClearShownPolygons();
445 AAS_ClearShownDebugLines();
446 AAS_GetRouteFirstVisPos( botlibglobals.goalorigin, origin, TFL_DEFAULT, eye );
447 //area we are currently in
448 AAS_ShowAreaPolygons( newarea, 1, qtrue );
449 //enemy position
450 AAS_ShowAreaPolygons( botlibglobals.goalareanum, 2, qtrue );
451 //area that is visible in path from enemy pos
452 hideposarea = BotFuzzyPointReachabilityArea( eye );
453 AAS_ShowAreaPolygons( hideposarea, 4, qtrue );
454 return 0;
455 }
456
457 //if (AAS_AgainstLadder(parm2)) botimport.Print(PRT_MESSAGE, "against ladder\n");
458 //BotOnGround(parm2, PRESENCE_NORMAL, 1, &newarea, &newarea);
459 //botimport.Print(PRT_MESSAGE, "%f %f %f\n", parm2[0], parm2[1], parm2[2]);
460 //*
461 highlightarea = LibVarGetValue( "bot_highlightarea" );
462 if ( highlightarea > 0 ) {
463 newarea = highlightarea;
464 } //end if
465 else
466 {
467 VectorCopy( parm2, origin );
468 origin[2] += 0.5;
469 //newarea = AAS_PointAreaNum(origin);
470 newarea = BotFuzzyPointReachabilityArea( origin );
471 } //end else
472
473 botimport.Print( PRT_MESSAGE, "\rtravel time to goal (%d) = %d ", botlibglobals.goalareanum,
474 AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT ) );
475 //newarea = BotReachabilityArea(origin, qtrue);
476 if ( newarea != area ) {
477 botimport.Print( PRT_MESSAGE, "origin = %f, %f, %f\n", origin[0], origin[1], origin[2] );
478 area = newarea;
479 botimport.Print( PRT_MESSAGE, "new area %d, cluster %d, presence type %d\n",
480 area, AAS_AreaCluster( area ), AAS_PointPresenceType( origin ) );
481 if ( ( *aasworld ).areasettings[area].areaflags & AREA_LIQUID ) {
482 botimport.Print( PRT_MESSAGE, "liquid area\n" );
483 } //end if
484 botimport.Print( PRT_MESSAGE, "area contents: " );
485 if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_WATER ) {
486 botimport.Print( PRT_MESSAGE, "water " );
487 } //end if
488 if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_LAVA ) {
489 botimport.Print( PRT_MESSAGE, "lava " );
490 } //end if
491 if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_SLIME ) {
492 // botimport.Print(PRT_MESSAGE, "slime ");
493 botimport.Print( PRT_MESSAGE, "slag " );
494 } //end if
495 if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_JUMPPAD ) {
496 botimport.Print( PRT_MESSAGE, "jump pad " );
497 } //end if
498 if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_CLUSTERPORTAL ) {
499 botimport.Print( PRT_MESSAGE, "cluster portal " );
500 } //end if
501 if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_DONOTENTER ) {
502 botimport.Print( PRT_MESSAGE, "do not enter " );
503 } //end if
504 if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_DONOTENTER_LARGE ) {
505 botimport.Print( PRT_MESSAGE, "do not enter large " );
506 } //end if
507 if ( !( *aasworld ).areasettings[area].contents ) {
508 botimport.Print( PRT_MESSAGE, "empty " );
509 } //end if
510 if ( ( *aasworld ).areasettings[area].areaflags & AREA_DISABLED ) {
511 botimport.Print( PRT_MESSAGE, "DISABLED" );
512 } //end if
513 botimport.Print( PRT_MESSAGE, "\n" );
514 botimport.Print( PRT_MESSAGE, "travel time to goal (%d) = %d\n", botlibglobals.goalareanum,
515 AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT | TFL_ROCKETJUMP ) );
516 /*
517 VectorCopy(origin, end);
518 end[2] += 5;
519 numareas = AAS_TraceAreas(origin, end, areas, NULL, 10);
520 AAS_TraceClientBBox(origin, end, PRESENCE_CROUCH, -1);
521 botimport.Print(PRT_MESSAGE, "num areas = %d, area = %d\n", numareas, areas[0]);
522 */
523 /*
524 botlibglobals.goalareanum = newarea;
525 VectorCopy(parm2, botlibglobals.goalorigin);
526 botimport.Print(PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n",
527 origin[0], origin[1], origin[2], newarea);
528 */
529 } //end if
530 //*
531 if ( parm0 & 1 ) {
532 botlibglobals.goalareanum = newarea;
533 VectorCopy( parm2, botlibglobals.goalorigin );
534 botimport.Print( PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n",
535 origin[0], origin[1], origin[2], newarea );
536 } //end if*/
537 // if (parm0 & BUTTON_USE)
538 // {
539 // botlibglobals.runai = !botlibglobals.runai;
540 // if (botlibglobals.runai) botimport.Print(PRT_MESSAGE, "started AI\n");
541 // else botimport.Print(PRT_MESSAGE, "stopped AI\n");
542 //* /
543 /*
544 goal.areanum = botlibglobals.goalareanum;
545 reachnum = BotGetReachabilityToGoal(parm2, newarea, 1,
546 ms.avoidreach, ms.avoidreachtimes,
547 &goal, TFL_DEFAULT);
548 if (!reachnum)
549 {
550 botimport.Print(PRT_MESSAGE, "goal not reachable\n");
551 } //end if
552 else
553 {
554 AAS_ReachabilityFromNum(reachnum, &reach);
555 AAS_ClearShownDebugLines();
556 AAS_ShowArea(area, qtrue);
557 AAS_ShowArea(reach.areanum, qtrue);
558 AAS_DrawCross(reach.start, 6, LINECOLOR_BLUE);
559 AAS_DrawCross(reach.end, 6, LINECOLOR_RED);
560 //
561 if (reach.traveltype == TRAVEL_ELEVATOR)
562 {
563 ElevatorBottomCenter(&reach, bottomcenter);
564 AAS_DrawCross(bottomcenter, 10, LINECOLOR_GREEN);
565 } //end if
566 } //end else*/
567 // botimport.Print(PRT_MESSAGE, "travel time to goal = %d\n",
568 // AAS_AreaTravelTimeToGoalArea(area, origin, botlibglobals.goalareanum, TFL_DEFAULT));
569 // botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n");
570 // AAS_Reachability_WeaponJump(703, 716);
571 // } //end if*/
572
573 /* face = AAS_AreaGroundFace(newarea, parm2);
574 if (face)
575 {
576 AAS_ShowFace(face - (*aasworld).faces);
577 } //end if*/
578 /*
579 AAS_ClearShownDebugLines();
580 AAS_ShowArea(newarea, parm0 & BUTTON_USE);
581 AAS_ShowReachableAreas(area);
582 */
583 AAS_ClearShownPolygons();
584 AAS_ClearShownDebugLines();
585 AAS_ShowAreaPolygons( newarea, 1, parm0 & 4 );
586 if ( parm0 & 2 ) {
587 AAS_ShowReachableAreas( area );
588 } else
589 {
590 static int lastgoalareanum, lastareanum;
591 static int avoidreach[MAX_AVOIDREACH];
592 static float avoidreachtimes[MAX_AVOIDREACH];
593 static int avoidreachtries[MAX_AVOIDREACH];
594 int reachnum;
595 bot_goal_t goal;
596 aas_reachability_t reach;
597
598 goal.areanum = botlibglobals.goalareanum;
599 VectorCopy( botlibglobals.goalorigin, goal.origin );
600 reachnum = BotGetReachabilityToGoal( origin, newarea, -1,
601 lastgoalareanum, lastareanum,
602 avoidreach, avoidreachtimes, avoidreachtries,
603 &goal, TFL_DEFAULT | TFL_FUNCBOB, TFL_DEFAULT | TFL_FUNCBOB );
604 AAS_ReachabilityFromNum( reachnum, &reach );
605 AAS_ShowReachability( &reach );
606 } //end else
607 VectorClear( forward );
608 //BotGapDistance(origin, forward, 0);
609 /*
610 if (parm0 & BUTTON_USE)
611 {
612 botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n");
613 AAS_Reachability_WeaponJump(703, 716);
614 } //end if*/
615
616 AngleVectors( parm3, forward, right, NULL );
617 //get the eye 16 units to the right of the origin
618 VectorMA( parm2, 8, right, eye );
619 //get the eye 24 units up
620 eye[2] += 24;
621 //get the end point for the line to be traced
622 VectorMA( eye, 800, forward, end );
623
624 // AAS_TestMovementPrediction(1, parm2, forward);
625 /* //trace the line to find the hit point
626 trace = AAS_TraceClientBBox(eye, end, PRESENCE_NORMAL, 1);
627 if (!line[0]) line[0] = botimport.DebugLineCreate();
628 botimport.DebugLineShow(line[0], eye, trace.endpos, LINECOLOR_BLUE);
629 //
630 AAS_ClearShownDebugLines();
631 if (trace.ent)
632 {
633 ent = &(*aasworld).entities[trace.ent];
634 AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
635 } //end if*/
636
637 /*
638 start_time = clock();
639 for (i = 0; i < 2000; i++)
640 {
641 AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
642 // AAS_TraceClientBBox(eye, end, PRESENCE_NORMAL, 1);
643 } //end for
644 end_time = clock();
645 botimport.Print(PRT_MESSAGE, "me %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC);
646 start_time = clock();
647 for (i = 0; i < 2000; i++)
648 {
649 AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
650 } //end for
651 end_time = clock();
652 botimport.Print(PRT_MESSAGE, "id %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC);
653 */
654
655 /*
656 AAS_ClearShownDebugLines();
657 //bsptrace = AAS_Trace(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID);
658 bsptrace = AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
659 if (!line[0]) line[0] = botimport.DebugLineCreate();
660 botimport.DebugLineShow(line[0], eye, bsptrace.endpos, LINECOLOR_YELLOW);
661 if (bsptrace.fraction < 1.0)
662 {
663 face = AAS_TraceEndFace(&trace);
664 if (face)
665 {
666 AAS_ShowFace(face - (*aasworld).faces);
667 } //end if
668 AAS_DrawPlaneCross(bsptrace.endpos,
669 bsptrace.plane.normal,
670 bsptrace.plane.dist + bsptrace.exp_dist,
671 bsptrace.plane.type, LINECOLOR_GREEN);
672 if (trace.ent)
673 {
674 ent = &(*aasworld).entities[trace.ent];
675 AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
676 } //end if
677 } //end if*/
678 /*/
679 //bsptrace = AAS_Trace2(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID);
680 bsptrace = AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
681 botimport.DebugLineShow(line[1], eye, bsptrace.endpos, LINECOLOR_BLUE);
682 if (bsptrace.fraction < 1.0)
683 {
684 AAS_DrawPlaneCross(bsptrace.endpos,
685 bsptrace.plane.normal,
686 bsptrace.plane.dist,// + bsptrace.exp_dist,
687 bsptrace.plane.type, LINECOLOR_RED);
688 if (bsptrace.ent)
689 {
690 ent = &(*aasworld).entities[bsptrace.ent];
691 AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
692 } //end if
693 } //end if
694 */
695 #endif
696 return 0;
697 } //end of the function BotExportTest
698
699
700 /*
701 ============
702 Init_AAS_Export
703 ============
704 */
Init_AAS_Export(aas_export_t * aas)705 static void Init_AAS_Export( aas_export_t *aas ) {
706 //--------------------------------------------
707 // be_aas_entity.c
708 //--------------------------------------------
709 aas->AAS_EntityInfo = AAS_EntityInfo;
710 //--------------------------------------------
711 // be_aas_main.c
712 //--------------------------------------------
713 aas->AAS_Initialized = AAS_Initialized;
714 aas->AAS_PresenceTypeBoundingBox = AAS_PresenceTypeBoundingBox;
715 aas->AAS_Time = AAS_Time;
716 //--------------------------------------------
717 // be_aas_sample.c
718 //--------------------------------------------
719 aas->AAS_PointAreaNum = AAS_PointAreaNum;
720 aas->AAS_TraceAreas = AAS_TraceAreas;
721 //--------------------------------------------
722 // be_aas_bspq3.c
723 //--------------------------------------------
724 aas->AAS_PointContents = AAS_PointContents;
725 aas->AAS_NextBSPEntity = AAS_NextBSPEntity;
726 aas->AAS_ValueForBSPEpairKey = AAS_ValueForBSPEpairKey;
727 aas->AAS_VectorForBSPEpairKey = AAS_VectorForBSPEpairKey;
728 aas->AAS_FloatForBSPEpairKey = AAS_FloatForBSPEpairKey;
729 aas->AAS_IntForBSPEpairKey = AAS_IntForBSPEpairKey;
730 //--------------------------------------------
731 // be_aas_reach.c
732 //--------------------------------------------
733 aas->AAS_AreaReachability = AAS_AreaReachability;
734 //--------------------------------------------
735 // be_aas_route.c
736 //--------------------------------------------
737 aas->AAS_AreaTravelTimeToGoalArea = AAS_AreaTravelTimeToGoalArea;
738 //--------------------------------------------
739 // be_aas_move.c
740 //--------------------------------------------
741 aas->AAS_Swimming = AAS_Swimming;
742 aas->AAS_PredictClientMovement = AAS_PredictClientMovement;
743
744 // Ridah, route-tables
745 //--------------------------------------------
746 // be_aas_routetable.c
747 //--------------------------------------------
748 aas->AAS_RT_ShowRoute = AAS_RT_ShowRoute;
749 aas->AAS_RT_GetHidePos = AAS_RT_GetHidePos;
750 aas->AAS_FindAttackSpotWithinRange = AAS_FindAttackSpotWithinRange;
751 aas->AAS_GetRouteFirstVisPos = AAS_GetRouteFirstVisPos;
752 aas->AAS_SetAASBlockingEntity = AAS_SetAASBlockingEntity;
753 // done.
754
755 // Ridah, multiple AAS files
756 aas->AAS_SetCurrentWorld = AAS_SetCurrentWorld;
757 // done.
758
759 }
760
761
762 /*
763 ============
764 Init_EA_Export
765 ============
766 */
Init_EA_Export(ea_export_t * ea)767 static void Init_EA_Export( ea_export_t *ea ) {
768 //ClientCommand elementary actions
769 ea->EA_Say = EA_Say;
770 ea->EA_SayTeam = EA_SayTeam;
771 ea->EA_UseItem = EA_UseItem;
772 ea->EA_DropItem = EA_DropItem;
773 ea->EA_UseInv = EA_UseInv;
774 ea->EA_DropInv = EA_DropInv;
775 ea->EA_Gesture = EA_Gesture;
776 ea->EA_Command = EA_Command;
777 ea->EA_SelectWeapon = EA_SelectWeapon;
778 ea->EA_Talk = EA_Talk;
779 ea->EA_Attack = EA_Attack;
780 ea->EA_Reload = EA_Reload;
781 ea->EA_Use = EA_Use;
782 ea->EA_Respawn = EA_Respawn;
783 ea->EA_Jump = EA_Jump;
784 ea->EA_DelayedJump = EA_DelayedJump;
785 ea->EA_Crouch = EA_Crouch;
786 ea->EA_MoveUp = EA_MoveUp;
787 ea->EA_MoveDown = EA_MoveDown;
788 ea->EA_MoveForward = EA_MoveForward;
789 ea->EA_MoveBack = EA_MoveBack;
790 ea->EA_MoveLeft = EA_MoveLeft;
791 ea->EA_MoveRight = EA_MoveRight;
792 ea->EA_Move = EA_Move;
793 ea->EA_View = EA_View;
794 ea->EA_GetInput = EA_GetInput;
795 ea->EA_EndRegular = EA_EndRegular;
796 ea->EA_ResetInput = EA_ResetInput;
797 }
798
799
800 /*
801 ============
802 Init_AI_Export
803 ============
804 */
Init_AI_Export(ai_export_t * ai)805 static void Init_AI_Export( ai_export_t *ai ) {
806 //-----------------------------------
807 // be_ai_char.h
808 //-----------------------------------
809 ai->BotLoadCharacter = BotLoadCharacter;
810 ai->BotFreeCharacter = BotFreeCharacter;
811 ai->Characteristic_Float = Characteristic_Float;
812 ai->Characteristic_BFloat = Characteristic_BFloat;
813 ai->Characteristic_Integer = Characteristic_Integer;
814 ai->Characteristic_BInteger = Characteristic_BInteger;
815 ai->Characteristic_String = Characteristic_String;
816 //-----------------------------------
817 // be_ai_chat.h
818 //-----------------------------------
819 ai->BotAllocChatState = BotAllocChatState;
820 ai->BotFreeChatState = BotFreeChatState;
821 ai->BotQueueConsoleMessage = BotQueueConsoleMessage;
822 ai->BotRemoveConsoleMessage = BotRemoveConsoleMessage;
823 ai->BotNextConsoleMessage = BotNextConsoleMessage;
824 ai->BotNumConsoleMessages = BotNumConsoleMessages;
825 ai->BotInitialChat = BotInitialChat;
826 ai->BotNumInitialChats = BotNumInitialChats;
827 ai->BotReplyChat = BotReplyChat;
828 ai->BotChatLength = BotChatLength;
829 ai->BotEnterChat = BotEnterChat;
830 ai->BotGetChatMessage = BotGetChatMessage;
831 ai->StringContains = StringContains;
832 ai->BotFindMatch = BotFindMatch;
833 ai->BotMatchVariable = BotMatchVariable;
834 ai->UnifyWhiteSpaces = UnifyWhiteSpaces;
835 ai->BotReplaceSynonyms = BotReplaceSynonyms;
836 ai->BotLoadChatFile = BotLoadChatFile;
837 ai->BotSetChatGender = BotSetChatGender;
838 ai->BotSetChatName = BotSetChatName;
839 //-----------------------------------
840 // be_ai_goal.h
841 //-----------------------------------
842 ai->BotResetGoalState = BotResetGoalState;
843 ai->BotResetAvoidGoals = BotResetAvoidGoals;
844 ai->BotRemoveFromAvoidGoals = BotRemoveFromAvoidGoals;
845 ai->BotPushGoal = BotPushGoal;
846 ai->BotPopGoal = BotPopGoal;
847 ai->BotEmptyGoalStack = BotEmptyGoalStack;
848 ai->BotDumpAvoidGoals = BotDumpAvoidGoals;
849 ai->BotDumpGoalStack = BotDumpGoalStack;
850 ai->BotGoalName = BotGoalName;
851 ai->BotGetTopGoal = BotGetTopGoal;
852 ai->BotGetSecondGoal = BotGetSecondGoal;
853 ai->BotChooseLTGItem = BotChooseLTGItem;
854 ai->BotChooseNBGItem = BotChooseNBGItem;
855 ai->BotTouchingGoal = BotTouchingGoal;
856 ai->BotItemGoalInVisButNotVisible = BotItemGoalInVisButNotVisible;
857 ai->BotGetLevelItemGoal = BotGetLevelItemGoal;
858 ai->BotGetNextCampSpotGoal = BotGetNextCampSpotGoal;
859 ai->BotGetMapLocationGoal = BotGetMapLocationGoal;
860 ai->BotAvoidGoalTime = BotAvoidGoalTime;
861 ai->BotInitLevelItems = BotInitLevelItems;
862 ai->BotUpdateEntityItems = BotUpdateEntityItems;
863 ai->BotLoadItemWeights = BotLoadItemWeights;
864 ai->BotFreeItemWeights = BotFreeItemWeights;
865 ai->BotInterbreedGoalFuzzyLogic = BotInterbreedGoalFuzzyLogic;
866 ai->BotSaveGoalFuzzyLogic = BotSaveGoalFuzzyLogic;
867 ai->BotMutateGoalFuzzyLogic = BotMutateGoalFuzzyLogic;
868 ai->BotAllocGoalState = BotAllocGoalState;
869 ai->BotFreeGoalState = BotFreeGoalState;
870 //-----------------------------------
871 // be_ai_move.h
872 //-----------------------------------
873 ai->BotResetMoveState = BotResetMoveState;
874 ai->BotMoveToGoal = BotMoveToGoal;
875 ai->BotMoveInDirection = BotMoveInDirection;
876 ai->BotResetAvoidReach = BotResetAvoidReach;
877 ai->BotResetLastAvoidReach = BotResetLastAvoidReach;
878 ai->BotReachabilityArea = BotReachabilityArea;
879 ai->BotMovementViewTarget = BotMovementViewTarget;
880 ai->BotPredictVisiblePosition = BotPredictVisiblePosition;
881 ai->BotAllocMoveState = BotAllocMoveState;
882 ai->BotFreeMoveState = BotFreeMoveState;
883 ai->BotInitMoveState = BotInitMoveState;
884 // Ridah
885 ai->BotInitAvoidReach = BotInitAvoidReach;
886 // done.
887 //-----------------------------------
888 // be_ai_weap.h
889 //-----------------------------------
890 ai->BotChooseBestFightWeapon = BotChooseBestFightWeapon;
891 ai->BotGetWeaponInfo = BotGetWeaponInfo;
892 ai->BotLoadWeaponWeights = BotLoadWeaponWeights;
893 ai->BotAllocWeaponState = BotAllocWeaponState;
894 ai->BotFreeWeaponState = BotFreeWeaponState;
895 ai->BotResetWeaponState = BotResetWeaponState;
896 //-----------------------------------
897 // be_ai_gen.h
898 //-----------------------------------
899 ai->GeneticParentsAndChildSelection = GeneticParentsAndChildSelection;
900 }
901
902
903 /*
904 ============
905 GetBotLibAPI
906 ============
907 */
GetBotLibAPI(int apiVersion,botlib_import_t * import)908 botlib_export_t *GetBotLibAPI( int apiVersion, botlib_import_t *import ) {
909 assert(import);
910 botimport = *import;
911 assert(botimport.Print);
912
913 memset( &be_botlib_export, 0, sizeof( be_botlib_export ) );
914
915 if ( apiVersion != BOTLIB_API_VERSION ) {
916 botimport.Print( PRT_ERROR, "Mismatched BOTLIB_API_VERSION: expected %i, got %i\n", BOTLIB_API_VERSION, apiVersion );
917 return NULL;
918 }
919
920 Init_AAS_Export( &be_botlib_export.aas );
921 Init_EA_Export( &be_botlib_export.ea );
922 Init_AI_Export( &be_botlib_export.ai );
923
924 be_botlib_export.BotLibSetup = Export_BotLibSetup;
925 be_botlib_export.BotLibShutdown = Export_BotLibShutdown;
926 be_botlib_export.BotLibVarSet = Export_BotLibVarSet;
927 be_botlib_export.BotLibVarGet = Export_BotLibVarGet;
928 be_botlib_export.PC_AddGlobalDefine = PC_AddGlobalDefine;
929 be_botlib_export.PC_LoadSourceHandle = PC_LoadSourceHandle;
930 be_botlib_export.PC_FreeSourceHandle = PC_FreeSourceHandle;
931 be_botlib_export.PC_ReadTokenHandle = PC_ReadTokenHandle;
932 be_botlib_export.PC_SourceFileAndLine = PC_SourceFileAndLine;
933
934 be_botlib_export.BotLibStartFrame = Export_BotLibStartFrame;
935 be_botlib_export.BotLibLoadMap = Export_BotLibLoadMap;
936 be_botlib_export.BotLibUpdateEntity = Export_BotLibUpdateEntity;
937 be_botlib_export.Test = BotExportTest;
938
939 return &be_botlib_export;
940 }
941