X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=sv_phys.c;h=7235fac729278bed36c7ad98dceefd8b6101edc3;hb=79e8047c4a704dd1c1688a5d6930c3e181cabe70;hp=bd8b50ce30262ed9a36b8092fd8f49a009552867;hpb=c078470162695c351cbf4c26baea145926abf609;p=xonotic%2Fdarkplaces.git diff --git a/sv_phys.c b/sv_phys.c index bd8b50ce..7235fac7 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -46,9 +46,8 @@ 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 = SV_GetModelFromEdict(ent)) ? model->type == mod_alias : @@ -214,10 +213,7 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int model = NULL; if ((int) touch->fields.server->solid == SOLID_BSP || type == MOVE_HITMODEL) { - unsigned int modelindex = (unsigned int)touch->fields.server->modelindex; - // 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]; + model = SV_GetModelFromEdict(touch); pitchsign = SV_GetPitchSign(touch); } if (model) @@ -225,10 +221,13 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int else Matrix4x4_CreateTranslate(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2]); Matrix4x4_Invert_Simple(&imatrix, &matrix); + VM_GenerateFrameGroupBlend(touch->priv.server->framegroupblend, touch); + VM_FrameBlendFromFrameGroupBlend(touch->priv.server->frameblend, touch->priv.server->framegroupblend, model); + VM_UpdateEdictSkeleton(touch, model, touch->priv.server->frameblend); if (type == MOVE_MISSILE && (int)touch->fields.server->flags & FL_MONSTER) - Collision_ClipToGenericEntity(&trace, model, (int) touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipstart, hitsupercontentsmask); + 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, clipstart, hitsupercontentsmask); else - Collision_ClipPointToGenericEntity(&trace, model, (int) touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, hitsupercontentsmask); + Collision_ClipPointToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, hitsupercontentsmask); Collision_CombineTraces(&cliptrace, &trace, (void *)touch, touch->fields.server->solid == SOLID_BSP); } @@ -272,12 +271,12 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ vec3_t end; vec_t len = 0; - if(!VectorCompare(start, pEnd)) + if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0) { // TRICK: make the trace 1 qu longer! VectorSubtract(pEnd, start, end); len = VectorNormalizeLength(end); - VectorAdd(pEnd, end, end); + VectorMA(pEnd, collision_endposnudge.value, end, end); } else VectorCopy(pEnd, end); @@ -377,10 +376,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ model = NULL; if ((int) touch->fields.server->solid == SOLID_BSP || type == MOVE_HITMODEL) { - unsigned int modelindex = (unsigned int)touch->fields.server->modelindex; - // 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]; + model = SV_GetModelFromEdict(touch); pitchsign = SV_GetPitchSign(touch); } if (model) @@ -388,18 +384,21 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ else Matrix4x4_CreateTranslate(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2]); Matrix4x4_Invert_Simple(&imatrix, &matrix); + VM_GenerateFrameGroupBlend(touch->priv.server->framegroupblend, touch); + VM_FrameBlendFromFrameGroupBlend(touch->priv.server->frameblend, touch->priv.server->framegroupblend, model); + VM_UpdateEdictSkeleton(touch, model, touch->priv.server->frameblend); if (type == MOVE_MISSILE && (int)touch->fields.server->flags & FL_MONSTER) - Collision_ClipToGenericEntity(&trace, model, (int) touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask); + 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, (int) touch->fields.server->frame, 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); Collision_CombineTraces(&cliptrace, &trace, (void *)touch, touch->fields.server->solid == SOLID_BSP); } finished: #ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND - if(!VectorCompare(start, pEnd)) - Collision_ShortenTrace(&cliptrace, len / (len + 1), pEnd); + if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0) + Collision_ShortenTrace(&cliptrace, len / (len + collision_endposnudge.value), pEnd); #endif return cliptrace; } @@ -451,12 +450,12 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co vec3_t end; vec_t len = 0; - if(!VectorCompare(start, pEnd)) + if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0) { // TRICK: make the trace 1 qu longer! VectorSubtract(pEnd, start, end); len = VectorNormalizeLength(end); - VectorAdd(pEnd, end, end); + VectorMA(pEnd, collision_endposnudge.value, end, end); } else VectorCopy(pEnd, end); @@ -577,11 +576,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co model = NULL; if ((int) touch->fields.server->solid == SOLID_BSP || type == MOVE_HITMODEL) { - unsigned int modelindex = (unsigned int)touch->fields.server->modelindex; - // 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; + model = SV_GetModelFromEdict(touch); pitchsign = SV_GetPitchSign(touch); } if (model) @@ -589,18 +584,21 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co else Matrix4x4_CreateTranslate(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2]); Matrix4x4_Invert_Simple(&imatrix, &matrix); + VM_GenerateFrameGroupBlend(touch->priv.server->framegroupblend, touch); + VM_FrameBlendFromFrameGroupBlend(touch->priv.server->frameblend, touch->priv.server->framegroupblend, model); + VM_UpdateEdictSkeleton(touch, model, touch->priv.server->frameblend); if (type == MOVE_MISSILE && (int)touch->fields.server->flags & FL_MONSTER) - Collision_ClipToGenericEntity(&trace, model, (int) touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask); + 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_ClipToGenericEntity(&trace, model, (int) touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask); + Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask); Collision_CombineTraces(&cliptrace, &trace, (void *)touch, touch->fields.server->solid == SOLID_BSP); } finished: #ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND - if(!VectorCompare(start, pEnd)) - Collision_ShortenTrace(&cliptrace, len / (len + 1), pEnd); + if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0) + Collision_ShortenTrace(&cliptrace, len / (len + collision_endposnudge.value), pEnd); #endif return cliptrace; } @@ -635,7 +633,6 @@ int SV_PointSuperContents(const vec3_t point) matrix4x4_t matrix, imatrix; // model of other entity dp_model_t *model; - unsigned int modelindex; int frame; // list of entities to test for collisions int numtouchedicts; @@ -666,10 +663,7 @@ int SV_PointSuperContents(const vec3_t point) continue; // might interact, so do an exact clip - modelindex = (unsigned int)touch->fields.server->modelindex; - if (modelindex >= MAX_MODELS) - continue; - model = sv.models[(int)touch->fields.server->modelindex]; + model = SV_GetModelFromEdict(touch); if (!model || !model->PointSuperContents) continue; Matrix4x4_CreateFromQuakeEntity(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2], touch->fields.server->angles[0], touch->fields.server->angles[1], touch->fields.server->angles[2], 1); @@ -795,6 +789,7 @@ void SV_LinkEdict (prvm_edict_t *ent) { dp_model_t *model; vec3_t mins, maxs; + int modelindex; if (ent == prog->edicts) return; // don't add the world @@ -802,6 +797,18 @@ void SV_LinkEdict (prvm_edict_t *ent) if (ent->priv.server->free) return; + modelindex = (int)ent->fields.server->modelindex; + if (modelindex < 0 || modelindex >= MAX_MODELS) + { + Con_Printf("edict %i: SOLID_BSP with invalid modelindex!\n", PRVM_NUM_FOR_EDICT(ent)); + modelindex = 0; + } + model = SV_GetModelByIndex(modelindex); + + VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent); + VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model); + VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend); + // set the abs box if (ent->fields.server->movetype == MOVETYPE_PHYSICS) @@ -814,13 +821,6 @@ void SV_LinkEdict (prvm_edict_t *ent) } else if (ent->fields.server->solid == SOLID_BSP) { - int modelindex = (int)ent->fields.server->modelindex; - if (modelindex < 0 || modelindex >= MAX_MODELS) - { - Con_Printf("edict %i: SOLID_BSP with invalid modelindex!\n", PRVM_NUM_FOR_EDICT(ent)); - modelindex = 0; - } - model = sv.models[modelindex]; if (model != NULL) { if (!model->TraceBox && developer.integer >= 1) @@ -1592,7 +1592,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime) Con_Printf("SV_PushMove: entity #%i has an invalid modelindex %f\n", PRVM_NUM_FOR_EDICT(pusher), pusher->fields.server->modelindex); return; } - pushermodel = sv.models[index]; + pushermodel = SV_GetModelByIndex(index); pusherowner = pusher->fields.server->owner; pusherprog = PRVM_EDICT_TO_PROG(pusher); @@ -1664,9 +1664,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime) pusher->fields.server->ltime += movetime; SV_LinkEdict(pusher); - pushermodel = NULL; - if (pusher->fields.server->modelindex >= 1 && pusher->fields.server->modelindex < MAX_MODELS) - pushermodel = sv.models[(int)pusher->fields.server->modelindex]; + pushermodel = SV_GetModelFromEdict(pusher); Matrix4x4_CreateFromQuakeEntity(&pusherfinalmatrix, pusher->fields.server->origin[0], pusher->fields.server->origin[1], pusher->fields.server->origin[2], pusher->fields.server->angles[0], pusher->fields.server->angles[1], pusher->fields.server->angles[2], 1); Matrix4x4_Invert_Simple(&pusherfinalimatrix, &pusherfinalmatrix); @@ -1710,7 +1708,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime) // final position, move it if (!((int)check->fields.server->flags & FL_ONGROUND) || PRVM_PROG_TO_EDICT(check->fields.server->groundentity) != pusher) { - Collision_ClipToGenericEntity(&trace, pushermodel, (int) pusher->fields.server->frame, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, checkcontents); + Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, checkcontents); //trace = SV_TraceBox(check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, MOVE_NOMONSTERS, check, checkcontents); if (!trace.startsolid) { @@ -1768,7 +1766,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime) check->fields.server->flags = (int)check->fields.server->flags & ~FL_ONGROUND; // if it is still inside the pusher, block - Collision_ClipToGenericEntity(&trace, pushermodel, (int) pusher->fields.server->frame, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, checkcontents); + Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, checkcontents); if (trace.startsolid) { // try moving the contacted entity a tiny bit further to account for precision errors @@ -1783,7 +1781,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime) continue; } pusher->fields.server->solid = savesolid; - Collision_ClipToGenericEntity(&trace, pushermodel, (int) pusher->fields.server->frame, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, checkcontents); + Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, checkcontents); if (trace.startsolid) { // try moving the contacted entity a tiny bit less to account for precision errors @@ -1797,7 +1795,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime) continue; } pusher->fields.server->solid = savesolid; - Collision_ClipToGenericEntity(&trace, pushermodel, (int) pusher->fields.server->frame, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, checkcontents); + Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, checkcontents); if (trace.startsolid) { // still inside pusher, so it's really blocked @@ -2159,7 +2157,7 @@ Only used by players */ void SV_WalkMove (prvm_edict_t *ent) { - int clip, oldonground, originalmove_clip, originalmove_flags, originalmove_groundentity, hitsupercontentsmask; + int clip, oldonground, originalmove_clip, originalmove_flags, originalmove_groundentity, hitsupercontentsmask, type; vec3_t upmove, downmove, start_origin, start_velocity, stepnormal, originalmove_origin, originalmove_velocity; trace_t downtrace, trace; qboolean applygravity; @@ -2185,8 +2183,27 @@ void SV_WalkMove (prvm_edict_t *ent) clip = SV_FlyMove (ent, sv.frametime, applygravity, NULL, hitsupercontentsmask); + if(sv_gameplayfix_downtracesupportsongroundflag.integer) + if(!(clip & 1)) + { + // only try this if there was no floor in the way in the trace (no, + // this check seems to be not REALLY necessary, because if clip & 1, + // our trace will hit that thing too) + VectorSet(upmove, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + 1); + VectorSet(downmove, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] - 1); + if (ent->fields.server->movetype == MOVETYPE_FLYMISSILE) + type = MOVE_MISSILE; + else if (ent->fields.server->solid == SOLID_TRIGGER || ent->fields.server->solid == SOLID_NOT) + type = MOVE_NOMONSTERS; // only clip against bmodels + else + type = MOVE_NORMAL; + trace = SV_TraceBox(upmove, ent->fields.server->mins, ent->fields.server->maxs, downmove, type, ent, SV_GenericHitSuperContentsMask(ent)); + if(trace.fraction < 1 && trace.plane.normal[2] > 0.7) + clip |= 1; // but we HAVE found a floor + } + // if the move did not hit the ground at any point, we're not on ground - if (!(clip & 1)) + if(!(clip & 1)) ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND; SV_CheckVelocity(ent);