]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_phys.c
added prvm_offsets.h which centralizes field/global/function lookups for
[xonotic/darkplaces.git] / sv_phys.c
index 13a0cc15f14536d57a6fe23a5a07b10b42716952..343b1dc9c124b6a25280c5a443e46ab8b451f842 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -52,7 +52,7 @@ int SV_GetPitchSign(prvm_edict_t *ent)
                        model->type == mod_alias
                        :
                        (
-                        (((unsigned char)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.pflags)->_float) & PFLAGS_FULLDYNAMIC)
+                        (((unsigned char)PRVM_serveredictfloat(ent, pflags)) & PFLAGS_FULLDYNAMIC)
                         ||
                         ((gamemode == GAME_TENEBRAE) && ((unsigned int)ent->fields.server->effects & (16 | 32)))
                        )
@@ -71,12 +71,11 @@ LINE TESTING IN HULLS
 
 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_serveredictfloat(passedict, dphitcontentsmask);
+               if (dphitcontentsmask)
+                       return dphitcontentsmask;
                else if (passedict->fields.server->solid == SOLID_SLIDEBOX)
                {
                        if ((int)passedict->fields.server->flags & FL_MONSTER)
@@ -299,7 +298,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
 #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;
@@ -393,7 +392,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                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);
        }
@@ -702,7 +701,6 @@ Linking entities into the world culling system
 
 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;
@@ -715,14 +713,10 @@ void SV_LinkEdict_TouchAreaGrid_Call(prvm_edict_t *touch, prvm_edict_t *ent)
        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_serverglobalfloat(trace_dpstartcontents) = 0;
+       PRVM_serverglobalfloat(trace_dphitcontents) = 0;
+       PRVM_serverglobalfloat(trace_dphitq3surfaceflags) = 0;
+       PRVM_serverglobalstring(trace_dphittexturename) = 0;
        PRVM_ExecuteProgram (touch->fields.server->touch, "QC function self.touch is missing");
 }
 
@@ -1012,7 +1006,6 @@ returns true if entity had a valid contentstransition function call
 int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
 {
        int bValidFunctionCall;
-       prvm_eval_t *contentstransition;
 
        // Default Valid Function Call to False
        bValidFunctionCall = false;
@@ -1020,9 +1013,7 @@ int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
        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_serveredictfunction(ent, contentstransition))
                { // Valid Function; Execute
                        // Assign Valid Function
                        bValidFunctionCall = true;
@@ -1034,7 +1025,7 @@ int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
                                // Assign Self
                                prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
                        // Execute VM Function
-                       PRVM_ExecuteProgram(contentstransition->function, "contentstransition: NULL function");
+                       PRVM_ExecuteProgram(PRVM_serveredictfunction(ent, contentstransition), "contentstransition: NULL function");
                }
        }
 
@@ -1128,25 +1119,20 @@ qboolean SV_RunThink (prvm_edict_t *ent)
 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;
@@ -1165,22 +1151,16 @@ qboolean SV_Impact (prvm_edict_t *e1, trace_t *trace)
                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_serverglobalfloat(trace_dpstartcontents) = 0;
+               PRVM_serverglobalfloat(trace_dphitcontents) = 0;
+               PRVM_serverglobalfloat(trace_dphitq3surfaceflags) = 0;
+               PRVM_serverglobalstring(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);
 }
 
 
@@ -1236,6 +1216,11 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, flo
        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)
@@ -1298,12 +1283,24 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, flo
                        //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);
-                       SV_PushEntity(&steptrace, ent, steppush, false, false);
+                       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]);
-                       SV_PushEntity(&steptrace2, ent, push, false, false);
+                       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]);
-                       SV_PushEntity(&steptrace3, ent, steppush, false, false);
+                       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)
@@ -1436,13 +1433,10 @@ SV_Gravity
 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_serveredictfloat(ent, gravity);
+       if (!ent_gravity)
+               ent_gravity = 1.0f;
        return ent_gravity * sv_gravity.value * sv.frametime;
 }
 
@@ -1468,7 +1462,7 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q
 {
        int type;
        int bump;
-       vec3_t original;
+       vec3_t original, original_velocity;
        vec3_t end;
 
        VectorCopy(ent->fields.server->origin, original);
@@ -1498,8 +1492,11 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q
        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
@@ -1514,9 +1511,9 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q
                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);
 }
 
 
@@ -2507,11 +2504,10 @@ void SV_Physics_Toss (prvm_edict_t *ent)
                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_serveredictfloat(ent, 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;
@@ -2519,25 +2515,22 @@ void SV_Physics_Toss (prvm_edict_t *ent)
                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_serveredictfloat(ent, bouncefactor);
+                       if (!bouncefactor)
+                               bouncefactor = 0.5f;
 
-                       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.bouncestop);
-                       if (val!=0 && val->_float)
-                               bouncestop = val->_float;
+                       bouncestop = PRVM_serveredictfloat(ent, 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_serveredictfloat(ent, 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);
@@ -2613,7 +2606,6 @@ void SV_Physics_Step (prvm_edict_t *ent)
        // 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
@@ -2647,9 +2639,7 @@ void SV_Physics_Step (prvm_edict_t *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_serveredictfunction(ent, movetypesteplandevent))
                                { // Valid Function; Execute
                                        // Prepare Parameters
                                                // Assign Velocity at Impact
@@ -2659,7 +2649,7 @@ void SV_Physics_Step (prvm_edict_t *ent)
                                                // Assign Self
                                                prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
                                        // Execute VM Function
-                                       PRVM_ExecuteProgram(movetypesteplandevent->function, "movetypesteplandevent: NULL function");
+                                       PRVM_ExecuteProgram(PRVM_serveredictfunction(ent, movetypesteplandevent), "movetypesteplandevent: NULL function");
                                }
                                else
                                // Check for Engine Landing Sound
@@ -3000,12 +2990,12 @@ void SV_Physics (void)
                prog->globals.server->force_retouch = max(0, prog->globals.server->force_retouch - 1);
 
        // LordHavoc: endframe support
-       if (prog->funcoffsets.EndFrame)
+       if (PRVM_serverfunction(EndFrame))
        {
                prog->globals.server->self = PRVM_EDICT_TO_PROG(prog->edicts);
                prog->globals.server->other = PRVM_EDICT_TO_PROG(prog->edicts);
                prog->globals.server->time = sv.time;
-               PRVM_ExecuteProgram (prog->funcoffsets.EndFrame, "QC function EndFrame is missing");
+               PRVM_ExecuteProgram (PRVM_serverfunction(EndFrame), "QC function EndFrame is missing");
        }
 
        // decrement prog->num_edicts if the highest number entities died