Index: common/cmodel.c =================================================================== --- common/cmodel.c (revision 15680) +++ common/cmodel.c (working copy) @@ -682,6 +682,7 @@ return 0; } + /** * @brief Checks traces against the world and all inline models * @param[in] start The position to start the trace. @@ -689,24 +690,23 @@ * @sa CM_TestLine * @sa CM_InlineModel * @sa CM_TransformedBoxTrace - * @return 1 - hit something - * @return 0 - hit nothing + * @return qtrue - hit something + * @return qfalse - hit nothing */ -static int CM_EntTestLine (vec3_t start, vec3_t stop) +qboolean CM_EntTestLine (vec3_t start, vec3_t stop) { trace_t trace; cBspModel_t *model; const char **name; - int worldFound; /* trace against world first */ if (CM_TestLine(start, stop)) - worldFound = 1; - else - worldFound = 0; - /* no local models */ + /* We hit the world, so we didn't make it anyway... */ + return qtrue; + + /* no local models, so we made it. */ if (!inlineList) - return worldFound; + return qfalse; for (name = inlineList; *name; name++) { /* check whether this is really an inline model */ @@ -719,15 +719,39 @@ /* if we started the trace in a wall */ /* or the trace is not finished */ if (trace.startsolid || trace.fraction < 1.0) - return 1; + return qtrue; } /* not blocked */ - return worldFound; + return qfalse; } /** + * @brief Checks traces against the world and all inline models + * @param[in] start The position to start the trace. + * @param[in] stop The position where the trace ends. + * @param[in] list of entities that might be on this line + * @sa CM_EntTestLine + * @return qtrue - hit something + * @return qfalse - hit nothing + */ +qboolean CM_TestLineWithEnt (vec3_t start, vec3_t stop, const char **entlist) +{ + qboolean hit; + + /* set the list of entities to check */ + inlineList = entlist; + /* do the line test */ + hit = CM_EntTestLine(start, stop); + /* zero the list */ + inlineList = NULL; + + return hit; +} + + +/** * @brief Checks traces against the world and all inline models, gives the hit position back * @param[in] start The position to start the trace. * @param[in] stop The position where the trace ends. Index: common/cmodel.h =================================================================== --- common/cmodel.h (revision 15680) +++ common/cmodel.h (working copy) @@ -51,6 +51,7 @@ trace_t CM_CompleteBoxTrace(vec3_t start, vec3_t end, const vec3_t mins, const vec3_t maxs, int levelmask, int brushmask); qboolean CM_TestLine(const vec3_t start, const vec3_t stop); +qboolean CM_TestLineWithEnt(vec3_t start, vec3_t stop, const char **entlist); qboolean CM_TestLineDM(const vec3_t start, const vec3_t stop, vec3_t end); /*========================================================== Index: game/g_client.c =================================================================== --- game/g_client.c (revision 15680) +++ game/g_client.c (working copy) @@ -329,12 +329,18 @@ */ static qboolean G_LineVis (vec3_t from, vec3_t to) { -#if 0 /* this version is more accurate the other version is much faster */ +#if 0 /* this version is more accurate and includes entity tests */ trace_t tr; tr = gi.trace(from, NULL, NULL, to, NULL, MASK_SOLID); - return (tr.fraction >= 1.0); -#else + return (tr.fraction < 1.0); +#elif 0 /* this version is much faster but has no entity test*/ return gi.TestLine(from, to); +#else /* a compromise- but still checks for entities that may obstruct view */ + const char *entList[MAX_EDICTS]; + /* generate entity list */ + G_GenerateEntList (entList); + /* test for visibility */ + return gi.TestLineWithEnt(from, to, entList); #endif } Index: game/g_spawn.c =================================================================== --- game/g_spawn.c (revision 15680) +++ game/g_spawn.c (working copy) @@ -297,13 +297,20 @@ ent = g_edicts; else ent = G_Spawn(); + entities = ED_ParseEdict(entities, ent); + ent->mapNum = entnum++; + + /* Set the position of the entity */ VecToPos(ent->origin, ent->pos); - gi.GridPosToVec(gi.routingMap, ent->pos, ent->origin); - ent->mapNum = entnum++; + /*Call this entity's specific initializer (sets ent->type) */ ED_CallSpawn(ent); + + /* if this entity is not an actor, then center its origin based on its position */ + if (ent->type != ET_BREAKABLE && ent->type != ET_BREAKABLE) + gi.GridPosToVec(gi.routingMap, ent->pos, ent->origin); } /* spawn ai players, if needed */ Index: game/g_utils.c =================================================================== --- game/g_utils.c (revision 15680) +++ game/g_utils.c (working copy) @@ -234,21 +234,32 @@ } /** - * @sa G_CompleteRecalcRouting - * @sa Grid_RecalcRouting + * @brief creates an entity list + * @param[out] entList A list of all active inline model entities + * @sa G_RecalcRouting + * @sa G_LineVis */ -void G_RecalcRouting (const edict_t * self) +void G_GenerateEntList (const char *entList[MAX_EDICTS]) { int i; edict_t *ent; - const char *entList[MAX_EDICTS]; /* generate entity list */ for (i = 0, ent = g_edicts; ent < &g_edicts[globals.num_edicts]; ent++) if (ent->inuse && ent->model && *ent->model == '*' && ent->solid == SOLID_BSP) entList[i++] = ent->model; entList[i] = NULL; +} +/** + * @sa G_CompleteRecalcRouting + * @sa Grid_RecalcRouting + */ +void G_RecalcRouting (const edict_t * self) +{ + const char *entList[MAX_EDICTS]; + /* generate entity list */ + G_GenerateEntList (entList); /* recalculate routing */ gi.GridRecalcRouting(gi.routingMap, self->model, self->angles, entList); } Index: game/game.h =================================================================== --- game/game.h (revision 15680) +++ game/game.h (working copy) @@ -151,6 +151,7 @@ int (IMPORT *BoxEdicts) (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype); qboolean (IMPORT *TestLine) (const vec3_t start, const vec3_t stop); + qboolean (IMPORT *TestLineWithEnt) (vec3_t start, vec3_t stop, const char **entlist); float (IMPORT *GrenadeTarget) (vec3_t from, vec3_t at, float speed, qboolean launched, qboolean rolled, vec3_t v0); void (IMPORT *MoveCalc) (struct routing_s * map, pos3_t from, int size, int distance, pos_t ** fb_list, int fb_length); Index: server/sv_game.c =================================================================== --- server/sv_game.c (revision 15680) +++ server/sv_game.c (working copy) @@ -388,6 +388,7 @@ import.BoxEdicts = SV_AreaEdicts; import.TestLine = CM_TestLine; + import.TestLineWithEnt = CM_TestLineWithEnt; import.GrenadeTarget = Com_GrenadeTarget; import.MoveCalc = Grid_MoveCalc; Index: server/sv_world.c =================================================================== --- server/sv_world.c (revision 15680) +++ server/sv_world.c (working copy) @@ -497,9 +497,16 @@ clip.maxs = maxs; clip.passedict = passedict; - /* create the bounding box of the entire move */ + /* create the bounding box for the entire path traveled by the shot */ SV_TraceBounds(start, clip.mins, clip.maxs, end, clip.boxmins, clip.boxmaxs); +#if 0 + /* Output the trace bounds */ + Com_Printf("Trace: (%i, %i, %i) (%i, %i, %i)\n", + (int) clip.boxmins[0], (int) clip.boxmins[1], (int) clip.boxmins[2], + (int) clip.boxmaxs[0], (int) clip.boxmaxs[1], (int) clip.boxmaxs[2]); +#endif + /* clip to other solid entities */ SV_ClipMoveToEntities(&clip);