model->type == mod_alias
:
(
- (((unsigned char)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.pflags)->_float) & PFLAGS_FULLDYNAMIC)
+ (((unsigned char)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.pflags)) & PFLAGS_FULLDYNAMIC)
||
((gamemode == GAME_TENEBRAE) && ((unsigned int)ent->fields.server->effects & (16 | 32)))
)
int SV_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
{
- prvm_eval_t *val;
if (passedict)
{
- val = PRVM_EDICTFIELDVALUE(passedict, prog->fieldoffsets.dphitcontentsmask);
- if (val && val->_float)
- return (int)val->_float;
+ int dphitcontentsmask = (int)PRVM_EDICTFIELDFLOAT(passedict, prog->fieldoffsets.dphitcontentsmask);
+ if (dphitcontentsmask)
+ return dphitcontentsmask;
else if (passedict->fields.server->solid == SOLID_SLIDEBOX)
{
if ((int)passedict->fields.server->flags & FL_MONSTER)
dp_model_t *model;
// list of entities to test for collisions
int numtouchedicts;
- prvm_edict_t *touchedicts[MAX_EDICTS];
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
//return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask);
dp_model_t *model;
// list of entities to test for collisions
int numtouchedicts;
- prvm_edict_t *touchedicts[MAX_EDICTS];
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
vec3_t end;
vec_t len = 0;
- if(!VectorCompare(start, pEnd))
+ if (VectorCompare(start, pEnd))
+ return SV_TracePoint(start, type, passedict, hitsupercontentsmask);
+
+ if(collision_endposnudge.value > 0)
{
// TRICK: make the trace 1 qu longer!
VectorSubtract(pEnd, start, end);
len = VectorNormalizeLength(end);
- VectorAdd(pEnd, end, end);
+ VectorMA(pEnd, collision_endposnudge.value, end, end);
}
else
VectorCopy(pEnd, end);
+#else
+ if (VectorCompare(start, end))
+ return SV_TracePoint(start, type, passedict, hitsupercontentsmask);
#endif
//return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask);
- if (VectorCompare(start, end))
- return SV_TracePoint(start, type, passedict, hitsupercontentsmask);
-
VectorCopy(start, clipstart);
VectorCopy(end, clipend);
VectorClear(clipmins2);
#endif
// clip to world
- Collision_ClipLineToWorld(&cliptrace, sv.worldmodel, clipstart, clipend, hitsupercontentsmask);
+ Collision_ClipLineToWorld(&cliptrace, sv.worldmodel, clipstart, clipend, hitsupercontentsmask, false);
cliptrace.bmodelstartsolid = cliptrace.startsolid;
if (cliptrace.startsolid || cliptrace.fraction < 1)
cliptrace.ent = prog->edicts;
if (type == MOVE_MISSILE && (int)touch->fields.server->flags & FL_MONSTER)
Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
else
- Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask);
+ Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, false);
Collision_CombineTraces(&cliptrace, &trace, (void *)touch, touch->fields.server->solid == SOLID_BSP);
}
finished:
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
- if(!VectorCompare(start, pEnd))
- Collision_ShortenTrace(&cliptrace, len / (len + 1), pEnd);
+ if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0)
+ Collision_ShortenTrace(&cliptrace, len / (len + collision_endposnudge.value), pEnd);
#endif
return cliptrace;
}
dp_model_t *model;
// list of entities to test for collisions
int numtouchedicts;
- prvm_edict_t *touchedicts[MAX_EDICTS];
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
vec3_t end;
vec_t len = 0;
- if(!VectorCompare(start, pEnd))
+ if (VectorCompare(mins, maxs))
+ {
+ vec3_t shiftstart, shiftend;
+ VectorAdd(start, mins, shiftstart);
+ VectorAdd(pEnd, mins, shiftend);
+ if (VectorCompare(start, pEnd))
+ trace = SV_TracePoint(shiftstart, type, passedict, hitsupercontentsmask);
+ else
+ trace = SV_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask);
+ VectorSubtract(trace.endpos, mins, trace.endpos);
+ return trace;
+ }
+
+ if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0)
{
// TRICK: make the trace 1 qu longer!
VectorSubtract(pEnd, start, end);
len = VectorNormalizeLength(end);
- VectorAdd(pEnd, end, end);
+ VectorMA(pEnd, collision_endposnudge.value, end, end);
}
else
VectorCopy(pEnd, end);
-#endif
-
+#else
if (VectorCompare(mins, maxs))
{
vec3_t shiftstart, shiftend;
VectorSubtract(trace.endpos, mins, trace.endpos);
return trace;
}
+#endif
VectorCopy(start, clipstart);
VectorCopy(end, clipend);
finished:
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
- if(!VectorCompare(start, pEnd))
- Collision_ShortenTrace(&cliptrace, len / (len + 1), pEnd);
+ if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0)
+ Collision_ShortenTrace(&cliptrace, len / (len + collision_endposnudge.value), pEnd);
#endif
return cliptrace;
}
int frame;
// list of entities to test for collisions
int numtouchedicts;
- prvm_edict_t *touchedicts[MAX_EDICTS];
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
// get world supercontents at this point
if (sv.worldmodel && sv.worldmodel->PointSuperContents)
void SV_LinkEdict_TouchAreaGrid_Call(prvm_edict_t *touch, prvm_edict_t *ent)
{
- prvm_eval_t *val;
prog->globals.server->self = PRVM_EDICT_TO_PROG(touch);
prog->globals.server->other = PRVM_EDICT_TO_PROG(ent);
prog->globals.server->time = sv.time;
VectorSet (prog->globals.server->trace_plane_normal, 0, 0, 1);
prog->globals.server->trace_plane_dist = 0;
prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(ent);
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
- val->_float = 0;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents)))
- val->_float = 0;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags)))
- val->_float = 0;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename)))
- val->string = 0;
+ PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dpstartcontents) = 0;
+ PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitcontents) = 0;
+ PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitq3surfaceflags) = 0;
+ PRVM_GLOBALFIELDSTRING(prog->globaloffsets.trace_dphittexturename) = 0;
PRVM_ExecuteProgram (touch->fields.server->touch, "QC function self.touch is missing");
}
void SV_LinkEdict_TouchAreaGrid(prvm_edict_t *ent)
{
int i, numtouchedicts, old_self, old_other;
- prvm_edict_t *touch, *touchedicts[MAX_EDICTS];
+ prvm_edict_t *touch;
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
if (ent == prog->edicts)
return; // don't add the world
{
if (model != NULL)
{
- if (!model->TraceBox && developer.integer >= 1)
- Con_Printf("edict %i: SOLID_BSP with non-collidable model\n", PRVM_NUM_FOR_EDICT(ent));
+ if (!model->TraceBox)
+ Con_DPrintf("edict %i: SOLID_BSP with non-collidable model\n", PRVM_NUM_FOR_EDICT(ent));
if (ent->fields.server->angles[0] || ent->fields.server->angles[2] || ent->fields.server->avelocity[0] || ent->fields.server->avelocity[2])
{
int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
{
int bValidFunctionCall;
- prvm_eval_t *contentstransition;
// Default Valid Function Call to False
bValidFunctionCall = false;
if(ent->fields.server->watertype != nContents)
{ // Changed Contents
// Acquire Contents Transition Function from QC
- contentstransition = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.contentstransition);
-
- if(contentstransition->function)
+ if(PRVM_EDICTFIELDFUNCTION(ent, prog->fieldoffsets.contentstransition))
{ // Valid Function; Execute
// Assign Valid Function
bValidFunctionCall = true;
// Assign Self
prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
// Execute VM Function
- PRVM_ExecuteProgram(contentstransition->function, "contentstransition: NULL function");
+ PRVM_ExecuteProgram(PRVM_EDICTFIELDFUNCTION(ent, prog->fieldoffsets.contentstransition), "contentstransition: NULL function");
}
}
SV_Impact
Two entities have touched, so run their touch functions
-returns true if the impact kept the origin of the touching entity intact
==================
*/
extern void VM_SetTraceGlobals(const trace_t *trace);
extern sizebuf_t vm_tempstringsbuf;
-qboolean SV_Impact (prvm_edict_t *e1, trace_t *trace)
+void SV_Impact (prvm_edict_t *e1, trace_t *trace)
{
int restorevm_tempstringsbuf_cursize;
int old_self, old_other;
- vec3_t org;
prvm_edict_t *e2 = (prvm_edict_t *)trace->ent;
- prvm_eval_t *val;
old_self = prog->globals.server->self;
old_other = prog->globals.server->other;
restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
- VectorCopy(e1->fields.server->origin, org);
-
VM_SetTraceGlobals(trace);
prog->globals.server->time = sv.time;
VectorNegate(trace->plane.normal, prog->globals.server->trace_plane_normal);
prog->globals.server->trace_plane_dist = -trace->plane.dist;
prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(e1);
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
- val->_float = 0;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents)))
- val->_float = 0;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags)))
- val->_float = 0;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename)))
- val->string = 0;
+ PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dpstartcontents) = 0;
+ PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitcontents) = 0;
+ PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitq3surfaceflags) = 0;
+ PRVM_GLOBALFIELDSTRING(prog->globaloffsets.trace_dphittexturename) = 0;
PRVM_ExecuteProgram (e2->fields.server->touch, "QC function self.touch is missing");
}
prog->globals.server->self = old_self;
prog->globals.server->other = old_other;
vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
-
- return VectorCompare(e1->fields.server->origin, org);
}
static float SV_Gravity (prvm_edict_t *ent);
static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean failonbmodelstartsolid, qboolean dolink);
#define MAX_CLIP_PLANES 5
-static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, float *stepnormal, int hitsupercontentsmask)
+static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, float *stepnormal, int hitsupercontentsmask, float stepheight)
{
int blocked, bumpcount;
int i, j, numplanes;
if (time <= 0)
return 0;
gravity = 0;
+
+ if(sv_gameplayfix_nogravityonground.integer)
+ if((int)ent->fields.server->flags & FL_ONGROUND)
+ applygravity = false;
+
if (applygravity)
{
if (sv_gameplayfix_gravityunaffectedbyticrate.integer)
break;
VectorScale(ent->fields.server->velocity, time_left, push);
-#if 0
- VectorAdd(ent->fields.server->origin, push, end);
-#endif
if(!SV_PushEntity(&trace, ent, push, false, false))
{
// we got teleported by a touch function
break;
}
-#if 0
- //if (trace.fraction < 0.002)
- {
-#if 1
- vec3_t start;
- trace_t testtrace;
- VectorCopy(ent->fields.server->origin, start);
- start[2] += 3;//0.03125;
- VectorMA(ent->fields.server->origin, time_left, ent->fields.server->velocity, end);
- end[2] += 3;//0.03125;
- testtrace = SV_TraceBox(start, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, hitsupercontentsmask);
- if (trace.fraction < testtrace.fraction && !testtrace.startsolid && (testtrace.fraction == 1 || DotProduct(trace.plane.normal, ent->fields.server->velocity) < DotProduct(testtrace.plane.normal, ent->fields.server->velocity)))
- {
- Con_Printf("got further (new %f > old %f)\n", testtrace.fraction, trace.fraction);
- trace = testtrace;
- }
-#endif
-#if 0
- //j = -1;
- for (i = 0;i < numplanes;i++)
- {
- VectorCopy(ent->fields.server->origin, start);
- VectorMA(ent->fields.server->origin, time_left, ent->fields.server->velocity, end);
- VectorMA(start, 3, planes[i], start);
- VectorMA(end, 3, planes[i], end);
- testtrace = SV_TraceBox(start, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, hitsupercontentsmask);
- if (trace.fraction < testtrace.fraction)
- {
- trace = testtrace;
- VectorCopy(start, ent->fields.server->origin);
- //j = i;
- }
- }
- //if (j >= 0)
- // VectorAdd(ent->fields.server->origin, planes[j], start);
-#endif
- }
-#endif
-
-#if 0
- Con_Printf("entity %i bump %i: velocity %f %f %f trace %f", ent - prog->edicts, bumpcount, ent->fields.server->velocity[0], ent->fields.server->velocity[1], ent->fields.server->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
-
-#if 0
- if (trace.bmodelstartsolid)
- {
- // LordHavoc: note: this code is what makes entities stick in place
- // if embedded in world only (you can walk through other objects if
- // stuck)
- // entity is trapped in another solid
- VectorClear(ent->fields.server->velocity);
- return 3;
- }
-#endif
-
if (trace.fraction == 1)
break;
if (trace.plane.normal[2])
ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
}
}
+ else if (stepheight)
+ {
+ // step - handle it immediately
+ vec3_t org;
+ vec3_t steppush;
+ trace_t steptrace;
+ trace_t steptrace2;
+ trace_t steptrace3;
+ //Con_Printf("step %f %f %f : ", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
+ VectorSet(steppush, 0, 0, stepheight);
+ VectorCopy(ent->fields.server->origin, org);
+ if(!SV_PushEntity(&steptrace, ent, steppush, false, false))
+ {
+ blocked |= 8;
+ break;
+ }
+ //Con_Printf("%f %f %f : ", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
+ if(!SV_PushEntity(&steptrace2, ent, push, false, false))
+ {
+ blocked |= 8;
+ break;
+ }
+ //Con_Printf("%f %f %f : ", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
+ VectorSet(steppush, 0, 0, org[2] - ent->fields.server->origin[2]);
+ if(!SV_PushEntity(&steptrace3, ent, steppush, false, false))
+ {
+ blocked |= 8;
+ break;
+ }
+ //Con_Printf("%f %f %f : ", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
+ // accept the new position if it made some progress...
+ if (fabs(ent->fields.server->origin[0] - org[0]) >= 0.03125 || fabs(ent->fields.server->origin[1] - org[1]) >= 0.03125)
+ {
+ //Con_Printf("accepted (delta %f %f %f)\n", ent->fields.server->origin[0] - org[0], ent->fields.server->origin[1] - org[1], ent->fields.server->origin[2] - org[2]);
+ trace = steptrace2;
+ VectorCopy(ent->fields.server->origin, trace.endpos);
+ time_left *= 1 - trace.fraction;
+ numplanes = 0;
+ continue;
+ }
+ else
+ {
+ //Con_Printf("REJECTED (delta %f %f %f)\n", ent->fields.server->origin[0] - org[0], ent->fields.server->origin[1] - org[1], ent->fields.server->origin[2] - org[2]);
+ VectorCopy(org, ent->fields.server->origin);
+ }
+ }
else
{
- // step
+ // step - return it to caller
blocked |= 2;
// save the trace for player extrafriction
if (stepnormal)
VectorCopy(trace.plane.normal, planes[numplanes]);
numplanes++;
- if (sv_newflymove.integer)
- ClipVelocity(ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 1);
- else
+ // modify original_velocity so it parallels all of the clip planes
+ for (i = 0;i < numplanes;i++)
{
- // 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++)
{
- ClipVelocity(original_velocity, planes[i], new_velocity, 1);
- for (j = 0;j < numplanes;j++)
+ if (j != i)
{
- if (j != i)
- {
- // not ok
- if (DotProduct(new_velocity, planes[j]) < 0)
- break;
- }
+ // not ok
+ if (DotProduct(new_velocity, planes[j]) < 0)
+ break;
}
- if (j == numplanes)
- break;
}
+ if (j == numplanes)
+ break;
+ }
- if (i != numplanes)
- {
- // go along this plane
- VectorCopy(new_velocity, ent->fields.server->velocity);
- }
- else
+ if (i != numplanes)
+ {
+ // go along this plane
+ VectorCopy(new_velocity, ent->fields.server->velocity);
+ }
+ else
+ {
+ // go along the crease
+ if (numplanes != 2)
{
- // go along the crease
- if (numplanes != 2)
- {
- VectorClear(ent->fields.server->velocity);
- blocked = 7;
- break;
- }
- 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->fields.server->velocity);
- VectorScale(dir, d, ent->fields.server->velocity);
+ VectorClear(ent->fields.server->velocity);
+ blocked = 7;
+ break;
}
+ 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->fields.server->velocity);
+ VectorScale(dir, d, ent->fields.server->velocity);
}
// if current velocity is against the original velocity,
static float SV_Gravity (prvm_edict_t *ent)
{
float ent_gravity;
- prvm_eval_t *val;
- val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.gravity);
- if (val!=0 && val->_float)
- ent_gravity = val->_float;
- else
- ent_gravity = 1.0;
+ ent_gravity = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.gravity);
+ if (!ent_gravity)
+ ent_gravity = 1.0f;
return ent_gravity * sv_gravity.value * sv.frametime;
}
{
int type;
int bump;
- vec3_t original;
+ vec3_t original, original_velocity;
vec3_t end;
VectorCopy(ent->fields.server->origin, original);
*trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent));
bump = 0;
- while (trace->startsolid && sv_gameplayfix_nudgeoutofsolid.integer)
+ while (trace->bmodelstartsolid && sv_gameplayfix_nudgeoutofsolid.integer)
{
vec_t nudge = -trace->startdepth + sv_gameplayfix_nudgeoutofsolid_bias.value;
VectorMA(ent->fields.server->origin, nudge, trace->startdepthnormal, ent->fields.server->origin);
if (trace->bmodelstartsolid && failonbmodelstartsolid)
return true;
-
VectorCopy (trace->endpos, ent->fields.server->origin);
+
+ VectorCopy(ent->fields.server->origin, original);
+ VectorCopy(ent->fields.server->velocity, original_velocity);
+
SV_LinkEdict(ent);
#if 0
SV_LinkEdict_TouchAreaGrid(ent);
if((ent->fields.server->solid >= SOLID_TRIGGER && trace->ent && (!((int)ent->fields.server->flags & FL_ONGROUND) || ent->fields.server->groundentity != PRVM_EDICT_TO_PROG(trace->ent))))
- return SV_Impact (ent, trace);
+ SV_Impact (ent, trace);
- return true;
+ return VectorCompare(ent->fields.server->origin, original) && VectorCompare(ent->fields.server->velocity, original_velocity);
}
dp_model_t *pushermodel;
trace_t trace, trace2;
matrix4x4_t pusherfinalmatrix, pusherfinalimatrix;
- unsigned short moved_edicts[MAX_EDICTS];
+ static unsigned short moved_edicts[MAX_EDICTS];
if (!pusher->fields.server->velocity[0] && !pusher->fields.server->velocity[1] && !pusher->fields.server->velocity[2] && !pusher->fields.server->avelocity[0] && !pusher->fields.server->avelocity[1] && !pusher->fields.server->avelocity[2])
{
Con_DPrintf("Unstuck entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname), offset[0], offset[1], offset[2]);
return true;
case UNSTICK_STUCK:
- if (developer.integer >= 100)
- Con_Printf("Stuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname));
+ if (developer_extra.integer)
+ Con_DPrintf("Stuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname));
return false;
default:
Con_Printf("SV_UnstickEntityReturnOffset returned a value outside its enum.\n");
*/
void SV_WalkMove (prvm_edict_t *ent)
{
- int clip, oldonground, originalmove_clip, originalmove_flags, originalmove_groundentity, hitsupercontentsmask;
+ int clip;
+ int oldonground;
+ //int originalmove_clip;
+ int originalmove_flags;
+ int originalmove_groundentity;
+ int hitsupercontentsmask;
+ int type;
vec3_t upmove, downmove, start_origin, start_velocity, stepnormal, originalmove_origin, originalmove_velocity;
trace_t downtrace, trace;
qboolean applygravity;
VectorCopy (ent->fields.server->origin, start_origin);
VectorCopy (ent->fields.server->velocity, start_velocity);
- clip = SV_FlyMove (ent, sv.frametime, applygravity, NULL, hitsupercontentsmask);
+ clip = SV_FlyMove (ent, sv.frametime, applygravity, NULL, hitsupercontentsmask, sv_gameplayfix_stepmultipletimes.integer ? sv_stepheight.value : 0);
+
+ if(sv_gameplayfix_downtracesupportsongroundflag.integer)
+ if(!(clip & 1))
+ {
+ // only try this if there was no floor in the way in the trace (no,
+ // this check seems to be not REALLY necessary, because if clip & 1,
+ // our trace will hit that thing too)
+ VectorSet(upmove, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + 1);
+ VectorSet(downmove, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] - 1);
+ if (ent->fields.server->movetype == MOVETYPE_FLYMISSILE)
+ type = MOVE_MISSILE;
+ else if (ent->fields.server->solid == SOLID_TRIGGER || ent->fields.server->solid == SOLID_NOT)
+ type = MOVE_NOMONSTERS; // only clip against bmodels
+ else
+ type = MOVE_NORMAL;
+ trace = SV_TraceBox(upmove, ent->fields.server->mins, ent->fields.server->maxs, downmove, type, ent, SV_GenericHitSuperContentsMask(ent));
+ if(trace.fraction < 1 && trace.plane.normal[2] > 0.7)
+ clip |= 1; // but we HAVE found a floor
+ }
// if the move did not hit the ground at any point, we're not on ground
- if (!(clip & 1))
+ if(!(clip & 1))
ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
SV_CheckVelocity(ent);
VectorCopy(ent->fields.server->origin, originalmove_origin);
VectorCopy(ent->fields.server->velocity, originalmove_velocity);
- originalmove_clip = clip;
+ //originalmove_clip = clip;
originalmove_flags = (int)ent->fields.server->flags;
originalmove_groundentity = ent->fields.server->groundentity;
// move forward
ent->fields.server->velocity[2] = 0;
- clip = SV_FlyMove (ent, sv.frametime, applygravity, stepnormal, hitsupercontentsmask);
+ clip = SV_FlyMove (ent, sv.frametime, applygravity, stepnormal, hitsupercontentsmask, 0);
ent->fields.server->velocity[2] += start_velocity[2];
if(clip & 8)
{
movetime *= 1 - min(1, trace.fraction);
if (ent->fields.server->movetype == MOVETYPE_BOUNCEMISSILE)
{
- prvm_eval_t *val;
- float bouncefactor = 1.0f;
- val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.bouncefactor);
- if (val!=0 && val->_float)
- bouncefactor = val->_float;
+ float bouncefactor;
+ bouncefactor = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.bouncefactor);
+ if (!bouncefactor)
+ bouncefactor = 1.0f;
ClipVelocity (ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 1 + bouncefactor);
ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
else if (ent->fields.server->movetype == MOVETYPE_BOUNCE)
{
float d, ent_gravity;
- prvm_eval_t *val;
- float bouncefactor = 0.5f;
- float bouncestop = 60.0f / 800.0f;
+ float bouncefactor;
+ float bouncestop;
- val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.bouncefactor);
- if (val!=0 && val->_float)
- bouncefactor = val->_float;
+ bouncefactor = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.bouncefactor);
+ if (!bouncefactor)
+ bouncefactor = 0.5f;
- val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.bouncestop);
- if (val!=0 && val->_float)
- bouncestop = val->_float;
+ bouncestop = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.bouncestop);
+ if (!bouncestop)
+ bouncestop = 60.0f / 800.0f;
ClipVelocity (ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 1 + bouncefactor);
+ ent_gravity = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.gravity);
+ if (!ent_gravity)
+ ent_gravity = 1.0f;
// LordHavoc: fixed grenades not bouncing when fired down a slope
- val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.gravity);
- if (val!=0 && val->_float)
- ent_gravity = val->_float;
- else
- ent_gravity = 1.0;
if (sv_gameplayfix_grenadebouncedownslopes.integer)
{
d = DotProduct(trace.plane.normal, ent->fields.server->velocity);
// DRESK
// Backup Velocity in the event that movetypesteplandevent is called,
// to provide a parameter with the entity's velocity at impact.
- prvm_eval_t *movetypesteplandevent;
vec3_t backupVelocity;
VectorCopy(ent->fields.server->velocity, backupVelocity);
// don't fall at all if fly/swim
{
ent->fields.server->flags -= FL_ONGROUND;
SV_CheckVelocity(ent);
- SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent));
+ SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0);
SV_LinkEdict(ent);
SV_LinkEdict_TouchAreaGrid(ent);
ent->priv.server->waterposition_forceupdate = true;
int hitsound = ent->fields.server->velocity[2] < sv_gravity.value * -0.1;
SV_CheckVelocity(ent);
- SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent));
+ SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0);
SV_LinkEdict(ent);
SV_LinkEdict_TouchAreaGrid(ent);
if (hitsound && (int)ent->fields.server->flags & FL_ONGROUND)
{
// DRESK - Check for Entity Land Event Function
- movetypesteplandevent = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.movetypesteplandevent);
-
- if(movetypesteplandevent->function)
+ if(PRVM_EDICTFIELDFUNCTION(ent, prog->fieldoffsets.movetypesteplandevent))
{ // Valid Function; Execute
// Prepare Parameters
// Assign Velocity at Impact
// Assign Self
prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
// Execute VM Function
- PRVM_ExecuteProgram(movetypesteplandevent->function, "movetypesteplandevent: NULL function");
+ PRVM_ExecuteProgram(PRVM_EDICTFIELDFUNCTION(ent, prog->fieldoffsets.movetypesteplandevent), "movetypesteplandevent: NULL function");
}
else
// Check for Engine Landing Sound