00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "server.h"
00030
00031 #define AREA_DEPTH 4
00032
00041 static worldSector_t *SV_CreateWorldSector (int depth, const vec3_t mins, const vec3_t maxs)
00042 {
00043 worldSector_t *anode;
00044 vec3_t size;
00045 vec3_t mins1, maxs1, mins2, maxs2;
00046
00047 if (sv.numWorldSectors >= lengthof(sv.worldSectors))
00048 Com_Error(ERR_DROP, "SV_CreateWorldSector: overflow");
00049
00050 anode = &sv.worldSectors[sv.numWorldSectors];
00051 sv.numWorldSectors++;
00052
00053 anode->entities = NULL;
00054
00055 if (depth == AREA_DEPTH) {
00056 anode->axis = LEAFNODE;
00057 anode->children[0] = anode->children[1] = NULL;
00058 return anode;
00059 }
00060
00061 VectorSubtract(maxs, mins, size);
00062 if (size[0] > size[1])
00063 anode->axis = PLANE_X;
00064 else
00065 anode->axis = PLANE_Y;
00066
00067 anode->dist = 0.5f * (maxs[anode->axis] + mins[anode->axis]);
00068 VectorCopy(mins, mins1);
00069 VectorCopy(mins, mins2);
00070 VectorCopy(maxs, maxs1);
00071 VectorCopy(maxs, maxs2);
00072
00073 maxs1[anode->axis] = mins2[anode->axis] = anode->dist;
00074
00075 anode->children[0] = SV_CreateWorldSector(depth + 1, mins2, maxs2);
00076 anode->children[1] = SV_CreateWorldSector(depth + 1, mins1, maxs1);
00077
00078 return anode;
00079 }
00080
00087 void SV_ClearWorld (void)
00088 {
00089 SV_CreateWorldSector(0, sv.mapData.mapMin, sv.mapData.mapMax);
00090 }
00091
00092 static inline sv_edict_t* SV_GetServerDataForEdict (const edict_t *ent)
00093 {
00094 if (!ent || ent->number < 0 || ent->number >= lengthof(sv.edicts))
00095 Com_Error(ERR_DROP, "SV_GetServerDataForEdict: bad game ent");
00096
00097 return &sv.edicts[ent->number];
00098 }
00099
00103 void SV_UnlinkEdict (edict_t * ent)
00104 {
00105 sv_edict_t *sv_ent = SV_GetServerDataForEdict(ent);
00106 sv_edict_t *scan;
00107 worldSector_t *ws;
00108
00109 sv_ent->linked = qfalse;
00110
00111 ws = sv_ent->worldSector;
00112 if (!ws)
00113 return;
00114
00115 sv_ent->worldSector = NULL;
00116
00117 if (ws->entities == sv_ent) {
00118 ws->entities = sv_ent->nextEntityInWorldSector;
00119 return;
00120 }
00121
00122 for (scan = ws->entities; scan; scan = scan->nextEntityInWorldSector) {
00123 if (scan->nextEntityInWorldSector == sv_ent) {
00124 scan->nextEntityInWorldSector = sv_ent->nextEntityInWorldSector;
00125 return;
00126 }
00127 }
00128
00129 Com_Printf("WARNING: SV_UnlinkEntity: not found in worldSector\n");
00130
00131 if (ent->child)
00132 SV_UnlinkEdict(ent->child);
00133 }
00134
00140 void SV_LinkEdict (edict_t * ent)
00141 {
00142 worldSector_t *node;
00143 sv_edict_t *sv_ent = SV_GetServerDataForEdict(ent);
00144
00145 if (sv_ent->worldSector)
00146 SV_UnlinkEdict(ent);
00147
00148 if (ent == svs.ge->edicts)
00149 return;
00150
00151 if (!ent->inuse)
00152 return;
00153
00154
00155 VectorSubtract(ent->maxs, ent->mins, ent->size);
00156
00157
00158 ent->linkcount++;
00159
00160
00161 if (ent->solid == SOLID_BSP && VectorNotEmpty(ent->angles)) {
00162 vec3_t minVec, maxVec, tmpMinVec, tmpMaxVec;
00163 vec3_t centerVec, halfVec, newCenterVec, newHalfVec;
00164 vec3_t m[3];
00165
00166
00167 VectorCenterFromMinsMaxs(ent->mins, ent->maxs, centerVec);
00168
00169
00170 VectorSubtract(ent->maxs, centerVec, halfVec);
00171
00172
00173 VectorCreateRotationMatrix(ent->angles, m);
00174 VectorRotate(m, centerVec, newCenterVec);
00175 VectorRotate(m, halfVec, newHalfVec);
00176
00177
00178 VectorSubtract(newCenterVec, newHalfVec, tmpMinVec);
00179 VectorAdd(newCenterVec, newHalfVec, tmpMaxVec);
00180
00181
00182 minVec[0] = min(tmpMinVec[0], tmpMaxVec[0]);
00183 minVec[1] = min(tmpMinVec[1], tmpMaxVec[1]);
00184 minVec[2] = min(tmpMinVec[2], tmpMaxVec[2]);
00185 maxVec[0] = max(tmpMinVec[0], tmpMaxVec[0]);
00186 maxVec[1] = max(tmpMinVec[1], tmpMaxVec[1]);
00187 maxVec[2] = max(tmpMinVec[2], tmpMaxVec[2]);
00188
00189
00190 VectorAdd(ent->origin, minVec, ent->absmin);
00191 VectorAdd(ent->origin, maxVec, ent->absmax);
00192 } else {
00193 VectorAdd(ent->origin, ent->mins, ent->absmin);
00194 VectorAdd(ent->origin, ent->maxs, ent->absmax);
00195 }
00196
00197
00198 if (ent->solid == SOLID_NOT)
00199 return;
00200
00201
00202 node = sv.worldSectors;
00203 while (1) {
00204
00205 if (node->axis == LEAFNODE)
00206 break;
00207 if (ent->absmin[node->axis] > node->dist)
00208 node = node->children[0];
00209 else if (ent->absmax[node->axis] < node->dist)
00210 node = node->children[1];
00211 else
00212 break;
00213 }
00214
00215
00216 sv_ent->nextEntityInWorldSector = node->entities;
00217 node->entities = sv_ent;
00218
00219 sv_ent->linked = qtrue;
00220 sv_ent->worldSector = node;
00221 sv_ent->ent = ent;
00222
00223
00224 if (ent->child) {
00225 VectorCopy(ent->absmin, ent->child->mins);
00226 VectorCopy(ent->absmax, ent->child->maxs);
00227
00228
00229 ent->child->mins[0] -= (UNIT_SIZE / 2);
00230 ent->child->mins[1] -= (UNIT_SIZE / 2);
00231 ent->child->maxs[0] += (UNIT_SIZE / 2);
00232 ent->child->maxs[1] += (UNIT_SIZE / 2);
00233
00234
00235 SV_LinkEdict(ent->child);
00236 }
00237 }
00238
00246 static qboolean SV_BoundingBoxesIntersect (const vec3_t mins, const vec3_t maxs, const edict_t *ent)
00247 {
00248 const qboolean outsideMaxs = ent->absmin[0] > maxs[0] || ent->absmin[1] > maxs[1] || ent->absmin[2] > maxs[2];
00249 const qboolean outsideMins = ent->absmax[0] < mins[0] || ent->absmax[1] < mins[1] || ent->absmax[2] < mins[2];
00250 if (outsideMaxs || outsideMins)
00251 return qfalse;
00252 return qtrue;
00253 }
00254
00255 typedef struct {
00256 const float *areaMins, *areaMaxs;
00257 edict_t **areaEdictList;
00258 int areaEdictListCount, areaEdictListMaxCount;
00259 } areaParms_t;
00260
00269 static void SV_AreaEdicts_r (worldSector_t * node, areaParms_t *ap)
00270 {
00271 sv_edict_t *check, *next;
00272
00273 for (check = node->entities; check; check = next) {
00274 next = check->nextEntityInWorldSector;
00275
00276
00277 if (check->ent->solid == SOLID_NOT)
00278 continue;
00279
00280 if (!check->ent->inuse)
00281 continue;
00282
00283 if (!SV_BoundingBoxesIntersect(ap->areaMins, ap->areaMaxs, check->ent))
00284 continue;
00285
00286 if (ap->areaEdictListCount == ap->areaEdictListMaxCount) {
00287 Com_Printf("SV_AreaEdicts_r: MAXCOUNT\n");
00288 return;
00289 }
00290
00291 ap->areaEdictList[ap->areaEdictListCount] = check->ent;
00292 ap->areaEdictListCount++;
00293 }
00294
00295 if (node->axis == LEAFNODE)
00296 return;
00297
00298
00299 if (ap->areaMaxs[node->axis] > node->dist)
00300 SV_AreaEdicts_r(node->children[0], ap);
00301 if (ap->areaMins[node->axis] < node->dist)
00302 SV_AreaEdicts_r(node->children[1], ap);
00303 }
00304
00313 int SV_AreaEdicts (const vec3_t mins, const vec3_t maxs, edict_t **list, int maxCount)
00314 {
00315 areaParms_t ap;
00316
00317 ap.areaMins = mins;
00318 ap.areaMaxs = maxs;
00319 ap.areaEdictList = list;
00320 ap.areaEdictListCount = 0;
00321 ap.areaEdictListMaxCount = maxCount;
00322
00323 SV_AreaEdicts_r(sv.worldSectors, &ap);
00324
00325 return ap.areaEdictListCount;
00326 }
00327
00328
00338 int SV_TouchEdicts (const vec3_t mins, const vec3_t maxs, edict_t **list, int maxCount, edict_t *skip)
00339 {
00340 int num = 0;
00341 const int max = min(maxCount, svs.ge->num_edicts);
00342 int i;
00343
00344
00345 for (i = 1; i < max; i++) {
00346 edict_t *e = EDICT_NUM(i);
00347
00348 if (e->solid == SOLID_NOT)
00349 continue;
00350 if (e == skip)
00351 continue;
00352 if (SV_BoundingBoxesIntersect(mins, maxs, e))
00353 list[num++] = e;
00354 }
00355
00356 return num;
00357 }
00358
00360 typedef struct {
00361 vec3_t boxmins, boxmaxs;
00362 const float *mins, *maxs;
00363 const float *start, *end;
00364 trace_t trace;
00365 const edict_t *passedict;
00366 int contentmask;
00367 } moveclip_t;
00368
00369
00381 static int SV_HullForEntity (const edict_t *ent, int *tile, vec3_t rmaShift)
00382 {
00383 assert(ent->solid != SOLID_NOT);
00384 assert(ent->solid != SOLID_TRIGGER);
00385
00386
00387 if (ent->solid == SOLID_BSP) {
00388 const cBspModel_t *model;
00389
00390 assert(ent->modelindex < MAX_MODELS);
00391
00392 model = sv.models[ent->modelindex];
00393 if (!model)
00394 Com_Error(ERR_FATAL, "SOLID_BSP with a non bsp model");
00395
00396 *tile = model->tile;
00397 VectorCopy(model->shift, rmaShift);
00398 assert(model->headnode < MAX_MAP_NODES);
00399 return model->headnode;
00400 }
00401
00402
00403 *tile = 0;
00404 VectorCopy(vec3_origin, rmaShift);
00405 return CM_HeadnodeForBox(&sv.mapTiles.mapTiles[*tile], ent->mins, ent->maxs);
00406 }
00407
00408
00414 static void SV_ClipMoveToEntities (moveclip_t *clip)
00415 {
00416 int i;
00417 edict_t *touchlist[MAX_EDICTS];
00418 trace_t trace;
00419 const float *angles;
00420 int headnode = 0;
00421 const int num = SV_AreaEdicts(clip->boxmins, clip->boxmaxs, touchlist, MAX_EDICTS);
00422
00423
00424
00425 for (i = 0; i < num; i++) {
00426 vec3_t rmaShift;
00427 edict_t *touch = touchlist[i];
00428 int tile = 0;
00429
00430 if (touch->solid == SOLID_NOT || touch->solid == SOLID_TRIGGER)
00431 continue;
00432 if (touch == clip->passedict)
00433 continue;
00434
00435 if (clip->trace.allsolid)
00436 return;
00437
00438 if (clip->passedict) {
00439 if (touch->owner == clip->passedict)
00440 continue;
00441 if (clip->passedict->owner == touch)
00442 continue;
00443 }
00444
00445
00446 headnode = SV_HullForEntity(touch, &tile, rmaShift);
00447 if (headnode >= MAX_MAP_NODES)
00448 continue;
00449
00450 if (touch->solid != SOLID_BSP)
00451 angles = vec3_origin;
00452 else
00453 angles = touch->angles;
00454
00455 assert(headnode < MAX_MAP_NODES);
00456 trace = CM_HintedTransformedBoxTrace(&sv.mapTiles.mapTiles[tile], clip->start, clip->end, clip->mins, clip->maxs, headnode,
00457 clip->contentmask, 0, touch->origin, angles, rmaShift, 1.0);
00458
00459 #ifdef PARANOID
00460 Com_DPrintf(DEBUG_SERVER, "SV_ClipMoveToEntities: %i %i: (%i %i %i) (%i %i %i) (%i %i %i)\n", touch->number, touch->modelindex,
00461 (int)touch->mins[0], (int)touch->mins[1], (int)touch->mins[2],
00462 (int)touch->maxs[0], (int)touch->maxs[1], (int)touch->maxs[2],
00463 (int)touch->origin[0], (int)touch->origin[1], (int)touch->origin[2]);
00464 #endif
00465
00466 if (trace.fraction < clip->trace.fraction) {
00467 qboolean oldStart;
00468
00469
00470 oldStart = clip->trace.startsolid;
00471 trace.ent = touch;
00472 clip->trace = trace;
00473 clip->trace.startsolid |= oldStart;
00474 } else if (trace.allsolid) {
00475 trace.ent = touch;
00476 clip->trace = trace;
00477 } else if (trace.startsolid) {
00478 trace.ent = touch;
00479 clip->trace.startsolid = qtrue;
00480 }
00481 }
00482 }
00483
00491 int SV_PointContents (vec3_t p)
00492 {
00493
00494 trace_t trace = CM_CompleteBoxTrace(&sv.mapTiles, p, p, vec3_origin, vec3_origin, TRACING_ALL_VISIBLE_LEVELS, MASK_ALL, 0);
00495 if (trace.fraction == 0)
00496 return trace.contentFlags;
00497 return 0;
00498 }
00499
00510 static void SV_TraceBounds (const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, vec3_t boxmins, vec3_t boxmaxs)
00511 {
00512 #if 0
00513
00514 boxmins[0] = boxmins[1] = boxmins[2] = -9999;
00515 boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999;
00516 #else
00517 int i;
00518
00519 for (i = 0; i < 3; i++) {
00520 if (end[i] > start[i]) {
00521 boxmins[i] = start[i] + mins[i] - 1;
00522 boxmaxs[i] = end[i] + maxs[i] + 1;
00523 } else {
00524 boxmins[i] = end[i] + mins[i] - 1;
00525 boxmaxs[i] = start[i] + maxs[i] + 1;
00526 }
00527 }
00528 #endif
00529 }
00530
00546 trace_t SV_Trace (const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, const edict_t * passedict, int contentmask)
00547 {
00548 moveclip_t clip;
00549
00550 if (!mins)
00551 mins = vec3_origin;
00552 if (!maxs)
00553 maxs = vec3_origin;
00554
00555 memset(&clip, 0, sizeof(clip));
00556
00557
00558 clip.trace = CM_CompleteBoxTrace(&sv.mapTiles, start, end, mins, maxs, TRACING_ALL_VISIBLE_LEVELS, contentmask, 0);
00561 clip.trace.ent = svs.ge->edicts;
00562 if (clip.trace.fraction == 0)
00563 return clip.trace;
00564
00565 clip.contentmask = contentmask;
00566 clip.start = start;
00567 clip.end = end;
00568 clip.mins = mins;
00569 clip.maxs = maxs;
00570 clip.passedict = passedict;
00571
00572
00573 SV_TraceBounds(start, clip.mins, clip.maxs, end, clip.boxmins, clip.boxmaxs);
00574
00575 #if 0
00576
00577 Com_Printf("Trace: (%i, %i, %i) (%i, %i, %i)\n",
00578 (int) clip.boxmins[0], (int) clip.boxmins[1], (int) clip.boxmins[2],
00579 (int) clip.boxmaxs[0], (int) clip.boxmaxs[1], (int) clip.boxmaxs[2]);
00580 #endif
00581
00582
00583 SV_ClipMoveToEntities(&clip);
00584
00585 return clip.trace;
00586 }
00587
00593 const char *SV_GetFootstepSound (const char *texture)
00594 {
00595 const terrainType_t *t = Com_GetTerrainType(texture);
00596 return t ? t->footStepSound : NULL;
00597 }
00598
00604 float SV_GetBounceFraction (const char *texture)
00605 {
00606 const terrainType_t *t = Com_GetTerrainType(texture);
00607 return t ? t->bounceFraction : 1.0f;
00608 }
00609
00616 static void SV_ModLoadAliasMD2Model (sv_model_t* mod, const byte *buffer)
00617 {
00618 const dMD2Model_t *md2 = (const dMD2Model_t *)buffer;
00619 const int num_frames = LittleLong(md2->num_frames);
00620 const int frameSize = LittleLong(md2->framesize);
00621 const dMD2Frame_t *frame = (const dMD2Frame_t *) ((const byte *) md2 + LittleLong(md2->ofs_frames) + mod->frame * frameSize);
00622 vec3_t scale, mins, maxs;
00623 int j;
00624
00625 if (mod->frame > num_frames)
00626 return;
00627
00628 for (j = 0; j < 3; j++) {
00629 scale[j] = LittleFloat(frame->scale[j]);
00630 mins[j] = LittleFloat(frame->translate[j]);
00631 }
00632
00633 VectorMA(mins, 255, scale, maxs);
00634 AddPointToBounds(mins, mod->mins, mod->maxs);
00635 AddPointToBounds(maxs, mod->mins, mod->maxs);
00636 }
00637
00644 static void SV_ModLoadAliasMD3Model (sv_model_t* mod, const byte *buffer)
00645 {
00646 const dmd3_t *md3 = (const dmd3_t *)buffer;
00647 const dmd3frame_t *frame = (const dmd3frame_t *)((const byte *)md3 + LittleLong(md3->ofs_frames));
00648 const int num_frames = LittleLong(md3->num_frames);
00649 vec3_t mins, maxs;
00650 int j;
00651
00652 if (mod->frame > num_frames)
00653 return;
00654
00655 frame += mod->frame;
00656 for (j = 0; j < 3; j++) {
00657 mins[j] = LittleFloat(frame->mins[j]);
00658 maxs[j] = LittleFloat(frame->maxs[j]);
00659 }
00660 AddPointToBounds(mins, mod->mins, mod->maxs);
00661 AddPointToBounds(maxs, mod->mins, mod->maxs);
00662 }
00663
00670 static void SV_ModLoadAliasDPMModel (sv_model_t* mod, const byte *buffer)
00671 {
00672 const dpmheader_t *dpm = (const dpmheader_t *)buffer;
00673 const int num_frames = BigLong(dpm->num_frames);
00674 const int ofs_frames = BigLong(dpm->ofs_frames);
00675 const dpmframe_t *frame = (const dpmframe_t *)((const byte *)dpm + ofs_frames);
00676
00677 if (mod->frame > num_frames)
00678 return;
00679
00680 frame += mod->frame;
00681
00682 mod->mins[0] = BigFloat(frame->mins[0]);
00683 mod->mins[1] = BigFloat(frame->mins[1]);
00684 mod->mins[2] = BigFloat(frame->mins[2]);
00685 mod->maxs[0] = BigFloat(frame->maxs[0]);
00686 mod->maxs[1] = BigFloat(frame->maxs[1]);
00687 mod->maxs[2] = BigFloat(frame->maxs[2]);
00688 }
00689
00696 static void SV_ModLoadObjModel (sv_model_t* mod, const byte *buffer, int bufferLength)
00697 {
00699 }
00700
00708 qboolean SV_LoadModelMinsMaxs (const char *model, int frame, vec3_t mins, vec3_t maxs)
00709 {
00710 sv_model_t *mod;
00711 byte *buf;
00712 unsigned int i;
00713 int modfilelen;
00714
00715 if (model[0] == '\0')
00716 Com_Error(ERR_DROP, "SV_LoadModelMinsMaxs: NULL model");
00717
00718
00719 for (i = 0, mod = sv.svModels; i < sv.numSVModels; i++, mod++)
00720 if (mod->frame == frame && !strcmp(mod->name, model)) {
00721 VectorCopy(mod->mins, mins);
00722 VectorCopy(mod->maxs, maxs);
00723 return qtrue;
00724 }
00725
00726
00727 for (i = 0, mod = sv.svModels; i < sv.numSVModels; i++, mod++) {
00728 if (!mod->name)
00729 break;
00730 }
00731
00732 if (i == sv.numSVModels) {
00733 if (sv.numSVModels == MAX_MOD_KNOWN)
00734 Com_Error(ERR_DROP, "sv.numSVModels == MAX_MOD_KNOWN");
00735 sv.numSVModels++;
00736 }
00737
00738 memset(mod, 0, sizeof(*mod));
00739 mod->name = Mem_PoolStrDup(model, com_genericPool, 0);
00740 mod->frame = frame;
00741
00742 VectorCopy(vec3_origin, mins);
00743 VectorCopy(vec3_origin, maxs);
00744
00745
00746 modfilelen = FS_LoadFile(model, &buf);
00747 if (!buf) {
00748 memset(mod->name, 0, sizeof(mod->name));
00749 sv.numSVModels--;
00750 return qfalse;
00751 }
00752
00753 ClearBounds(mod->mins, mod->maxs);
00754
00755
00756 switch (LittleLong(*(unsigned *) buf)) {
00757 case IDALIASHEADER:
00758 SV_ModLoadAliasMD2Model(mod, buf);
00759 break;
00760
00761 case DPMHEADER:
00762 SV_ModLoadAliasDPMModel(mod, buf);
00763 break;
00764
00765 case IDMD3HEADER:
00766 SV_ModLoadAliasMD3Model(mod, buf);
00767 break;
00768
00769 default:
00770 if (!Q_strcasecmp(mod->name + strlen(mod->name) - 4, ".obj"))
00771 SV_ModLoadObjModel(mod, buf, modfilelen);
00772 else {
00773 FS_FreeFile(buf);
00774 return qfalse;
00775 }
00776 }
00777
00778 VectorCopy(mod->mins, mins);
00779 VectorCopy(mod->maxs, maxs);
00780
00781 FS_FreeFile(buf);
00782 return qtrue;
00783 }