DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
cl_collision.c
Go to the documentation of this file.
1
2#include "quakedef.h"
3#include "cl_collision.h"
4
5float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int *hitent, entity_render_t *ignoreent)
6{
7 float maxfrac;
8 int n;
10 vec_t tracemins[3], tracemaxs[3];
11 trace_t trace;
12 vec_t tempnormal[3], starttransformed[3], endtransformed[3];
13
14 memset (&trace, 0 , sizeof(trace_t));
15 trace.fraction = 1;
16 VectorCopy (end, trace.endpos);
17
18 if (hitent)
19 *hitent = 0;
20 if (cl.worldmodel && cl.worldmodel->TraceLine)
21 cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, start, end, SUPERCONTENTS_SOLID, 0, 0);
22
23 if (normal)
25 maxfrac = trace.fraction;
26
27 tracemins[0] = min(start[0], end[0]);
28 tracemaxs[0] = max(start[0], end[0]);
29 tracemins[1] = min(start[1], end[1]);
30 tracemaxs[1] = max(start[1], end[1]);
31 tracemins[2] = min(start[2], end[2]);
32 tracemaxs[2] = max(start[2], end[2]);
33
34 // look for embedded bmodels
35 for (n = 0;n < cl.num_entities;n++)
36 {
37 if (!cl.entities_active[n])
38 continue;
39 ent = &cl.entities[n].render;
40 if (!BoxesOverlap(ent->mins, ent->maxs, tracemins, tracemaxs))
41 continue;
42 if (!ent->model || !ent->model->TraceLine)
43 continue;
45 continue;
46 // if transparent and not selectable, skip entity
47 if (!(cl.entities[n].state_current.effects & EF_SELECTABLE) && (ent->alpha < 1 || (ent->effects & (EF_ADDITIVE | EF_NODEPTHTEST))))
48 continue;
49 if (ent == ignoreent)
50 continue;
51 Matrix4x4_Transform(&ent->inversematrix, start, starttransformed);
52 Matrix4x4_Transform(&ent->inversematrix, end, endtransformed);
53 Collision_ClipTrace_Box(&trace, ent->model->normalmins, ent->model->normalmaxs, starttransformed, vec3_origin, vec3_origin, endtransformed, SUPERCONTENTS_SOLID, 0, 0, SUPERCONTENTS_SOLID, 0, NULL);
54 if (maxfrac < trace.fraction)
55 continue;
56
57 ent->model->TraceLine(ent->model, ent->frameblend, ent->skeleton, &trace, starttransformed, endtransformed, SUPERCONTENTS_SOLID, 0, 0);
58
59 if (maxfrac > trace.fraction)
60 {
61 if (hitent)
62 *hitent = n;
63 maxfrac = trace.fraction;
64 if (normal)
65 {
66 VectorCopy(trace.plane.normal, tempnormal);
67 Matrix4x4_Transform3x3(&ent->matrix, tempnormal, normal);
68 }
69 }
70 }
71 maxfrac = bound(0, maxfrac, 1);
72 //maxrealfrac = bound(0, maxrealfrac, 1);
73 //if (maxfrac < 0 || maxfrac > 1) Con_Printf("fraction out of bounds %f %s:%d\n", maxfrac, __FILE__, __LINE__);
74 if (impact)
75 VectorLerp(start, maxfrac, end, impact);
76 return maxfrac;
77}
78
79void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius)
80{
81 // FIXME: check multiple brush models
82 if (cl.worldmodel && cl.worldmodel->brush.FindNonSolidLocation)
83 cl.worldmodel->brush.FindNonSolidLocation(cl.worldmodel, in, out, radius);
84}
85
87{
88 if(!modelindex)
89 return NULL;
90 if (modelindex < 0)
91 {
95 }
96 else
97 {
100 }
101 return NULL;
102}
103
105{
106 prvm_prog_t *prog = CLVM_prog;
107 if (!ed || ed->free)
108 return NULL;
110}
111
113{
114 prvm_prog_t *prog = CLVM_prog;
116
117 if (ent == prog->edicts)
118 return; // don't add the world
119
120 if (ent->free)
121 return;
122
123 // set the abs box
124
126 {
128 if (model == NULL)
129 {
130 Con_Printf("edict %i: SOLID_BSP with invalid modelindex!\n", PRVM_NUM_FOR_EDICT(ent));
131
133 }
134
135 if( model != NULL )
136 {
137 if (!model->TraceBox)
138 Con_DPrintf("edict %i: SOLID_BSP with non-collidable model\n", PRVM_NUM_FOR_EDICT(ent));
139
141 {
142 VectorAdd(PRVM_clientedictvector(ent, origin), model->rotatedmins, mins);
143 VectorAdd(PRVM_clientedictvector(ent, origin), model->rotatedmaxs, maxs);
144 }
146 {
149 }
150 else
151 {
152 VectorAdd(PRVM_clientedictvector(ent, origin), model->normalmins, mins);
153 VectorAdd(PRVM_clientedictvector(ent, origin), model->normalmaxs, maxs);
154 }
155 }
156 else
157 {
158 // SOLID_BSP with no model is valid, mainly because some QC setup code does so temporarily
161 }
162 }
163 else
164 {
167 }
168
171
173}
174
200
201/*
202==================
203CL_Move
204==================
205*/
206trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, qbool hitnetworkbrushmodels, qbool hitnetworkplayers, int *hitnetworkentity, qbool hitcsqcentities)
207{
208 prvm_prog_t *prog = CLVM_prog;
209 int i, bodysupercontents;
210 int passedictprog;
211 prvm_edict_t *traceowner, *touch;
212 trace_t trace;
213 // temporary storage because prvm_vec_t may need conversion
214 vec3_t touchmins, touchmaxs;
215 // bounding box of entire move area
216 vec3_t clipboxmins, clipboxmaxs;
217 // size when clipping against monsters
218 vec3_t clipmins2, clipmaxs2;
219 // start and end origin of move
220 vec3_t clipstart;
221 // trace results
222 trace_t cliptrace;
223 // matrices to transform into/out of other entity's space
224 matrix4x4_t matrix, imatrix;
225 // model of other entity
226 model_t *model;
227 // list of entities to test for collisions
228 int numtouchedicts;
229 static prvm_edict_t *touchedicts[MAX_EDICTS];
230 int clipgroup;
231
232 if (hitnetworkentity)
233 *hitnetworkentity = 0;
234
235 VectorCopy(start, clipstart);
236 VectorClear(clipmins2);
237 VectorClear(clipmaxs2);
238#if COLLISIONPARANOID >= 3
239 Con_Printf("move(%f %f %f)", clipstart[0], clipstart[1], clipstart[2]);
240#endif
241
242 // clip to world
243 Collision_ClipPointToWorld(&cliptrace, cl.worldmodel, clipstart, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
244 cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
245 if (cliptrace.startsolid || cliptrace.fraction < 1)
246 cliptrace.ent = prog ? prog->edicts : NULL;
247 if (type == MOVE_WORLDONLY)
248 goto finished;
249
250 if (type == MOVE_MISSILE)
251 {
252 // LadyHavoc: modified this, was = -15, now -= 15
253 for (i = 0;i < 3;i++)
254 {
255 clipmins2[i] -= 15;
256 clipmaxs2[i] += 15;
257 }
258 }
259
260 // create the bounding box of the entire move
261 for (i = 0;i < 3;i++)
262 {
263 clipboxmins[i] = clipstart[i] - 1;
264 clipboxmaxs[i] = clipstart[i] + 1;
265 }
266
267 // debug override to test against everything
269 {
270 clipboxmins[0] = clipboxmins[1] = clipboxmins[2] = (vec_t)-999999999;
271 clipboxmaxs[0] = clipboxmaxs[1] = clipboxmaxs[2] = (vec_t)999999999;
272 }
273
274 // if the passedict is world, make it NULL (to avoid two checks each time)
275 // this checks prog because this function is often called without a CSQC
276 // VM context
277 if (prog == NULL || passedict == prog->edicts)
278 passedict = NULL;
279 // precalculate prog value for passedict for comparisons
280 passedictprog = prog != NULL ? PRVM_EDICT_TO_PROG(passedict) : 0;
281 // precalculate passedict's owner edict pointer for comparisons
282 traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_clientedictedict(passedict, owner)) : NULL;
283
284 clipgroup = passedict ? (int)PRVM_clientedictfloat(passedict, clipgroup) : 0;
285
286 // collide against network entities
287 if (hitnetworkbrushmodels)
288 {
289 for (i = 0;i < cl.num_brushmodel_entities;i++)
290 {
292 if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
293 continue;
294 Collision_ClipPointToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
295 if (cliptrace.fraction > trace.fraction && hitnetworkentity)
296 *hitnetworkentity = cl.brushmodel_entities[i];
297 Collision_CombineTraces(&cliptrace, &trace, NULL, true);
298 }
299 }
300
301 // collide against player entities
302 if (hitnetworkplayers)
303 {
304 vec3_t origin, entmins, entmaxs;
305 matrix4x4_t entmatrix, entinversematrix;
306
308 {
309 // don't hit network players, if we are a nonsolid player
310 if(cl.scores[cl.playerentity-1].frags == -666 || cl.scores[cl.playerentity-1].frags == -616)
311 goto skipnetworkplayers;
312 }
313
314 for (i = 1;i <= cl.maxclients;i++)
315 {
317
318 // don't hit ourselves
319 if (i == cl.playerentity)
320 continue;
321
322 // don't hit players that don't exist
323 if (!cl.entities_active[i])
324 continue;
325 if (!cl.scores[i-1].name[0])
326 continue;
327
329 {
330 // don't hit spectators or nonsolid players
331 if(cl.scores[i-1].frags == -666 || cl.scores[i-1].frags == -616)
332 continue;
333 }
334
338 if (!BoxesOverlap(clipboxmins, clipboxmaxs, entmins, entmaxs))
339 continue;
340 Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]);
341 Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]);
342 Collision_ClipPointToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
343 if (cliptrace.fraction > trace.fraction && hitnetworkentity)
344 *hitnetworkentity = i;
345 Collision_CombineTraces(&cliptrace, &trace, NULL, false);
346 }
347
348skipnetworkplayers:
349 ;
350 }
351
352 // clip to entities
353 // because this uses World_EntitiestoBox, we know all entity boxes overlap
354 // the clip region, so we can skip culling checks in the loop below
355 // note: if prog is NULL then there won't be any linked entities
356 numtouchedicts = 0;
357 if (hitcsqcentities && prog != NULL)
358 {
359 numtouchedicts = World_EntitiesInBox(&cl.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
360 if (numtouchedicts > MAX_EDICTS)
361 {
362 // this never happens
363 Con_Printf("CL_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
364 numtouchedicts = MAX_EDICTS;
365 }
366 }
367 for (i = 0;i < numtouchedicts;i++)
368 {
369 touch = touchedicts[i];
370
372 continue;
374 continue;
375
376 if (passedict)
377 {
378 // don't clip against self
379 if (passedict == touch)
380 continue;
381 // don't clip owned entities against owner
382 if (traceowner == touch)
383 continue;
384 // don't clip owner against owned entities
385 if (passedictprog == PRVM_clientedictedict(touch, owner))
386 continue;
387 // don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP)
388 if (clipgroup && clipgroup == (int)PRVM_clientedictfloat(touch, clipgroup))
389 continue;
390 // don't clip points against points (they can't collide)
392 continue;
393 }
394
396
397 // might interact, so do an exact clip
398 model = NULL;
399 if ((int) PRVM_clientedictfloat(touch, solid) == SOLID_BSP || type == MOVE_HITMODEL)
401 if (model)
403 else
405 Matrix4x4_Invert_Simple(&imatrix, &matrix);
406 VectorCopy(PRVM_clientedictvector(touch, mins), touchmins);
407 VectorCopy(PRVM_clientedictvector(touch, maxs), touchmaxs);
408 if ((int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER)
409 Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipstart, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, 0.0f);
410 else
411 Collision_ClipPointToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
412
413 if (cliptrace.fraction > trace.fraction && hitnetworkentity)
414 *hitnetworkentity = 0;
415 Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_clientedictfloat(touch, solid) == SOLID_BSP);
416 }
417
418finished:
419 return cliptrace;
420}
421
422/*
423==================
424CL_TraceLine
425==================
426*/
427trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qbool hitnetworkbrushmodels, qbool hitnetworkplayers, int *hitnetworkentity, qbool hitcsqcentities, qbool hitsurfaces)
428{
429 prvm_prog_t *prog = CLVM_prog;
430 int i, bodysupercontents;
431 int passedictprog;
432 prvm_edict_t *traceowner, *touch;
433 trace_t trace;
434 // temporary storage because prvm_vec_t may need conversion
435 vec3_t touchmins, touchmaxs;
436 // bounding box of entire move area
437 vec3_t clipboxmins, clipboxmaxs;
438 // size when clipping against monsters
439 vec3_t clipmins2, clipmaxs2;
440 // start and end origin of move
441 vec3_t clipstart, clipend;
442 // trace results
443 trace_t cliptrace;
444 // matrices to transform into/out of other entity's space
445 matrix4x4_t matrix, imatrix;
446 // model of other entity
447 model_t *model;
448 // list of entities to test for collisions
449 int numtouchedicts;
450 static prvm_edict_t *touchedicts[MAX_EDICTS];
451 int clipgroup;
452 if (VectorCompare(start, end))
453 return CL_TracePoint(start, type, passedict, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
454
455 if (hitnetworkentity)
456 *hitnetworkentity = 0;
457
458 VectorCopy(start, clipstart);
459 VectorCopy(end, clipend);
460 VectorClear(clipmins2);
461 VectorClear(clipmaxs2);
462#if COLLISIONPARANOID >= 3
463 Con_Printf("move(%f %f %f,%f %f %f)", clipstart[0], clipstart[1], clipstart[2], clipend[0], clipend[1], clipend[2]);
464#endif
465
466 // clip to world
467 Collision_ClipLineToWorld(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitsurfaces);
468 cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
469 if (cliptrace.startsolid || cliptrace.fraction < 1)
470 cliptrace.ent = prog ? prog->edicts : NULL;
471 if (type == MOVE_WORLDONLY)
472 goto finished;
473
474 if (type == MOVE_MISSILE)
475 {
476 // LadyHavoc: modified this, was = -15, now -= 15
477 for (i = 0;i < 3;i++)
478 {
479 clipmins2[i] -= 15;
480 clipmaxs2[i] += 15;
481 }
482 }
483
484 // create the bounding box of the entire move
485 for (i = 0;i < 3;i++)
486 {
487 clipboxmins[i] = min(clipstart[i], cliptrace.endpos[i]) + clipmins2[i] - 1;
488 clipboxmaxs[i] = max(clipstart[i], cliptrace.endpos[i]) + clipmaxs2[i] + 1;
489 }
490
491 // debug override to test against everything
493 {
494 clipboxmins[0] = clipboxmins[1] = clipboxmins[2] = (vec_t)-999999999;
495 clipboxmaxs[0] = clipboxmaxs[1] = clipboxmaxs[2] = (vec_t)999999999;
496 }
497
498 // if the passedict is world, make it NULL (to avoid two checks each time)
499 // this checks prog because this function is often called without a CSQC
500 // VM context
501 if (prog == NULL || passedict == prog->edicts)
502 passedict = NULL;
503 // precalculate prog value for passedict for comparisons
504 passedictprog = prog != NULL ? PRVM_EDICT_TO_PROG(passedict) : 0;
505 // precalculate passedict's owner edict pointer for comparisons
506 traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_clientedictedict(passedict, owner)) : NULL;
507
508 clipgroup = passedict ? (int)PRVM_clientedictfloat(passedict, clipgroup) : 0;
509
510 // collide against network entities
511 if (hitnetworkbrushmodels)
512 {
513 for (i = 0;i < cl.num_brushmodel_entities;i++)
514 {
516 if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
517 continue;
518 Collision_ClipLineToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitsurfaces);
519 if (cliptrace.fraction > trace.fraction && hitnetworkentity)
520 *hitnetworkentity = cl.brushmodel_entities[i];
521 Collision_CombineTraces(&cliptrace, &trace, NULL, true);
522 }
523 }
524
525 // collide against player entities
526 if (hitnetworkplayers)
527 {
528 vec3_t origin, entmins, entmaxs;
529 matrix4x4_t entmatrix, entinversematrix;
530
532 {
533 // don't hit network players, if we are a nonsolid player
534 if(cl.scores[cl.playerentity-1].frags == -666 || cl.scores[cl.playerentity-1].frags == -616)
535 goto skipnetworkplayers;
536 }
537
538 for (i = 1;i <= cl.maxclients;i++)
539 {
541
542 // don't hit ourselves
543 if (i == cl.playerentity)
544 continue;
545
546 // don't hit players that don't exist
547 if (!cl.entities_active[i])
548 continue;
549 if (!cl.scores[i-1].name[0])
550 continue;
551
553 {
554 // don't hit spectators or nonsolid players
555 if(cl.scores[i-1].frags == -666 || cl.scores[i-1].frags == -616)
556 continue;
557 }
558
562 if (!BoxesOverlap(clipboxmins, clipboxmaxs, entmins, entmaxs))
563 continue;
564 Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]);
565 Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]);
566 Collision_ClipLineToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitsurfaces);
567 if (cliptrace.fraction > trace.fraction && hitnetworkentity)
568 *hitnetworkentity = i;
569 Collision_CombineTraces(&cliptrace, &trace, NULL, false);
570 }
571
572skipnetworkplayers:
573 ;
574 }
575
576 // clip to entities
577 // because this uses World_EntitiestoBox, we know all entity boxes overlap
578 // the clip region, so we can skip culling checks in the loop below
579 // note: if prog is NULL then there won't be any linked entities
580 numtouchedicts = 0;
581 if (hitcsqcentities && prog != NULL)
582 {
583 numtouchedicts = World_EntitiesInBox(&cl.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
584 if (numtouchedicts > MAX_EDICTS)
585 {
586 // this never happens
587 Con_Printf("CL_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
588 numtouchedicts = MAX_EDICTS;
589 }
590 }
591 for (i = 0;i < numtouchedicts;i++)
592 {
593 touch = touchedicts[i];
594
596 continue;
598 continue;
599
600 if (passedict)
601 {
602 // don't clip against self
603 if (passedict == touch)
604 continue;
605 // don't clip owned entities against owner
606 if (traceowner == touch)
607 continue;
608 // don't clip owner against owned entities
609 if (passedictprog == PRVM_clientedictedict(touch, owner))
610 continue;
611 // don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP)
612 if (clipgroup && clipgroup == (int)PRVM_clientedictfloat(touch, clipgroup))
613 continue;
614 // don't clip points against points (they can't collide)
616 continue;
617 }
618
620
621 // might interact, so do an exact clip
622 model = NULL;
623 if ((int) PRVM_clientedictfloat(touch, solid) == SOLID_BSP || type == MOVE_HITMODEL)
625 if (model)
627 else
629 Matrix4x4_Invert_Simple(&imatrix, &matrix);
630 VectorCopy(PRVM_clientedictvector(touch, mins), touchmins);
631 VectorCopy(PRVM_clientedictvector(touch, maxs), touchmaxs);
632 if (type == MOVE_MISSILE && (int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER)
633 Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend);
634 else
635 Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitsurfaces);
636
637 if (cliptrace.fraction > trace.fraction && hitnetworkentity)
638 *hitnetworkentity = 0;
639 Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_clientedictfloat(touch, solid) == SOLID_BSP);
640 }
641
642finished:
643 return cliptrace;
644}
645
646/*
647==================
648CL_Move
649==================
650*/
651trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qbool hitnetworkbrushmodels, qbool hitnetworkplayers, int *hitnetworkentity, qbool hitcsqcentities)
652{
653 prvm_prog_t *prog = CLVM_prog;
654 vec3_t hullmins, hullmaxs;
655 int i, bodysupercontents;
656 int passedictprog;
657 qbool pointtrace;
658 prvm_edict_t *traceowner, *touch;
659 trace_t trace;
660 // temporary storage because prvm_vec_t may need conversion
661 vec3_t touchmins, touchmaxs;
662 // bounding box of entire move area
663 vec3_t clipboxmins, clipboxmaxs;
664 // size of the moving object
665 vec3_t clipmins, clipmaxs;
666 // size when clipping against monsters
667 vec3_t clipmins2, clipmaxs2;
668 // start and end origin of move
669 vec3_t clipstart, clipend;
670 // trace results
671 trace_t cliptrace;
672 // matrices to transform into/out of other entity's space
673 matrix4x4_t matrix, imatrix;
674 // model of other entity
675 model_t *model;
676 // list of entities to test for collisions
677 int numtouchedicts;
678 static prvm_edict_t *touchedicts[MAX_EDICTS];
679 int clipgroup;
680 if (VectorCompare(mins, maxs))
681 {
682 vec3_t shiftstart, shiftend;
683 VectorAdd(start, mins, shiftstart);
684 VectorAdd(end, mins, shiftend);
685 if (VectorCompare(start, end))
686 trace = CL_TracePoint(shiftstart, type, passedict, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
687 else
688 trace = CL_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities, false);
689 VectorSubtract(trace.endpos, mins, trace.endpos);
690 return trace;
691 }
692
693 if (hitnetworkentity)
694 *hitnetworkentity = 0;
695
696 VectorCopy(start, clipstart);
697 VectorCopy(end, clipend);
698 VectorCopy(mins, clipmins);
699 VectorCopy(maxs, clipmaxs);
700 VectorCopy(mins, clipmins2);
701 VectorCopy(maxs, clipmaxs2);
702#if COLLISIONPARANOID >= 3
703 Con_Printf("move(%f %f %f,%f %f %f)", clipstart[0], clipstart[1], clipstart[2], clipend[0], clipend[1], clipend[2]);
704#endif
705
706 // clip to world
707 Collision_ClipToWorld(&cliptrace, cl.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend);
708 cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
709 if (cliptrace.startsolid || cliptrace.fraction < 1)
710 cliptrace.ent = prog ? prog->edicts : NULL;
711 if (type == MOVE_WORLDONLY)
712 goto finished;
713
714 if (type == MOVE_MISSILE)
715 {
716 // LadyHavoc: modified this, was = -15, now -= 15
717 for (i = 0;i < 3;i++)
718 {
719 clipmins2[i] -= 15;
720 clipmaxs2[i] += 15;
721 }
722 }
723
724 // get adjusted box for bmodel collisions if the world is q1bsp or hlbsp
725 if (cl.worldmodel && cl.worldmodel->brush.RoundUpToHullSize)
726 cl.worldmodel->brush.RoundUpToHullSize(cl.worldmodel, clipmins, clipmaxs, hullmins, hullmaxs);
727 else
728 {
729 VectorCopy(clipmins, hullmins);
730 VectorCopy(clipmaxs, hullmaxs);
731 }
732
733 // create the bounding box of the entire move
734 for (i = 0;i < 3;i++)
735 {
736 clipboxmins[i] = min(clipstart[i], cliptrace.endpos[i]) + min(hullmins[i], clipmins2[i]) - 1;
737 clipboxmaxs[i] = max(clipstart[i], cliptrace.endpos[i]) + max(hullmaxs[i], clipmaxs2[i]) + 1;
738 }
739
740 // debug override to test against everything
742 {
743 clipboxmins[0] = clipboxmins[1] = clipboxmins[2] = (vec_t)-999999999;
744 clipboxmaxs[0] = clipboxmaxs[1] = clipboxmaxs[2] = (vec_t)999999999;
745 }
746
747 // if the passedict is world, make it NULL (to avoid two checks each time)
748 // this checks prog because this function is often called without a CSQC
749 // VM context
750 if (prog == NULL || passedict == prog->edicts)
751 passedict = NULL;
752 // precalculate prog value for passedict for comparisons
753 passedictprog = prog != NULL ? PRVM_EDICT_TO_PROG(passedict) : 0;
754 // figure out whether this is a point trace for comparisons
755 pointtrace = VectorCompare(clipmins, clipmaxs);
756 // precalculate passedict's owner edict pointer for comparisons
757 traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_clientedictedict(passedict, owner)) : NULL;
758
759 clipgroup = passedict ? (int)PRVM_clientedictfloat(passedict, clipgroup) : 0;
760
761 // collide against network entities
762 if (hitnetworkbrushmodels)
763 {
764 for (i = 0;i < cl.num_brushmodel_entities;i++)
765 {
767 if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
768 continue;
769 Collision_ClipToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, mins, maxs, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend);
770 if (cliptrace.fraction > trace.fraction && hitnetworkentity)
771 *hitnetworkentity = cl.brushmodel_entities[i];
772 Collision_CombineTraces(&cliptrace, &trace, NULL, true);
773 }
774 }
775
776 // collide against player entities
777 if (hitnetworkplayers)
778 {
779 vec3_t origin, entmins, entmaxs;
780 matrix4x4_t entmatrix, entinversematrix;
781
783 {
784 // don't hit network players, if we are a nonsolid player
785 if(cl.scores[cl.playerentity-1].frags == -666 || cl.scores[cl.playerentity-1].frags == -616)
786 goto skipnetworkplayers;
787 }
788
789 for (i = 1;i <= cl.maxclients;i++)
790 {
792
793 // don't hit ourselves
794 if (i == cl.playerentity)
795 continue;
796
797 // don't hit players that don't exist
798 if (!cl.entities_active[i])
799 continue;
800 if (!cl.scores[i-1].name[0])
801 continue;
802
804 {
805 // don't hit spectators or nonsolid players
806 if(cl.scores[i-1].frags == -666 || cl.scores[i-1].frags == -616)
807 continue;
808 }
809
813 if (!BoxesOverlap(clipboxmins, clipboxmaxs, entmins, entmaxs))
814 continue;
815 Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]);
816 Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]);
817 Collision_ClipToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, mins, maxs, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend);
818 if (cliptrace.fraction > trace.fraction && hitnetworkentity)
819 *hitnetworkentity = i;
820 Collision_CombineTraces(&cliptrace, &trace, NULL, false);
821 }
822
823skipnetworkplayers:
824 ;
825 }
826
827 // clip to entities
828 // because this uses World_EntitiestoBox, we know all entity boxes overlap
829 // the clip region, so we can skip culling checks in the loop below
830 // note: if prog is NULL then there won't be any linked entities
831 numtouchedicts = 0;
832 if (hitcsqcentities && prog != NULL)
833 {
834 numtouchedicts = World_EntitiesInBox(&cl.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
835 if (numtouchedicts > MAX_EDICTS)
836 {
837 // this never happens
838 Con_Printf("CL_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
839 numtouchedicts = MAX_EDICTS;
840 }
841 }
842 for (i = 0;i < numtouchedicts;i++)
843 {
844 touch = touchedicts[i];
845
847 continue;
849 continue;
850
851 if (passedict)
852 {
853 // don't clip against self
854 if (passedict == touch)
855 continue;
856 // don't clip owned entities against owner
857 if (traceowner == touch)
858 continue;
859 // don't clip owner against owned entities
860 if (passedictprog == PRVM_clientedictedict(touch, owner))
861 continue;
862 // don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP)
863 if (clipgroup && clipgroup == (int)PRVM_clientedictfloat(touch, clipgroup))
864 continue;
865 // don't clip points against points (they can't collide)
866 if (pointtrace && VectorCompare(PRVM_clientedictvector(touch, mins), PRVM_clientedictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER)))
867 continue;
868 }
869
871
872 // might interact, so do an exact clip
873 model = NULL;
874 if ((int) PRVM_clientedictfloat(touch, solid) == SOLID_BSP || type == MOVE_HITMODEL)
876 if (model)
878 else
880 Matrix4x4_Invert_Simple(&imatrix, &matrix);
881 VectorCopy(PRVM_clientedictvector(touch, mins), touchmins);
882 VectorCopy(PRVM_clientedictvector(touch, maxs), touchmaxs);
883 if ((int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER)
884 Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend);
885 else
886 Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend);
887
888 if (cliptrace.fraction > trace.fraction && hitnetworkentity)
889 *hitnetworkentity = 0;
890 Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_clientedictfloat(touch, solid) == SOLID_BSP);
891 }
892
893finished:
894 return cliptrace;
895}
896
897/*
898==================
899CL_Cache_TraceLine
900==================
901*/
902trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
903{
904 prvm_prog_t *prog = CLVM_prog;
905 int i;
906 prvm_edict_t *touch;
907 trace_t trace;
908 // bounding box of entire move area
909 vec3_t clipboxmins, clipboxmaxs;
910 // start and end origin of move
911 vec3_t clipstart, clipend;
912 // trace results
913 trace_t cliptrace;
914 // matrices to transform into/out of other entity's space
915 matrix4x4_t matrix, imatrix;
916 // model of other entity
917 model_t *model;
918 // list of entities to test for collisions
919 int numtouchedicts;
920 static prvm_edict_t *touchedicts[MAX_EDICTS];
921
922 VectorCopy(start, clipstart);
923 VectorCopy(end, clipend);
924#if COLLISIONPARANOID >= 3
925 Con_Printf("move(%f %f %f,%f %f %f)", clipstart[0], clipstart[1], clipstart[2], clipend[0], clipend[1], clipend[2]);
926#endif
927
928 // clip to world
929 Collision_Cache_ClipLineToWorldSurfaces(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
930 cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
931 if (cliptrace.startsolid || cliptrace.fraction < 1)
932 cliptrace.ent = prog ? prog->edicts : NULL;
933 if (type == MOVE_WORLDONLY)
934 goto finished;
935
936 // create the bounding box of the entire move
937 for (i = 0;i < 3;i++)
938 {
939 clipboxmins[i] = min(clipstart[i], cliptrace.endpos[i]) - 1;
940 clipboxmaxs[i] = max(clipstart[i], cliptrace.endpos[i]) + 1;
941 }
942
943 // if the passedict is world, make it NULL (to avoid two checks each time)
944 // this checks prog because this function is often called without a CSQC
945 // VM context
946
947 // collide against network entities
948 for (i = 0;i < cl.num_brushmodel_entities;i++)
949 {
951 if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
952 continue;
953 Collision_Cache_ClipLineToGenericEntitySurfaces(&trace, ent->model, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
954 Collision_CombineTraces(&cliptrace, &trace, NULL, true);
955 }
956
957 // clip to entities
958 // because this uses World_EntitiestoBox, we know all entity boxes overlap
959 // the clip region, so we can skip culling checks in the loop below
960 // note: if prog is NULL then there won't be any linked entities
961 numtouchedicts = 0;
962 if (prog != NULL)
963 {
964 numtouchedicts = World_EntitiesInBox(&cl.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
965 if (numtouchedicts > MAX_EDICTS)
966 {
967 // this never happens
968 Con_Printf("CL_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
969 numtouchedicts = MAX_EDICTS;
970 }
971 }
972 for (i = 0;i < numtouchedicts;i++)
973 {
974 touch = touchedicts[i];
975 // might interact, so do an exact clip
976 // only hit entity models, not collision shapes
978 if (!model)
979 continue;
980 // animated models are not suitable for caching
981 if ((touch->priv.server->frameblend[0].lerp != 1.0 || touch->priv.server->frameblend[0].subframe != 0) || touch->priv.server->skeleton.relativetransforms)
982 continue;
984 continue;
986 Matrix4x4_Invert_Simple(&imatrix, &matrix);
987 Collision_Cache_ClipLineToGenericEntitySurfaces(&trace, model, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
988 Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_clientedictfloat(touch, solid) == SOLID_BSP);
989 }
990
991finished:
992 return cliptrace;
993}
994
#define SUPERCONTENTS_BODY
Definition bspfile.h:201
#define SUPERCONTENTS_MONSTERCLIP
Definition bspfile.h:205
#define SUPERCONTENTS_SOLID
Definition bspfile.h:196
#define SUPERCONTENTS_CORPSE
Definition bspfile.h:202
#define SUPERCONTENTS_PLAYERCLIP
Definition bspfile.h:204
int CL_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qbool hitnetworkbrushmodels, qbool hitnetworkplayers, int *hitnetworkentity, qbool hitcsqcentities, qbool hitsurfaces)
trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qbool hitnetworkbrushmodels, qbool hitnetworkplayers, int *hitnetworkentity, qbool hitcsqcentities)
trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, qbool hitnetworkbrushmodels, qbool hitnetworkplayers, int *hitnetworkentity, qbool hitcsqcentities)
model_t * CL_GetModelFromEdict(prvm_edict_t *ed)
void CL_LinkEdict(prvm_edict_t *ent)
void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius)
float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int *hitent, entity_render_t *ignoreent)
Definition cl_collision.c:5
model_t * CL_GetModelByIndex(int modelindex)
trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
client_state_t cl
Definition cl_main.c:117
cvar_t cl_areagrid_link_SOLID_NOT
Definition cl_main.c:112
void Collision_ClipToWorld(trace_t *trace, model_t *model, const vec3_t tstart, const vec3_t mins, const vec3_t maxs, const vec3_t tend, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend)
Definition collision.c:1834
void Collision_ClipLineToWorld(trace_t *trace, model_t *model, const vec3_t tstart, const vec3_t tend, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qbool hitsurfaces)
Definition collision.c:1870
void Collision_CombineTraces(trace_t *cliptrace, const trace_t *trace, void *touch, qbool isbmodel)
Definition collision.c:1914
void Collision_ClipLineToGenericEntity(trace_t *trace, model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t tstart, const vec3_t tend, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qbool hitsurfaces)
Definition collision.c:1844
void Collision_ClipToGenericEntity(trace_t *trace, model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t tstart, const vec3_t mins, const vec3_t maxs, const vec3_t tend, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend)
Definition collision.c:1791
void Collision_Cache_ClipLineToWorldSurfaces(trace_t *trace, model_t *model, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
Definition collision.c:1705
void Collision_Cache_ClipLineToGenericEntitySurfaces(trace_t *trace, model_t *model, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
Definition collision.c:1691
void Collision_ClipPointToWorld(trace_t *trace, model_t *model, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
Definition collision.c:1905
void Collision_ClipPointToGenericEntity(trace_t *trace, model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
Definition collision.c:1883
void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture)
gamemode_t gamemode
Definition com_game.c:26
#define IS_OLDNEXUIZ_DERIVED(g)
Definition com_game.h:73
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
float flags
float modelindex
vector avelocity
entity owner
vector mins
float clipgroup
vector maxs
vector angles
vector absmax
vector origin
string model
float solid
vector absmin
float dphitcontentsmask
#define n(x, y)
static int(ZEXPORT *qz_inflate)(z_stream *strm
GLenum type
Definition glquake.h:656
vec3_t vec3_origin
Definition mathlib.c:26
#define VectorLerp(v1, lerp, v2, out)
Definition mathlib.h:120
#define max(A, B)
Definition mathlib.h:38
#define min(A, B)
Definition mathlib.h:37
#define BoxesOverlap(a, b, c, d)
Definition mathlib.h:122
#define VectorClear(a)
Definition mathlib.h:97
#define bound(min, num, max)
Definition mathlib.h:34
#define VectorSubtract(a, b, out)
Definition mathlib.h:99
#define VectorCompare(a, b)
Definition mathlib.h:113
#define VectorCopy(in, out)
Definition mathlib.h:101
#define VectorAdd(a, b, out)
Definition mathlib.h:100
void Matrix4x4_Transform(const matrix4x4_t *in, const float v[3], float out[3])
Definition matrixlib.c:1657
void Matrix4x4_CreateTranslate(matrix4x4_t *out, double x, double y, double z)
Definition matrixlib.c:584
void Matrix4x4_Transform3x3(const matrix4x4_t *in, const float v[3], float out[3])
Definition matrixlib.c:1685
void Matrix4x4_CreateFromQuakeEntity(matrix4x4_t *out, double x, double y, double z, double pitch, double yaw, double roll, double scale)
Definition matrixlib.c:715
void Matrix4x4_Invert_Simple(matrix4x4_t *out, const matrix4x4_t *in1)
Definition matrixlib.c:422
void Matrix4x4_OriginFromMatrix(const matrix4x4_t *in, float *out)
Definition matrixlib.c:1792
#define CLVM_prog
Definition progsvm.h:767
#define PRVM_clientedictedict(ed, fieldname)
Definition progsvm.h:187
#define PRVM_EDICT_TO_PROG(e)
Definition progsvm.h:875
#define PRVM_NUM_FOR_EDICT(e)
Definition progsvm.h:870
#define PRVM_PROG_TO_EDICT(n)
Definition progsvm.h:877
#define PRVM_clientedictvector(ed, fieldname)
Definition progsvm.h:185
#define PRVM_clientedictfloat(ed, fieldname)
Definition progsvm.h:184
#define RENDER_EXTERIORMODEL
Definition protocol.h:359
#define EF_NODEPTHTEST
Definition protocol.h:81
#define EF_ADDITIVE
Definition protocol.h:73
#define EF_SELECTABLE
Definition protocol.h:82
int i
#define MAX_EDICTS
max number of objects in game world at once (32768 protocol limit)
Definition qdefs.h:105
#define MAX_MODELS
max number of models loaded at once (including during level transitions)
Definition qdefs.h:106
#define NULL
Definition qtypes.h:12
float vec_t
Definition qtypes.h:68
vec_t vec3_t[3]
Definition qtypes.h:71
bool qbool
Definition qtypes.h:9
cvar_t chase_active
Definition view.c:132
#define FL_MONSTER
movement is smoothed on the client side by step based interpolation
Definition server.h:362
#define SOLID_BBOX
touch on edge, block
Definition server.h:334
#define SOLID_SLIDEBOX
touch on edge, but not an onground
Definition server.h:335
cvar_t sv_debugmove
Definition sv_main.c:97
#define SOLID_CORPSE
same as SOLID_BBOX, except it behaves as SOLID_NOT against SOLID_SLIDEBOX objects (players/monsters)
Definition server.h:338
#define SOLID_TRIGGER
touch on edge, but not blocking
Definition server.h:333
#define SOLID_BSP
bsp clip, touch on edge, block
Definition server.h:336
vec3 normal
vec3_t playerstandmins
Definition client.h:972
int num_brushmodel_entities
Definition client.h:1005
unsigned char * entities_active
Definition client.h:993
scoreboard_t * scores
Definition client.h:945
vec3_t playerstandmaxs
Definition client.h:973
int * brushmodel_entities
Definition client.h:999
entity_t * entities
Definition client.h:991
struct model_s * worldmodel
Definition client.h:934
world_t world
Definition client.h:1122
struct model_s * model_precache[MAX_MODELS]
Definition client.h:888
struct model_s * csqc_model_precache[MAX_MODELS]
Definition client.h:836
int playerentity
Definition client.h:910
int integer
Definition cvar.h:73
frameblend_t frameblend[MAX_FRAMEBLENDS]
Definition client.h:373
matrix4x4_t inversematrix
Definition client.h:334
matrix4x4_t matrix
Definition client.h:332
vec3_t mins
Definition client.h:371
model_t * model
Definition client.h:343
vec3_t maxs
Definition client.h:371
skeleton_t * skeleton
Definition client.h:375
entity_state_t state_current
Definition client.h:471
entity_render_t render
Definition client.h:477
vec3_t normalmaxs
vec3_t normalmins
void(* TraceLine)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
qbool free
true if this edict is unused
Definition progsvm.h:93
union prvm_edict_t::@29 priv
struct edict_engineprivate_s * server
FIXME: this server pointer really means world, not server (it is used by both server qc and client qc...
Definition progsvm.h:106
prvm_edict_t * edicts
Definition progsvm.h:680
char name[MAX_SCOREBOARDNAME]
Definition client.h:489
void * ent
Definition collision.h:47
qbool bmodelstartsolid
Definition collision.h:30
double fraction
Definition collision.h:40
qbool worldstartsolid
Definition collision.h:28
double endpos[3]
Definition collision.h:42
plane_t plane
Definition collision.h:44
qbool startsolid
Definition collision.h:26
vec3_t normal
Definition collision.h:13
int World_EntitiesInBox(world_t *world, const vec3_t requestmins, const vec3_t requestmaxs, int maxlist, prvm_edict_t **list)
Definition world.c:188
void World_LinkEdict(world_t *world, prvm_edict_t *ent, const vec3_t mins, const vec3_t maxs, qbool link_solid_not)
Definition world.c:320
#define MOVE_MISSILE
Definition world.h:30
#define MOVE_HITMODEL
Definition world.h:32
#define MOVE_WORLDONLY
Definition world.h:31
#define MOVE_NOMONSTERS
Definition world.h:29