DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
sv_move.c File Reference
#include "quakedef.h"
#include "prvm_cmds.h"
+ Include dependency graph for sv_move.c:

Go to the source code of this file.

Macros

#define DI_NODIR   -1
 

Functions

qbool SV_CheckBottom (prvm_edict_t *ent)
 
static qbool SV_CloseEnough (prvm_edict_t *ent, prvm_edict_t *goal, float dist)
 
static void SV_FixCheckBottom (prvm_edict_t *ent)
 
qbool SV_movestep (prvm_edict_t *ent, vec3_t move, qbool relink, qbool noenemy, qbool settrace)
 
static void SV_NewChaseDir (prvm_edict_t *actor, prvm_edict_t *enemy, float dist)
 
static qbool SV_StepDirection (prvm_edict_t *ent, float yaw, float dist)
 
void VM_SV_MoveToGoal (prvm_prog_t *prog)
 

Variables

int c_no
 
int c_yes
 

Macro Definition Documentation

◆ DI_NODIR

#define DI_NODIR   -1

Definition at line 309 of file sv_move.c.

Referenced by SV_NewChaseDir().

Function Documentation

◆ SV_CheckBottom()

qbool SV_CheckBottom ( prvm_edict_t * ent)

Definition at line 36 of file sv_move.c.

37{
38 prvm_prog_t *prog = SVVM_prog;
39 vec3_t mins, maxs, start, stop;
40 trace_t trace;
41 int x, y;
42 float mid, bottom;
43
46
47// if all of the points under the corners are solid world, don't bother
48// with the tougher checks
49// the corners must be within 16 of the midpoint
50 start[2] = mins[2] - 1;
51 for (x=0 ; x<=1 ; x++)
52 for (y=0 ; y<=1 ; y++)
53 {
54 start[0] = x ? maxs[0] : mins[0];
55 start[1] = y ? maxs[1] : mins[1];
57 goto realcheck;
58 }
59
60 c_yes++;
61 return true; // we got out easy
62
63realcheck:
64 c_no++;
65//
66// check it for real...
67//
68 start[2] = mins[2];
69
70// the midpoint must be within 16 of the bottom
71 start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
72 start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
73 stop[2] = start[2] - 2*sv_stepheight.value;
75
76 if (trace.fraction == 1.0)
77 return false;
78 mid = bottom = trace.endpos[2];
79
80// the corners must be within 16 of the midpoint
81 for (x=0 ; x<=1 ; x++)
82 for (y=0 ; y<=1 ; y++)
83 {
84 start[0] = stop[0] = x ? maxs[0] : mins[0];
85 start[1] = stop[1] = y ? maxs[1] : mins[1];
86
88
89 if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
90 bottom = trace.endpos[2];
91 if (trace.fraction == 1.0 || mid - trace.endpos[2] > sv_stepheight.value)
92 return false;
93 }
94
95 c_yes++;
96 return true;
97}
#define SUPERCONTENTS_BODY
Definition bspfile.h:201
#define SUPERCONTENTS_SOLID
Definition bspfile.h:196
cvar_t collision_extendmovelength
Definition collision.c:14
vector mins
vector maxs
vector origin
GLint GLenum GLint GLint y
Definition glquake.h:651
GLint GLenum GLint x
Definition glquake.h:651
#define VectorAdd(a, b, out)
Definition mathlib.h:100
#define PRVM_serveredictvector(ed, fieldname)
Definition progsvm.h:173
#define SVVM_prog
Definition progsvm.h:766
vec_t vec3_t[3]
Definition qtypes.h:71
trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend)
Definition sv_phys.c:256
int SV_GenericHitSuperContentsMask(const prvm_edict_t *edict)
calculates hitsupercontentsmask for a generic qc entity
Definition sv_phys.c:73
cvar_t sv_stepheight
Definition sv_main.c:153
int SV_PointSuperContents(const vec3_t point)
Definition sv_phys.c:611
float value
Definition cvar.h:74
double fraction
Definition collision.h:40
double endpos[3]
Definition collision.h:42
int c_yes
Definition sv_move.c:34
int c_no
Definition sv_move.c:34
#define MOVE_NOMONSTERS
Definition world.h:29

