/** * @brief Checks if we can move in the given vertical direction * @return false if we can't move there */ bool Step::checkVerticalDirections () const { if (dir == DIRECTION_FALL) { if (flier) { /* Fliers cannot fall intentionally. */ return false; } else if (routing.getFloor(actorSize, fromPos) >= 0) { /* We cannot fall if there is a floor in this cell. */ return false; } else if (hasLadderSupport) { /* The actor can't fall if there is ladder support. */ return false; } } else if (dir == DIRECTION_CLIMB_UP) { if (flier && QuantToModel(routing.getCeiling(actorSize, fromPos)) < UNIT_HEIGHT * 2 - PLAYER_HEIGHT) { /* Not enough headroom to fly up. */ return false; } /* If the actor is not a flyer and tries to move up, there must be a ladder. */ if (dir == DIRECTION_CLIMB_UP && !hasLadderToClimb) { return false; } } else if (dir == DIRECTION_CLIMB_DOWN) { if (flier) { if (routing.getFloor(actorSize, fromPos) >= 0 ) { /* Can't fly down through a floor. */ return false; } } else { /* If the actor is not a flyer and tries to move down, there must be a ladder. */ if (!hasLadderToClimb) { return false; } } } return true; }
/** * @brief Checks if we can move in the given vertical direction * @param[in] step The struct describing the move * @param[in] pos Current location in the map. * @param[in] dir Direction vector index (see DIRECTIONS and dvecs) * @return false if we can't move there */ static qboolean Grid_StepCheckVerticalDirections (step_t *step, const pos3_t pos, const int dir) { if (dir == DIRECTION_FALL) { if (step->flier) { /* Fliers cannot fall intentionally. */ return qfalse; } else if (RT_FLOOR_POS(step->map, step->actorSize, pos) >= 0) { /* We cannot fall if there is a floor in this cell. */ return qfalse; } else if (step->hasLadderSupport) { /* The actor can't fall if there is ladder support. */ return qfalse; } } else if (dir == DIRECTION_CLIMB_UP) { if (step->flier && QuantToModel(RT_CEILING_POS(step->map, step->actorSize, pos)) < UNIT_HEIGHT * 2 - PLAYER_HEIGHT) { /* Not enough headroom to fly up. */ return qfalse; } /* If the actor is not a flyer and tries to move up, there must be a ladder. */ if (dir == DIRECTION_CLIMB_UP && !step->hasLadderToClimb) { return qfalse; } } else if (dir == DIRECTION_CLIMB_DOWN) { if (step->flier) { if (RT_FLOOR_POS(step->map, step->actorSize, pos) >= 0 ) { /* Can't fly down through a floor. */ return qfalse; } } else { /* If the actor is not a flyer and tries to move down, there must be a ladder. */ if (!step->hasLadderToClimb) { return qfalse; } } } return qtrue; }
/** * @brief Returns the maximum height of an obstruction that an actor can travel over. * @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 * @param[in] dir the direction in which we are moving * @return The actual model height increase needed to move into an adjacent cell. */ pos_t Grid_StepUp (const routing_t *map, const actorSizeEnum_t actorSize, const pos3_t pos, const int dir) { /* max 8 levels */ if (pos[2] >= PATHFINDING_HEIGHT) { Com_Printf("Grid_StepUp: Warning: z level is bigger than 7: %i\n", pos[2]); } return QuantToModel(RT_STEPUP(map, actorSize, pos[0], pos[1], pos[2] & (PATHFINDING_HEIGHT - 1), dir)); }
/** * @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 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 ceiling. */ unsigned int Grid_Ceiling (const routing_t *map, const actorSizeEnum_t actorSize, const pos3_t pos) { /* max 8 levels */ if (pos[2] >= PATHFINDING_HEIGHT) { Com_Printf("Grid_Height: Warning: z level is bigger than %i: %i\n", (PATHFINDING_HEIGHT - 1), pos[2]); } return QuantToModel(RT_CEILING(map, actorSize, pos[0], pos[1], pos[2] & 7)); }
/** * @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; }
/** * @brief Returns the height of the floor in a cell. * @param[in] routing Reference 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 &routing, const actorSizeEnum_t actorSize, const pos3_t pos) { assert(pos[2] < PATHFINDING_HEIGHT); return QuantToModel(routing.getFloor(actorSize, pos[0], pos[1], pos[2] & (PATHFINDING_HEIGHT - 1))); }
/** * @brief Returns the height of the floor in a cell. * @param[in] routing Reference 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 ceiling. */ unsigned int Grid_Ceiling (const Routing &routing, const actorSizeEnum_t actorSize, const pos3_t pos) { assert(pos[2] < PATHFINDING_HEIGHT); return QuantToModel(routing.getCeiling(actorSize, pos[0], pos[1], pos[2] & 7)); }