Index: common/cmodel.c =================================================================== --- common/cmodel.c (revision 15647) +++ common/cmodel.c (working copy) @@ -122,7 +122,7 @@ } mapTile_t; /** - * @brief Pathfinding routing structure + * @brief Pathfinding routing structure and tile layout * @note Comments strongly WIP! * * ROUTE @@ -159,6 +159,17 @@ * AREASTORED * The stored mask (the cached move) of the routing data. (See Grid_MoveLength) * + * TILE LAYOUT AND PATHING + * Maps are comprised of tiles. Each tile has a number of levels corresponding to entities in game. + * All static entities in the tile are located in levels 0-255, with the main world located in 0. + * Levels 256-258 are reserved, see LEVEL_* constants in src/shared/shared.h. Non-static entities + * (ET_BREAKABLE and ET_ROTATING, ET_DOOR, etc.) are contained in levels 259 and above. These entities' + * models are named *##, beginning from 1, and each corresponds to level LEVEL_STEPON + ##. + * + * The code that handles the pathing has separate checks for the static and non-static levels in a tile. + * The static levels have their bounds precalculated by CM_MakeTracingNodes and stored in tile->theads. + * The other levels are checked in the fly when Grid_CheckUnit is called. + * */ typedef struct routing_s { byte route[PATHFINDING_HEIGHT][PATHFINDING_WIDTH][PATHFINDING_WIDTH]; @@ -803,9 +814,14 @@ /* get step height and trace vectors */ sh = R_STEP(map, x, y, z) ? sh_big : sh_low; h = R_HEIGHT(map, x, y, z); + + /* Setup the points used to check for walls and such */ VectorSet(pos, x, y, z); PosToVec(pos, start); - start[2] += h * 4; + /* Adjust height to the actual floor height. */ + start[2] += h * QUANT; + /* Set the end point to the edge of the field unit in the direction traveling */ + /** @todo: should this check into the center of the adjacent field unit insead of just to the edge? */ VectorSet(end, start[0] + (UNIT_HEIGHT / 2) * dvecs[dir][0], start[1] + (UNIT_HEIGHT / 2) * dvecs[dir][1], start[2]); ax = x + dvecs[dir][0]; @@ -831,12 +847,13 @@ if (R_HEIGHT(map, ax, ay, az) > h) return; + /** @todo: Do we need to use a bounding box to check for things in the way of this move? */ /* center check */ if (CM_EntTestLine(start, end)) return; /* lower check */ - start[2] = end[2] -= UNIT_HEIGHT / 2 - sh * 4 - 2; + start[2] = end[2] -= UNIT_HEIGHT / 2 - sh * QUANT - 2; if (CM_EntTestLine(start, end)) return; @@ -1157,7 +1174,7 @@ if (l->filelen + 1 > MAX_MAP_ENTSTRING) Com_Error(ERR_DROP, "CMod_LoadEntityString: Map has too large entity lump"); - /* marge entitystring information */ + /* merge entitystring information */ es = (char *) (cmod_base + l->fileofs); while (1) { /* parse the opening brace */ @@ -1734,6 +1751,8 @@ /** * @sa CM_ClipBoxToBrush + * @sa CM_TestBoxInBrush + * @sa CM_RecursiveHullCheck */ static void CM_TraceToLeaf (int leafnum) { @@ -2855,8 +2874,11 @@ y = pos[1] - dy; z = sz; - /** @todo: What exactly is checked here? Exact description wanted/needed. */ - if (R_AREA(map, x, y, z) != (l - TU_MOVE_STRAIGHT) - (dir > 3)) + /** + * This code verifies the TE table. If the table does not match the movement calculation, + * we skip this invalid comparison. + */ + if (R_AREA(map, x, y, z) != l - ((dir > 3) ? TU_MOVE_DIAGONAL : TU_MOVE_STRAIGHT)) continue; /* connection checks */ @@ -2922,7 +2944,7 @@ } /* shouldn't happen */ - Com_Printf("failed...\n"); + Com_Printf("Grid_MoveNext failed...\n"); /* ROUTING_NOT_REACHABLE means, not possible/reachable */ return ROUTING_NOT_REACHABLE; } Index: game/g_func.c =================================================================== --- game/g_func.c (revision 15647) +++ game/g_func.c (working copy) @@ -32,6 +32,17 @@ /** * @brief QUAKED func_breakable (0.3 0.3 0.3) ? * Used for breakable objects. + * SPAWNFLAGS bit values: + * 0x0001 Visible from layer 1 + * 0x0002 Visible from layer 2 + * 0x0004 Visible from layer 3 + * 0x0008 Visible from layer 4 + * 0x0010 Visible from layer 5 + * 0x0020 Visible from layer 6 + * 0x0040 Visible from layer 7 + * 0x0080 Visible from layer 8 + * 0x0100 Not present during day (defined in src/client/cl_view.c) + * 0x0200 Glows (defined in src/client/cl_view.c) * @note These edicts are added client side as local models * the are stored in the lmList (because they are inline models) * for tracing (see inlineList in cmodel.c) Index: game/q_shared.h =================================================================== --- game/q_shared.h (revision 15647) +++ game/q_shared.h (working copy) @@ -136,7 +136,7 @@ #define GROUND_DELTA 28 /* player height - 12 to be able to walk trough doors * UNIT_HEIGHT is the height of one level */ -#define PLAYER_HEIGHT (UNIT_HEIGHT-12) +#define PLAYER_HEIGHT (UNIT_HEIGHT - 16) /* LINKED LIST STUFF */ Index: tools/ufo2map/bsp.c =================================================================== --- tools/ufo2map/bsp.c (revision 15647) +++ tools/ufo2map/bsp.c (working copy) @@ -76,7 +76,7 @@ list = ChopBrushes(list); tree = BrushBSP(list, mins, maxs); if (tree->headnode->planenum == PLANENUM_LEAF) - Sys_Error("No head node bmodel of %s\n", ValueForKey(e, "classname")); + Sys_Error("No head node bmodel of %s (%i)\n", ValueForKey(e, "classname"), entityNum); MakeTreePortals(tree); MarkVisibleSides(tree, start, end); MakeFaces(tree->headnode); Index: tools/ufo2map/routing.c =================================================================== --- tools/ufo2map/routing.c (revision 15647) +++ tools/ufo2map/routing.c (working copy) @@ -80,8 +80,8 @@ /* prepare fall down check */ VectorCopy(end, start); - start[2] -= UNIT_HEIGHT / 2 - 4; - end[2] -= UNIT_HEIGHT / 2 + 4; + start[2] -= UNIT_HEIGHT / 2 - QUANT; + end[2] -= UNIT_HEIGHT / 2 + QUANT; /* FIXME: Don't allow falling over more than 1 level (z-direction) */ /* test for fall down */ @@ -190,6 +190,7 @@ /* prepare trace */ VectorSet(pos, x, y, z); PosToVec(pos, start); + /* Adjust height to actual floor height. */ start[2] += h * QUANT; VectorCopy(start, ts); @@ -224,8 +225,8 @@ ay = y - 1; break; } - /* range check*/ - if (x < 0 || x >= PATHFINDING_WIDTH || y < 0 || y >= PATHFINDING_WIDTH) + /* range check- ensure that ax and ay are on the map*/ + if (ax < 0 || ax >= PATHFINDING_WIDTH || ay < 0 || ay >= PATHFINDING_WIDTH) continue; /* height check */ if ((route[sz][ay][ax] & 0x0F) > h) @@ -237,7 +238,7 @@ if ((fall[ay][ax] & deep_fall[sz]) == deep_fall[sz]) continue; - /* test for walls */ + /* Create the end point of the line to test. */ VectorAdd(start, move_vec[i], te); /* center check */