]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_phys.c
implemented QW gamedir switching and manual gamedir switching (via "gamedir" command...
[xonotic/darkplaces.git] / sv_phys.c
index 11c2ad73c65722e5af4ffc354fa519bc8fcd19da..c00abe7f267f5acc19b46dd372058667b6705fa8 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -121,6 +121,46 @@ void SV_CheckAllEnts (void)
        }
 }
 
+// DRESK - Support for Entity Contents Transition Event
+/*
+================
+SV_CheckContentsTransition
+
+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;
+
+       if(ent->fields.server->watertype != nContents)
+       { // Changed Contents
+               // Acquire Contents Transition Function from QC
+               contentstransition = PRVM_GETEDICTFIELDVALUE(ent, eval_contentstransition);
+
+               if(contentstransition->function)
+               { // Valid Function; Execute
+                       // Assign Valid Function
+                       bValidFunctionCall = true;
+                       // Prepare Parameters (Original Contents, New Contents)
+                               // Original Contents
+                               PRVM_G_FLOAT(OFS_PARM0) = ent->fields.server->watertype;
+                               // New Contents
+                               PRVM_G_FLOAT(OFS_PARM1) = nContents;
+                       // Execute VM Function
+                       PRVM_ExecuteProgram(contentstransition->function, "contentstransition: NULL function");
+               }
+       }
+
+       // Return if Function Call was Valid
+       return bValidFunctionCall;
+}
+
+
 /*
 ================
 SV_CheckVelocity
@@ -374,6 +414,7 @@ int SV_FlyMove (prvm_edict_t *ent, float time, float *stepnormal)
                Con_Print("\n");
 #endif
 
+#if 0
                if (trace.bmodelstartsolid)
                {
                        // LordHavoc: note: this code is what makes entities stick in place
@@ -383,6 +424,7 @@ int SV_FlyMove (prvm_edict_t *ent, float time, float *stepnormal)
                        VectorClear(ent->fields.server->velocity);
                        return 3;
                }
+#endif
 
                // break if it moved the entire distance
                if (trace.fraction == 1)
@@ -571,7 +613,7 @@ SV_PushEntity
 Does not change the entities velocity at all
 ============
 */
-trace_t SV_PushEntity (prvm_edict_t *ent, vec3_t push, qboolean failonstartsolid)
+static trace_t SV_PushEntity (prvm_edict_t *ent, vec3_t push, qboolean failonbmodelstartsolid)
 {
        int type;
        trace_t trace;
@@ -587,13 +629,13 @@ trace_t SV_PushEntity (prvm_edict_t *ent, vec3_t push, qboolean failonstartsolid
                type = MOVE_NORMAL;
 
        trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, type, ent);
-       if (trace.startsolid && failonstartsolid)
+       if (trace.bmodelstartsolid && failonbmodelstartsolid)
                return trace;
 
        VectorCopy (trace.endpos, ent->fields.server->origin);
        SV_LinkEdict (ent, true);
 
-       if (trace.ent && (!((int)ent->fields.server->flags & FL_ONGROUND) || ent->fields.server->groundentity != PRVM_EDICT_TO_PROG(trace.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)))
                SV_Impact (ent, &trace);
        return trace;
 }
@@ -773,12 +815,11 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                // 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);
+               //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)
                {
-                                       Con_Printf("%s:%d\n", __FILE__, __LINE__);
                        // try moving the contacted entity a tiny bit further to account for precision errors
                        vec3_t move2;
                        pusher->fields.server->solid = SOLID_NOT;
@@ -789,7 +830,6 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                        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)
                        {
-                                       Con_Printf("%s:%d\n", __FILE__, __LINE__);
                                // try moving the contacted entity a tiny bit less to account for precision errors
                                pusher->fields.server->solid = SOLID_NOT;
                                VectorScale(move, 0.9, move2);
@@ -799,18 +839,13 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                                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)
                                {
-                                       Con_Printf("%s:%d\n", __FILE__, __LINE__);
                                        // still inside pusher, so it's really blocked
 
                                        // fail the move
                                        if (check->fields.server->mins[0] == check->fields.server->maxs[0])
-                                       {
-                                       Con_Printf("%s:%d\n", __FILE__, __LINE__);
                                                continue;
-                                       }
                                        if (check->fields.server->solid == SOLID_NOT || check->fields.server->solid == SOLID_TRIGGER)
                                        {
-                                       Con_Printf("%s:%d\n", __FILE__, __LINE__);
                                                // corpse
                                                check->fields.server->mins[0] = check->fields.server->mins[1] = 0;
                                                VectorCopy (check->fields.server->mins, check->fields.server->maxs);
@@ -979,18 +1014,34 @@ SV_CheckWater
 qboolean SV_CheckWater (prvm_edict_t *ent)
 {
        int cont;
+       int nNativeContents;
        vec3_t point;
 
        point[0] = ent->fields.server->origin[0];
        point[1] = ent->fields.server->origin[1];
        point[2] = ent->fields.server->origin[2] + ent->fields.server->mins[2] + 1;
 
+       // DRESK - Support for Entity Contents Transition Event
+       // NOTE: Some logic needed to be slightly re-ordered
+       // to not affect performance and allow for the feature.
+
+       // Acquire Super Contents Prior to Resets
+       cont = SV_PointSuperContents(point);
+       // Acquire Native Contents Here
+       nNativeContents = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, cont);
+
+       // DRESK - Support for Entity Contents Transition Event
+       if(ent->fields.server->watertype)
+               // Entity did NOT Spawn; Check
+               SV_CheckContentsTransition(ent, nNativeContents);
+
+
        ent->fields.server->waterlevel = 0;
        ent->fields.server->watertype = CONTENTS_EMPTY;
        cont = SV_PointSuperContents(point);
        if (cont & (SUPERCONTENTS_LIQUIDSMASK))
        {
-               ent->fields.server->watertype = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, cont);
+               ent->fields.server->watertype = nNativeContents;
                ent->fields.server->waterlevel = 1;
                point[2] = ent->fields.server->origin[2] + (ent->fields.server->mins[2] + ent->fields.server->maxs[2])*0.5;
                if (SV_PointSuperContents(point) & (SUPERCONTENTS_LIQUIDSMASK))
@@ -1299,9 +1350,16 @@ void SV_CheckWaterTransition (prvm_edict_t *ent)
                return;
        }
 
-       // check if the entity crossed into or out of water
-       if (sv_sound_watersplash.string && ((ent->fields.server->watertype == CONTENTS_WATER || ent->fields.server->watertype == CONTENTS_SLIME) != (cont == CONTENTS_WATER || cont == CONTENTS_SLIME)))
-               SV_StartSound (ent, 0, sv_sound_watersplash.string, 255, 1);
+       // DRESK - Support for Entity Contents Transition Event
+       // NOTE: Call here BEFORE updating the watertype below,
+       // and suppress watersplash sound if a valid function
+       // call was made to allow for custom "splash" sounds.
+       if( !SV_CheckContentsTransition(ent, cont) )
+       { // Contents Transition Function Invalid; Potentially Play Water Sound
+               // check if the entity crossed into or out of water
+               if (sv_sound_watersplash.string && ((ent->fields.server->watertype == CONTENTS_WATER || ent->fields.server->watertype == CONTENTS_SLIME) != (cont == CONTENTS_WATER || cont == CONTENTS_SLIME)))
+                       SV_StartSound (ent, 0, sv_sound_watersplash.string, 255, 1);
+       }
 
        if (cont <= CONTENTS_WATER)
        {