cvar_t sv_sound_watersplash = {0, "sv_sound_watersplash", "misc/h2ohit1.wav", "sound to play when MOVETYPE_FLY/TOSS/BOUNCE/STEP entity enters or leaves water (empty cvar disables the sound)"};
cvar_t sv_sound_land = {0, "sv_sound_land", "demon/dland2.wav", "sound to play when MOVETYPE_STEP entity hits the ground at high speed (empty cvar disables the sound)"};
+// TODO: move this extern to server.h
+extern cvar_t sv_clmovement_waitforinput;
+
#define MOVE_EPSILON 0.01
void SV_Physics_Toss (prvm_edict_t *ent);
Con_Print("\n");
#endif
+#if 0
if (trace.bmodelstartsolid)
{
// LordHavoc: note: this code is what makes entities stick in place
VectorClear(ent->fields.server->velocity);
return 3;
}
+#endif
// break if it moved the entire distance
if (trace.fraction == 1)
trace = SV_Move(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
}
*/
+
+ // LordHavoc: this came from QW and allows you to get out of water more easily
+ if (sv_gameplayfix_qwplayerphysics.integer && ((int)ent->fields.server->flags & FL_WATERJUMP))
+ VectorCopy(primal_velocity, ent->fields.server->velocity);
return blocked;
}
Does not change the entities velocity at all
============
*/
-trace_t SV_PushEntity (prvm_edict_t *ent, vec3_t push)
+static trace_t SV_PushEntity (prvm_edict_t *ent, vec3_t push, qboolean failonbmodelstartsolid)
{
int type;
trace_t trace;
type = MOVE_NORMAL;
trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, type, ent);
+ if (trace.bmodelstartsolid && failonbmodelstartsolid)
+ return trace;
VectorCopy (trace.endpos, ent->fields.server->origin);
SV_LinkEdict (ent, true);
continue;
// if the entity is standing on the pusher, it will definitely be moved
- if (!(((int)check->fields.server->flags & FL_ONGROUND) && PRVM_PROG_TO_EDICT(check->fields.server->groundentity) == pusher))
+ if (((int)check->fields.server->flags & FL_ONGROUND) && PRVM_PROG_TO_EDICT(check->fields.server->groundentity) == pusher)
{
- // if the entity is not inside the pusher's final position, leave it alone
- if (!SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
- continue;
// remove the onground flag for non-players
if (check->fields.server->movetype != MOVETYPE_WALK)
check->fields.server->flags = (int)check->fields.server->flags & ~FL_ONGROUND;
}
+ else
+ {
+ // if the entity is not inside the pusher's final position, leave it alone
+ if (!SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
+ continue;
+ }
if (forward[0] != 1 || left[1] != 1) // quick way to check if any rotation is used
// try moving the contacted entity
pusher->fields.server->solid = SOLID_NOT;
- trace = SV_PushEntity (check, move);
+ trace = SV_PushEntity (check, move, true);
// FIXME: turn players specially
check->fields.server->angles[1] += trace.fraction * moveangle[1];
pusher->fields.server->solid = savesolid; // was SOLID_BSP
+ //Con_Printf("%s:%d frac %f startsolid %d bmodelstartsolid %d allsolid %d\n", __FILE__, __LINE__, trace.fraction, trace.startsolid, trace.bmodelstartsolid, trace.allsolid);
// if it is still inside the pusher, block
if (SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
VectorScale(move, 1.1, move2);
VectorCopy (check->priv.server->moved_from, check->fields.server->origin);
VectorCopy (check->priv.server->moved_fromangles, check->fields.server->angles);
- SV_PushEntity (check, move2);
+ SV_PushEntity (check, move2, true);
pusher->fields.server->solid = savesolid;
if (SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
{
VectorScale(move, 0.9, move2);
VectorCopy (check->priv.server->moved_from, check->fields.server->origin);
VectorCopy (check->priv.server->moved_fromangles, check->fields.server->angles);
- SV_PushEntity (check, move2);
+ SV_PushEntity (check, move2, true);
pusher->fields.server->solid = savesolid;
if (SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
{
case 7: dir[0] = -2; dir[1] = -2; break;
}
- SV_PushEntity (ent, dir);
+ SV_PushEntity (ent, dir, false);
// retry the original move
ent->fields.server->velocity[0] = oldvel[0];
VectorClear (upmove);
upmove[2] = sv_stepheight.value;
// FIXME: don't link?
- SV_PushEntity(ent, upmove);
+ SV_PushEntity(ent, upmove, false);
// move forward
ent->fields.server->velocity[2] = 0;
VectorClear (downmove);
downmove[2] = -sv_stepheight.value + start_velocity[2]*sv.frametime;
// FIXME: don't link?
- downtrace = SV_PushEntity (ent, downmove);
+ downtrace = SV_PushEntity (ent, downmove, false);
if (downtrace.fraction < 1 && downtrace.plane.normal[2] > 0.7)
{
// if onground, return without moving
if ((int)ent->fields.server->flags & FL_ONGROUND)
{
- // don't stick to ground if onground and moving upward
- if (ent->fields.server->velocity[2] >= (1.0 / 32.0))
+ if (ent->fields.server->velocity[2] >= (1.0 / 32.0) && sv_gameplayfix_upwardvelocityclearsongroundflag.integer)
+ {
+ // don't stick to ground if onground and moving upward
ent->fields.server->flags -= FL_ONGROUND;
- else
+ }
+ else if (!ent->fields.server->groundentity || !sv_gameplayfix_noairborncorpse.integer)
+ {
+ // we can trust FL_ONGROUND if groundentity is world because it never moves
+ return;
+ }
+ else if (ent->priv.server->suspendedinairflag && PRVM_PROG_TO_EDICT(ent->fields.server->groundentity)->priv.server->free)
{
- prvm_edict_t *ground = PRVM_PROG_TO_EDICT(ent->fields.server->groundentity);
- if (ground->fields.server->solid == SOLID_BSP || !sv_gameplayfix_noairborncorpse.integer)
- return;
// if ent was supported by a brush model on previous frame,
- // and groundentity is now freed, set groundentity to 0 (floating)
- if (ent->priv.server->suspendedinairflag && ground->priv.server->free)
- {
- // leave it suspended in the air
- ent->fields.server->groundentity = 0;
- return;
- }
+ // and groundentity is now freed, set groundentity to 0 (world)
+ // which leaves it suspended in the air
+ ent->fields.server->groundentity = 0;
+ return;
}
}
ent->priv.server->suspendedinairflag = false;
// move origin
VectorScale (ent->fields.server->velocity, sv.frametime, move);
- trace = SV_PushEntity (ent, move);
+ trace = SV_PushEntity (ent, move, true);
if (ent->priv.server->free)
return;
if (trace.bmodelstartsolid)
{
// try to unstick the entity
SV_UnstickEntity(ent);
- trace = SV_PushEntity (ent, move);
+ trace = SV_PushEntity (ent, move, false);
if (ent->priv.server->free)
return;
}
if (flags & FL_ONGROUND)
{
// freefall if onground and moving upward
- // freefall if not standing on a world surface (it may be a lift)
- prvm_edict_t *ground = PRVM_PROG_TO_EDICT(ent->fields.server->groundentity);
- if (ent->fields.server->velocity[2] >= (1.0 / 32.0) || (ground->fields.server->solid != SOLID_BSP && sv_gameplayfix_noairborncorpse.integer))
+ // freefall if not standing on a world surface (it may be a lift or trap door)
+ if ((ent->fields.server->velocity[2] >= (1.0 / 32.0) && sv_gameplayfix_upwardvelocityclearsongroundflag.integer) || ent->fields.server->groundentity)
{
ent->fields.server->flags -= FL_ONGROUND;
SV_AddGravity(ent);
if (!host_client->spawned)
memset(&host_client->cmd, 0, sizeof(host_client->cmd));
// don't run physics here if running asynchronously
- else if (!host_client->movesequence)
+ else if (host_client->clmovement_skipphysicsframes > 0)
+ host_client->clmovement_skipphysicsframes--;
+ else
SV_Physics_ClientEntity(ent);
}
}