diff options
Diffstat (limited to 'src/baseq2/m_move.c')
-rw-r--r-- | src/baseq2/m_move.c | 343 |
1 files changed, 153 insertions, 190 deletions
diff --git a/src/baseq2/m_move.c b/src/baseq2/m_move.c index 02a11fe..192b629 100644 --- a/src/baseq2/m_move.c +++ b/src/baseq2/m_move.c @@ -8,7 +8,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -34,26 +34,25 @@ is not a staircase. */ int c_yes, c_no; -qboolean M_CheckBottom (edict_t *ent) +qboolean M_CheckBottom(edict_t *ent) { vec3_t mins, maxs, start, stop; trace_t trace; int x, y; float mid, bottom; - - VectorAdd (ent->s.origin, ent->mins, mins); - VectorAdd (ent->s.origin, ent->maxs, maxs); + + VectorAdd(ent->s.origin, ent->mins, mins); + VectorAdd(ent->s.origin, ent->maxs, maxs); // if all of the points under the corners are solid world, don't bother // with the tougher checks // the corners must be within 16 of the midpoint start[2] = mins[2] - 1; - for (x=0 ; x<=1 ; x++) - for (y=0 ; y<=1 ; y++) - { + for (x = 0 ; x <= 1 ; x++) + for (y = 0 ; y <= 1 ; y++) { start[0] = x ? maxs[0] : mins[0]; start[1] = y ? maxs[1] : mins[1]; - if (gi.pointcontents (start) != CONTENTS_SOLID) + if (gi.pointcontents(start) != CONTENTS_SOLID) goto realcheck; } @@ -66,26 +65,25 @@ realcheck: // check it for real... // start[2] = mins[2]; - + // the midpoint must be within 16 of the bottom - start[0] = stop[0] = (mins[0] + maxs[0])*0.5; - start[1] = stop[1] = (mins[1] + maxs[1])*0.5; - stop[2] = start[2] - 2*STEPSIZE; - trace = gi.trace (start, vec3_origin, vec3_origin, stop, ent, MASK_MONSTERSOLID); + start[0] = stop[0] = (mins[0] + maxs[0]) * 0.5; + start[1] = stop[1] = (mins[1] + maxs[1]) * 0.5; + stop[2] = start[2] - 2 * STEPSIZE; + trace = gi.trace(start, vec3_origin, vec3_origin, stop, ent, MASK_MONSTERSOLID); if (trace.fraction == 1.0) return qfalse; mid = bottom = trace.endpos[2]; - -// the corners must be within 16 of the midpoint - for (x=0 ; x<=1 ; x++) - for (y=0 ; y<=1 ; y++) - { + +// the corners must be within 16 of the midpoint + for (x = 0 ; x <= 1 ; x++) + for (y = 0 ; y <= 1 ; y++) { start[0] = stop[0] = x ? maxs[0] : mins[0]; start[1] = stop[1] = y ? maxs[1] : mins[1]; - - trace = gi.trace (start, vec3_origin, vec3_origin, stop, ent, MASK_MONSTERSOLID); - + + trace = gi.trace(start, vec3_origin, vec3_origin, stop, ent, MASK_MONSTERSOLID); + if (trace.fraction != 1.0 && trace.endpos[2] > bottom) bottom = trace.endpos[2]; if (trace.fraction == 1.0 || mid - trace.endpos[2] > STEPSIZE) @@ -109,7 +107,7 @@ pr_global_struct->trace_normal is set to the normal of the blocking wall */ //FIXME since we need to test end position contents here, can we avoid doing //it again later in catagorize position? -qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) +qboolean SV_movestep(edict_t *ent, vec3_t move, qboolean relink) { float dz; vec3_t oldorg, neworg, end; @@ -119,32 +117,26 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) vec3_t test; int contents; -// try the move - VectorCopy (ent->s.origin, oldorg); - VectorAdd (ent->s.origin, move, neworg); +// try the move + VectorCopy(ent->s.origin, oldorg); + VectorAdd(ent->s.origin, move, neworg); // flying monsters don't step up - if ( ent->flags & (FL_SWIM | FL_FLY) ) - { - // try one move with vertical motion, then one without - for (i=0 ; i<2 ; i++) - { - VectorAdd (ent->s.origin, move, neworg); - if (i == 0 && ent->enemy) - { + if (ent->flags & (FL_SWIM | FL_FLY)) { + // try one move with vertical motion, then one without + for (i = 0 ; i < 2 ; i++) { + VectorAdd(ent->s.origin, move, neworg); + if (i == 0 && ent->enemy) { if (!ent->goalentity) ent->goalentity = ent->enemy; dz = ent->s.origin[2] - ent->goalentity->s.origin[2]; - if (ent->goalentity->client) - { + if (ent->goalentity->client) { if (dz > 40) neworg[2] -= 8; if (!((ent->flags & FL_SWIM) && (ent->waterlevel < 2))) if (dz < 30) neworg[2] += 8; - } - else - { + } else { if (dz > 8) neworg[2] -= 8; else if (dz > 0) @@ -155,13 +147,11 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) neworg[2] += dz; } } - trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, neworg, ent, MASK_MONSTERSOLID); - + trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, neworg, ent, MASK_MONSTERSOLID); + // fly monsters don't enter water voluntarily - if (ent->flags & FL_FLY) - { - if (!ent->waterlevel) - { + if (ent->flags & FL_FLY) { + if (!ent->waterlevel) { test[0] = trace.endpos[0]; test[1] = trace.endpos[1]; test[2] = trace.endpos[2] + ent->mins[2] + 1; @@ -172,10 +162,8 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) } // swim monsters don't exit water voluntarily - if (ent->flags & FL_SWIM) - { - if (ent->waterlevel < 2) - { + if (ent->flags & FL_SWIM) { + if (ent->waterlevel < 2) { test[0] = trace.endpos[0]; test[1] = trace.endpos[1]; test[2] = trace.endpos[2] + ent->mins[2] + 1; @@ -185,21 +173,19 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) } } - if (trace.fraction == 1) - { - VectorCopy (trace.endpos, ent->s.origin); - if (relink) - { - gi.linkentity (ent); - G_TouchTriggers (ent); + if (trace.fraction == 1) { + VectorCopy(trace.endpos, ent->s.origin); + if (relink) { + gi.linkentity(ent); + G_TouchTriggers(ent); } return qtrue; } - + if (!ent->enemy) break; } - + return qfalse; } @@ -210,84 +196,75 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) stepsize = 1; neworg[2] += stepsize; - VectorCopy (neworg, end); - end[2] -= stepsize*2; + VectorCopy(neworg, end); + end[2] -= stepsize * 2; - trace = gi.trace (neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID); + trace = gi.trace(neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID); if (trace.allsolid) return qfalse; - if (trace.startsolid) - { + if (trace.startsolid) { neworg[2] -= stepsize; - trace = gi.trace (neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID); + trace = gi.trace(neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID); if (trace.allsolid || trace.startsolid) return qfalse; } // don't go in to water - if (ent->waterlevel == 0) - { + if (ent->waterlevel == 0) { test[0] = trace.endpos[0]; test[1] = trace.endpos[1]; - test[2] = trace.endpos[2] + ent->mins[2] + 1; + test[2] = trace.endpos[2] + ent->mins[2] + 1; contents = gi.pointcontents(test); if (contents & MASK_WATER) return qfalse; } - if (trace.fraction == 1) - { - // if monster had the ground pulled out, go ahead and fall - if ( ent->flags & FL_PARTIALGROUND ) - { - VectorAdd (ent->s.origin, move, ent->s.origin); - if (relink) - { - gi.linkentity (ent); - G_TouchTriggers (ent); + if (trace.fraction == 1) { + // if monster had the ground pulled out, go ahead and fall + if (ent->flags & FL_PARTIALGROUND) { + VectorAdd(ent->s.origin, move, ent->s.origin); + if (relink) { + gi.linkentity(ent); + G_TouchTriggers(ent); } ent->groundentity = NULL; return qtrue; } - + return qfalse; // walked off an edge } // check point traces down for dangling corners - VectorCopy (trace.endpos, ent->s.origin); - - if (!M_CheckBottom (ent)) - { - if ( ent->flags & FL_PARTIALGROUND ) - { // entity had floor mostly pulled out from underneath it + VectorCopy(trace.endpos, ent->s.origin); + + if (!M_CheckBottom(ent)) { + if (ent->flags & FL_PARTIALGROUND) { + // entity had floor mostly pulled out from underneath it // and is trying to correct - if (relink) - { - gi.linkentity (ent); - G_TouchTriggers (ent); + if (relink) { + gi.linkentity(ent); + G_TouchTriggers(ent); } return qtrue; } - VectorCopy (oldorg, ent->s.origin); + VectorCopy(oldorg, ent->s.origin); return qfalse; } - if ( ent->flags & FL_PARTIALGROUND ) - { + if (ent->flags & FL_PARTIALGROUND) { ent->flags &= ~FL_PARTIALGROUND; } ent->groundentity = trace.ent; ent->groundentity_linkcount = trace.ent->linkcount; // the move is ok - if (relink) - { - gi.linkentity (ent); - G_TouchTriggers (ent); + if (relink) { + gi.linkentity(ent); + G_TouchTriggers(ent); } return qtrue; } @@ -301,13 +278,13 @@ M_ChangeYaw =============== */ -void M_ChangeYaw (edict_t *ent) +void M_ChangeYaw(edict_t *ent) { float ideal; float current; float move; float speed; - + current = anglemod(ent->s.angles[YAW]); ideal = ent->ideal_yaw; @@ -316,28 +293,22 @@ void M_ChangeYaw (edict_t *ent) move = ideal - current; speed = ent->yaw_speed; - if (ideal > current) - { + if (ideal > current) { if (move >= 180) move = move - 360; - } - else - { + } else { if (move <= -180) move = move + 360; } - if (move > 0) - { + if (move > 0) { if (move > speed) move = speed; - } - else - { + } else { if (move < -speed) move = -speed; } - - ent->s.angles[YAW] = anglemod (current + move); + + ent->s.angles[YAW] = anglemod(current + move); } @@ -350,33 +321,32 @@ facing it. ====================== */ -qboolean SV_StepDirection (edict_t *ent, float yaw, float dist) +qboolean SV_StepDirection(edict_t *ent, float yaw, float dist) { vec3_t move, oldorigin; float delta; - + ent->ideal_yaw = yaw; - M_ChangeYaw (ent); - - yaw = yaw*M_PI*2 / 360; - move[0] = cos(yaw)*dist; - move[1] = sin(yaw)*dist; + M_ChangeYaw(ent); + + yaw = yaw * M_PI * 2 / 360; + move[0] = cos(yaw) * dist; + move[1] = sin(yaw) * dist; move[2] = 0; - VectorCopy (ent->s.origin, oldorigin); - if (SV_movestep (ent, move, qfalse)) - { + VectorCopy(ent->s.origin, oldorigin); + if (SV_movestep(ent, move, qfalse)) { delta = ent->s.angles[YAW] - ent->ideal_yaw; - if (delta > 45 && delta < 315) - { // not turned far enough, so don't take the step - VectorCopy (oldorigin, ent->s.origin); + if (delta > 45 && delta < 315) { + // not turned far enough, so don't take the step + VectorCopy(oldorigin, ent->s.origin); } - gi.linkentity (ent); - G_TouchTriggers (ent); + gi.linkentity(ent); + G_TouchTriggers(ent); return qtrue; } - gi.linkentity (ent); - G_TouchTriggers (ent); + gi.linkentity(ent); + G_TouchTriggers(ent); return qfalse; } @@ -386,7 +356,7 @@ SV_FixCheckBottom ====================== */ -void SV_FixCheckBottom (edict_t *ent) +void SV_FixCheckBottom(edict_t *ent) { ent->flags |= FL_PARTIALGROUND; } @@ -400,9 +370,9 @@ SV_NewChaseDir ================ */ #define DI_NODIR -1 -void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist) +void SV_NewChaseDir(edict_t *actor, edict_t *enemy, float dist) { - float deltax,deltay; + float deltax, deltay; float d[3]; float tdir, olddir, turnaround; @@ -410,80 +380,75 @@ void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist) if (!enemy) return; - olddir = anglemod( (int)(actor->ideal_yaw/45)*45 ); + olddir = anglemod((int)(actor->ideal_yaw / 45) * 45); turnaround = anglemod(olddir - 180); deltax = enemy->s.origin[0] - actor->s.origin[0]; deltay = enemy->s.origin[1] - actor->s.origin[1]; - if (deltax>10) - d[1]= 0; - else if (deltax<-10) - d[1]= 180; + if (deltax > 10) + d[1] = 0; + else if (deltax < -10) + d[1] = 180; else - d[1]= DI_NODIR; - if (deltay<-10) - d[2]= 270; - else if (deltay>10) - d[2]= 90; + d[1] = DI_NODIR; + if (deltay < -10) + d[2] = 270; + else if (deltay > 10) + d[2] = 90; else - d[2]= DI_NODIR; + d[2] = DI_NODIR; // try direct route - if (d[1] != DI_NODIR && d[2] != DI_NODIR) - { + if (d[1] != DI_NODIR && d[2] != DI_NODIR) { if (d[1] == 0) tdir = d[2] == 90 ? 45 : 315; else tdir = d[2] == 90 ? 135 : 215; - + if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) return; } // try other directions - if ( ((rand()&3) & 1) || abs(deltay)>abs(deltax)) - { - tdir=d[1]; - d[1]=d[2]; - d[2]=tdir; + if (((rand() & 3) & 1) || abs(deltay) > abs(deltax)) { + tdir = d[1]; + d[1] = d[2]; + d[2] = tdir; } - if (d[1]!=DI_NODIR && d[1]!=turnaround - && SV_StepDirection(actor, d[1], dist)) - return; + if (d[1] != DI_NODIR && d[1] != turnaround + && SV_StepDirection(actor, d[1], dist)) + return; - if (d[2]!=DI_NODIR && d[2]!=turnaround - && SV_StepDirection(actor, d[2], dist)) - return; + if (d[2] != DI_NODIR && d[2] != turnaround + && SV_StepDirection(actor, d[2], dist)) + return; -/* there is no direct path to the player, so pick another direction */ + /* there is no direct path to the player, so pick another direction */ - if (olddir!=DI_NODIR && SV_StepDirection(actor, olddir, dist)) - return; + if (olddir != DI_NODIR && SV_StepDirection(actor, olddir, dist)) + return; - if (rand()&1) /*randomly determine direction of search*/ - { - for (tdir=0 ; tdir<=315 ; tdir += 45) - if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) - return; - } - else - { - for (tdir=315 ; tdir >=0 ; tdir -= 45) - if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) - return; + if (rand() & 1) { /*randomly determine direction of search*/ + for (tdir = 0 ; tdir <= 315 ; tdir += 45) + if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) + return; + } else { + for (tdir = 315 ; tdir >= 0 ; tdir -= 45) + if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) + return; } - if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist) ) - return; + if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist)) + return; actor->ideal_yaw = olddir; // can't move // if a bridge was pulled out from underneath a monster, it may not have // a valid standing position at all - if (!M_CheckBottom (actor)) - SV_FixCheckBottom (actor); + if (!M_CheckBottom(actor)) + SV_FixCheckBottom(actor); } /* @@ -492,12 +457,11 @@ SV_CloseEnough ====================== */ -qboolean SV_CloseEnough (edict_t *ent, edict_t *goal, float dist) +qboolean SV_CloseEnough(edict_t *ent, edict_t *goal, float dist) { int i; - - for (i=0 ; i<3 ; i++) - { + + for (i = 0 ; i < 3 ; i++) { if (goal->absmin[i] > ent->absmax[i] + dist) return qfalse; if (goal->absmax[i] < ent->absmin[i] - dist) @@ -512,24 +476,23 @@ qboolean SV_CloseEnough (edict_t *ent, edict_t *goal, float dist) M_MoveToGoal ====================== */ -void M_MoveToGoal (edict_t *ent, float dist) +void M_MoveToGoal(edict_t *ent, float dist) { edict_t *goal; - + goal = ent->goalentity; - if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM))) + if (!ent->groundentity && !(ent->flags & (FL_FLY | FL_SWIM))) return; // if the next step hits the enemy, return immediately - if (ent->enemy && SV_CloseEnough (ent, ent->enemy, dist) ) + if (ent->enemy && SV_CloseEnough(ent, ent->enemy, dist)) return; // bump around... - if ( (rand()&3)==1 || !SV_StepDirection (ent, ent->ideal_yaw, dist)) - { + if ((rand() & 3) == 1 || !SV_StepDirection(ent, ent->ideal_yaw, dist)) { if (ent->inuse) - SV_NewChaseDir (ent, goal, dist); + SV_NewChaseDir(ent, goal, dist); } } @@ -539,17 +502,17 @@ void M_MoveToGoal (edict_t *ent, float dist) M_walkmove =============== */ -qboolean M_walkmove (edict_t *ent, float yaw, float dist) +qboolean M_walkmove(edict_t *ent, float yaw, float dist) { vec3_t move; - - if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM))) + + if (!ent->groundentity && !(ent->flags & (FL_FLY | FL_SWIM))) return qfalse; - yaw = yaw*M_PI*2 / 360; - - move[0] = cos(yaw)*dist; - move[1] = sin(yaw)*dist; + yaw = yaw * M_PI * 2 / 360; + + move[0] = cos(yaw) * dist; + move[1] = sin(yaw) * dist; move[2] = 0; return SV_movestep(ent, move, qtrue); |