00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "qbsp.h"
00024 #include "l_mem.h"
00025 #include "../botlib/aasfile.h"
00026 #include "aas_store.h"
00027 #include "aas_cfg.h"
00028 #include "../game/surfaceflags.h"
00029
00030 #define SPAWNFLAG_NOT_EASY 0x00000100
00031 #define SPAWNFLAG_NOT_MEDIUM 0x00000200
00032 #define SPAWNFLAG_NOT_HARD 0x00000400
00033 #define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
00034 #define SPAWNFLAG_NOT_COOP 0x00001000
00035
00036 #define STATE_TOP 0
00037 #define STATE_BOTTOM 1
00038 #define STATE_UP 2
00039 #define STATE_DOWN 3
00040
00041 #define DOOR_START_OPEN 1
00042 #define DOOR_REVERSE 2
00043 #define DOOR_CRUSHER 4
00044 #define DOOR_NOMONSTER 8
00045 #define DOOR_TOGGLE 32
00046 #define DOOR_X_AXIS 64
00047 #define DOOR_Y_AXIS 128
00048
00049 #define BBOX_NORMAL_EPSILON 0.0001
00050
00051
00052
00053
00054
00055
00056
00057 vec_t BoxOriginDistanceFromPlane(vec3_t normal, vec3_t mins, vec3_t maxs, int side)
00058 {
00059 vec3_t v1, v2;
00060 int i;
00061
00062 if (side)
00063 {
00064 for (i = 0; i < 3; i++)
00065 {
00066 if (normal[i] > BBOX_NORMAL_EPSILON) v1[i] = maxs[i];
00067 else if (normal[i] < -BBOX_NORMAL_EPSILON) v1[i] = mins[i];
00068 else v1[i] = 0;
00069 }
00070 }
00071 else
00072 {
00073 for (i = 0; i < 3; i++)
00074 {
00075 if (normal[i] > BBOX_NORMAL_EPSILON) v1[i] = mins[i];
00076 else if (normal[i] < -BBOX_NORMAL_EPSILON) v1[i] = maxs[i];
00077 else v1[i] = 0;
00078 }
00079 }
00080 VectorCopy(normal, v2);
00081 VectorInverse(v2);
00082 return DotProduct(v1, v2);
00083 }
00084
00085
00086
00087
00088
00089
00090 vec_t CapsuleOriginDistanceFromPlane(vec3_t normal, vec3_t mins, vec3_t maxs)
00091 {
00092 float offset_up, offset_down, width, radius;
00093
00094 width = maxs[0] - mins[0];
00095
00096 if (maxs[2] - mins[2] < width) {
00097 width = maxs[2] - mins[2];
00098 }
00099 radius = width * 0.5;
00100
00101 offset_up = maxs[2] - radius;
00102 offset_down = -mins[2] - radius;
00103
00104
00105 if ( normal[2] > 0 ) {
00106
00107 return normal[2] * offset_down + radius;
00108 }
00109 else {
00110
00111 return -normal[2] * offset_up + radius;
00112 }
00113 }
00114
00115
00116
00117
00118
00119
00120 void AAS_ExpandMapBrush(mapbrush_t *brush, vec3_t mins, vec3_t maxs)
00121 {
00122 int sn;
00123 float dist;
00124 side_t *s;
00125 plane_t *plane;
00126
00127 for (sn = 0; sn < brush->numsides; sn++)
00128 {
00129 s = brush->original_sides + sn;
00130 plane = &mapplanes[s->planenum];
00131 dist = plane->dist;
00132 if (capsule_collision) {
00133 dist += CapsuleOriginDistanceFromPlane(plane->normal, mins, maxs);
00134 }
00135 else {
00136 dist += BoxOriginDistanceFromPlane(plane->normal, mins, maxs, 0);
00137 }
00138 s->planenum = FindFloatPlane(plane->normal, dist);
00139
00140 s->flags &= ~SFL_BEVEL;
00141
00142 s->surf &= ~SURF_SKIP;
00143
00144
00145
00146
00147 }
00148 }
00149
00150
00151
00152
00153
00154
00155 void AAS_SetTexinfo(mapbrush_t *brush)
00156 {
00157 int n;
00158 side_t *side;
00159
00160 if (brush->contents & (CONTENTS_LADDER
00161 | CONTENTS_AREAPORTAL
00162 | CONTENTS_CLUSTERPORTAL
00163 | CONTENTS_TELEPORTER
00164 | CONTENTS_JUMPPAD
00165 | CONTENTS_DONOTENTER
00166 | CONTENTS_WATER
00167 | CONTENTS_LAVA
00168 | CONTENTS_SLIME
00169 | CONTENTS_WINDOW
00170 | CONTENTS_PLAYERCLIP))
00171 {
00172
00173
00174 for (n = 0; n < brush->numsides; n++)
00175 {
00176 side = brush->original_sides + n;
00177
00178 side->texinfo = 0;
00179 }
00180 }
00181 else
00182 {
00183
00184
00185 for (n = 0; n < brush->numsides; n++)
00186 {
00187 side = brush->original_sides + n;
00188
00189 if (side->flags & (SFL_TEXTURED|SFL_BEVEL)) side->texinfo = 0;
00190 else side->texinfo = TEXINFO_NODE;
00191 }
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200 void FreeBrushWindings(mapbrush_t *brush)
00201 {
00202 int n;
00203 side_t *side;
00204
00205 for (n = 0; n < brush->numsides; n++)
00206 {
00207 side = brush->original_sides + n;
00208
00209 if (side->winding) FreeWinding(side->winding);
00210 }
00211 }
00212
00213
00214
00215
00216
00217
00218 void AAS_AddMapBrushSide(mapbrush_t *brush, int planenum)
00219 {
00220 side_t *side;
00221
00222 if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
00223 Error ("MAX_MAPFILE_BRUSHSIDES");
00224
00225 side = brush->original_sides + brush->numsides;
00226 side->original = NULL;
00227 side->winding = NULL;
00228 side->contents = brush->contents;
00229 side->flags &= ~(SFL_BEVEL|SFL_VISIBLE);
00230 side->surf = 0;
00231 side->planenum = planenum;
00232 side->texinfo = 0;
00233
00234 nummapbrushsides++;
00235 brush->numsides++;
00236 }
00237
00238
00239
00240
00241
00242
00243 void AAS_FixMapBrush(mapbrush_t *brush)
00244 {
00245 int i, j, planenum;
00246 float dist;
00247 winding_t *w;
00248 plane_t *plane, *plane1, *plane2;
00249 side_t *side;
00250 vec3_t normal;
00251
00252
00253 ClearBounds(brush->mins, brush->maxs);
00254 for (i = 0; i < brush->numsides; i++)
00255 {
00256 plane = &mapplanes[brush->original_sides[i].planenum];
00257 w = BaseWindingForPlane(plane->normal, plane->dist);
00258 for (j = 0; j < brush->numsides && w; j++)
00259 {
00260 if (i == j) continue;
00261
00262 if (brush->original_sides[j].flags & SFL_BEVEL) continue;
00263 plane = &mapplanes[brush->original_sides[j].planenum^1];
00264 ChopWindingInPlace(&w, plane->normal, plane->dist, 0);
00265 }
00266
00267 side = &brush->original_sides[i];
00268 side->winding = w;
00269 if (w)
00270 {
00271 for (j = 0; j < w->numpoints; j++)
00272 {
00273 AddPointToBounds(w->p[j], brush->mins, brush->maxs);
00274 }
00275 }
00276 }
00277
00278 for (i = 0; i < brush->numsides; i++)
00279 {
00280 for (j = 0; j < brush->numsides; j++)
00281 {
00282 if (i == j) continue;
00283 plane1 = &mapplanes[brush->original_sides[i].planenum];
00284 plane2 = &mapplanes[brush->original_sides[j].planenum];
00285 if (WindingsNonConvex(brush->original_sides[i].winding,
00286 brush->original_sides[j].winding,
00287 plane1->normal, plane2->normal,
00288 plane1->dist, plane2->dist))
00289 {
00290 Log_Print("non convex brush");
00291 }
00292 }
00293 }
00294
00295
00296 for (i = 0; i < 3; i++)
00297 {
00298 if (brush->mins[i] < -MAX_MAP_BOUNDS)
00299 {
00300 VectorClear(normal);
00301 normal[i] = -1;
00302 dist = MAX_MAP_BOUNDS - 10;
00303 planenum = FindFloatPlane(normal, dist);
00304
00305 Log_Print("mins out of range: added extra brush side\n");
00306 AAS_AddMapBrushSide(brush, planenum);
00307 }
00308 if (brush->maxs[i] > MAX_MAP_BOUNDS)
00309 {
00310 VectorClear(normal);
00311 normal[i] = 1;
00312 dist = MAX_MAP_BOUNDS - 10;
00313 planenum = FindFloatPlane(normal, dist);
00314
00315 Log_Print("maxs out of range: added extra brush side\n");
00316 AAS_AddMapBrushSide(brush, planenum);
00317 }
00318 if (brush->mins[i] > MAX_MAP_BOUNDS || brush->maxs[i] < -MAX_MAP_BOUNDS)
00319 {
00320 Log_Print("entity %i, brush %i: no visible sides on brush\n", brush->entitynum, brush->brushnum);
00321 }
00322 }
00323
00324 FreeBrushWindings(brush);
00325 }
00326
00327
00328
00329
00330
00331
00332 qboolean AAS_MakeBrushWindings(mapbrush_t *ob)
00333 {
00334 int i, j;
00335 winding_t *w;
00336 side_t *side;
00337 plane_t *plane, *plane1, *plane2;
00338
00339 ClearBounds (ob->mins, ob->maxs);
00340
00341 for (i = 0; i < ob->numsides; i++)
00342 {
00343 plane = &mapplanes[ob->original_sides[i].planenum];
00344 w = BaseWindingForPlane(plane->normal, plane->dist);
00345 for (j = 0; j <ob->numsides && w; j++)
00346 {
00347 if (i == j) continue;
00348 if (ob->original_sides[j].flags & SFL_BEVEL) continue;
00349 plane = &mapplanes[ob->original_sides[j].planenum^1];
00350 ChopWindingInPlace(&w, plane->normal, plane->dist, 0);
00351 }
00352
00353 side = &ob->original_sides[i];
00354 side->winding = w;
00355 if (w)
00356 {
00357 side->flags |= SFL_VISIBLE;
00358 for (j = 0; j < w->numpoints; j++)
00359 AddPointToBounds (w->p[j], ob->mins, ob->maxs);
00360 }
00361 }
00362
00363 for (i = 0; i < ob->numsides; i++)
00364 {
00365 for (j = 0; j < ob->numsides; j++)
00366 {
00367 if (i == j) continue;
00368 plane1 = &mapplanes[ob->original_sides[i].planenum];
00369 plane2 = &mapplanes[ob->original_sides[j].planenum];
00370 if (WindingsNonConvex(ob->original_sides[i].winding,
00371 ob->original_sides[j].winding,
00372 plane1->normal, plane2->normal,
00373 plane1->dist, plane2->dist))
00374 {
00375 Log_Print("non convex brush");
00376 }
00377 }
00378 }
00379
00380 for (i = 0; i < 3; i++)
00381 {
00382
00383 if (ob->mins[i] < -MAX_MAP_BOUNDS || ob->maxs[i] > MAX_MAP_BOUNDS)
00384 {
00385 Log_Print("entity %i, brush %i: bounds out of range\n", ob->entitynum, ob->brushnum);
00386 Log_Print("ob->mins[%d] = %f, ob->maxs[%d] = %f\n", i, ob->mins[i], i, ob->maxs[i]);
00387 ob->numsides = 0;
00388 break;
00389 }
00390 if (ob->mins[i] > MAX_MAP_BOUNDS || ob->maxs[i] < -MAX_MAP_BOUNDS)
00391 {
00392 Log_Print("entity %i, brush %i: no visible sides on brush\n", ob->entitynum, ob->brushnum);
00393 Log_Print("ob->mins[%d] = %f, ob->maxs[%d] = %f\n", i, ob->mins[i], i, ob->maxs[i]);
00394 ob->numsides = 0;
00395 break;
00396 }
00397 }
00398 return true;
00399 }
00400
00401
00402
00403
00404
00405
00406 mapbrush_t *AAS_CopyMapBrush(mapbrush_t *brush, entity_t *mapent)
00407 {
00408 int n;
00409 mapbrush_t *newbrush;
00410 side_t *side, *newside;
00411
00412 if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
00413 Error ("MAX_MAPFILE_BRUSHES");
00414
00415 newbrush = &mapbrushes[nummapbrushes];
00416 newbrush->original_sides = &brushsides[nummapbrushsides];
00417 newbrush->entitynum = brush->entitynum;
00418 newbrush->brushnum = nummapbrushes - mapent->firstbrush;
00419 newbrush->numsides = brush->numsides;
00420 newbrush->contents = brush->contents;
00421
00422
00423 for (n = 0; n < brush->numsides; n++)
00424 {
00425 if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
00426 Error ("MAX_MAPFILE_BRUSHSIDES");
00427 side = brush->original_sides + n;
00428
00429 newside = newbrush->original_sides + n;
00430 newside->original = NULL;
00431 newside->winding = NULL;
00432 newside->contents = side->contents;
00433 newside->flags = side->flags;
00434 newside->surf = side->surf;
00435 newside->planenum = side->planenum;
00436 newside->texinfo = side->texinfo;
00437 nummapbrushsides++;
00438 }
00439
00440 nummapbrushes++;
00441 mapent->numbrushes++;
00442 return newbrush;
00443 }
00444
00445
00446
00447
00448
00449
00450 int mark_entities[MAX_MAP_ENTITIES];
00451
00452 int AAS_AlwaysTriggered_r(char *targetname)
00453 {
00454 int i;
00455
00456 if (!strlen(targetname)) {
00457 return false;
00458 }
00459
00460 for (i = 0; i < num_entities; i++) {
00461
00462 if ( !strcmp(targetname, ValueForKey(&entities[i], "target")) ) {
00463
00464 if (!(atoi(ValueForKey(&entities[i], "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH)) {
00465
00466 if (!strcmp("trigger_always", ValueForKey(&entities[i], "classname"))) {
00467 return true;
00468 }
00469
00470 if ( mark_entities[i] ) {
00471 Warning( "entity %d, classname %s has recursive targetname %s\n", i,
00472 ValueForKey(&entities[i], "classname"), targetname );
00473 return false;
00474 }
00475 mark_entities[i] = true;
00476 if ( AAS_AlwaysTriggered_r(ValueForKey(&entities[i], "targetname")) ) {
00477 return true;
00478 }
00479 }
00480 }
00481 }
00482 return false;
00483 }
00484
00485 int AAS_AlwaysTriggered(char *targetname) {
00486 memset( mark_entities, 0, sizeof(mark_entities) );
00487 return AAS_AlwaysTriggered_r( targetname );
00488 }
00489
00490
00491
00492
00493
00494
00495 int AAS_ValidEntity(entity_t *mapent)
00496 {
00497 int i;
00498 char target[1024];
00499
00500
00501 if (mapent == &entities[0])
00502 {
00503 return true;
00504 }
00505
00506 else if (!strcmp("func_wall", ValueForKey(mapent, "classname")))
00507 {
00508
00509
00510 if (!(atoi(ValueForKey(mapent, "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH))
00511 {
00512
00513 return true;
00514 }
00515 }
00516 else if (!strcmp("func_door_rotating", ValueForKey(mapent, "classname")))
00517 {
00518
00519 if (!(atoi(ValueForKey(mapent, "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH))
00520 {
00521
00522 if (AAS_AlwaysTriggered(ValueForKey(mapent, "targetname")))
00523 {
00524
00525 return true;
00526 }
00527 }
00528 }
00529 else if (!strcmp("trigger_hurt", ValueForKey(mapent, "classname")))
00530 {
00531
00532 return true;
00533 }
00534 else if (!strcmp("trigger_push", ValueForKey(mapent, "classname")))
00535 {
00536 return true;
00537 }
00538 else if (!strcmp("trigger_multiple", ValueForKey(mapent, "classname")))
00539 {
00540
00541 strcpy(target, ValueForKey(mapent, "target"));
00542 for (i = 0; i < num_entities; i++)
00543 {
00544
00545 if (!strcmp(target, ValueForKey(&entities[i], "targetname")))
00546 {
00547 if (!strcmp("target_teleporter", ValueForKey(&entities[i], "classname")))
00548 {
00549 return true;
00550 }
00551 }
00552 }
00553 }
00554 else if (!strcmp("trigger_teleport", ValueForKey(mapent, "classname")))
00555 {
00556 return true;
00557 }
00558 else if (!strcmp("func_static", ValueForKey(mapent, "classname")))
00559 {
00560
00561 return true;
00562 }
00563 else if (!strcmp("func_door", ValueForKey(mapent, "classname")))
00564 {
00565 return true;
00566 }
00567 return false;
00568 }
00569
00570
00571
00572
00573
00574
00575 int AAS_TransformPlane(int planenum, vec3_t origin, vec3_t angles)
00576 {
00577 float newdist, matrix[3][3];
00578 vec3_t normal;
00579
00580
00581 VectorCopy(mapplanes[planenum].normal, normal);
00582 CreateRotationMatrix(angles, matrix);
00583 RotatePoint(normal, matrix);
00584 newdist = mapplanes[planenum].dist + DotProduct(normal, origin);
00585 return FindFloatPlane(normal, newdist);
00586 }
00587
00588
00589
00590
00591
00592
00593
00594 void AAS_PositionFuncRotatingBrush(entity_t *mapent, mapbrush_t *brush)
00595 {
00596 int spawnflags, i;
00597 float distance;
00598 vec3_t movedir, angles, pos1, pos2;
00599 side_t *s;
00600
00601 spawnflags = FloatForKey(mapent, "spawnflags");
00602 VectorClear(movedir);
00603 if (spawnflags & DOOR_X_AXIS)
00604 movedir[2] = 1.0;
00605 else if (spawnflags & DOOR_Y_AXIS)
00606 movedir[0] = 1.0;
00607 else
00608 movedir[1] = 1.0;
00609
00610
00611 if (spawnflags & DOOR_REVERSE)
00612 VectorInverse(movedir);
00613
00614 distance = FloatForKey(mapent, "distance");
00615 if (!distance) distance = 90;
00616
00617 GetVectorForKey(mapent, "angles", angles);
00618 VectorCopy(angles, pos1);
00619 VectorMA(angles, -distance, movedir, pos2);
00620
00621 if (spawnflags & DOOR_START_OPEN)
00622 {
00623 VectorCopy(pos2, angles);
00624 VectorCopy(pos1, pos2);
00625 VectorCopy(angles, pos1);
00626 VectorInverse(movedir);
00627 }
00628
00629 for (i = 0; i < brush->numsides; i++)
00630 {
00631 s = &brush->original_sides[i];
00632 s->planenum = AAS_TransformPlane(s->planenum, mapent->origin, pos2);
00633 }
00634
00635 FreeBrushWindings(brush);
00636 AAS_MakeBrushWindings(brush);
00637 AddBrushBevels(brush);
00638 FreeBrushWindings(brush);
00639 }
00640
00641
00642
00643
00644
00645
00646 void AAS_PositionBrush(entity_t *mapent, mapbrush_t *brush)
00647 {
00648 side_t *s;
00649 float newdist;
00650 int i, notteam;
00651 char *model;
00652
00653 if (!strcmp(ValueForKey(mapent, "classname"), "func_door_rotating"))
00654 {
00655 AAS_PositionFuncRotatingBrush(mapent, brush);
00656 }
00657 else
00658 {
00659 if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2])
00660 {
00661 for (i = 0; i < brush->numsides; i++)
00662 {
00663 s = &brush->original_sides[i];
00664 newdist = mapplanes[s->planenum].dist +
00665 DotProduct(mapplanes[s->planenum].normal, mapent->origin);
00666 s->planenum = FindFloatPlane(mapplanes[s->planenum].normal, newdist);
00667 }
00668 }
00669
00670 if (!strcmp("trigger_hurt", ValueForKey(mapent, "classname")))
00671 {
00672 notteam = FloatForKey(mapent, "bot_notteam");
00673 if ( notteam == 1 ) {
00674 brush->contents |= CONTENTS_NOTTEAM1;
00675 }
00676 else if ( notteam == 2 ) {
00677 brush->contents |= CONTENTS_NOTTEAM2;
00678 }
00679 else {
00680
00681 brush->contents |= CONTENTS_LAVA;
00682 }
00683 }
00684
00685 else if (!strcmp("trigger_push", ValueForKey(mapent, "classname")))
00686 {
00687
00688 brush->contents = CONTENTS_JUMPPAD;
00689
00690 }
00691
00692 else if (!strcmp("trigger_multiple", ValueForKey(mapent, "classname")))
00693 {
00694
00695 brush->contents = CONTENTS_TELEPORTER;
00696
00697 }
00698
00699 else if (!strcmp("trigger_teleport", ValueForKey(mapent, "classname")))
00700 {
00701
00702 brush->contents = CONTENTS_TELEPORTER;
00703
00704 }
00705 else if (!strcmp("func_door", ValueForKey(mapent, "classname")))
00706 {
00707
00708 brush->contents = CONTENTS_MOVER;
00709
00710 model = ValueForKey(mapent, "model");
00711 brush->modelnum = atoi(model+1);
00712 }
00713 }
00714 }
00715
00716
00717
00718
00719
00720
00721
00722 void AAS_CreateMapBrushes(mapbrush_t *brush, entity_t *mapent, int addbevels)
00723 {
00724 int i;
00725
00726 mapbrush_t *bboxbrushes[16];
00727
00728
00729 if (!AAS_ValidEntity(mapent))
00730 {
00731 nummapbrushsides -= brush->numsides;
00732 brush->numsides = 0;
00733 return;
00734 }
00735
00736 AAS_PositionBrush(mapent, brush);
00737
00738
00739 AAS_SetTexinfo(brush);
00740
00741
00742 brush->contents &= ~CONTENTS_DETAIL;
00743
00744 if (brush->contents & (CONTENTS_AREAPORTAL|CONTENTS_CLUSTERPORTAL))
00745 {
00746 brush->contents = CONTENTS_CLUSTERPORTAL;
00747 brush->leafnum = -1;
00748 }
00749
00750 if (brush->contents & (CONTENTS_WINDOW | CONTENTS_PLAYERCLIP))
00751 {
00752
00753 brush->contents &= ~(CONTENTS_WINDOW | CONTENTS_PLAYERCLIP);
00754 brush->contents |= CONTENTS_SOLID;
00755 brush->leafnum = -1;
00756 }
00757
00758 if (brush->contents & CONTENTS_BOTCLIP)
00759 {
00760 brush->contents = CONTENTS_SOLID;
00761 brush->leafnum = -1;
00762 }
00763
00764
00765
00766
00767
00768 if (!(brush->contents & (CONTENTS_SOLID
00769 | CONTENTS_LADDER
00770 | CONTENTS_CLUSTERPORTAL
00771 | CONTENTS_DONOTENTER
00772 | CONTENTS_TELEPORTER
00773 | CONTENTS_JUMPPAD
00774 | CONTENTS_WATER
00775 | CONTENTS_LAVA
00776 | CONTENTS_SLIME
00777 | CONTENTS_MOVER
00778 )))
00779 {
00780 nummapbrushsides -= brush->numsides;
00781 brush->numsides = 0;
00782 return;
00783 }
00784
00785
00786
00787 if (addbevels)
00788 {
00789
00790
00791
00792
00793
00794
00795 AAS_MakeBrushWindings(brush);
00796 AddBrushBevels(brush);
00797 FreeBrushWindings(brush);
00798 }
00799
00800 mapent = &entities[0];
00801
00802 nummapbrushes++;
00803 mapent->numbrushes++;
00804
00805 if (brush->contents & (CONTENTS_WATER
00806 | CONTENTS_LAVA
00807 | CONTENTS_SLIME
00808 | CONTENTS_TELEPORTER
00809 | CONTENTS_JUMPPAD
00810 | CONTENTS_DONOTENTER
00811 | CONTENTS_MOVER
00812 ))
00813 {
00814 brush->expansionbbox = 0;
00815
00816
00817 AAS_ExpandMapBrush(brush, cfg.bboxes[0].mins, cfg.bboxes[0].maxs);
00818 AAS_MakeBrushWindings(brush);
00819 }
00820
00821 else if (brush->contents & CONTENTS_CLUSTERPORTAL)
00822 {
00823 brush->expansionbbox = 0;
00824
00825
00826 AAS_ExpandMapBrush(brush, cfg.bboxes[0].mins, cfg.bboxes[0].maxs);
00827 AAS_MakeBrushWindings(brush);
00828 }
00829
00830 else if (brush->contents & (CONTENTS_SOLID
00831 | CONTENTS_LADDER
00832 ))
00833 {
00834
00835 bboxbrushes[0] = brush;
00836
00837 for (i = 1; i < cfg.numbboxes; i++)
00838 {
00839 bboxbrushes[i] = AAS_CopyMapBrush(brush, mapent);
00840 }
00841
00842 for (i = 0; i < cfg.numbboxes; i++)
00843 {
00844 AAS_ExpandMapBrush(bboxbrushes[i], cfg.bboxes[i].mins, cfg.bboxes[i].maxs);
00845 bboxbrushes[i]->expansionbbox = cfg.bboxes[i].presencetype;
00846 AAS_MakeBrushWindings(bboxbrushes[i]);
00847 }
00848 }
00849 }