/* Does not change the entities velocity at all */ trace_t SV_PushEntity (edict_t *ent, vec3_t push) { trace_t trace; vec3_t end; Math_VectorAdd (ent->v.origin, push, end); if (ent->v.movetype == (MOVETYPE_FLYMISSILE || MOVETYPE_FLYBOUNCE)) trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_MISSILE, ent); else if (ent->Physics.iSolid == SOLID_TRIGGER || ent->Physics.iSolid == SOLID_NOT) // 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); Math_VectorCopy (trace.endpos, ent->v.origin); SV_LinkEdict(ent,true); if(trace.ent) Physics_Impact(ent,trace.ent); return trace; }
/* Does not change the entities velocity at all */ trace_t Physics_PushEntity(ServerEntity_t *eEntity, MathVector3f_t mvPush) { trace_t trace; MathVector3f_t end; Math_VectorAdd(eEntity->v.origin, mvPush, end); if (eEntity->v.movetype == (MOVETYPE_FLYMISSILE || MOVETYPE_FLYBOUNCE)) trace = Engine.Server_Move(eEntity->v.origin, eEntity->v.mins, eEntity->v.maxs, end, MOVE_MISSILE, eEntity); else if (eEntity->Physics.iSolid == SOLID_TRIGGER || eEntity->Physics.iSolid == SOLID_NOT) // only clip against bmodels trace = Engine.Server_Move(eEntity->v.origin, eEntity->v.mins, eEntity->v.maxs, end, MOVE_NOMONSTERS, eEntity); else trace = Engine.Server_Move(eEntity->v.origin, eEntity->v.mins, eEntity->v.maxs, end, MOVE_NORMAL, eEntity); Math_VectorCopy(trace.endpos, eEntity->v.origin); Entity_Link(eEntity, true); if (trace.ent) Physics_Impact(eEntity, trace.ent); return trace; }
int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) { int bumpcount, numbumps; vec3_t dir; float d; int numplanes; vec3_t planes[MAX_CLIP_PLANES]; vec3_t primal_velocity, original_velocity, new_velocity; int i, j; trace_t trace; vec3_t end; float time_left; int blocked; numbumps = 4; blocked = 0; Math_VectorCopy (ent->v.velocity, original_velocity); Math_VectorCopy (ent->v.velocity, primal_velocity); numplanes = 0; time_left = time; for (bumpcount=0 ; bumpcount<numbumps ; bumpcount++) { 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]; trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, FALSE, ent); if(trace.bAllSolid) { // Entity is trapped in another solid Math_VectorCopy(mv3Origin, ent->v.velocity); return 3; } if (trace.fraction > 0) { // Actually covered some distance Math_VectorCopy (trace.endpos, ent->v.origin); Math_VectorCopy (ent->v.velocity, original_velocity); numplanes = 0; } if (trace.fraction == 1) break; // moved the entire distance if(!trace.ent) { Sys_Error ("SV_FlyMove: !trace.ent"); return 0; } if (trace.plane.normal[2] > 0.7) { blocked |= 1; // floor if (trace.ent->Physics.iSolid == SOLID_BSP) { ent->v.flags |= FL_ONGROUND; ent->v.groundentity = trace.ent; } } if (!trace.plane.normal[2]) { blocked |= 2; // step if (steptrace) *steptrace = trace; // save for player extrafriction } // Run the impact function Physics_Impact(ent,trace.ent); if (ent->free) 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 Math_VectorCopy(mv3Origin, ent->v.velocity); return 3; } Math_VectorCopy (trace.plane.normal, planes[numplanes]); numplanes++; // Modify original_velocity so it parallels all of the clip planes for(i = 0; i < numplanes; i++) { ClipVelocity (original_velocity, planes[i], new_velocity, 1); for (j=0 ; j<numplanes ; j++) if (j != i) { if(Math_DotProduct(new_velocity,planes[j]) < 0) break; // not ok } if (j == numplanes) break; } if (i != numplanes) Math_VectorCopy (new_velocity, ent->v.velocity); else { // Go along the crease if (numplanes != 2) { Math_VectorCopy(mv3Origin, ent->v.velocity); return 7; } Math_CrossProduct(planes[0], planes[1], dir); d = Math_DotProduct(dir, ent->v.velocity); Math_VectorScale(dir, d, ent->v.velocity); } // if original velocity is against the original velocity, stop dead // to avoid tiny occilations in sloping corners if(Math_DotProduct(ent->v.velocity,primal_velocity) <= 0) { Math_VectorCopy(mv3Origin,ent->v.velocity); return blocked; } } return blocked; }