X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=sv_phys.c;h=628591e23ec569a575412974df229e04a44b1052;hb=d2878a072b9a0399379741b3e19536b7327cb388;hp=e1ef0f96cc3ad79c86990e94b73e6a5ba275881e;hpb=10a2c31f2afb01affc8eacb388248fc787b09eb8;p=xonotic%2Fdarkplaces.git diff --git a/sv_phys.c b/sv_phys.c index e1ef0f96..628591e2 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -86,7 +86,7 @@ void SV_CheckAllEnts (void) continue; if (SV_TestEntityPosition (check)) - Con_Printf ("entity in invalid position\n"); + Con_Print("entity in invalid position\n"); } } @@ -107,12 +107,12 @@ void SV_CheckVelocity (edict_t *ent) { if (IS_NAN(ent->v->velocity[i])) { - Con_Printf ("Got a NaN velocity on %s\n", PR_GetString(ent->v->classname)); + Con_Printf("Got a NaN velocity on %s\n", PR_GetString(ent->v->classname)); ent->v->velocity[i] = 0; } if (IS_NAN(ent->v->origin[i])) { - Con_Printf ("Got a NaN origin on %s\n", PR_GetString(ent->v->classname)); + Con_Printf("Got a NaN origin on %s\n", PR_GetString(ent->v->classname)); ent->v->origin[i] = 0; } } @@ -234,226 +234,183 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal) { int blocked, bumpcount; edict_t *hackongroundentity; + int i, j, impact, numplanes; + float d, time_left; + vec3_t dir, end, planes[MAX_CLIP_PLANES], primal_velocity, original_velocity, new_velocity; + trace_t trace; + blocked = 0; + VectorCopy(ent->v->velocity, original_velocity); + VectorCopy(ent->v->velocity, primal_velocity); + numplanes = 0; + time_left = time; hackongroundentity = NULL; - if (sv_newflymove.integer) + for (bumpcount = 0;bumpcount < 8;bumpcount++) { - int impact; - vec3_t end, primal_velocity; - trace_t trace; - - blocked = 0; - VectorCopy (ent->v->velocity, primal_velocity); + if (!ent->v->velocity[0] && !ent->v->velocity[1] && !ent->v->velocity[2]) + break; - for (bumpcount = 0;bumpcount < 8;bumpcount++) + VectorMA(ent->v->origin, time_left, ent->v->velocity, end); + trace = SV_Move(ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); +#if 0 + //if (trace.fraction < 0.002) { - //Con_Printf("entity %i bump %i: blocked %i velocity %f %f %f\n", ent - sv.edicts, bumpcount, blocked, ent->v->velocity[0], ent->v->velocity[1], ent->v->velocity[2]); - if (!ent->v->velocity[0] && !ent->v->velocity[1] && !ent->v->velocity[2]) - break; - - VectorMA(ent->v->origin, time, ent->v->velocity, end); - trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); - //Con_Printf("trace %f %f %f : %f : %f %f %f\n", trace.endpos[0], trace.endpos[1], trace.endpos[2], trace.fraction, trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2]); - - /* - if (trace.startsolid) - { - // LordHavoc: note: this code is what makes entities stick in place if embedded in another object (which can be the world) - // entity is trapped in another solid - VectorClear(ent->v->velocity); - return 3; - } - */ - - if (trace.fraction >= 0.001) - { - // actually covered some distance - VectorCopy (trace.endpos, ent->v->origin); - } - - // break if it moved the entire distance - if (trace.fraction == 1) - break; - - if (!trace.ent) - Host_Error ("SV_FlyMove: !trace.ent"); - - if ((int) ent->v->flags & FL_ONGROUND) +#if 1 + vec3_t start; + trace_t testtrace; + VectorCopy(ent->v->origin, start); + start[2] += 3;//0.03125; + VectorMA(ent->v->origin, time_left, ent->v->velocity, end); + end[2] += 3;//0.03125; + testtrace = SV_Move(start, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); + if (trace.fraction < testtrace.fraction && !testtrace.startsolid && (testtrace.fraction == 1 || DotProduct(trace.plane.normal, ent->v->velocity) < DotProduct(testtrace.plane.normal, ent->v->velocity))) { - if (ent->v->groundentity == EDICT_TO_PROG(trace.ent)) - impact = false; - else - { - ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND; - impact = true; - } + Con_Printf("got further (new %f > old %f)\n", testtrace.fraction, trace.fraction); + trace = testtrace; } - else - impact = true; - - if (trace.plane.normal[2]) +#endif +#if 0 + //j = -1; + for (i = 0;i < numplanes;i++) { - if (trace.plane.normal[2] > 0.7) + VectorCopy(ent->v->origin, start); + VectorMA(ent->v->origin, time_left, ent->v->velocity, end); + VectorMA(start, 3, planes[i], start); + VectorMA(end, 3, planes[i], end); + testtrace = SV_Move(start, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); + if (trace.fraction < testtrace.fraction) { - // floor - blocked |= 1; - ent->v->flags = (int)ent->v->flags | FL_ONGROUND; - ent->v->groundentity = EDICT_TO_PROG(trace.ent); + trace = testtrace; + VectorCopy(start, ent->v->origin); + //j = i; } - else if (trace.fraction < 0.001) - hackongroundentity = trace.ent; - } - else - { - // step - blocked |= 2; - // save the trace for player extrafriction - if (stepnormal) - VectorCopy(trace.plane.normal, stepnormal); - } - - // run the impact function - if (impact) - { - SV_Impact (ent, trace.ent); - - // break if removed by the impact function - if (ent->e->free) - break; - } - - time *= 1 - trace.fraction; - - ClipVelocity (ent->v->velocity, trace.plane.normal, ent->v->velocity, 1); - - // if original velocity is against the original velocity, - // stop dead to avoid tiny occilations in sloping corners - if (DotProduct (ent->v->velocity, primal_velocity) < 0) - { - VectorClear(ent->v->velocity); - break; } + //if (j >= 0) + // VectorAdd(ent->v->origin, planes[j], start); +#endif } - } - else - { - int i, j, impact, numplanes; - float d, time_left; - vec3_t dir, end, planes[MAX_CLIP_PLANES], primal_velocity, original_velocity, new_velocity; - trace_t trace; +#endif - blocked = 0; - VectorCopy (ent->v->velocity, original_velocity); - VectorCopy (ent->v->velocity, primal_velocity); - numplanes = 0; +#if 0 + Con_Printf("entity %i bump %i: velocity %f %f %f trace %f", ent - sv.edicts, bumpcount, ent->v->velocity[0], ent->v->velocity[1], ent->v->velocity[2], trace.fraction); + if (trace.fraction < 1) + Con_Printf(" : %f %f %f", trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2]); + Con_Print("\n"); +#endif - time_left = time; - - for (bumpcount = 0;bumpcount < 8;bumpcount++) + /* + if (trace.startsolid) { - //Con_Printf("entity %i bump %i: blocked %i velocity %f %f %f\n", ent - sv.edicts, bumpcount, blocked, ent->v->velocity[0], ent->v->velocity[1], ent->v->velocity[2]); - if (!ent->v->velocity[0] && !ent->v->velocity[1] && !ent->v->velocity[2]) - break; - - for (i=0 ; i<3 ; i++) - end[i] = ent->v->origin[i] + time_left * ent->v->velocity[i]; + // LordHavoc: note: this code is what makes entities stick in place if embedded in another object (which can be the world) + // entity is trapped in another solid + VectorClear(ent->v->velocity); + return 3; + } + */ - trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); + // break if it moved the entire distance + if (trace.fraction == 1) + { + VectorCopy(trace.endpos, ent->v->origin); + break; + } - /* - if (trace.startsolid) - { - // LordHavoc: note: this code is what makes entities stick in place if embedded in another object (which can be the world) - // entity is trapped in another solid - VectorClear(ent->v->velocity); - return 3; - } - */ + if (!trace.ent) + Host_Error("SV_FlyMove: !trace.ent"); - if (trace.fraction > 0) + if ((int) ent->v->flags & FL_ONGROUND) + { + if (ent->v->groundentity == EDICT_TO_PROG(trace.ent)) + impact = false; + else { - // actually covered some distance - VectorCopy (trace.endpos, ent->v->origin); - VectorCopy (ent->v->velocity, original_velocity); - numplanes = 0; + ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND; + impact = true; } + } + else + impact = true; - // break if it moved the entire distance - if (trace.fraction == 1) - break; - - if (!trace.ent) - Host_Error ("SV_FlyMove: !trace.ent"); - - if ((int) ent->v->flags & FL_ONGROUND) + if (trace.plane.normal[2]) + { + if (trace.plane.normal[2] > 0.7) { - if (ent->v->groundentity == EDICT_TO_PROG(trace.ent)) - impact = false; - else - { - ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND; - impact = true; - } + // floor + blocked |= 1; + ent->v->flags = (int)ent->v->flags | FL_ONGROUND; + ent->v->groundentity = EDICT_TO_PROG(trace.ent); } - else - impact = true; + else if (trace.fraction < 0.001) + hackongroundentity = trace.ent; + } + else + { + // step + blocked |= 2; + // save the trace for player extrafriction + if (stepnormal) + VectorCopy(trace.plane.normal, stepnormal); + } - if (trace.plane.normal[2]) - { - if (trace.plane.normal[2] > 0.7) - { - // floor - blocked |= 1; - ent->v->flags = (int)ent->v->flags | FL_ONGROUND; - ent->v->groundentity = EDICT_TO_PROG(trace.ent); - } - else if (trace.fraction < 0.001) - hackongroundentity = trace.ent; - } - else - { - // step - blocked |= 2; - // save the trace for player extrafriction - if (stepnormal) - VectorCopy(trace.plane.normal, stepnormal); - } + if (trace.fraction >= 0.001) + { + // actually covered some distance + VectorCopy(trace.endpos, ent->v->origin); + VectorCopy(ent->v->velocity, original_velocity); + numplanes = 0; + } - // run the impact function - if (impact) - { - SV_Impact (ent, trace.ent); + // run the impact function + if (impact) + { + SV_Impact(ent, trace.ent); - // break if removed by the impact function - if (ent->e->free) - break; - } + // break if removed by the impact function + if (ent->e->free) + break; + } + time_left *= 1 - trace.fraction; - time_left -= time_left * trace.fraction; + // clipped to another plane + if (numplanes >= MAX_CLIP_PLANES) + { + // this shouldn't really happen + VectorClear(ent->v->velocity); + blocked = 3; + break; + } - // clipped to another plane - if (numplanes >= MAX_CLIP_PLANES) - { - // this shouldn't really happen - VectorClear(ent->v->velocity); - blocked = 3; + /* + for (i = 0;i < numplanes;i++) + if (DotProduct(trace.plane.normal, planes[i]) > 0.99) break; - } + if (i < numplanes) + { + VectorAdd(ent->v->velocity, trace.plane.normal, ent->v->velocity); + continue; + } + */ - VectorCopy (trace.plane.normal, planes[numplanes]); - numplanes++; + VectorCopy(trace.plane.normal, planes[numplanes]); + numplanes++; + if (sv_newflymove.integer) + ClipVelocity(ent->v->velocity, trace.plane.normal, ent->v->velocity, 1); + else + { // modify original_velocity so it parallels all of the clip planes - for (i=0 ; iv->velocity); + VectorCopy(new_velocity, ent->v->velocity); } else { @@ -472,20 +429,20 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal) blocked = 7; break; } - CrossProduct (planes[0], planes[1], dir); + CrossProduct(planes[0], planes[1], dir); // LordHavoc: thanks to taniwha of QuakeForge for pointing out this fix for slowed falling in corners VectorNormalize(dir); - d = DotProduct (dir, ent->v->velocity); - VectorScale (dir, d, ent->v->velocity); + d = DotProduct(dir, ent->v->velocity); + VectorScale(dir, d, ent->v->velocity); } + } - // if original velocity is against the original velocity, - // stop dead to avoid tiny occilations in sloping corners - if (DotProduct (ent->v->velocity, primal_velocity) <= 0) - { - VectorClear(ent->v->velocity); - break; - } + // if original velocity is against the original velocity, + // stop dead to avoid tiny occilations in sloping corners + if (DotProduct(ent->v->velocity, primal_velocity) <= 0) + { + VectorClear(ent->v->velocity); + break; } } @@ -508,7 +465,7 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal) { // LordHavoc: fix the 'fall to your death in a wedge corner' glitch // flag ONGROUND if there's ground under it - trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); + trace = SV_Move(ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); } */ return blocked; @@ -703,7 +660,8 @@ void SV_PushMove (edict_t *pusher, float movetime) if (check->v->movetype == MOVETYPE_PUSH || check->v->movetype == MOVETYPE_NONE || check->v->movetype == MOVETYPE_FOLLOW - || check->v->movetype == MOVETYPE_NOCLIP) + || check->v->movetype == MOVETYPE_NOCLIP + || check->v->movetype == MOVETYPE_FAKEPUSH) continue; // if the entity is standing on the pusher, it will definitely be moved @@ -867,7 +825,7 @@ void SV_CheckStuck (edict_t *ent) VectorCopy (ent->v->oldorigin, ent->v->origin); if (!SV_TestEntityPosition(ent)) { - Con_DPrintf ("Unstuck.\n"); + Con_DPrint("Unstuck.\n"); SV_LinkEdict (ent, true); return; } @@ -881,14 +839,14 @@ void SV_CheckStuck (edict_t *ent) ent->v->origin[2] = org[2] + z; if (!SV_TestEntityPosition(ent)) { - Con_DPrintf ("Unstuck.\n"); + Con_DPrint("Unstuck.\n"); SV_LinkEdict (ent, true); return; } } VectorCopy (org, ent->v->origin); - Con_DPrintf ("player is stuck.\n"); + Con_DPrint("player is stuck.\n"); } @@ -997,7 +955,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel) if (fabs(oldorg[1] - ent->v->origin[1]) > 4 || fabs(oldorg[0] - ent->v->origin[0]) > 4) { - Con_DPrintf("TryUnstick - success.\n"); + Con_DPrint("TryUnstick - success.\n"); return clip; } @@ -1007,7 +965,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel) // still not moving VectorClear (ent->v->velocity); - Con_DPrintf("TryUnstick - failure.\n"); + Con_DPrint("TryUnstick - failure.\n"); return 7; } @@ -1287,9 +1245,11 @@ void SV_Physics_Toss (edict_t *ent) } else if (ent->v->movetype == MOVETYPE_BOUNCE) { + float d; ClipVelocity (ent->v->velocity, trace.plane.normal, ent->v->velocity, 1.5); // LordHavoc: fixed grenades not bouncing when fired down a slope - if (trace.plane.normal[2] > 0.7 && DotProduct(trace.plane.normal, ent->v->velocity) < 60) + d = DotProduct(trace.plane.normal, ent->v->velocity); + if (trace.plane.normal[2] > 0.7 && fabs(d) < 60) { ent->v->flags = (int)ent->v->flags | FL_ONGROUND; ent->v->groundentity = EDICT_TO_PROG(trace.ent); @@ -1391,25 +1351,29 @@ void SV_Physics (void) if (pr_global_struct->force_retouch) SV_LinkEdict (ent, true); // force retouch even for stationary - if (i <= svs.maxclients && i > 0) + if (i <= svs.maxclients) { - if (!svs.clients[i-1].spawned) - continue; - // connected slot - // call standard client pre-think - SV_CheckVelocity (ent); - pr_global_struct->time = sv.time; - pr_global_struct->self = EDICT_TO_PROG(ent); - PR_ExecuteProgram (pr_global_struct->PlayerPreThink, "QC function PlayerPreThink is missing"); - SV_CheckVelocity (ent); + if (i > 0) + { + if (!svs.clients[i-1].spawned) + continue; + // connected slot + // call standard client pre-think + SV_CheckVelocity (ent); + pr_global_struct->time = sv.time; + pr_global_struct->self = EDICT_TO_PROG(ent); + PR_ExecuteProgram (pr_global_struct->PlayerPreThink, "QC function PlayerPreThink is missing"); + SV_CheckVelocity (ent); + } } else if (sv_freezenonclients.integer) - break; + continue; // LordHavoc: merged client and normal entity physics switch ((int) ent->v->movetype) { case MOVETYPE_PUSH: + case MOVETYPE_FAKEPUSH: SV_Physics_Pusher (ent); break; case MOVETYPE_NONE: @@ -1469,7 +1433,7 @@ void SV_Physics (void) break; } - if (i > 0 && i <= svs.maxclients && !ent->e->free) + if (i <= svs.maxclients && i > 0 && !ent->e->free) { SV_CheckVelocity (ent); @@ -1496,7 +1460,8 @@ void SV_Physics (void) PR_ExecuteProgram ((func_t)(EndFrameQC - pr_functions), ""); } - sv.time += sv.frametime; + if (!sv_freezenonclients.integer) + sv.time += sv.frametime; }