diff --git a/source/cl_input.c b/source/cl_input.c index cd78d61..933e302 100644 --- a/source/cl_input.c +++ b/source/cl_input.c @@ -510,7 +510,7 @@ void CL_SendMove (usercmd_t *cmd) int bits; sizebuf_t buf; byte data[128]; - + vec3_t tempv; buf.maxsize = 128; buf.cursize = 0; buf.data = data; @@ -559,9 +559,10 @@ void CL_SendMove (usercmd_t *cmd) MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times + VectorAdd(cl.gun_kick, cl.viewangles, tempv); for (i=0 ; i<3 ; i++) - MSG_WriteAngle (&buf, cl.viewangles[i]); - + MSG_WriteFloat (&buf, tempv[i]); + MSG_WriteShort (&buf, cmd->forwardmove); MSG_WriteShort (&buf, cmd->sidemove); MSG_WriteShort (&buf, cmd->upmove); @@ -608,13 +609,6 @@ void CL_SendMove (usercmd_t *cmd) MSG_WriteByte (&buf, in_impulse); in_impulse = 0; -#ifdef QUAKE2 -// -// light level -// - MSG_WriteByte (&buf, cmd->lightlevel); -#endif - // // deliver the message // @@ -627,7 +621,7 @@ void CL_SendMove (usercmd_t *cmd) // if (++cl.movemessages <= 2) return; - + if (NET_SendUnreliableMessage (cls.netcon, &buf) == -1) { Con_Printf ("CL_SendMove: lost server connection\n"); diff --git a/source/mathlib.c b/source/mathlib.c index 41e9f94..5925cc3 100644 --- a/source/mathlib.c +++ b/source/mathlib.c @@ -638,3 +638,127 @@ fixed16_t Invert24To16(fixed16_t val) } #endif + +/* +======================================================================== + + Matrix4x4 operations + +======================================================================== +*/ +void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] ) +{ + out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2] + in[0][3]; + out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2] + in[1][3]; + out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2] + in[2][3]; +} + +void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] ) +{ + vec3_t dir; + + dir[0] = v[0] - in[0][3]; + dir[1] = v[1] - in[1][3]; + dir[2] = v[2] - in[2][3]; + + out[0] = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0]; + out[1] = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1]; + out[2] = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2]; +} + +void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale ) +{ + float angle, sr, sp, sy, cr, cp, cy; + + if( angles[ROLL] ) + { + angle = angles[YAW] * (M_PI*2 / 360); + sincos( angle, &sy, &cy ); + angle = angles[PITCH] * (M_PI*2 / 360); + sincos( angle, &sp, &cp ); + angle = angles[ROLL] * (M_PI*2 / 360); + sincos( angle, &sr, &cr ); + + out[0][0] = (cp*cy) * scale; + out[0][1] = (sr*sp*cy+cr*-sy) * scale; + out[0][2] = (cr*sp*cy+-sr*-sy) * scale; + out[0][3] = origin[0]; + out[1][0] = (cp*sy) * scale; + out[1][1] = (sr*sp*sy+cr*cy) * scale; + out[1][2] = (cr*sp*sy+-sr*cy) * scale; + out[1][3] = origin[1]; + out[2][0] = (-sp) * scale; + out[2][1] = (sr*cp) * scale; + out[2][2] = (cr*cp) * scale; + out[2][3] = origin[2]; + out[3][0] = 0; + out[3][1] = 0; + out[3][2] = 0; + out[3][3] = 1; + } + else if( angles[PITCH] ) + { + angle = angles[YAW] * (M_PI*2 / 360); + sincos( angle, &sy, &cy ); + angle = angles[PITCH] * (M_PI*2 / 360); + sincos( angle, &sp, &cp ); + + out[0][0] = (cp*cy) * scale; + out[0][1] = (-sy) * scale; + out[0][2] = (sp*cy) * scale; + out[0][3] = origin[0]; + out[1][0] = (cp*sy) * scale; + out[1][1] = (cy) * scale; + out[1][2] = (sp*sy) * scale; + out[1][3] = origin[1]; + out[2][0] = (-sp) * scale; + out[2][1] = 0; + out[2][2] = (cp) * scale; + out[2][3] = origin[2]; + out[3][0] = 0; + out[3][1] = 0; + out[3][2] = 0; + out[3][3] = 1; + } + else if( angles[YAW] ) + { + angle = angles[YAW] * (M_PI*2 / 360); + sincos( angle, &sy, &cy ); + + out[0][0] = (cy) * scale; + out[0][1] = (-sy) * scale; + out[0][2] = 0; + out[0][3] = origin[0]; + out[1][0] = (sy) * scale; + out[1][1] = (cy) * scale; + out[1][2] = 0; + out[1][3] = origin[1]; + out[2][0] = 0; + out[2][1] = 0; + out[2][2] = scale; + out[2][3] = origin[2]; + out[3][0] = 0; + out[3][1] = 0; + out[3][2] = 0; + out[3][3] = 1; + } + else + { + out[0][0] = scale; + out[0][1] = 0; + out[0][2] = 0; + out[0][3] = origin[0]; + out[1][0] = 0; + out[1][1] = scale; + out[1][2] = 0; + out[1][3] = origin[1]; + out[2][0] = 0; + out[2][1] = 0; + out[2][2] = scale; + out[2][3] = origin[2]; + out[3][0] = 0; + out[3][1] = 0; + out[3][2] = 0; + out[3][3] = 1; + } +} \ No newline at end of file diff --git a/source/mathlib.h b/source/mathlib.h index 7e98af6..c1a5472 100644 --- a/source/mathlib.h +++ b/source/mathlib.h @@ -23,6 +23,7 @@ typedef float vec_t; typedef vec_t vec3_t[3]; typedef vec_t vec5_t[5]; typedef vec_t vec2_t[2]; +typedef vec_t matrix4x4[4][4]; typedef int fixed4_t; typedef int fixed8_t; @@ -97,6 +98,10 @@ void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane); float anglemod(float a); +void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale ); +void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] ); +void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] ); + extern int _mathlib_temp_int1, _mathlib_temp_int2, _mathlib_temp_int3; extern float _mathlib_temp_float1, _mathlib_temp_float2, _mathlib_temp_float3; extern vec3_t _mathlib_temp_vec1, _mathlib_temp_vec2, _mathlib_temp_vec3; diff --git a/source/sv_move.c b/source/sv_move.c index 7e24895..ae4a642 100644 --- a/source/sv_move.c +++ b/source/sv_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. @@ -40,7 +40,7 @@ qboolean SV_CheckBottom (edict_t *ent) trace_t trace; int x, y; float mid, bottom; - + VectorAdd (ent->v.origin, ent->v.mins, mins); VectorAdd (ent->v.origin, ent->v.maxs, maxs); @@ -66,7 +66,7 @@ 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; @@ -76,16 +76,16 @@ realcheck: if (trace.fraction == 1.0) return false; mid = bottom = trace.endpos[2]; - -// the corners must be within 16 of the midpoint + +// 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 = SV_Move (start, vec3_origin, vec3_origin, stop, true, ent); - + if (trace.fraction != 1.0 && trace.endpos[2] > bottom) bottom = trace.endpos[2]; if (trace.fraction == 1.0 || mid - trace.endpos[2] > STEPSIZE) @@ -107,7 +107,8 @@ possible, no move is done, false is returned, and pr_global_struct->trace_normal is set to the normal of the blocking wall ============= */ -qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) + +qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink)//Blubs edited this to make zombies walk through zombies { float dz; vec3_t oldorg, neworg, end; @@ -115,7 +116,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) int i; edict_t *enemy; -// try the move +// try the move VectorCopy (ent->v.origin, oldorg); VectorAdd (ent->v.origin, move, neworg); @@ -135,23 +136,22 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) if (dz < 30) neworg[2] += 8; } - trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, neworg, MOVE_NOMONSTERS, ent); //sB fixing zombies, was FALSE thanks blubs - + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, neworg,MOVE_NOMONSTERS, ent);//blubs edit, was 'false' + if (trace.fraction == 1) { if ( ((int)ent->v.flags & FL_SWIM) && SV_PointContents(trace.endpos) == CONTENTS_EMPTY ) return false; // swim monster left water - + VectorCopy (trace.endpos, ent->v.origin); if (relink) SV_LinkEdict (ent, true); return true; } - + if (enemy == sv.edicts) break; } - return false; } @@ -160,17 +160,21 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) VectorCopy (neworg, end); end[2] -= STEPSIZE*2; - trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, MOVE_NOMONSTERS, ent); //sB see above + trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end,MOVE_NOMONSTERS , ent);//blubsmove, 'false' if (trace.allsolid) + { return false; + } if (trace.startsolid) { neworg[2] -= STEPSIZE; - trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, MOVE_NOMONSTERS, ent); //sB + trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end,MOVE_NOMONSTERS , ent);//blubs edit, 'false' if (trace.allsolid || trace.startsolid) + { return false; + } } if (trace.fraction == 1) { @@ -181,16 +185,14 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) if (relink) SV_LinkEdict (ent, true); ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; -// Con_Printf ("fall down\n"); return true; } - return false; // walked off an edge } // check point traces down for dangling corners VectorCopy (trace.endpos, ent->v.origin); - + if (!SV_CheckBottom (ent)) { if ( (int)ent->v.flags & FL_PARTIALGROUND ) @@ -206,7 +208,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) if ( (int)ent->v.flags & FL_PARTIALGROUND ) { -// Con_Printf ("back on ground\n"); +// Con_Printf ("back on ground\n"); ent->v.flags = (int)ent->v.flags & ~FL_PARTIALGROUND; } ent->v.groundentity = EDICT_TO_PROG(trace.ent); @@ -234,13 +236,13 @@ qboolean SV_StepDirection (edict_t *ent, float yaw, float dist) { vec3_t move, oldorigin; float delta; - + ent->v.ideal_yaw = yaw; PF_changeyaw(); - + yaw = yaw*M_PI*2 / 360; - move[0] = cos(yaw)*dist; - move[1] = sin(yaw)*dist; + move[0] = cosf(yaw)*dist; + move[1] = sinf(yaw)*dist; move[2] = 0; VectorCopy (ent->v.origin, oldorigin); @@ -255,7 +257,7 @@ qboolean SV_StepDirection (edict_t *ent, float yaw, float dist) return true; } SV_LinkEdict (ent, true); - + return false; } @@ -268,7 +270,7 @@ SV_FixCheckBottom void SV_FixCheckBottom (edict_t *ent) { // Con_Printf ("SV_FixCheckBottom\n"); - + ent->v.flags = (int)ent->v.flags | FL_PARTIALGROUND; } @@ -312,7 +314,7 @@ void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist) tdir = d[2] == 90 ? 45 : 315; else tdir = d[2] == 90 ? 135 : 215; - + if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) return; } @@ -325,7 +327,95 @@ void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist) d[2]=tdir; } - if (d[1]!=DI_NODIR && d[1]!=turnaround + 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; + +/* there is no direct path to the player, so pick another direction */ + + 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 (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist) ) + return; + + actor->v.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 (!SV_CheckBottom (actor)) + SV_FixCheckBottom (actor); + +} +/* +================ +SV_NewChaseDirO + +================ +*/ +void SV_NewChaseDirO (edict_t *actor, vec3_t goal, float dist) +{ + float deltax,deltay; + float d[3]; + float tdir, olddir, turnaround; + + olddir = anglemod( (int)(actor->v.ideal_yaw/45)*45 ); + turnaround = anglemod(olddir - 180); + + deltax = goal[0] - actor->v.origin[0]; + deltay = goal[1] - actor->v.origin[1]; + 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; + else + d[2]= DI_NODIR; + +// try direct route + 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 (d[1]!=DI_NODIR && d[1]!=turnaround && SV_StepDirection(actor, d[1], dist)) return; @@ -373,7 +463,7 @@ SV_CloseEnough qboolean SV_CloseEnough (edict_t *ent, edict_t *goal, float dist) { int i; - + for (i=0 ; i<3 ; i++) { if (goal->v.absmin[i] > ent->v.absmax[i] + dist) @@ -384,6 +474,26 @@ qboolean SV_CloseEnough (edict_t *ent, edict_t *goal, float dist) return true; } +/* +====================== +SV_CloseEnough + +====================== +*/ +qboolean SV_CloseEnoughO (edict_t *ent, vec3_t goal, float dist) +{ + int i; + + for (i=0 ; i<3 ; i++) + { + if (goal[i] > ent->v.absmax[i] + dist) + return false; + if (goal[i] < ent->v.absmin[i] - dist) + return false; + } + return true; +} + /* ====================== SV_MoveToGoal @@ -392,15 +502,14 @@ SV_MoveToGoal */ void SV_MoveToGoal (void) { - edict_t *ent, *goal; + edict_t *ent; float dist; -#ifdef QUAKE2 - edict_t *enemy; -#endif + float *goal; ent = PROG_TO_EDICT(pr_global_struct->self); - goal = PROG_TO_EDICT(ent->v.goalentity); + dist = G_FLOAT(OFS_PARM0); + goal = G_VECTOR(OFS_PARM1); if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) ) { @@ -409,20 +518,13 @@ void SV_MoveToGoal (void) } // if the next step hits the enemy, return immediately -#ifdef QUAKE2 - enemy = PROG_TO_EDICT(ent->v.enemy); - if (enemy != sv.edicts && SV_CloseEnough (ent, enemy, dist) ) -#else - if ( PROG_TO_EDICT(ent->v.enemy) != sv.edicts && SV_CloseEnough (ent, goal, dist) ) -#endif + if ( PROG_TO_EDICT(ent->v.enemy) != sv.edicts && SV_CloseEnoughO (ent, goal, dist) ) return; // bump around... - if ( (rand()&3)==1 || - !SV_StepDirection (ent, ent->v.ideal_yaw, dist)) - { - SV_NewChaseDir (ent, goal, dist); - } + if ((rand()&3)==1 || !SV_StepDirection (ent, ent->v.ideal_yaw, dist)) + SV_NewChaseDirO (ent, goal, dist); + } /* @@ -455,3 +557,4 @@ void SV_MoveToOrigin (void) SV_NewChaseDir (ent, goal, dist); } + diff --git a/source/sv_phys.c b/source/sv_phys.c index 5a037e0..3d5902e 100644 --- a/source/sv_phys.c +++ b/source/sv_phys.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. @@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. pushmove objects do not obey gravity, and do not interact with each other or trigger fields, but block normal movement and push normal objects when they move. -onground is set for toss objects when they come to a complete rest. it is set for steping or walking objects +onground is set for toss objects when they come to a complete rest. it is set for steping or walking objects doors, plats, etc are SOLID_BSP, and MOVETYPE_PUSH bonus items are SOLID_TRIGGER touch, and MOVETYPE_TOSS @@ -45,10 +45,6 @@ cvar_t sv_gravity = {"sv_gravity","800",false,true}; cvar_t sv_maxvelocity = {"sv_maxvelocity","100000"}; cvar_t sv_nostep = {"sv_nostep","0"}; -#ifdef QUAKE2 -static vec3_t vec_origin = {0.0, 0.0, 0.0}; -#endif - #define MOVE_EPSILON 0.01 void SV_Physics_Toss (edict_t *ent); @@ -71,9 +67,7 @@ void SV_CheckAllEnts (void) continue; if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE -#ifdef QUAKE2 || check->v.movetype == MOVETYPE_FOLLOW -#endif || check->v.movetype == MOVETYPE_NOCLIP) continue; @@ -130,7 +124,7 @@ qboolean SV_RunThink (edict_t *ent) thinktime = ent->v.nextthink; if (thinktime <= 0 || thinktime > sv.time + host_frametime) return true; - + if (thinktime < sv.time) thinktime = sv.time; // don't let things stay in the past. // it is possible to start that way @@ -153,10 +147,10 @@ Two entities have touched, so run their touch functions void SV_Impact (edict_t *e1, edict_t *e2) { int old_self, old_other; - + old_self = pr_global_struct->self; old_other = pr_global_struct->other; - + pr_global_struct->time = sv.time; if (e1->v.touch && e1->v.solid != SOLID_NOT) { @@ -164,7 +158,7 @@ void SV_Impact (edict_t *e1, edict_t *e2) pr_global_struct->other = EDICT_TO_PROG(e2); PR_ExecuteProgram (e1->v.touch); } - + if (e2->v.touch && e2->v.solid != SOLID_NOT) { pr_global_struct->self = EDICT_TO_PROG(e2); @@ -192,13 +186,13 @@ int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) float backoff; float change; int i, blocked; - + blocked = 0; if (normal[2] > 0) blocked |= 1; // floor if (!normal[2]) blocked |= 2; // step - + backoff = DotProduct (in, normal) * overbounce; for (i=0 ; i<3 ; i++) @@ -208,7 +202,7 @@ int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON) out[i] = 0; } - + return blocked; } @@ -239,14 +233,14 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) vec3_t end; float time_left; int blocked; - + numbumps = 4; - + blocked = 0; VectorCopy (ent->v.velocity, original_velocity); VectorCopy (ent->v.velocity, primal_velocity); numplanes = 0; - + time_left = time; for (bumpcount=0 ; bumpcountfree) break; // removed by the impact function - + time_left -= time_left * trace.fraction; - + // cliped to another plane if (numplanes >= MAX_CLIP_PLANES) { // this shouldn't really happen @@ -329,7 +323,7 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) if (j == numplanes) break; } - + if (i != numplanes) { // go along this plane VectorCopy (new_velocity, ent->v.velocity); @@ -372,20 +366,13 @@ void SV_AddGravity (edict_t *ent) { float ent_gravity; -#ifdef QUAKE2 - if (ent->v.gravity) - ent_gravity = ent->v.gravity; - else - ent_gravity = 1.0; -#else eval_t *val; - val = GetEdictFieldValue(ent, "gravity"); + val = GETEDICTFIELDVALUE(ent, eval_gravity); if (val && val->_float) ent_gravity = val->_float; else ent_gravity = 1.0; -#endif ent->v.velocity[2] -= ent_gravity * sv_gravity.value * host_frametime; } @@ -398,6 +385,23 @@ PUSHMOVE =============================================================================== */ +/* +============ +SV_AllowPushRotate +Allows to change entity yaw? +============ +*/ +qboolean SV_AllowPushRotate( edict_t *ent ) +{ + model_t *mod; + + mod = sv.models[ (int)ent->v.modelindex ]; + if(!mod || mod->type != mod_brush) + return true; + + return /*(mod->flags & MODEL_HAS_ORIGIN) ? true :*/ false; +} + /* ============ SV_PushEntity @@ -405,11 +409,11 @@ SV_PushEntity Does not change the entities velocity at all ============ */ -trace_t SV_PushEntity (edict_t *ent, vec3_t push) +trace_t SV_PushEntity (edict_t *ent, vec3_t push, vec3_t apush) { trace_t trace; vec3_t end; - + VectorAdd (ent->v.origin, push, end); if (ent->v.movetype == MOVETYPE_FLYMISSILE) @@ -418,16 +422,30 @@ trace_t SV_PushEntity (edict_t *ent, vec3_t push) // only clip against bmodels trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NOMONSTERS, ent); else - trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent); - - VectorCopy (trace.endpos, ent->v.origin); + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent); + + if( trace.fraction != 0.0f ) + { + VectorCopy( trace.endpos, ent->v.origin ); + + if( apush[YAW] && ( (int)ent->v.flags & FL_CLIENT )) + { + ent->v.avelocity[1] += apush[1]; + ent->v.fixangle = 2; + } + + // don't rotate pushables! + if( SV_AllowPushRotate( ent )) + ent->v.angles[YAW] += trace.fraction * apush[YAW]; + } + SV_LinkEdict (ent, true); if (trace.ent) - SV_Impact (ent, trace.ent); + SV_Impact (ent, trace.ent); return trace; -} +} /* @@ -436,23 +454,23 @@ SV_PushMove ============ */ -void SV_PushMove (edict_t *pusher, float movetime) +edict_t *moved_edict[MAX_EDICTS]; +vec3_t moved_from[MAX_EDICTS]; +edict_t * SV_PushMove (edict_t *pusher, float movetime) { - int i, e; + int i, e, oldsolid; edict_t *check, *block; vec3_t mins, maxs, move; vec3_t entorig, pushorig; int num_moved; - edict_t *moved_edict[MAX_EDICTS]; - vec3_t moved_from[MAX_EDICTS]; if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2]) { pusher->v.ltime += movetime; - return; + return NULL; } - for (i=0 ; i<3 ; i++) + for (i = 0; i < 3; i++) { move[i] = pusher->v.velocity[i] * movetime; mins[i] = pusher->v.absmin[i] + move[i]; @@ -460,73 +478,79 @@ void SV_PushMove (edict_t *pusher, float movetime) } VectorCopy (pusher->v.origin, pushorig); - -// move the pusher to it's final position + // move the pusher to it's final position VectorAdd (pusher->v.origin, move, pusher->v.origin); - pusher->v.ltime += movetime; SV_LinkEdict (pusher, false); + pusher->v.ltime += movetime; + oldsolid = pusher->v.solid; + // non-solid pushers can't push anything + if( pusher->v.solid == SOLID_NOT ) + return NULL; -// see if any solid entities are inside the final position - num_moved = 0; - check = NEXT_EDICT(sv.edicts); - for (e=1 ; efree) continue; + if (check->v.movetype == MOVETYPE_PUSH - || check->v.movetype == MOVETYPE_NONE -#ifdef QUAKE2 - || check->v.movetype == MOVETYPE_FOLLOW -#endif - || check->v.movetype == MOVETYPE_NOCLIP) + || check->v.movetype == MOVETYPE_NONE + || check->v.movetype == MOVETYPE_NOCLIP) continue; - // if the entity is standing on the pusher, it will definately be moved - if ( ! ( ((int)check->v.flags & FL_ONGROUND) - && PROG_TO_EDICT(check->v.groundentity) == pusher) ) + // if the entity is standing on the pusher, it will definately be moved + if (!(((int) check->v.flags & FL_ONGROUND) + && PROG_TO_EDICT (check->v.groundentity) == pusher)) { - if ( check->v.absmin[0] >= maxs[0] - || check->v.absmin[1] >= maxs[1] - || check->v.absmin[2] >= maxs[2] - || check->v.absmax[0] <= mins[0] - || check->v.absmax[1] <= mins[1] - || check->v.absmax[2] <= mins[2] ) + if (check->v.absmin[0] >= maxs[0] + || check->v.absmin[1] >= maxs[1] + || check->v.absmin[2] >= maxs[2] + || check->v.absmax[0] <= mins[0] + || check->v.absmax[1] <= mins[1] + || check->v.absmax[2] <= mins[2]) continue; - // see if the ent's bbox is inside the pusher's final position + // see if the ent's bbox is inside the pusher's final position if (!SV_TestEntityPosition (check)) continue; } - // remove the onground flag for non-players + // remove the onground flag for non-players if (check->v.movetype != MOVETYPE_WALK) - check->v.flags = (int)check->v.flags & ~FL_ONGROUND; - + check->v.flags = (int) check->v.flags & ~FL_ONGROUND; + VectorCopy (check->v.origin, entorig); VectorCopy (check->v.origin, moved_from[num_moved]); moved_edict[num_moved] = check; num_moved++; - // try moving the contacted entity + // try moving the contacted entity pusher->v.solid = SOLID_NOT; - SV_PushEntity (check, move); - pusher->v.solid = SOLID_BSP; + SV_PushEntity (check, move, vec3_origin); + pusher->v.solid = oldsolid; - // if it is still inside the pusher, block + // if it is still inside the pusher, block block = SV_TestEntityPosition (check); + if (block) - { // fail the move + { + // fail the move if (check->v.mins[0] == check->v.maxs[0]) continue; + if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER) - { // corpse + { + // corpse check->v.mins[0] = check->v.mins[1] = 0; VectorCopy (check->v.mins, check->v.maxs); continue; } - + VectorCopy (entorig, check->v.origin); SV_LinkEdict (check, true); @@ -538,128 +562,142 @@ void SV_PushMove (edict_t *pusher, float movetime) // otherwise, just stay in place until the obstacle is gone if (pusher->v.blocked) { - pr_global_struct->self = EDICT_TO_PROG(pusher); - pr_global_struct->other = EDICT_TO_PROG(check); + pr_global_struct->self = EDICT_TO_PROG (pusher); + pr_global_struct->other = EDICT_TO_PROG (check); PR_ExecuteProgram (pusher->v.blocked); + } - - // move back any entities we already moved - for (i=0 ; iv.origin); - SV_LinkEdict (moved_edict[i], false); + SV_LinkEdict (moved_edict[i], (moved_edict[i] == check) ? true : false); } - return; - } + return check; + } } - - + return NULL; } -#ifdef QUAKE2 + /* ============ SV_PushRotate ============ */ -void SV_PushRotate (edict_t *pusher, float movetime) +edict_t * SV_PushRotate (edict_t *pusher, float movetime) { - int i, e; - edict_t *check, *block; - vec3_t move, a, amove; - vec3_t entorig, pushorig; - int num_moved; - edict_t *moved_edict[MAX_EDICTS]; - vec3_t moved_from[MAX_EDICTS]; - vec3_t org, org2; - vec3_t forward, right, up; + int i, e, oldsolid; + matrix4x4 start_l, end_l;; + edict_t *check, *block; + vec3_t move, amove; + vec3_t entorig, pushorig; + int num_moved; + vec3_t org, org2, temp; if (!pusher->v.avelocity[0] && !pusher->v.avelocity[1] && !pusher->v.avelocity[2]) { pusher->v.ltime += movetime; - return; + return NULL; } - for (i=0 ; i<3 ; i++) + for (i = 0; i < 3; i++) amove[i] = pusher->v.avelocity[i] * movetime; - VectorSubtract (vec3_origin, amove, a); - AngleVectors (a, forward, right, up); + // create pusher initial position + Matrix4x4_CreateFromEntity( start_l, pusher->v.angles, pusher->v.origin, 1.0f ); VectorCopy (pusher->v.angles, pushorig); - -// move the pusher to it's final position + // move the pusher to it's final position VectorAdd (pusher->v.angles, amove, pusher->v.angles); pusher->v.ltime += movetime; SV_LinkEdict (pusher, false); + oldsolid = pusher->v.solid; + // non-solid pushers can't push anything + if( pusher->v.solid == SOLID_NOT ) + return NULL; -// see if any solid entities are inside the final position - num_moved = 0; - check = NEXT_EDICT(sv.edicts); - for (e=1 ; ev.angles, pusher->v.origin, 1.0f ); + + // see if any solid entities are inside the final position + num_moved = 0; + check = NEXT_EDICT (sv.edicts); + + for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (check)) { if (check->free) continue; + if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE || check->v.movetype == MOVETYPE_FOLLOW || check->v.movetype == MOVETYPE_NOCLIP) continue; - // if the entity is standing on the pusher, it will definately be moved - if ( ! ( ((int)check->v.flags & FL_ONGROUND) - && PROG_TO_EDICT(check->v.groundentity) == pusher) ) + // if the entity is standing on the pusher, it will definately be moved + if (!(((int) check->v.flags & FL_ONGROUND) && PROG_TO_EDICT (check->v.groundentity) == pusher)) { - if ( check->v.absmin[0] >= pusher->v.absmax[0] - || check->v.absmin[1] >= pusher->v.absmax[1] - || check->v.absmin[2] >= pusher->v.absmax[2] - || check->v.absmax[0] <= pusher->v.absmin[0] - || check->v.absmax[1] <= pusher->v.absmin[1] - || check->v.absmax[2] <= pusher->v.absmin[2] ) + if (check->v.absmin[0] >= pusher->v.absmax[0] + || check->v.absmin[1] >= pusher->v.absmax[1] + || check->v.absmin[2] >= pusher->v.absmax[2] + || check->v.absmax[0] <= pusher->v.absmin[0] + || check->v.absmax[1] <= pusher->v.absmin[1] + || check->v.absmax[2] <= pusher->v.absmin[2]) continue; - // see if the ent's bbox is inside the pusher's final position + // see if the ent's bbox is inside the pusher's final position if (!SV_TestEntityPosition (check)) continue; } - // remove the onground flag for non-players + // remove the onground flag for non-players if (check->v.movetype != MOVETYPE_WALK) - check->v.flags = (int)check->v.flags & ~FL_ONGROUND; - + check->v.flags = (int) check->v.flags & ~FL_ONGROUND; + VectorCopy (check->v.origin, entorig); VectorCopy (check->v.origin, moved_from[num_moved]); + moved_edict[num_moved] = check; num_moved++; // calculate destination position - VectorSubtract (check->v.origin, pusher->v.origin, org); - org2[0] = DotProduct (org, forward); - org2[1] = -DotProduct (org, right); - org2[2] = DotProduct (org, up); - VectorSubtract (org2, org, move); + //if( check->v.movetype == MOVETYPE_PUSHSTEP ) + // VectorAverage( check->v.absmin, check->v.absmax, org ); + //else + VectorCopy( check->v.origin, org ); - // try moving the contacted entity + Matrix4x4_VectorITransform( start_l, org, temp ); + Matrix4x4_VectorTransform( end_l, temp, org2 ); + VectorSubtract( org2, org, move ); + + // try moving the contacted entity pusher->v.solid = SOLID_NOT; - SV_PushEntity (check, move); - pusher->v.solid = SOLID_BSP; + SV_PushEntity (check, move, amove); + pusher->v.solid = oldsolid; - // if it is still inside the pusher, block + + // if it is still inside the pusher, block block = SV_TestEntityPosition (check); + if (block) - { // fail the move + { + // fail the move if (check->v.mins[0] == check->v.maxs[0]) continue; + if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER) - { // corpse + { + // corpse check->v.mins[0] = check->v.mins[1] = 0; VectorCopy (check->v.mins, check->v.maxs); continue; } - + VectorCopy (entorig, check->v.origin); SV_LinkEdict (check, true); @@ -671,29 +709,29 @@ void SV_PushRotate (edict_t *pusher, float movetime) // otherwise, just stay in place until the obstacle is gone if (pusher->v.blocked) { - pr_global_struct->self = EDICT_TO_PROG(pusher); - pr_global_struct->other = EDICT_TO_PROG(check); + pr_global_struct->self = EDICT_TO_PROG (pusher); + pr_global_struct->other = EDICT_TO_PROG (check); PR_ExecuteProgram (pusher->v.blocked); } - - // move back any entities we already moved - for (i=0 ; iv.origin); VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles); - SV_LinkEdict (moved_edict[i], false); + SV_LinkEdict (moved_edict[i], (moved_edict[i] == check) ? true : false); } - return; + return check; } else { VectorAdd (check->v.angles, amove, check->v.angles); } - } - + } + return NULL; } -#endif + /* ================ @@ -708,7 +746,7 @@ void SV_Physics_Pusher (edict_t *ent) float movetime; oldltime = ent->v.ltime; - + thinktime = ent->v.nextthink; if (thinktime < ent->v.ltime + host_frametime) { @@ -719,16 +757,15 @@ void SV_Physics_Pusher (edict_t *ent) else movetime = host_frametime; - if (movetime) - { -#ifdef QUAKE2 - if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2]) - SV_PushRotate (ent, movetime); - else -#endif - SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked - } - + + + if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2]) + SV_PushRotate (ent, host_frametime); + + if (movetime) + SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked + + if (thinktime > oldltime && thinktime <= ent->v.ltime) { ent->v.nextthink = 0; @@ -779,7 +816,7 @@ void SV_CheckStuck (edict_t *ent) SV_LinkEdict (ent, true); return; } - + for (z=0 ; z< 18 ; z++) for (i=-1 ; i <= 1 ; i++) for (j=-1 ; j <= 1 ; j++) @@ -794,7 +831,7 @@ void SV_CheckStuck (edict_t *ent) return; } } - + VectorCopy (org, ent->v.origin); Con_DPrintf ("player is stuck.\n"); } @@ -809,22 +846,16 @@ qboolean SV_CheckWater (edict_t *ent) { vec3_t point; int cont; -#ifdef QUAKE2 - int truecont; -#endif point[0] = ent->v.origin[0]; point[1] = ent->v.origin[1]; - point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; - + point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; + ent->v.waterlevel = 0; ent->v.watertype = CONTENTS_EMPTY; cont = SV_PointContents (point); if (cont <= CONTENTS_WATER) { -#ifdef QUAKE2 - truecont = SV_TruePointContents (point); -#endif ent->v.watertype = cont; ent->v.waterlevel = 1; point[2] = ent->v.origin[2] + (ent->v.mins[2] + ent->v.maxs[2])*0.5; @@ -837,24 +868,8 @@ qboolean SV_CheckWater (edict_t *ent) if (cont <= CONTENTS_WATER) ent->v.waterlevel = 3; } -#ifdef QUAKE2 - if (truecont <= CONTENTS_CURRENT_0 && truecont >= CONTENTS_CURRENT_DOWN) - { - static vec3_t current_table[] = - { - {1, 0, 0}, - {0, 1, 0}, - {-1, 0, 0}, - {0, -1, 0}, - {0, 0, 1}, - {0, 0, -1} - }; - - VectorMA (ent->v.basevelocity, 150.0*ent->v.waterlevel/3.0, current_table[CONTENTS_CURRENT_0 - truecont], ent->v.basevelocity); - } -#endif } - + return ent->v.waterlevel > 1; } @@ -869,19 +884,19 @@ void SV_WallFriction (edict_t *ent, trace_t *trace) vec3_t forward, right, up; float d, i; vec3_t into, side; - + AngleVectors (ent->v.v_angle, forward, right, up); d = DotProduct (trace->plane.normal, forward); - + d += 0.5; if (d >= 0) return; - + // cut the tangential velocity i = DotProduct (trace->plane.normal, ent->v.velocity); VectorScale (trace->plane.normal, i, into); VectorSubtract (ent->v.velocity, into, side); - + ent->v.velocity[0] = side[0] * (1 + d); ent->v.velocity[1] = side[1] * (1 + d); } @@ -905,7 +920,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel) vec3_t dir; int clip; trace_t steptrace; - + VectorCopy (ent->v.origin, oldorg); VectorCopy (vec3_origin, dir); @@ -923,8 +938,8 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel) case 6: dir[0] = 2; dir[1] = -2; break; case 7: dir[0] = -2; dir[1] = -2; break; } - - SV_PushEntity (ent, dir); + + SV_PushEntity (ent, dir, vec3_origin); // retry the original move ent->v.velocity[0] = oldvel[0]; @@ -932,17 +947,17 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel) ent->v. velocity[2] = 0; clip = SV_FlyMove (ent, 0.1, &steptrace); - if ( fabs(oldorg[1] - ent->v.origin[1]) > 4 - || fabs(oldorg[0] - ent->v.origin[0]) > 4 ) + if ( fabsf(oldorg[1] - ent->v.origin[1]) > 4 + || fabsf(oldorg[0] - ent->v.origin[0]) > 4 ) { //Con_DPrintf ("unstuck!\n"); return clip; } - + // go back to the original pos and try again VectorCopy (oldorg, ent->v.origin); } - + VectorCopy (vec3_origin, ent->v.velocity); return 7; // still not moving } @@ -963,16 +978,16 @@ void SV_WalkMove (edict_t *ent) int clip; int oldonground; trace_t steptrace, downtrace; - + // // do a regular slide move unless it looks like you ran into a step // oldonground = (int)ent->v.flags & FL_ONGROUND; ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; - + VectorCopy (ent->v.origin, oldorg); VectorCopy (ent->v.velocity, oldvel); - + clip = SV_FlyMove (ent, host_frametime, &steptrace); if ( !(clip & 2) ) @@ -980,13 +995,13 @@ void SV_WalkMove (edict_t *ent) if (!oldonground && ent->v.waterlevel == 0) return; // don't stair up while jumping - + if (ent->v.movetype != MOVETYPE_WALK) return; // gibbed by a trigger - + if (sv_nostep.value) return; - + if ( (int)sv_player->v.flags & FL_WATERJUMP ) return; @@ -1004,7 +1019,7 @@ void SV_WalkMove (edict_t *ent) downmove[2] = -STEPSIZE + oldvel[2]*host_frametime; // move up - SV_PushEntity (ent, upmove); // FIXME: don't link? + SV_PushEntity (ent, upmove, vec3_origin); // FIXME: don't link? // move forward ent->v.velocity[0] = oldvel[0]; @@ -1016,19 +1031,19 @@ void SV_WalkMove (edict_t *ent) // in the clipping hulls if (clip) { - if ( fabs(oldorg[1] - ent->v.origin[1]) < 0.03125 - && fabs(oldorg[0] - ent->v.origin[0]) < 0.03125 ) + if ( fabsf(oldorg[1] - ent->v.origin[1]) < 0.03125 + && fabsf(oldorg[0] - ent->v.origin[0]) < 0.03125 ) { // stepping up didn't make any progress clip = SV_TryUnstick (ent, oldvel); } } - + // extra friction based on view angle if ( clip & 2 ) SV_WallFriction (ent, &steptrace); // move down - downtrace = SV_PushEntity (ent, downmove); // FIXME: don't link? + downtrace = SV_PushEntity (ent, downmove, vec3_origin); // FIXME: don't link? if (downtrace.plane.normal[2] > 0.7) { @@ -1042,7 +1057,7 @@ void SV_WalkMove (edict_t *ent) { // if the push down didn't end up on good ground, use the move without // the step up. This happens near wall / slope combinations, and can -// cause the player to hop up higher on a slope too steep to climb +// cause the player to hop up higher on a slope too steep to climb VectorCopy (nosteporg, ent->v.origin); VectorCopy (nostepvel, ent->v.velocity); } @@ -1208,16 +1223,15 @@ void SV_CheckStuck_IgnoreMonsters (edict_t *ent) if (!SV_TestEntityPosition_NOMONSTERS(ent)) { VectorCopy (ent->v.origin, ent->v.oldorigin); - //ent->v.zoom = 0; // naievil -- fixme + ent->v.zoom = 0; return; } - // naievil -- fixme - //if(ent->v.zoom == 1)//if used setorigin - //{ - // VectorCopy (ent->v.origin, ent->v.oldorigin); - // return;//we don't care to adjust for stuckness, whoever used setorigin in qc better handle that - //} + if(ent->v.zoom == 1)//if used setorigin + { + VectorCopy (ent->v.origin, ent->v.oldorigin); + return;//we don't care to adjust for stuckness, whoever used setorigin in qc better handle that + } VectorCopy (ent->v.origin, org); VectorCopy (ent->v.oldorigin, ent->v.origin); if (!SV_TestEntityPosition_NOMONSTERS(ent)) @@ -1254,36 +1268,31 @@ void SV_CheckStuck_IgnoreMonsters (edict_t *ent) void SV_PushAwayZombies(edict_t *ent) { edict_t *other_ent; - float rad = 64;//approx. length of bbox corner + float rad = 23;//approx. length of bbox corner float *org = ent->v.origin; vec3_t eorg; int i, j; other_ent = NEXT_EDICT(sv.edicts); for (i=1 ; ifree) - //continue; + { + if (other_ent->free) + continue; //if (ent->v.solid == SOLID_NOT) // continue; - if( other_ent->v.solid != SOLID_CORPSE) + if( other_ent->v.solid != SOLID_SLIDEBOX) continue; if( other_ent->v.movetype != MOVETYPE_WALK) continue; for (j=0 ; j<3 ; j++) eorg[j] = org[j] - (other_ent->v.origin[j] + (other_ent->v.mins[j] + other_ent->v.maxs[j])*0.5); if (Length(eorg) > rad) - { - Con_Printf ("Length Greater than bbox corner. \n"); continue; - } + //Process nearby zombie for(j = 0; j < 2; j++)//only x & y - { - Con_Printf ("Pushing Zombie \n"); - other_ent->v.velocity[j] += (other_ent->v.origin[j] - ent->v.origin[j]) * 0.01;//push away other zombie was 0.001 + other_ent->v.velocity[j] += (other_ent->v.origin[j] - ent->v.origin[j]) * 0.001;//push away other zombie //ent->v.velocity[j] += (ent->v.origin[j] - other_ent->v.origin[j]) * 0.01;//push away self - } } } //============================= @@ -1304,7 +1313,7 @@ void SV_Physics_Walk(edict_t *ent) VectorCopy(ent->v.mins,old_mins); VectorCopy(ent->v.maxs,old_maxs); - //'-16,-16,-32', '16,16,40' sB reenabled PushAwayZombies + //'-16,-16,-32', '16,16,40' ent->v.mins[0] = -16; ent->v.mins[1] = -16; ent->v.mins[2] = -32; ent->v.maxs[0] = 16; ent->v.maxs[1] = 16; ent->v.maxs[2] = 40; @@ -1354,6 +1363,7 @@ void SV_Physics_Walk(edict_t *ent) SV_LinkEdict(ent,true); } + /* ================ SV_Physics_Client @@ -1368,11 +1378,11 @@ void SV_Physics_Client (edict_t *ent, int num) // // call standard client pre-think -// +// pr_global_struct->time = sv.time; pr_global_struct->self = EDICT_TO_PROG(ent); PR_ExecuteProgram (pr_global_struct->PlayerPreThink); - + // // do a move // @@ -1394,16 +1404,10 @@ void SV_Physics_Client (edict_t *ent, int num) if (!SV_CheckWater (ent) && ! ((int)ent->v.flags & FL_WATERJUMP) ) SV_AddGravity (ent); SV_CheckStuck (ent); -#ifdef QUAKE2 - VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); -#endif SV_WalkMove (ent); -#ifdef QUAKE2 - VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); -#endif break; - + case MOVETYPE_TOSS: case MOVETYPE_BOUNCE: SV_Physics_Toss (ent); @@ -1414,20 +1418,21 @@ void SV_Physics_Client (edict_t *ent, int num) return; SV_FlyMove (ent, host_frametime, NULL); break; - + case MOVETYPE_NOCLIP: if (!SV_RunThink (ent)) return; VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin); break; - + default: Sys_Error ("SV_Physics_client: bad movetype %i", (int)ent->v.movetype); } // // call standard player post-think -// +// + SV_LinkEdict (ent, true); pr_global_struct->time = sv.time; @@ -1450,6 +1455,7 @@ void SV_Physics_None (edict_t *ent) SV_RunThink (ent); } + /* ============= SV_Physics_Follow @@ -1477,7 +1483,7 @@ void SV_Physics_Noclip (edict_t *ent) // regular thinking if (!SV_RunThink (ent)) return; - + VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles); VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin); @@ -1501,38 +1507,29 @@ SV_CheckWaterTransition void SV_CheckWaterTransition (edict_t *ent) { int cont; -#ifdef QUAKE2 - vec3_t point; - - point[0] = ent->v.origin[0]; - point[1] = ent->v.origin[1]; - point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; - cont = SV_PointContents (point); -#else cont = SV_PointContents (ent->v.origin); -#endif if (!ent->v.watertype) { // just spawned here ent->v.watertype = cont; ent->v.waterlevel = 1; return; } - + if (cont <= CONTENTS_WATER) { - if (ent->v.watertype == CONTENTS_EMPTY) + /*if (ent->v.watertype == CONTENTS_EMPTY) { // just crossed into water - //SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); - } + SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); + } */ ent->v.watertype = cont; ent->v.waterlevel = 1; } else - { + {/* if (ent->v.watertype != CONTENTS_EMPTY) { // just crossed into water - //SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); - } + SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); + } */ ent->v.watertype = CONTENTS_EMPTY; ent->v.waterlevel = cont; } @@ -1550,9 +1547,9 @@ void SV_Physics_Toss (edict_t *ent) trace_t trace; vec3_t move; float backoff; + #ifdef QUAKE2 edict_t *groundentity; - groundentity = PROG_TO_EDICT(ent->v.groundentity); if ((int)groundentity->v.flags & FL_CONVEYOR) VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity); @@ -1560,6 +1557,7 @@ void SV_Physics_Toss (edict_t *ent) VectorCopy(vec_origin, ent->v.basevelocity); SV_CheckWater (ent); #endif + // regular thinking if (!SV_RunThink (ent)) return; @@ -1603,7 +1601,7 @@ void SV_Physics_Toss (edict_t *ent) VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); #endif VectorScale (ent->v.velocity, host_frametime, move); - trace = SV_PushEntity (ent, move); + trace = SV_PushEntity (ent, move, vec3_origin); #ifdef QUAKE2 VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); #endif @@ -1611,7 +1609,7 @@ void SV_Physics_Toss (edict_t *ent) return; if (ent->free) return; - + if (ent->v.movetype == MOVETYPE_BOUNCE) backoff = 1.5; #ifdef QUAKE2 @@ -1625,7 +1623,7 @@ void SV_Physics_Toss (edict_t *ent) // stop if on ground if (trace.plane.normal[2] > 0.7) - { + { #ifdef QUAKE2 if (ent->v.velocity[2] < 60 || (ent->v.movetype != MOVETYPE_BOUNCE && ent->v.movetype != MOVETYPE_BOUNCEMISSILE)) #else @@ -1638,11 +1636,12 @@ void SV_Physics_Toss (edict_t *ent) VectorCopy (vec3_origin, ent->v.avelocity); } } - + // check for in water SV_CheckWaterTransition (ent); } + /* =============================================================================== @@ -1662,107 +1661,7 @@ This is also used for objects that have become still on the ground, but will fall if the floor is pulled out from under them. ============= */ -#ifdef QUAKE2 -void SV_Physics_Step (edict_t *ent) -{ - qboolean wasonground; - qboolean inwater; - qboolean hitsound = false; - float *vel; - float speed, newspeed, control; - float friction; - edict_t *groundentity; - groundentity = PROG_TO_EDICT(ent->v.groundentity); - if ((int)groundentity->v.flags & FL_CONVEYOR) - VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity); - else - VectorCopy(vec_origin, ent->v.basevelocity); -//@@ - pr_global_struct->time = sv.time; - pr_global_struct->self = EDICT_TO_PROG(ent); - PF_WaterMove(); - - SV_CheckVelocity (ent); - - wasonground = (int)ent->v.flags & FL_ONGROUND; -// ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; - - // add gravity except: - // flying monsters - // swimming monsters who are in the water - inwater = SV_CheckWater(ent); - if (! wasonground) - if (!((int)ent->v.flags & FL_FLY)) - if (!(((int)ent->v.flags & FL_SWIM) && (ent->v.waterlevel > 0))) - { - if (ent->v.velocity[2] < sv_gravity.value*-0.1) - hitsound = true; - if (!inwater) - SV_AddGravity (ent); - } - - if (!VectorCompare(ent->v.velocity, vec_origin) || !VectorCompare(ent->v.basevelocity, vec_origin)) - { - ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; - // apply friction - // let dead monsters who aren't completely onground slide - if (wasonground) - if (!(ent->v.health <= 0.0 && !SV_CheckBottom(ent))) - { - vel = ent->v.velocity; - speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]); - if (speed) - { - friction = sv_friction.value; - - control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed; - newspeed = speed - host_frametime*control*friction; - - if (newspeed < 0) - newspeed = 0; - newspeed /= speed; - - vel[0] = vel[0] * newspeed; - vel[1] = vel[1] * newspeed; - } - } - - VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); - SV_FlyMove (ent, host_frametime, NULL); - VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); - - // determine if it's on solid ground at all - { - vec3_t mins, maxs, point; - int x, y; - - VectorAdd (ent->v.origin, ent->v.mins, mins); - VectorAdd (ent->v.origin, ent->v.maxs, maxs); - - point[2] = mins[2] - 1; - for (x=0 ; x<=1 ; x++) - for (y=0 ; y<=1 ; y++) - { - point[0] = x ? maxs[0] : mins[0]; - point[1] = y ? maxs[1] : mins[1]; - if (SV_PointContents (point) == CONTENTS_SOLID) - { - ent->v.flags = (int)ent->v.flags | FL_ONGROUND; - break; - } - } - - } - - SV_LinkEdict (ent, true); - } - -// regular thinking - SV_RunThink (ent); - SV_CheckWaterTransition (ent); -} -#else void SV_Physics_Step (edict_t *ent) { qboolean hitsound; @@ -1779,14 +1678,19 @@ void SV_Physics_Step (edict_t *ent) SV_CheckVelocity (ent); SV_FlyMove (ent, host_frametime, NULL); SV_LinkEdict (ent, true); + + /*if ( (int)ent->v.flags & FL_ONGROUND ) // just hit ground + { + if (hitsound) + SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1); + }*/ } // regular thinking SV_RunThink (ent); - + SV_CheckWaterTransition (ent); } -#endif //============================================================================ @@ -1820,9 +1724,8 @@ void SV_Physics (void) if (pr_global_struct->force_retouch) { - SV_LinkEdict (ent, true); // force retouch even for stationary + SV_LinkEdict (ent, true);// force retouch even for stationary } - if (i > 0 && i <= svs.maxclients) SV_Physics_Client (ent, i); else if (ent->v.movetype == MOVETYPE_PUSH) @@ -1837,14 +1740,14 @@ void SV_Physics (void) SV_Physics_Noclip (ent); else if (ent->v.movetype == MOVETYPE_STEP) SV_Physics_Step (ent); - else if (ent->v.movetype == MOVETYPE_TOSS + else if (ent->v.movetype == MOVETYPE_TOSS || ent->v.movetype == MOVETYPE_BOUNCE || ent->v.movetype == MOVETYPE_BOUNCEMISSILE || ent->v.movetype == MOVETYPE_FLY || ent->v.movetype == MOVETYPE_FLYMISSILE) SV_Physics_Toss (ent); else - Sys_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype); + Sys_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype); } if (EndFrame) @@ -1856,30 +1759,24 @@ void SV_Physics (void) PR_ExecuteProgram (EndFrame); } - + if (pr_global_struct->force_retouch) - pr_global_struct->force_retouch--; + pr_global_struct->force_retouch--; sv.time += host_frametime; } - -#ifdef QUAKE2 trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore) { + double save_frametime; + vec3_t move, end; edict_t tempent, *tent; trace_t trace; - vec3_t move; - vec3_t end; - double save_frametime; -// extern particle_t *active_particles, *free_particles; -// particle_t *p; - save_frametime = host_frametime; host_frametime = 0.05; - memcpy(&tempent, ent, sizeof(edict_t)); + memcpy_vfpu(&tempent, ent, sizeof(edict_t)); tent = &tempent; while (1) @@ -1889,29 +1786,14 @@ trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore) VectorMA (tent->v.angles, host_frametime, tent->v.avelocity, tent->v.angles); VectorScale (tent->v.velocity, host_frametime, move); VectorAdd (tent->v.origin, move, end); - trace = SV_Move (tent->v.origin, tent->v.mins, tent->v.maxs, end, MOVE_NORMAL, tent); + trace = SV_Move (tent->v.origin, tent->v.mins, tent->v.maxs, end, MOVE_NORMAL, tent); VectorCopy (trace.endpos, tent->v.origin); -// p = free_particles; -// if (p) -// { -// free_particles = p->next; -// p->next = active_particles; -// active_particles = p; -// -// p->die = 256; -// p->color = 15; -// p->type = pt_static; -// VectorCopy (vec3_origin, p->vel); -// VectorCopy (tent->v.origin, p->org); -// } - if (trace.ent) if (trace.ent != ignore) break; } -// p->color = 224; host_frametime = save_frametime; + return trace; } -#endif diff --git a/source/sv_user.c b/source/sv_user.c index c9f3a73..884e307 100644 --- a/source/sv_user.c +++ b/source/sv_user.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. @@ -58,34 +58,34 @@ void SV_SetIdealPitch (void) float z[MAX_FORWARD]; int i, j; int step, dir, steps; - + if (!((int)sv_player->v.flags & FL_ONGROUND)) return; - + angleval = sv_player->v.angles[YAW] * M_PI*2 / 360; - sinval = sin(angleval); - cosval = cos(angleval); + sinval = sinf(angleval); + cosval = cosf(angleval); for (i=0 ; iv.origin[0] + cosval*(i+3)*12; top[1] = sv_player->v.origin[1] + sinval*(i+3)*12; top[2] = sv_player->v.origin[2] + sv_player->v.view_ofs[2]; - + bottom[0] = top[0]; bottom[1] = top[1]; bottom[2] = top[2] - 160; - + tr = SV_Move (top, vec3_origin, vec3_origin, bottom, 1, sv_player); if (tr.allsolid) return; // looking at a wall, leave ideal the way is was if (tr.fraction == 1) return; // near a dropoff - + z[i] = top[2] + tr.fraction*(bottom[2]-top[2]); } - + dir = 0; steps = 0; for (j=1 ; j ON_EPSILON || step-dir < -ON_EPSILON ) ) return; // mixed changes - steps++; + steps++; dir = step; } - + if (!dir) { sv_player->v.idealpitch = 0; return; } - + if (steps < 2) return; sv_player->v.idealpitch = -dir * sv_idealpitchscale.value; @@ -126,10 +126,10 @@ void SV_UserFriction (void) vec3_t start, stop; float friction; trace_t trace; - + vel = velocity; - - speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]); + + speed = sqrtf(vel[0]*vel[0] +vel[1]*vel[1]); if (!speed) return; @@ -146,10 +146,10 @@ void SV_UserFriction (void) else friction = sv_friction.value; -// apply friction +// apply friction control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed; newspeed = speed - host_frametime*control*friction; - + if (newspeed < 0) newspeed = 0; newspeed /= speed; @@ -182,9 +182,9 @@ void SV_Accelerate (vec3_t wishvel) accelspeed = sv_accelerate.value*host_frametime*addspeed; if (accelspeed > addspeed) accelspeed = addspeed; - + for (i=0 ; i<3 ; i++) - velocity[i] += accelspeed*pushvec[i]; + velocity[i] += accelspeed*pushvec[i]; } #endif void SV_Accelerate (void) @@ -199,16 +199,16 @@ void SV_Accelerate (void) accelspeed = sv_accelerate.value*host_frametime*wishspeed; if (accelspeed > addspeed) accelspeed = addspeed; - + for (i=0 ; i<3 ; i++) - velocity[i] += accelspeed*wishdir[i]; + velocity[i] += accelspeed*wishdir[i]; } void SV_AirAccelerate (vec3_t wishveloc) { int i; float addspeed, wishspd, accelspeed, currentspeed; - + wishspd = VectorNormalize (wishveloc); if (wishspd > 30) wishspd = 30; @@ -220,19 +220,19 @@ void SV_AirAccelerate (vec3_t wishveloc) accelspeed = sv_accelerate.value*wishspeed * host_frametime; if (accelspeed > addspeed) accelspeed = addspeed; - + for (i=0 ; i<3 ; i++) - velocity[i] += accelspeed*wishveloc[i]; + velocity[i] += accelspeed*wishveloc[i]; } void DropPunchAngle (void) { float len; - + len = VectorNormalize (sv_player->v.punchangle); - - len -= 10*host_frametime; + + len -= 20*host_frametime; if (len < 0) len = 0; VectorScale (sv_player->v.punchangle, len, sv_player->v.punchangle); @@ -279,12 +279,12 @@ void SV_WaterMove (void) { newspeed = speed - host_frametime * speed * sv_friction.value; if (newspeed < 0) - newspeed = 0; + newspeed = 0; VectorScale (velocity, newspeed/speed, velocity); } else newspeed = 0; - + // // water acceleration // @@ -333,11 +333,11 @@ void SV_AirMove (void) fmove = cmd.forwardmove; smove = cmd.sidemove; - + // hack to not let you back into teleporter if (sv.time < sv_player->v.teleport_time && fmove < 0) fmove = 0; - + for (i=0 ; i<3 ; i++) wishvel[i] = forward[i]*fmove + right[i]*smove; @@ -353,12 +353,12 @@ void SV_AirMove (void) VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel); wishspeed = sv_maxspeed.value; } - + if ( sv_player->v.movetype == MOVETYPE_NOCLIP) { // noclip VectorCopy (wishvel, velocity); } - else if ( (int)sv_player->v.flags & FL_ONGROUND ) + else if ( onground ) { SV_UserFriction (); SV_Accelerate (); @@ -366,7 +366,7 @@ void SV_AirMove (void) else { // not on ground, so little effect on velocity SV_AirAccelerate (wishvel); - } + } } /* @@ -383,14 +383,17 @@ void SV_ClientThink (void) if (sv_player->v.movetype == MOVETYPE_NONE) return; - - onground = (int)sv_player->v.flags & FL_ONGROUND; + + if ((int)sv_player->v.flags & FL_ONGROUND) + onground = qtrue; + else + onground = qfalse; origin = sv_player->v.origin; velocity = sv_player->v.velocity; DropPunchAngle (); - + // // if dead, behave differently // @@ -402,7 +405,7 @@ void SV_ClientThink (void) // show 1/3 the pitch angle and all the roll angle cmd = host_client->cmd; angles = sv_player->v.angles; - + VectorAdd (sv_player->v.v_angle, sv_player->v.punchangle, v_angle); angles[ROLL] = V_CalcRoll (sv_player->v.angles, sv_player->v.velocity)*4; if (!sv_player->v.fixangle) @@ -426,7 +429,7 @@ void SV_ClientThink (void) return; } - SV_AirMove (); + SV_AirMove (); } @@ -440,23 +443,23 @@ void SV_ReadClientMove (usercmd_t *move) int i; vec3_t angle; int bits; - + // read ping time host_client->ping_times[host_client->num_pings%NUM_PING_TIMES] = sv.time - MSG_ReadFloat (); host_client->num_pings++; -// read current angles +// read current angles for (i=0 ; i<3 ; i++) - angle[i] = MSG_ReadAngle (); + angle[i] = MSG_ReadFloat (); VectorCopy (angle, host_client->edict->v.v_angle); - + // read movement move->forwardmove = MSG_ReadShort (); move->sidemove = MSG_ReadShort (); move->upmove = MSG_ReadShort (); - + // read buttons bits = MSG_ReadLong (); host_client->edict->v.button0 = bits & 1; @@ -472,11 +475,6 @@ void SV_ReadClientMove (usercmd_t *move) i = MSG_ReadByte (); if (i) host_client->edict->v.impulse = i; - -#ifdef QUAKE2 -// read light level - host_client->edict->v.light_level = MSG_ReadByte (); -#endif } /* @@ -491,7 +489,7 @@ qboolean SV_ReadClientMessage (void) int ret; int cmd; char *s; - + do { nextmsg: @@ -503,9 +501,9 @@ nextmsg: } if (!ret) return true; - + MSG_BeginReading (); - + while (1) { if (!host_client->active) @@ -515,24 +513,24 @@ nextmsg: { Sys_Printf ("SV_ReadClientMessage: badread\n"); return false; - } - + } + cmd = MSG_ReadChar (); - + switch (cmd) { case -1: goto nextmsg; // end of message - + default: Sys_Printf ("SV_ReadClientMessage: unknown command char\n"); return false; - + case clc_nop: // Sys_Printf ("clc_nop\n"); break; - - case clc_stringcmd: + + case clc_stringcmd: s = MSG_ReadString (); if (host_client->privileged) ret = 2; @@ -583,18 +581,18 @@ nextmsg: else Con_DPrintf("%s tried to %s\n", host_client->name, s); break; - + case clc_disconnect: // Sys_Printf ("SV_ReadClientMessage: client disconnected\n"); return false; - + case clc_move: SV_ReadClientMove (&host_client->cmd); break; } } } while (ret == 1); - + return true; } @@ -607,12 +605,12 @@ SV_RunClients void SV_RunClients (void) { int i; - + for (i=0, host_client = svs.clients ; iactive) continue; - + sv_player = host_client->edict; if (!SV_ReadClientMessage ())