References c_no, c_yes, collision_extendmovelength, trace_t::endpos, trace_t::fraction, maxs, mins, MOVE_NOMONSTERS, origin, PRVM_serveredictvector, SUPERCONTENTS_BODY, SUPERCONTENTS_SOLID, SV_GenericHitSuperContentsMask(), SV_PointSuperContents(), sv_stepheight, SV_TraceLine(), SVVM_prog, cvar_t::value, VectorAdd, x, and y.

Referenced by SV_movestep(), SV_NewChaseDir(), and VM_SV_checkbottom().

◆ SV_CloseEnough()

static qbool SV_CloseEnough ( prvm_edict_t * ent,
prvm_edict_t * goal,
float dist )
static

Definition at line 400 of file sv_move.c.

401{
402 int i;
403
404 for (i=0 ; i<3 ; i++)
405 {
406 if (goal->priv.server->areamins[i] > ent->priv.server->areamaxs[i] + dist)
407 return false;
408 if (goal->priv.server->areamaxs[i] < ent->priv.server->areamins[i] - dist)
409 return false;
410 }
411 return true;
412}
int i
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

References i, prvm_edict_t::priv, and prvm_edict_t::server.

Referenced by VM_SV_MoveToGoal().

◆ SV_FixCheckBottom()

static void SV_FixCheckBottom ( prvm_edict_t * ent)
static

Definition at line 295 of file sv_move.c.

