cvar_t sv_maxvelocity = {"sv_maxvelocity","2000"};
cvar_t sv_nostep = {"sv_nostep","0"};
-static vec3_t vec_origin = {0.0, 0.0, 0.0};
-
#define MOVE_EPSILON 0.01
void SV_Physics_Toss (edict_t *ent);
eval_t *val;
val = GETEDICTFIELDVALUE(ent, eval_gravity);
- if (val && val->_float)
+ if (val!=0 && val->_float)
ent_gravity = val->_float;
else
ent_gravity = 1.0;
void SV_PushMove (edict_t *pusher, float movetime)
{
int i, e;
- edict_t *check, *block;
+ edict_t *check;
vec3_t mins, maxs, move;
vec3_t entorig, pushorig;
int num_moved;
vec3_t moved_from[MAX_EDICTS];
float savesolid;
+ switch ((int) pusher->v.solid)
+ {
+ // LordHavoc: valid pusher types
+ case SOLID_BSP:
+ case SOLID_BBOX:
+ case SOLID_SLIDEBOX:
+ case SOLID_CORPSE: // LordHavoc: this would be weird...
+ break;
+ // LordHavoc: no collisions
+ case SOLID_NOT:
+ case SOLID_TRIGGER:
+ VectorMA (pusher->v.origin, movetime, pusher->v.velocity, pusher->v.origin);
+ pusher->v.ltime += movetime;
+ SV_LinkEdict (pusher, false);
+ return;
+ default:
+ Host_Error("SV_PushMove: unrecognized solid type %f\n", pusher->v.solid);
+ }
if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])
{
pusher->v.ltime += movetime;
pusher->v.solid = savesolid; // was SOLID_BSP
// if it is still inside the pusher, block
- if (block = SV_TestEntityPosition (check))
+ if (SV_TestEntityPosition (check))
{ // fail the move
if (check->v.mins[0] == check->v.maxs[0])
continue;
SV_LinkEdict (pusher, false);
pusher->v.ltime -= movetime;
- // if the pusher has a "blocked" function, call it
- // otherwise, just stay in place until the obstacle is gone
+ // if the pusher has a "blocked" function, call it, otherwise just stay in place until the obstacle is gone
if (pusher->v.blocked)
{
pr_global_struct->self = EDICT_TO_PROG(pusher);
}
// move back any entities we already moved
+ num_moved--; // LordHavoc: pop off check, because it was already restored
for (i=0 ; i<num_moved ; i++)
{
VectorCopy (moved_from[i], moved_edict[i]->v.origin);
void SV_PushRotate (edict_t *pusher, float movetime)
{
int i, e;
- edict_t *check, *block;
+ edict_t *check;
vec3_t move, a, amove;
- vec3_t entorig, pushorig;
+ vec3_t entorigin, entangles, pushorigin, pushangles;
int num_moved;
edict_t *moved_edict[MAX_EDICTS];
vec3_t moved_from[MAX_EDICTS];
+ vec3_t angled_from[MAX_EDICTS];
vec3_t org, org2;
vec3_t forward, right, up;
float savesolid;
+ switch ((int) pusher->v.solid)
+ {
+ // LordHavoc: valid pusher types
+ case SOLID_BSP:
+ case SOLID_BBOX:
+ case SOLID_SLIDEBOX:
+ case SOLID_CORPSE: // LordHavoc: this would be weird...
+ break;
+ // LordHavoc: no collisions
+ case SOLID_NOT:
+ case SOLID_TRIGGER:
+ VectorMA (pusher->v.angles, movetime, pusher->v.avelocity, pusher->v.angles);
+ pusher->v.ltime += movetime;
+ SV_LinkEdict (pusher, false);
+ return;
+ default:
+ Host_Error("SV_PushRotate: unrecognized solid type %f\n", pusher->v.solid);
+ }
if (!pusher->v.avelocity[0] && !pusher->v.avelocity[1] && !pusher->v.avelocity[2])
{
pusher->v.ltime += movetime;
VectorSubtract (vec3_origin, amove, a);
AngleVectors (a, forward, right, up);
- VectorCopy (pusher->v.angles, pushorig);
+ VectorCopy (pusher->v.origin, pushorigin);
+ VectorCopy (pusher->v.angles, pushangles);
// move the pusher to it's final position
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)
+ || 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 (!(((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
if (check->v.movetype != MOVETYPE_WALK)
check->v.flags = (int)check->v.flags & ~FL_ONGROUND;
- VectorCopy (check->v.origin, entorig);
+ VectorCopy (check->v.origin, entorigin);
VectorCopy (check->v.origin, moved_from[num_moved]);
+ VectorCopy (check->v.angles, entangles);
+ VectorCopy (check->v.angles, angled_from[num_moved]);
moved_edict[num_moved] = check;
num_moved++;
SV_PushEntity (check, move);
pusher->v.solid = savesolid; // LordHavoc: restore to correct solid type
+ VectorAdd (check->v.angles, amove, check->v.angles);
+
// if it is still inside the pusher, block
- block = SV_TestEntityPosition (check);
- if (block)
+ if (SV_TestEntityPosition (check))
{ // fail the move
if (check->v.mins[0] == check->v.maxs[0])
continue;
continue;
}
- VectorCopy (entorig, check->v.origin);
+ VectorCopy (entorigin, check->v.origin);
+ VectorCopy (entangles, check->v.angles);
SV_LinkEdict (check, true);
- VectorCopy (pushorig, pusher->v.angles);
+ VectorCopy (pushorigin, pusher->v.origin);
+ VectorCopy (pushangles, pusher->v.angles);
SV_LinkEdict (pusher, false);
pusher->v.ltime -= movetime;
- // if the pusher has a "blocked" function, call it
- // otherwise, just stay in place until the obstacle is gone
+ // if the pusher has a "blocked" function, call it, otherwise just stay in place until the obstacle is gone
if (pusher->v.blocked)
{
pr_global_struct->self = EDICT_TO_PROG(pusher);
}
// move back any entities we already moved
+ num_moved--; // LordHavoc: pop off check, because it was already restored
for (i=0 ; i<num_moved ; i++)
{
VectorCopy (moved_from[i], moved_edict[i]->v.origin);
- VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles);
+ VectorCopy (angled_from[i], moved_edict[i]->v.angles);
SV_LinkEdict (moved_edict[i], false);
}
return;
}
- else
- {
- VectorAdd (check->v.angles, amove, check->v.angles);
- }
}
-
-
}
-//#endif
/*
================
*/
void SV_Physics_Follow (edict_t *ent)
{
- vec3_t vf, vu, vr, angles;
+ vec3_t vf, vr, vu, angles;
edict_t *e;
// regular thinking
- SV_RunThink (ent);
+ if (!SV_RunThink (ent))
+ return;
// LordHavoc: implemented rotation on MOVETYPE_FOLLOW objects
e = PROG_TO_EDICT(ent->v.aiment);
- angles[0] = -e->v.angles[0];
- angles[1] = e->v.angles[1];
- angles[2] = e->v.angles[2];
- AngleVectors (angles, vf, vr, vu);
- VectorMA (e->v.origin, ent->v.view_ofs[0], vf, ent->v.origin);
- VectorMA (ent->v.origin, ent->v.view_ofs[1], vr, ent->v.origin);
- VectorMA (ent->v.origin, ent->v.view_ofs[2], vu, ent->v.origin);
+ if (e->v.angles[0] == ent->v.punchangle[0] && e->v.angles[1] == ent->v.punchangle[1] && e->v.angles[2] == ent->v.punchangle[2])
+ {
+ // quick case for no rotation
+ VectorAdd(e->v.origin, ent->v.view_ofs, ent->v.origin);
+ }
+ else
+ {
+ angles[0] = -(e->v.angles[0] - ent->v.punchangle[0]);
+ angles[1] = e->v.angles[1] - ent->v.punchangle[1];
+ angles[2] = e->v.angles[2] - ent->v.punchangle[2];
+ AngleVectors (angles, vf, vr, vu);
+ ent->v.origin[0] = ent->v.view_ofs[0] * vf[0] + ent->v.view_ofs[1] * vr[0] + ent->v.view_ofs[2] * vu[0] + e->v.origin[0];
+ ent->v.origin[1] = ent->v.view_ofs[0] * vf[1] + ent->v.view_ofs[1] * vr[1] + ent->v.view_ofs[2] * vu[1] + e->v.origin[1];
+ ent->v.origin[2] = ent->v.view_ofs[0] * vf[2] + ent->v.view_ofs[1] * vr[2] + ent->v.view_ofs[2] * vu[2] + e->v.origin[2];
+ /*
+ ent->v.origin[0] = ent->v.view_ofs[0] * vf[0] + ent->v.view_ofs[0] * vf[1] + ent->v.view_ofs[0] * vf[2] + e->v.origin[0];
+ ent->v.origin[1] = ent->v.view_ofs[1] * vr[0] + ent->v.view_ofs[1] * vr[1] + ent->v.view_ofs[1] * vr[2] + e->v.origin[1];
+ ent->v.origin[2] = ent->v.view_ofs[2] * vu[0] + ent->v.view_ofs[2] * vu[1] + ent->v.view_ofs[2] * vu[2] + e->v.origin[2];
+ */
+ }
VectorAdd (e->v.angles, ent->v.v_angle, ent->v.angles);
// VectorAdd (PROG_TO_EDICT(ent->v.aiment)->v.origin, ent->v.v_angle, ent->v.origin);
SV_LinkEdict (ent, true);
continue;
if (pr_global_struct->force_retouch)
- {
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)
+ continue;
+ }
+
+ switch ((int) ent->v.movetype)
+ {
+ case MOVETYPE_PUSH:
SV_Physics_Pusher (ent);
- else if (ent->v.movetype == MOVETYPE_NONE)
+ break;
+ case MOVETYPE_NONE:
SV_Physics_None (ent);
- else if (ent->v.movetype == MOVETYPE_FOLLOW)
+ break;
+ case MOVETYPE_FOLLOW:
SV_Physics_Follow (ent);
- else if (ent->v.movetype == MOVETYPE_NOCLIP)
+ break;
+ case MOVETYPE_NOCLIP:
SV_Physics_Noclip (ent);
- else if (ent->v.movetype == MOVETYPE_STEP)
+ break;
+ case MOVETYPE_STEP:
SV_Physics_Step (ent);
+ break;
// LordHavoc: added support for MOVETYPE_WALK on normal entities! :)
- else if (ent->v.movetype == MOVETYPE_WALK)
- {
+ case MOVETYPE_WALK:
if (SV_RunThink (ent))
{
if (!SV_CheckWater (ent) && ! ((int)ent->v.flags & FL_WATERJUMP) )
SV_CheckStuck (ent);
SV_WalkMove (ent);
}
- }
- 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)
+ break;
+ case MOVETYPE_TOSS:
+ case MOVETYPE_BOUNCE:
+ case MOVETYPE_BOUNCEMISSILE:
+ case MOVETYPE_FLY:
+ case MOVETYPE_FLYMISSILE:
SV_Physics_Toss (ent);
- else
- Host_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype);
+ break;
+ default:
+ Host_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype);
+ break;
+ }
}
if (pr_global_struct->force_retouch)