/** * @brief Calculated the new height level when something falls down from a certain position. * @param[in] map Pointer to client or server side routing table (clMap, svMap) * @param[in] pos Position in the map to start the fall (starting height is the z-value in this position) * @param[in] actorSize Give the field size of the actor (e.g. for 2x2 units) to check linked fields as well. * @return New z (height) value. * @return 0xFF if an error occurred. */ pos_t Grid_Fall (const routing_t *map, const actorSizeEnum_t actorSize, const pos3_t pos) { int z = pos[2], base, diff; qboolean flier = qfalse; /** @todo if an actor can fly, then set this to true. */ /* Is z off the map? */ if (z >= PATHFINDING_HEIGHT) { Com_DPrintf(DEBUG_PATHING, "Grid_Fall: z (height) out of bounds): z=%i max=%i\n", z, PATHFINDING_HEIGHT); return 0xFF; } /* If we can fly, then obviously we won't fall. */ if (flier) return z; /* Easy math- get the floor, integer divide by CELL_HEIGHT, add to z. * If z < 0, we are going down. * If z >= CELL_HEIGHT, we are going up. * If 0 <= z <= CELL_HEIGHT, then z / 16 = 0, no change. */ base = RT_FLOOR(map, actorSize, pos[0], pos[1], z); /* Hack to deal with negative numbers- otherwise rounds toward 0 instead of down. */ diff = base < 0 ? (base - (CELL_HEIGHT - 1)) / CELL_HEIGHT : base / CELL_HEIGHT; z += diff; /* The tracing code will set locations without a floor to -1. Compensate for that. */ if (z < 0) z = 0; else if (z >= PATHFINDING_HEIGHT) z = PATHFINDING_HEIGHT - 1; return z; }
/** * @brief Returns the height of the floor in a cell. * @param[in] map Pointer to client or server side routing table (clMap, svMap) * @param[in] actorSize width of the actor in cells * @param[in] pos Position in the map to check the height * @return The actual model height of the cell's floor. */ int Grid_Floor (const routing_t *map, const actorSizeEnum_t actorSize, const pos3_t pos) { /* max 8 levels */ if (pos[2] >= PATHFINDING_HEIGHT) { Com_Printf("Grid_Floor: Warning: z level is bigger than %i: %i\n", (PATHFINDING_HEIGHT - 1), pos[2]); } return QuantToModel(RT_FLOOR(map, actorSize, pos[0], pos[1], pos[2] & (PATHFINDING_HEIGHT - 1))); }
/** * @brief evaluate access state for given position for given routing data * @param routes routing data * @param pos position to evaluate * @return access state as enum value for later rendering */ static EAccessState evaluateAccessState (const routing_t routes[ACTOR_MAX_SIZE], const pos3_t pos, const int actorSize) { const int height = QuantToModel(RT_CEILING(routes, actorSize, pos[0], pos[1], pos[2] & (PATHFINDING_HEIGHT - 1)) - RT_FLOOR(routes, actorSize, pos[0], pos[1], pos[2] & (PATHFINDING_HEIGHT - 1))); if (height >= PLAYER_STANDING_HEIGHT) return ACC_STAND; else if (height >= PLAYER_CROUCHING_HEIGHT) return ACC_CROUCH; else return ACC_DISABLED; }