From a53f08b7a4c95132c6d6bd3aad981df62ffa493d Mon Sep 17 00:00:00 2001 From: black Date: Thu, 10 Jan 2008 13:40:57 +0000 Subject: [PATCH] Fix the bmodel collision bug in csqc. clvm's setmodel and setmodelindex also update the min, max and size now (just like they do in sqc). git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7948 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_collision.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++-- clvm_cmds.c | 40 ++++++++++++++++++++++++++++++++------ svvm_cmds.c | 4 ++-- 3 files changed, 86 insertions(+), 10 deletions(-) diff --git a/cl_collision.c b/cl_collision.c index 527acecc..45acfefa 100644 --- a/cl_collision.c +++ b/cl_collision.c @@ -114,14 +114,62 @@ model_t *CL_GetModelFromEdict(prvm_edict_t *ed) void CL_LinkEdict(prvm_edict_t *ent) { + vec3_t mins, maxs; + if (ent == prog->edicts) return; // don't add the world if (ent->priv.server->free) return; - VectorAdd(ent->fields.client->origin, ent->fields.client->mins, ent->fields.client->absmin); - VectorAdd(ent->fields.client->origin, ent->fields.client->maxs, ent->fields.client->absmax); + // set the abs box + + if (ent->fields.client->solid == SOLID_BSP) + { + model_t *model = CL_GetModelByIndex( (int)ent->fields.client->modelindex ); + if (model == NULL) + { + Con_Printf("edict %i: SOLID_BSP with invalid modelindex!\n", PRVM_NUM_FOR_EDICT(ent)); + + model = CL_GetModelByIndex( 0 ); + } + + if( model != NULL ) + { + if (!model->TraceBox && developer.integer >= 1) + Con_Printf("edict %i: SOLID_BSP with non-collidable model\n", PRVM_NUM_FOR_EDICT(ent)); + + if (ent->fields.client->angles[0] || ent->fields.client->angles[2] || ent->fields.client->avelocity[0] || ent->fields.client->avelocity[2]) + { + VectorAdd(ent->fields.client->origin, model->rotatedmins, mins); + VectorAdd(ent->fields.client->origin, model->rotatedmaxs, maxs); + } + else if (ent->fields.client->angles[1] || ent->fields.client->avelocity[1]) + { + VectorAdd(ent->fields.client->origin, model->yawmins, mins); + VectorAdd(ent->fields.client->origin, model->yawmaxs, maxs); + } + else + { + VectorAdd(ent->fields.client->origin, model->normalmins, mins); + VectorAdd(ent->fields.client->origin, model->normalmaxs, maxs); + } + } + else + { + // SOLID_BSP with no model is valid, mainly because some QC setup code does so temporarily + VectorAdd(ent->fields.client->origin, ent->fields.client->mins, mins); + VectorAdd(ent->fields.client->origin, ent->fields.client->maxs, maxs); + } + } + else + { + VectorAdd(ent->fields.client->origin, ent->fields.client->mins, mins); + VectorAdd(ent->fields.client->origin, ent->fields.client->maxs, maxs); + } + + VectorCopy(mins, ent->fields.client->absmin); + VectorCopy(maxs, ent->fields.client->absmax); World_LinkEdict(&cl.world, ent, ent->fields.client->absmin, ent->fields.client->absmax); } diff --git a/clvm_cmds.c b/clvm_cmds.c index 290ad287..2f589274 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -56,12 +56,28 @@ void VM_CL_setorigin (void) CL_LinkEdict(e); } +static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max) +{ + int i; + + for (i=0 ; i<3 ; i++) + if (min[i] > max[i]) + PRVM_ERROR("SetMinMaxSize: backwards mins/maxs"); + + // set derived values + VectorCopy (min, e->fields.client->mins); + VectorCopy (max, e->fields.client->maxs); + VectorSubtract (max, min, e->fields.client->size); + + CL_LinkEdict (e); +} + // #3 void(entity e, string m) setmodel void VM_CL_setmodel (void) { prvm_edict_t *e; const char *m; - struct model_s *mod; + model_t *mod; int i; VM_SAFEPARMCOUNT(2, VM_CL_setmodel); @@ -92,6 +108,14 @@ void VM_CL_setmodel (void) e->fields.client->modelindex = 0; e->fields.client->model = 0; VM_Warning ("setmodel: model '%s' not precached\n", m); + + // TODO: check if this breaks needed consistency and maybe add a cvar for it too?? [1/10/2008 Black] + if (mod) + { + SetMinMaxSize (e, mod->normalmins, mod->normalmaxs); + } + else + SetMinMaxSize (e, vec3_origin, vec3_origin); } // #4 void(entity e, vector min, vector max) setsize @@ -115,9 +139,7 @@ static void VM_CL_setsize (void) min = PRVM_G_VECTOR(OFS_PARM1); max = PRVM_G_VECTOR(OFS_PARM2); - VectorCopy (min, e->fields.client->mins); - VectorCopy (max, e->fields.client->maxs); - VectorSubtract (max, min, e->fields.client->size); + SetMinMaxSize( e, min, max ); CL_LinkEdict(e); } @@ -196,8 +218,6 @@ static void VM_CL_spawn (void) { prvm_edict_t *ed; ed = PRVM_ED_Alloc(); - // FIXME: WTF.. this should be removed imo.. entnum points to the server.. [12/17/2007 Black] - ed->fields.client->entnum = PRVM_NUM_FOR_EDICT(ed); //[515]: not needed any more ? VM_RETURN_EDICT(ed); } @@ -978,6 +998,14 @@ static void VM_CL_setmodelindex (void) } t->fields.client->model = PRVM_SetEngineString(model->name); t->fields.client->modelindex = i; + + // TODO: check if this breaks needed consistency and maybe add a cvar for it too?? [1/10/2008 Black] + if (model) + { + SetMinMaxSize (t, model->normalmins, model->normalmaxs); + } + else + SetMinMaxSize (t, vec3_origin, vec3_origin); } //#334 string(float mdlindex) modelnameforindex (EXT_CSQC) diff --git a/svvm_cmds.c b/svvm_cmds.c index a48dda5d..57eaab80 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -181,8 +181,8 @@ static void VM_SV_setorigin (void) SV_LinkEdict (e, false); } - -void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate) +// TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black] +static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate) { int i; -- 2.39.2