1 // m_move.c -- monster movement
2
3 #include "g_local.h"
4
5 #define STEPSIZE 18
6
7 /*
8 =============
9 M_CheckBottom
10
11 Returns false if any part of the bottom of the entity is off an edge that
12 is not a staircase.
13
14 =============
15 */
16 int c_yes, c_no;
17
M_CheckBottom(edict_t * ent)18 qboolean M_CheckBottom (edict_t *ent)
19 {
20 vec3_t mins, maxs, start, stop;
21 trace_t trace;
22 int x, y;
23 float mid, bottom;
24
25 VectorAdd (ent->s.origin, ent->mins, mins);
26 VectorAdd (ent->s.origin, ent->maxs, maxs);
27
28 // if all of the points under the corners are solid world, don't bother
29 // with the tougher checks
30 // the corners must be within 16 of the midpoint
31 start[2] = mins[2] - 1;
32 for (x=0 ; x<=1 ; x++)
33 for (y=0 ; y<=1 ; y++)
34 {
35 start[0] = x ? maxs[0] : mins[0];
36 start[1] = y ? maxs[1] : mins[1];
37 if (gi.pointcontents (start) != CONTENTS_SOLID)
38 goto realcheck;
39 }
40
41 c_yes++;
42 return true; // we got out easy
43
44 realcheck:
45 c_no++;
46 //
47 // check it for real...
48 //
49 start[2] = mins[2];
50
51 // the midpoint must be within 16 of the bottom
52 start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
53 start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
54 stop[2] = start[2] - 2*STEPSIZE;
55 trace = gi.trace (start, vec3_origin, vec3_origin, stop, ent,MASK_PLAYERSOLID /*MASK_MONSTERSOLID*/);
56
57 if (trace.fraction == 1.0)
58 return false;
59 mid = bottom = trace.endpos[2];
60
61 // the corners must be within 16 of the midpoint
62 for (x=0 ; x<=1 ; x++)
63 for (y=0 ; y<=1 ; y++)
64 {
65 start[0] = stop[0] = x ? maxs[0] : mins[0];
66 start[1] = stop[1] = y ? maxs[1] : mins[1];
67
68 trace = gi.trace (start, vec3_origin, vec3_origin, stop, ent, MASK_PLAYERSOLID /*MASK_MONSTERSOLID*/);
69
70 if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
71 bottom = trace.endpos[2];
72 if (trace.fraction == 1.0 || mid - trace.endpos[2] > STEPSIZE)
73 return false;
74 }
75
76 c_yes++;
77 return true;
78 }
79
80
81