296{
297 prvm_prog_t *prog = SVVM_prog;
299}
float flags
static int(ZEXPORT *qz_inflate)(z_stream *strm
#define PRVM_serveredictfloat(ed, fieldname)
Definition progsvm.h:172
#define FL_PARTIALGROUND
not all corners are valid
Definition server.h:367

References FL_PARTIALGROUND, flags, int(), PRVM_serveredictfloat, and SVVM_prog.

Referenced by SV_NewChaseDir().

◆ SV_movestep()

qbool SV_movestep ( prvm_edict_t * ent,
vec3_t move,
qbool relink,
qbool noenemy,
qbool settrace )

Definition at line 109 of file sv_move.c.

110{
111 prvm_prog_t *prog = SVVM_prog;
112 float dz;
113 vec3_t oldorg, neworg, end, traceendpos, entorigin, entmins, entmaxs;
114 trace_t trace;
115 int i;
117
118// try the move
120 VectorAdd (PRVM_serveredictvector(ent, origin), move, neworg);
121 VectorCopy(PRVM_serveredictvector(ent, mins), entmins);
122 VectorCopy(PRVM_serveredictvector(ent, maxs), entmaxs);
123
124// flying monsters don't step up
125 if ( (int)PRVM_serveredictfloat(ent, flags) & (FL_SWIM | FL_FLY) )
126 {
127 // try one move with vertical motion, then one without
128 for (i=0 ; i<2 ; i++)
129 {
130 VectorAdd (PRVM_serveredictvector(ent, origin), move, neworg);
131 if (noenemy)
132 enemy = prog->edicts;
133 else
134 {
136 if (i == 0 && enemy != prog->edicts)
137 {
139 if (dz > 40)
140 neworg[2] -= 8;
141 if (dz < 30)
142 neworg[2] += 8;
143 }
144 }
145 VectorCopy(PRVM_serveredictvector(ent, origin), entorigin);
146 trace = SV_TraceBox(entorigin, entmins, entmaxs, neworg, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value);
147
148 if (trace.fraction == 1)
149 {
150 VectorCopy(trace.endpos, traceendpos);
152 return false; // swim monster left water
153
154 VectorCopy (traceendpos, PRVM_serveredictvector(ent, origin));
155 if (relink)
156 {
157 SV_LinkEdict(ent);
159 }
160 return true;
161 }
162
163 if (enemy == prog->edicts)
164 break;
165 }
166
167 return false;
168 }
169
170// push down from a step height above the wished position
171 neworg[2] += sv_stepheight.value;
172 VectorCopy (neworg, end);
173 end[2] -= sv_stepheight.value*2;
174
175 trace = SV_TraceBox(neworg, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value);
176
177 if (trace.startsolid)
178 {
179 neworg[2] -= sv_stepheight.value;
180 trace = SV_TraceBox(neworg, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value);
181 if (trace.startsolid)
182 return false;
183 }
184 if (trace.fraction == 1)
185 {
186 // if monster had the ground pulled out, go ahead and fall
188 {
190 if (relink)
191 {
192 SV_LinkEdict(ent);
194 }
195 PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) & ~FL_ONGROUND;
196 return true;
197 }
198
199 return false; // walked off an edge
200 }
201
202// check point traces down for dangling corners
204
205 if (!SV_CheckBottom (ent))
206 {
208 { // entity had floor mostly pulled out from underneath it
209 // and is trying to correct
210 if (relink)
211 {
212 SV_LinkEdict(ent);
214 }
215 return true;
216 }
218 return false;
219 }
220
222 PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) & ~FL_PARTIALGROUND;
223
224// gameplayfix: check if reached pretty steep plane and bail
226 {
227 if (trace.plane.normal[ 2 ] < 0.5)
228 {
230 return false;
231 }
232 }
233
235
236// the move is ok
237 if (relink)
238 {
239 SV_LinkEdict(ent);
241 }
242 return true;
243}
#define SUPERCONTENTS_LIQUIDSMASK
Definition bspfile.h:218
entity enemy
#define VectorCopy(in, out)
Definition mathlib.h:101
entity groundentity
Definition progsdefs.qc:134
#define PRVM_serveredictedict(ed, fieldname)
Definition progsvm.h:175
#define PRVM_EDICT_TO_PROG(e)
Definition progsvm.h:875
#define PRVM_PROG_TO_EDICT(n)
Definition progsvm.h:877
#define FL_FLY
Definition server.h:357
void SV_LinkEdict(prvm_edict_t *ent)
Definition sv_phys.c:804
cvar_t sv_gameplayfix_nostepmoveonsteepslopes
Definition sv_main.c:125
trace_t SV_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)
traces a box move against worldmodel and all entities in the specified area
Definition sv_phys.c:414
#define FL_SWIM
Definition server.h:358
void SV_LinkEdict_TouchAreaGrid(prvm_edict_t *ent)
Definition sv_phys.c:727
int integer
Definition cvar.h:73
prvm_edict_t * edicts
Definition progsvm.h:680
void * ent
Definition collision.h:47
plane_t plane
Definition collision.h:44
qbool startsolid
Definition collision.h:26
qbool SV_CheckBottom(prvm_edict_t *ent)
Definition sv_move.c:36
vec3_t normal
Definition collision.h:13
#define MOVE_NORMAL
Definition world.h:28

References collision_extendmovelength, prvm_prog_t::edicts, trace_t::endpos, enemy, trace_t::ent, FL_FLY, FL_PARTIALGROUND, FL_SWIM, flags, trace_t::fraction, groundentity, i, int(), cvar_t::integer, maxs, mins, MOVE_NORMAL, plane_t::normal, origin, trace_t::plane, PRVM_EDICT_TO_PROG, PRVM_PROG_TO_EDICT, PRVM_serveredictedict, PRVM_serveredictfloat, PRVM_serveredictvector, trace_t::startsolid, SUPERCONTENTS_LIQUIDSMASK, SV_CheckBottom(), sv_gameplayfix_nostepmoveonsteepslopes, SV_GenericHitSuperContentsMask(), SV_LinkEdict(), SV_LinkEdict_TouchAreaGrid(), SV_PointSuperContents(), sv_stepheight, SV_TraceBox(), SVVM_prog, cvar_t::value, VectorAdd, and VectorCopy.

