Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

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