]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_phys.c
makefile: new flag DP_ODE_DYNAMIC
[xonotic/darkplaces.git] / sv_phys.c
index 15355fd409bc8c8c91fab282b9177651484a80f0..db221566c2a5b20b007f420be6ffc236d9a74a67 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -43,6 +43,25 @@ solid_edge items only clip against bsp models.
 
 void SV_Physics_Toss (prvm_edict_t *ent);
 
+int SV_GetPitchSign(prvm_edict_t *ent)
+{
+       dp_model_t *model;
+       int modelindex;
+       if (
+                       ((modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
+                       ?
+                       model->type == mod_alias
+                       :
+                       (
+                        (((unsigned char)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.pflags)->_float) & PFLAGS_FULLDYNAMIC)
+                        ||
+                        ((gamemode == GAME_TENEBRAE) && ((unsigned int)ent->fields.server->effects & (16 | 32)))
+                       )
+          )
+               return -1;
+       return 1;
+}
+
 /*
 ===============================================================================
 
@@ -199,19 +218,7 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
                        // if the modelindex is 0, it shouldn't be SOLID_BSP!
                        if (modelindex > 0 && modelindex < MAX_MODELS)
                                model = sv.models[(int)touch->fields.server->modelindex];
-                       //pitchsign = 1;
-                       if (
-                               ((modelindex = (int)touch->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS && (model = sv.models[(int)touch->fields.server->modelindex]))
-                               ?
-                                       model->type == mod_alias
-                               :
-                                       (
-                                               (((unsigned char)PRVM_EDICTFIELDVALUE(touch, prog->fieldoffsets.pflags)->_float) & PFLAGS_FULLDYNAMIC)
-                                               ||
-                                               ((gamemode == GAME_TENEBRAE) && ((unsigned int)touch->fields.server->effects & (16 | 32)))
-                                       )
-                       )
-                               pitchsign = -1;
+                       pitchsign = SV_GetPitchSign(touch);
                }
                if (model)
                        Matrix4x4_CreateFromQuakeEntity(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2], pitchsign * touch->fields.server->angles[0], touch->fields.server->angles[1], touch->fields.server->angles[2], 1);
@@ -374,19 +381,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                        // if the modelindex is 0, it shouldn't be SOLID_BSP!
                        if (modelindex > 0 && modelindex < MAX_MODELS)
                                model = sv.models[(int)touch->fields.server->modelindex];
-                       //pitchsign = 1;
-                       if (
-                               ((modelindex = (int)touch->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS && (model = sv.models[(int)touch->fields.server->modelindex]))
-                               ?
-                                       model->type == mod_alias
-                               :
-                                       (
-                                               (((unsigned char)PRVM_EDICTFIELDVALUE(touch, prog->fieldoffsets.pflags)->_float) & PFLAGS_FULLDYNAMIC)
-                                               ||
-                                               ((gamemode == GAME_TENEBRAE) && ((unsigned int)touch->fields.server->effects & (16 | 32)))
-                                       )
-                       )
-                               pitchsign = -1;
+                       pitchsign = SV_GetPitchSign(touch);
                }
                if (model)
                        Matrix4x4_CreateFromQuakeEntity(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2], pitchsign * touch->fields.server->angles[0], touch->fields.server->angles[1], touch->fields.server->angles[2], 1);
@@ -587,18 +582,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                        if (modelindex > 0 && modelindex < MAX_MODELS)
                                model = sv.models[(int)touch->fields.server->modelindex];
                        //pitchsign = 1;
-                       if (
-                               ((modelindex = (int)touch->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS && (model = sv.models[(int)touch->fields.server->modelindex]))
-                               ?
-                                       model->type == mod_alias
-                               :
-                                       (
-                                               (((unsigned char)PRVM_EDICTFIELDVALUE(touch, prog->fieldoffsets.pflags)->_float) & PFLAGS_FULLDYNAMIC)
-                                               ||
-                                               ((gamemode == GAME_TENEBRAE) && ((unsigned int)touch->fields.server->effects & (16 | 32)))
-                                       )
-                       )
-                               pitchsign = -1;
+                       pitchsign = SV_GetPitchSign(touch);
                }
                if (model)
                        Matrix4x4_CreateFromQuakeEntity(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2], pitchsign * touch->fields.server->angles[0], touch->fields.server->angles[1], touch->fields.server->angles[2], 1);
@@ -1634,12 +1618,18 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
        for (e = 0;e < numcheckentities;e++)
        {
                prvm_edict_t *check = checkentities[e];
-               if (check->fields.server->movetype == MOVETYPE_NONE
-                || check->fields.server->movetype == MOVETYPE_PUSH
-                || check->fields.server->movetype == MOVETYPE_FOLLOW
-                || check->fields.server->movetype == MOVETYPE_NOCLIP
-                || check->fields.server->movetype == MOVETYPE_FAKEPUSH)
+               int movetype = (int)check->fields.server->movetype;
+               switch(movetype)
+               {
+               case MOVETYPE_NONE:
+               case MOVETYPE_PUSH:
+               case MOVETYPE_FOLLOW:
+               case MOVETYPE_NOCLIP:
+               case MOVETYPE_FAKEPUSH:
                        continue;
+               default:
+                       break;
+               }
 
                if (check->fields.server->owner == pusherprog)
                        continue;
@@ -1687,6 +1677,15 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                VectorCopy (check->fields.server->angles, check->priv.server->moved_fromangles);
                moved_edicts[num_moved++] = PRVM_NUM_FOR_EDICT(check);
 
+               // physics objects need better collisions than this code can do
+               if (movetype == MOVETYPE_PHYSICS)
+               {
+                       VectorAdd(check->fields.server->origin, move, check->fields.server->origin);
+                       SV_LinkEdict(check);
+                       SV_LinkEdict_TouchAreaGrid(check);
+                       continue;
+               }
+
                // try moving the contacted entity
                pusher->fields.server->solid = SOLID_NOT;
                if(!SV_PushEntity (&trace, check, move, true, true))
@@ -2432,7 +2431,13 @@ void SV_Physics_Toss (prvm_edict_t *ent)
                movetime *= 1 - min(1, trace.fraction);
                if (ent->fields.server->movetype == MOVETYPE_BOUNCEMISSILE)
                {
-                       ClipVelocity (ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 2.0);
+                       prvm_eval_t *val;
+                       float bouncefactor = 1.0f;
+                       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.bouncefactor);
+                       if (val!=0 && val->_float)
+                               bouncefactor = val->_float;
+
+                       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)
@@ -2654,6 +2659,13 @@ static void SV_Physics_Entity (prvm_edict_t *ent)
                if (SV_RunThink (ent))
                        SV_Physics_Toss (ent);
                break;
+       case MOVETYPE_PHYSICS:
+               if (SV_RunThink(ent))
+               {
+                       SV_LinkEdict(ent);
+                       SV_LinkEdict_TouchAreaGrid(ent);
+               }
+               break;
        default:
                Con_Printf ("SV_Physics: bad movetype %i\n", (int)ent->fields.server->movetype);
                break;
@@ -2818,6 +2830,9 @@ static void SV_Physics_ClientEntity(prvm_edict_t *ent)
                SV_RunThink (ent);
                SV_WalkMove (ent);
                break;
+       case MOVETYPE_PHYSICS:
+               SV_RunThink (ent);
+               break;
        default:
                Con_Printf ("SV_Physics_ClientEntity: bad movetype %i\n", (int)ent->fields.server->movetype);
                break;
@@ -2849,6 +2864,9 @@ void SV_Physics (void)
        prog->globals.server->frametime = sv.frametime;
        PRVM_ExecuteProgram (prog->globals.server->StartFrame, "QC function StartFrame is missing");
 
+       // run physics engine
+       World_Physics_Frame(&sv.world, sv.frametime, sv_gravity.value);
+
 //
 // treat each object in turn
 //