Referenced by SV_StepDirection(), and VM_SV_walkmove().

◆ SV_NewChaseDir()

static void SV_NewChaseDir ( prvm_edict_t * actor,
prvm_edict_t * enemy,
float dist )
static

Definition at line 310 of file sv_move.c.

311{
312 prvm_prog_t *prog = SVVM_prog;
313 float deltax,deltay;
314 float d[3];
315 float tdir, olddir, turnaround;
316
317 olddir = ANGLEMOD((int)(PRVM_serveredictfloat(actor, ideal_yaw)/45)*45);
318 turnaround = ANGLEMOD(olddir - 180);
319
322 if (deltax>10)
323 d[1]= 0;
324 else if (deltax<-10)
325 d[1]= 180;
326 else
327 d[1]= DI_NODIR;
328 if (deltay<-10)
329 d[2]= 270;
330 else if (deltay>10)
331 d[2]= 90;
332 else
333 d[2]= DI_NODIR;
334
335// try direct route
336 if (d[1] != DI_NODIR && d[2] != DI_NODIR)
337 {
338 if (d[1] == 0)
339 tdir = d[2] == 90 ? 45 : 315;
340 else
341 tdir = d[2] == 90 ? 135 : 215;
342
343 if (tdir != turnaround && SV_StepDirection(actor, tdir, dist))
344 return;
345 }
346
347// try other directions
348 if ( ((rand()&3) & 1) || fabs(deltay)>fabs(deltax))
349 {
350 tdir=d[1];
351 d[1]=d[2];
352 d[2]=tdir;
353 }
354
355 if (d[1]!=DI_NODIR && d[1]!=turnaround
356 && SV_StepDirection(actor, d[1], dist))
357 return;
358
359 if (d[2]!=DI_NODIR && d[2]!=turnaround
360 && SV_StepDirection(actor, d[2], dist))
361 return;
362
363/* there is no direct path to the player, so pick another direction */
364
365 if (olddir!=DI_NODIR && SV_StepDirection(actor, olddir, dist))
366 return;
367
368 if (rand()&1) /*randomly determine direction of search*/
369 {
370 for (tdir=0 ; tdir<=315 ; tdir += 45)
371 if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) )
372 return;
373 }
374 else
375 {
376 for (tdir=315 ; tdir >=0 ; tdir -= 45)
377 if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) )
378 return;
379 }
380
381 if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist) )
382 return;
383
384 PRVM_serveredictfloat(actor, ideal_yaw) = olddir; // can't move
385
386// if a bridge was pulled out from underneath a monster, it may not have
387// a valid standing position at all
388
389 if (!SV_CheckBottom (actor))
390 SV_FixCheckBottom (actor);
391
392}
#define ANGLEMOD(a)
Definition mathlib.h:67
float fabs(float f)
float ideal_yaw
Definition progsdefs.qc:184
#define DI_NODIR
Definition sv_move.c:309
static void SV_FixCheckBottom(prvm_edict_t *ent)
Definition sv_move.c:295
static qbool SV_StepDirection(prvm_edict_t *ent, float yaw, float dist)
Definition sv_move.c:257

References ANGLEMOD, DI_NODIR, enemy, fabs(), ideal_yaw, origin, PRVM_serveredictfloat, PRVM_serveredictvector, SV_CheckBottom(), SV_FixCheckBottom(), SV_StepDirection(), and SVVM_prog.

Referenced by VM_SV_MoveToGoal().

◆ SV_StepDirection()

static qbool SV_StepDirection ( prvm_edict_t * ent,
float yaw,
float dist )
static

Definition at line 257 of file sv_move.c.

