]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_main.c
fixed a bug with sv_gameplayfix_nudgeoutofsolid where the player might
[xonotic/darkplaces.git] / sv_main.c
index 8096d5588bd29f6dd1d882678f1fcad7429f887c..3a9037518e89de7d1d48ea44dda7116aaf1a5ce6 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -98,7 +98,7 @@ cvar_t sv_gameplayfix_multiplethinksperframe = {0, "sv_gameplayfix_multiplethink
 cvar_t sv_gameplayfix_noairborncorpse = {0, "sv_gameplayfix_noairborncorpse", "1", "causes entities (corpses, items, etc) sitting ontop of moving entities (players) to fall when the moving entity (player) is no longer supporting them"};
 cvar_t sv_gameplayfix_noairborncorpse_allowsuspendeditems = {0, "sv_gameplayfix_noairborncorpse_allowsuspendeditems", "1", "causes entities sitting ontop of objects that are instantaneously remove to float in midair (special hack to allow a common level design trick for floating items)"};
 cvar_t sv_gameplayfix_nudgeoutofsolid = {0, "sv_gameplayfix_nudgeoutofsolid", "1", "attempts to fix physics errors (where an object ended up in solid for some reason)"};
-cvar_t sv_gameplayfix_nudgeoutofsolid_bias = {0, "sv_gameplayfix_nudgeoutofsolid_bias", "0.03125", "over-correction on nudgeoutofsolid logic, to prevent constant contact"};
+cvar_t sv_gameplayfix_nudgeoutofsolid_bias = {0, "sv_gameplayfix_nudgeoutofsolid_bias", "0", "over-correction on nudgeoutofsolid logic, to prevent constant contact"};
 cvar_t sv_gameplayfix_q2airaccelerate = {0, "sv_gameplayfix_q2airaccelerate", "0", "Quake2-style air acceleration"};
 cvar_t sv_gameplayfix_setmodelrealbox = {0, "sv_gameplayfix_setmodelrealbox", "1", "fixes a bug in Quake that made setmodel always set the entity box to ('-16 -16 -16', '16 16 16') rather than properly checking the model box, breaks some poorly coded mods"};
 cvar_t sv_gameplayfix_slidemoveprojectiles = {0, "sv_gameplayfix_slidemoveprojectiles", "1", "allows MOVETYPE_FLY/FLYMISSILE/TOSS/BOUNCE/BOUNCEMISSILE entities to finish their move in a frame even if they hit something, fixes 'gravity accumulation' bug for grenades on steep slopes"};
@@ -1063,7 +1063,7 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        // LordHavoc: this could kill tags attached to an invisible entity, I
        // just hope we never have to support that case
        i = (int)ent->fields.server->modelindex;
-       modelindex = (i >= 1 && i < MAX_MODELS && ent->fields.server->model && *PRVM_GetString(ent->fields.server->model)) ? i : 0;
+       modelindex = (i >= 1 && i < MAX_MODELS && ent->fields.server->model && *PRVM_GetString(ent->fields.server->model) && sv.models[i]) ? i : 0;
 
        flags = 0;
        i = (int)(PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.glow_size)->_float * 0.25f);
@@ -1235,7 +1235,7 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        // calculate the visible box of this entity (don't use the physics box
        // as that is often smaller than a model, and would not count
        // specialvisibilityradius)
-       if ((model = sv.models[modelindex]) && (model->type != mod_null))
+       if ((model = SV_GetModelByIndex(modelindex)) && (model->type != mod_null))
        {
                float scale = cs->scale * (1.0f / 16.0f);
                if (cs->angles[0] || cs->angles[2]) // pitch and roll
@@ -1353,7 +1353,6 @@ qboolean SV_CanSeeBox(int numtraces, vec_t enlarge, vec3_t eye, vec3_t entboxmin
        dp_model_t *model;
        prvm_edict_t *touch;
        prvm_edict_t *touchedicts[MAX_EDICTS];
-       unsigned int modelindex;
        vec3_t boxmins, boxmaxs;
        vec3_t clipboxmins, clipboxmaxs;
        vec3_t endpoints[MAX_LINEOFSIGHTTRACES];
@@ -1402,13 +1401,8 @@ qboolean SV_CanSeeBox(int numtraces, vec_t enlarge, vec3_t eye, vec3_t entboxmin
                touch = touchedicts[touchindex];
                if (touch->fields.server->solid != SOLID_BSP)
                        continue;
-               modelindex = (unsigned int)touch->fields.server->modelindex;
-               if (!modelindex)
-                       continue;
-               if (modelindex >= MAX_MODELS)
-                       continue; // error?
-               model = sv.models[(int)touch->fields.server->modelindex];
-               if (!model->brush.TraceLineOfSight)
+               model = SV_GetModelFromEdict(touch);
+               if (!model || !model->brush.TraceLineOfSight)
                        continue;
                // skip obviously transparent entities
                alpha = PRVM_EDICTFIELDVALUE(touch, prog->fieldoffsets.alpha)->_float;
@@ -1432,8 +1426,7 @@ qboolean SV_CanSeeBox(int numtraces, vec_t enlarge, vec3_t eye, vec3_t entboxmin
                for (touchindex = 0;touchindex < numtouchedicts;touchindex++)
                {
                        touch = touchedicts[touchindex];
-                       modelindex = (unsigned int)touch->fields.server->modelindex;
-                       model = (modelindex >= 1 && modelindex < MAX_MODELS) ? sv.models[(int)touch->fields.server->modelindex] : NULL;
+                       model = SV_GetModelFromEdict(touch);
                        if(model && model->brush.TraceLineOfSight)
                        {
                                // get the entity matrix
@@ -1494,7 +1487,7 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s)
                if (!s->modelindex && s->specialvisibilityradius == 0)
                        return;
 
-               isbmodel = (model = sv.models[s->modelindex]) != NULL && model->name[0] == '*';
+               isbmodel = (model = SV_GetModelByIndex(s->modelindex)) != NULL && model->name[0] == '*';
                // viewmodels don't have visibility checking
                if (s->viewmodelforclient)
                {
@@ -2770,6 +2763,20 @@ int SV_ParticleEffectIndex(const char *name)
        return 0;
 }
 
+dp_model_t *SV_GetModelByIndex(int modelindex)
+{
+       return (modelindex > 0 && modelindex < MAX_MODELS) ? sv.models[modelindex] : NULL;
+}
+
+dp_model_t *SV_GetModelFromEdict(prvm_edict_t *ed)
+{
+       int modelindex;
+       if (!ed || ed->priv.server->free)
+               return NULL;
+       modelindex = (int)ed->fields.server->modelindex;
+       return (modelindex > 0 && modelindex < MAX_MODELS) ? sv.models[modelindex] : NULL;
+}
+
 /*
 ================
 SV_CreateBaseline
@@ -3296,6 +3303,7 @@ static void SV_VM_CB_FreeEdict(prvm_edict_t *ed)
        ed->fields.server->nextthink = -1;
        ed->fields.server->solid = 0;
 
+       VM_RemoveEdictSkeleton(ed);
        World_Physics_RemoveFromEntity(&sv.world, ed);
        World_Physics_RemoveJointFromEntity(&sv.world, ed);