]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_phys.c
implemented r_transparent_alphatocoverage 2 which promotes alphablend if
[xonotic/darkplaces.git] / sv_phys.c
index 7558be896a987111e13bffa2f26f8f174138c480..61a5dc4e59d9a33ed5ed8defdd4f71f0fc99cd52 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)
@@ -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");
                }
        }
 
@@ -1137,7 +1128,6 @@ void SV_Impact (prvm_edict_t *e1, trace_t *trace)
        int restorevm_tempstringsbuf_cursize;
        int old_self, old_other;
        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;
@@ -1161,14 +1151,10 @@ void 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");
        }
 
@@ -1447,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;
 }
 
@@ -1477,39 +1460,68 @@ Returns true if the push did not result in the entity being teleported by QC cod
 */
 static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean failonbmodelstartsolid, qboolean dolink)
 {
+       int solid;
+       int movetype;
        int type;
        int bump;
+       vec3_t mins, maxs;
        vec3_t original, original_velocity;
+       vec3_t start;
        vec3_t end;
 
-       VectorCopy(ent->fields.server->origin, original);
-       VectorAdd (ent->fields.server->origin, push, end);
+       solid = (int)ent->fields.server->solid;
+       movetype = (int)ent->fields.server->movetype;
+       VectorCopy(ent->fields.server->mins, mins);
+       VectorCopy(ent->fields.server->maxs, maxs);
+
+       // move start position out of solids
+       if (sv_gameplayfix_nudgeoutofsolid.integer && sv_gameplayfix_nudgeoutofsolid_separation.value >= 0)
+       {
+               trace_t stucktrace;
+               vec3_t stuckorigin;
+               vec3_t stuckmins, stuckmaxs;
+               vec_t nudge;
+               vec_t separation = sv_gameplayfix_nudgeoutofsolid_separation.value;
+               if (sv.worldmodel && sv.worldmodel->brushq1.numclipnodes)
+                       separation = 0.0f; // when using hulls, it can not be enlarged
+               VectorCopy(ent->fields.server->origin, stuckorigin);
+               VectorCopy(mins, stuckmins);
+               VectorCopy(maxs, stuckmaxs);
+               stuckmins[0] -= separation;
+               stuckmins[1] -= separation;
+               stuckmins[2] -= separation;
+               stuckmaxs[0] += separation;
+               stuckmaxs[1] += separation;
+               stuckmaxs[2] += separation;
+               for (bump = 0;bump < 10;bump++)
+               {
+                       stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent));
+                       if (!stucktrace.bmodelstartsolid || stucktrace.startdepth >= 0)
+                       {
+                               // found a good location, use it
+                               VectorCopy(stuckorigin, ent->fields.server->origin);
+                               break;
+                       }
+                       nudge = -stucktrace.startdepth;
+                       VectorMA(stuckorigin, nudge, stucktrace.startdepthnormal, stuckorigin);
+               }
+       }
+
+       VectorCopy(ent->fields.server->origin, start);
+       VectorAdd(start, push, end);
 
-       if (ent->fields.server->movetype == MOVETYPE_FLYMISSILE)
+       if (movetype == MOVETYPE_FLYMISSILE)
                type = MOVE_MISSILE;
-       else if (ent->fields.server->solid == SOLID_TRIGGER || ent->fields.server->solid == SOLID_NOT)
+       else if (solid == SOLID_TRIGGER || solid == SOLID_NOT)
                type = MOVE_NOMONSTERS; // only clip against bmodels
        else
                type = MOVE_NORMAL;
 
-       *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->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);
-               *trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent));
-               bump++;
-               if (bump > 10)
-               {
-                       VectorCopy(original, ent->fields.server->origin);
-                       break;
-               }
-       }
+       *trace = SV_TraceBox(start, mins, maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent));
        if (trace->bmodelstartsolid && failonbmodelstartsolid)
                return true;
 
-       VectorCopy (trace->endpos, ent->fields.server->origin);
+       VectorCopy(trace->endpos, ent->fields.server->origin);
 
        VectorCopy(ent->fields.server->origin, original);
        VectorCopy(ent->fields.server->velocity, original_velocity);
@@ -2521,11 +2533,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;
@@ -2533,25 +2544,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);
@@ -2627,7 +2635,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
@@ -2661,9 +2668,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
@@ -2673,7 +2678,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
@@ -3014,12 +3019,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