258{
259 prvm_prog_t *prog = SVVM_prog;
260 vec3_t move, oldorigin;
261 float delta;
262
264 VM_changeyaw(prog);
265
266 yaw = yaw*M_PI*2 / 360;
267 move[0] = cos(yaw)*dist;
268 move[1] = sin(yaw)*dist;
269 move[2] = 0;
270
272 if (SV_movestep (ent, move, false, false, false))
273 {
275 if (delta > 45 && delta < 315)
276 { // not turned far enough, so don't take the step
278 }
279 SV_LinkEdict(ent);
281 return true;
282 }
283 SV_LinkEdict(ent);
285
286 return false;
287}
vector angles
vector oldorigin
#define M_PI
Definition mathlib.h:28
float cos(float f)
float sin(float f)
void VM_changeyaw(prvm_prog_t *prog)
Definition prvm_cmds.c:4747
#define YAW
Definition qtypes.h:19
qbool SV_movestep(prvm_edict_t *ent, vec3_t move, qbool relink, qbool noenemy, qbool settrace)
Definition sv_move.c:109

References angles, cos(), ideal_yaw, M_PI, oldorigin, origin, PRVM_serveredictfloat, PRVM_serveredictvector, sin(), SV_LinkEdict(), SV_LinkEdict_TouchAreaGrid(), SV_movestep(), SVVM_prog, VectorCopy, VM_changeyaw(), and YAW.

Referenced by SV_NewChaseDir(), and VM_SV_MoveToGoal().

◆ VM_SV_MoveToGoal()

void VM_SV_MoveToGoal ( prvm_prog_t * prog)

Definition at line 420 of file sv_move.c.

421{
422 prvm_edict_t *ent, *goal;
423 float dist;
424
426
429 dist = PRVM_G_FLOAT(OFS_PARM0);
430
431 if ( !( (int)PRVM_serveredictfloat(ent, flags) & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
432 {
434 return;
435 }
436
437// if the next step hits the enemy, return immediately
438 if ( PRVM_PROG_TO_EDICT(PRVM_serveredictedict(ent, enemy)) != prog->edicts && SV_CloseEnough (ent, goal, dist) )
439 return;
440
441// bump around...
442 if ( (rand()&3)==1 ||
444 {
445 SV_NewChaseDir (ent, goal, dist);
446 }
447}
entity self
#define OFS_RETURN
Definition pr_comp.h:33
#define OFS_PARM0
Definition pr_comp.h:34
entity goalentity
Definition progsdefs.qc:189
#define PRVM_serverglobaledict(fieldname)
Definition progsvm.h:180
#define PRVM_G_FLOAT(o)
Definition progsvm.h:882
#define VM_SAFEPARMCOUNT(p, f)
Definition prvm_cmds.h:207
#define FL_ONGROUND
Definition server.h:366
static void SV_NewChaseDir(prvm_edict_t *actor, prvm_edict_t *enemy, float dist)
Definition sv_move.c:310
void VM_SV_MoveToGoal(prvm_prog_t *prog)
Definition sv_move.c:420
static qbool SV_CloseEnough(prvm_edict_t *ent, prvm_edict_t *goal, float dist)
Definition sv_move.c:400

References prvm_prog_t::edicts, enemy, FL_FLY, FL_ONGROUND, FL_SWIM, flags, goalentity, ideal_yaw, OFS_PARM0, OFS_RETURN, PRVM_G_FLOAT, PRVM_PROG_TO_EDICT, PRVM_serveredictedict, PRVM_serveredictfloat, PRVM_serverglobaledict, self, SV_CloseEnough(), SV_NewChaseDir(), SV_StepDirection(), VM_SAFEPARMCOUNT, and VM_SV_MoveToGoal().

Referenced by VM_SV_MoveToGoal().

Variable Documentation

◆ c_no

int c_no

Definition at line 34 of file sv_move.c.

Referenced by SV_CheckBottom().

◆ c_yes

int c_yes

Definition at line 34 of file sv_move.c.

Referenced by SV_CheckBottom().