be_aas_bspq3.c (14645B)
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 Foobar; 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_aas_bspq3.c 25 * 26 * desc: BSP, Environment Sampling 27 * 28 * $Archive: /MissionPack/code/botlib/be_aas_bspq3.c $ 29 * 30 *****************************************************************************/ 31 32 #include "../game/q_shared.h" 33 #include "l_memory.h" 34 #include "l_script.h" 35 #include "l_precomp.h" 36 #include "l_struct.h" 37 #include "aasfile.h" 38 #include "../game/botlib.h" 39 #include "../game/be_aas.h" 40 #include "be_aas_funcs.h" 41 #include "be_aas_def.h" 42 43 extern botlib_import_t botimport; 44 45 //#define TRACE_DEBUG 46 47 #define ON_EPSILON 0.005 48 //#define DEG2RAD( a ) (( a * M_PI ) / 180.0F) 49 50 #define MAX_BSPENTITIES 2048 51 52 typedef struct rgb_s 53 { 54 int red; 55 int green; 56 int blue; 57 } rgb_t; 58 59 //bsp entity epair 60 typedef struct bsp_epair_s 61 { 62 char *key; 63 char *value; 64 struct bsp_epair_s *next; 65 } bsp_epair_t; 66 67 //bsp data entity 68 typedef struct bsp_entity_s 69 { 70 bsp_epair_t *epairs; 71 } bsp_entity_t; 72 73 //id Sofware BSP data 74 typedef struct bsp_s 75 { 76 //true when bsp file is loaded 77 int loaded; 78 //entity data 79 int entdatasize; 80 char *dentdata; 81 //bsp entities 82 int numentities; 83 bsp_entity_t entities[MAX_BSPENTITIES]; 84 } bsp_t; 85 86 //global bsp 87 bsp_t bspworld; 88 89 90 #ifdef BSP_DEBUG 91 typedef struct cname_s 92 { 93 int value; 94 char *name; 95 } cname_t; 96 97 cname_t contentnames[] = 98 { 99 {CONTENTS_SOLID,"CONTENTS_SOLID"}, 100 {CONTENTS_WINDOW,"CONTENTS_WINDOW"}, 101 {CONTENTS_AUX,"CONTENTS_AUX"}, 102 {CONTENTS_LAVA,"CONTENTS_LAVA"}, 103 {CONTENTS_SLIME,"CONTENTS_SLIME"}, 104 {CONTENTS_WATER,"CONTENTS_WATER"}, 105 {CONTENTS_MIST,"CONTENTS_MIST"}, 106 {LAST_VISIBLE_CONTENTS,"LAST_VISIBLE_CONTENTS"}, 107 108 {CONTENTS_AREAPORTAL,"CONTENTS_AREAPORTAL"}, 109 {CONTENTS_PLAYERCLIP,"CONTENTS_PLAYERCLIP"}, 110 {CONTENTS_MONSTERCLIP,"CONTENTS_MONSTERCLIP"}, 111 {CONTENTS_CURRENT_0,"CONTENTS_CURRENT_0"}, 112 {CONTENTS_CURRENT_90,"CONTENTS_CURRENT_90"}, 113 {CONTENTS_CURRENT_180,"CONTENTS_CURRENT_180"}, 114 {CONTENTS_CURRENT_270,"CONTENTS_CURRENT_270"}, 115 {CONTENTS_CURRENT_UP,"CONTENTS_CURRENT_UP"}, 116 {CONTENTS_CURRENT_DOWN,"CONTENTS_CURRENT_DOWN"}, 117 {CONTENTS_ORIGIN,"CONTENTS_ORIGIN"}, 118 {CONTENTS_MONSTER,"CONTENTS_MONSTER"}, 119 {CONTENTS_DEADMONSTER,"CONTENTS_DEADMONSTER"}, 120 {CONTENTS_DETAIL,"CONTENTS_DETAIL"}, 121 {CONTENTS_TRANSLUCENT,"CONTENTS_TRANSLUCENT"}, 122 {CONTENTS_LADDER,"CONTENTS_LADDER"}, 123 {0, 0} 124 }; 125 126 void PrintContents(int contents) 127 { 128 int i; 129 130 for (i = 0; contentnames[i].value; i++) 131 { 132 if (contents & contentnames[i].value) 133 { 134 botimport.Print(PRT_MESSAGE, "%s\n", contentnames[i].name); 135 } //end if 136 } //end for 137 } //end of the function PrintContents 138 139 #endif // BSP_DEBUG 140 //=========================================================================== 141 // traces axial boxes of any size through the world 142 // 143 // Parameter: - 144 // Returns: - 145 // Changes Globals: - 146 //=========================================================================== 147 bsp_trace_t AAS_Trace(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask) 148 { 149 bsp_trace_t bsptrace; 150 botimport.Trace(&bsptrace, start, mins, maxs, end, passent, contentmask); 151 return bsptrace; 152 } //end of the function AAS_Trace 153 //=========================================================================== 154 // returns the contents at the given point 155 // 156 // Parameter: - 157 // Returns: - 158 // Changes Globals: - 159 //=========================================================================== 160 int AAS_PointContents(vec3_t point) 161 { 162 return botimport.PointContents(point); 163 } //end of the function AAS_PointContents 164 //=========================================================================== 165 // 166 // Parameter: - 167 // Returns: - 168 // Changes Globals: - 169 //=========================================================================== 170 qboolean AAS_EntityCollision(int entnum, 171 vec3_t start, vec3_t boxmins, vec3_t boxmaxs, vec3_t end, 172 int contentmask, bsp_trace_t *trace) 173 { 174 bsp_trace_t enttrace; 175 176 botimport.EntityTrace(&enttrace, start, boxmins, boxmaxs, end, entnum, contentmask); 177 if (enttrace.fraction < trace->fraction) 178 { 179 Com_Memcpy(trace, &enttrace, sizeof(bsp_trace_t)); 180 return qtrue; 181 } //end if 182 return qfalse; 183 } //end of the function AAS_EntityCollision 184 //=========================================================================== 185 // returns true if in Potentially Hearable Set 186 // 187 // Parameter: - 188 // Returns: - 189 // Changes Globals: - 190 //=========================================================================== 191 qboolean AAS_inPVS(vec3_t p1, vec3_t p2) 192 { 193 return botimport.inPVS(p1, p2); 194 } //end of the function AAS_InPVS 195 //=========================================================================== 196 // returns true if in Potentially Visible Set 197 // 198 // Parameter: - 199 // Returns: - 200 // Changes Globals: - 201 //=========================================================================== 202 qboolean AAS_inPHS(vec3_t p1, vec3_t p2) 203 { 204 return qtrue; 205 } //end of the function AAS_inPHS 206 //=========================================================================== 207 // 208 // Parameter: - 209 // Returns: - 210 // Changes Globals: - 211 //=========================================================================== 212 void AAS_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin) 213 { 214 botimport.BSPModelMinsMaxsOrigin(modelnum, angles, mins, maxs, origin); 215 } //end of the function AAS_BSPModelMinsMaxs 216 //=========================================================================== 217 // unlinks the entity from all leaves 218 // 219 // Parameter: - 220 // Returns: - 221 // Changes Globals: - 222 //=========================================================================== 223 void AAS_UnlinkFromBSPLeaves(bsp_link_t *leaves) 224 { 225 } //end of the function AAS_UnlinkFromBSPLeaves 226 //=========================================================================== 227 // 228 // Parameter: - 229 // Returns: - 230 // Changes Globals: - 231 //=========================================================================== 232 bsp_link_t *AAS_BSPLinkEntity(vec3_t absmins, vec3_t absmaxs, int entnum, int modelnum) 233 { 234 return NULL; 235 } //end of the function AAS_BSPLinkEntity 236 //=========================================================================== 237 // 238 // Parameter: - 239 // Returns: - 240 // Changes Globals: - 241 //=========================================================================== 242 int AAS_BoxEntities(vec3_t absmins, vec3_t absmaxs, int *list, int maxcount) 243 { 244 return 0; 245 } //end of the function AAS_BoxEntities 246 //=========================================================================== 247 // 248 // Parameter: - 249 // Returns: - 250 // Changes Globals: - 251 //=========================================================================== 252 int AAS_NextBSPEntity(int ent) 253 { 254 ent++; 255 if (ent >= 1 && ent < bspworld.numentities) return ent; 256 return 0; 257 } //end of the function AAS_NextBSPEntity 258 //=========================================================================== 259 // 260 // Parameter: - 261 // Returns: - 262 // Changes Globals: - 263 //=========================================================================== 264 int AAS_BSPEntityInRange(int ent) 265 { 266 if (ent <= 0 || ent >= bspworld.numentities) 267 { 268 botimport.Print(PRT_MESSAGE, "bsp entity out of range\n"); 269 return qfalse; 270 } //end if 271 return qtrue; 272 } //end of the function AAS_BSPEntityInRange 273 //=========================================================================== 274 // 275 // Parameter: - 276 // Returns: - 277 // Changes Globals: - 278 //=========================================================================== 279 int AAS_ValueForBSPEpairKey(int ent, char *key, char *value, int size) 280 { 281 bsp_epair_t *epair; 282 283 value[0] = '\0'; 284 if (!AAS_BSPEntityInRange(ent)) return qfalse; 285 for (epair = bspworld.entities[ent].epairs; epair; epair = epair->next) 286 { 287 if (!strcmp(epair->key, key)) 288 { 289 strncpy(value, epair->value, size-1); 290 value[size-1] = '\0'; 291 return qtrue; 292 } //end if 293 } //end for 294 return qfalse; 295 } //end of the function AAS_FindBSPEpair 296 //=========================================================================== 297 // 298 // Parameter: - 299 // Returns: - 300 // Changes Globals: - 301 //=========================================================================== 302 int AAS_VectorForBSPEpairKey(int ent, char *key, vec3_t v) 303 { 304 char buf[MAX_EPAIRKEY]; 305 double v1, v2, v3; 306 307 VectorClear(v); 308 if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse; 309 //scanf into doubles, then assign, so it is vec_t size independent 310 v1 = v2 = v3 = 0; 311 sscanf(buf, "%lf %lf %lf", &v1, &v2, &v3); 312 v[0] = v1; 313 v[1] = v2; 314 v[2] = v3; 315 return qtrue; 316 } //end of the function AAS_VectorForBSPEpairKey 317 //=========================================================================== 318 // 319 // Parameter: - 320 // Returns: - 321 // Changes Globals: - 322 //=========================================================================== 323 int AAS_FloatForBSPEpairKey(int ent, char *key, float *value) 324 { 325 char buf[MAX_EPAIRKEY]; 326 327 *value = 0; 328 if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse; 329 *value = atof(buf); 330 return qtrue; 331 } //end of the function AAS_FloatForBSPEpairKey 332 //=========================================================================== 333 // 334 // Parameter: - 335 // Returns: - 336 // Changes Globals: - 337 //=========================================================================== 338 int AAS_IntForBSPEpairKey(int ent, char *key, int *value) 339 { 340 char buf[MAX_EPAIRKEY]; 341 342 *value = 0; 343 if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse; 344 *value = atoi(buf); 345 return qtrue; 346 } //end of the function AAS_IntForBSPEpairKey 347 //=========================================================================== 348 // 349 // Parameter: - 350 // Returns: - 351 // Changes Globals: - 352 //=========================================================================== 353 void AAS_FreeBSPEntities(void) 354 { 355 int i; 356 bsp_entity_t *ent; 357 bsp_epair_t *epair, *nextepair; 358 359 for (i = 1; i < bspworld.numentities; i++) 360 { 361 ent = &bspworld.entities[i]; 362 for (epair = ent->epairs; epair; epair = nextepair) 363 { 364 nextepair = epair->next; 365 // 366 if (epair->key) FreeMemory(epair->key); 367 if (epair->value) FreeMemory(epair->value); 368 FreeMemory(epair); 369 } //end for 370 } //end for 371 bspworld.numentities = 0; 372 } //end of the function AAS_FreeBSPEntities 373 //=========================================================================== 374 // 375 // Parameter: - 376 // Returns: - 377 // Changes Globals: - 378 //=========================================================================== 379 void AAS_ParseBSPEntities(void) 380 { 381 script_t *script; 382 token_t token; 383 bsp_entity_t *ent; 384 bsp_epair_t *epair; 385 386 script = LoadScriptMemory(bspworld.dentdata, bspworld.entdatasize, "entdata"); 387 SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES|SCFL_NOSTRINGESCAPECHARS);//SCFL_PRIMITIVE); 388 389 bspworld.numentities = 1; 390 391 while(PS_ReadToken(script, &token)) 392 { 393 if (strcmp(token.string, "{")) 394 { 395 ScriptError(script, "invalid %s\n", token.string); 396 AAS_FreeBSPEntities(); 397 FreeScript(script); 398 return; 399 } //end if 400 if (bspworld.numentities >= MAX_BSPENTITIES) 401 { 402 botimport.Print(PRT_MESSAGE, "too many entities in BSP file\n"); 403 break; 404 } //end if 405 ent = &bspworld.entities[bspworld.numentities]; 406 bspworld.numentities++; 407 ent->epairs = NULL; 408 while(PS_ReadToken(script, &token)) 409 { 410 if (!strcmp(token.string, "}")) break; 411 epair = (bsp_epair_t *) GetClearedHunkMemory(sizeof(bsp_epair_t)); 412 epair->next = ent->epairs; 413 ent->epairs = epair; 414 if (token.type != TT_STRING) 415 { 416 ScriptError(script, "invalid %s\n", token.string); 417 AAS_FreeBSPEntities(); 418 FreeScript(script); 419 return; 420 } //end if 421 StripDoubleQuotes(token.string); 422 epair->key = (char *) GetHunkMemory(strlen(token.string) + 1); 423 strcpy(epair->key, token.string); 424 if (!PS_ExpectTokenType(script, TT_STRING, 0, &token)) 425 { 426 AAS_FreeBSPEntities(); 427 FreeScript(script); 428 return; 429 } //end if 430 StripDoubleQuotes(token.string); 431 epair->value = (char *) GetHunkMemory(strlen(token.string) + 1); 432 strcpy(epair->value, token.string); 433 } //end while 434 if (strcmp(token.string, "}")) 435 { 436 ScriptError(script, "missing }\n"); 437 AAS_FreeBSPEntities(); 438 FreeScript(script); 439 return; 440 } //end if 441 } //end while 442 FreeScript(script); 443 } //end of the function AAS_ParseBSPEntities 444 //=========================================================================== 445 // 446 // Parameter: - 447 // Returns: - 448 // Changes Globals: - 449 //=========================================================================== 450 int AAS_BSPTraceLight(vec3_t start, vec3_t end, vec3_t endpos, int *red, int *green, int *blue) 451 { 452 return 0; 453 } //end of the function AAS_BSPTraceLight 454 //=========================================================================== 455 // 456 // Parameter: - 457 // Returns: - 458 // Changes Globals: - 459 //=========================================================================== 460 void AAS_DumpBSPData(void) 461 { 462 AAS_FreeBSPEntities(); 463 464 if (bspworld.dentdata) FreeMemory(bspworld.dentdata); 465 bspworld.dentdata = NULL; 466 bspworld.entdatasize = 0; 467 // 468 bspworld.loaded = qfalse; 469 Com_Memset( &bspworld, 0, sizeof(bspworld) ); 470 } //end of the function AAS_DumpBSPData 471 //=========================================================================== 472 // load an bsp file 473 // 474 // Parameter: - 475 // Returns: - 476 // Changes Globals: - 477 //=========================================================================== 478 int AAS_LoadBSPFile(void) 479 { 480 AAS_DumpBSPData(); 481 bspworld.entdatasize = strlen(botimport.BSPEntityData()) + 1; 482 bspworld.dentdata = (char *) GetClearedHunkMemory(bspworld.entdatasize); 483 Com_Memcpy(bspworld.dentdata, botimport.BSPEntityData(), bspworld.entdatasize); 484 AAS_ParseBSPEntities(); 485 bspworld.loaded = qtrue; 486 return BLERR_NOERROR; 487 } //end of the function AAS_LoadBSPFile