ICT290 / src / scene / theArchanist / map / gameMap.h
gameMap.h
Raw
#pragma once
#include "../../../engine/resources.h"
#include "gameRoom.h"

#define GM_X_MAX 50
#define GM_Z_MAX 50

typedef std::vector<std::pair<int, int>> DoorSet;
typedef std::vector<std::vector<std::vector<glm::vec3>>> WallPoints;
typedef std::vector<std::vector<std::pair<glm::vec3, float>>> EntityBSphere;

/**
 * @class gameMap
 * @brief A class to create a series of rooms and connect them via corridors.
 * A map contains the information for each room and all entities, as well as
 * debug data.
 *
 * @author Chase Percy
 *
 */
class gameMap {
   public:
    gameMap() = default;

    gameMap(std::size_t numRooms,
            const Resources& resources,
            std::string& modelList,
            int seed);

    /**
     * Draws all rooms in the map.
     */
    void draw();

    /**
     * Only draws the rooms in the map that are within the specified distance of
     * the cameras current location.
     * @param camPos the current camera position.
     * @param distance the max draw distance
     */
    void draw(glm::vec3 camPos, float distance);

    /**
     * return the wall points for the main rooms
     * @return wall points
     */
    const WallPoints& getWallPoints();

    /**
     * return the corridor wall points
     * @return wall points
     */
    const WallPoints& getCorridorWallPoints();

    /**
     * return the entity boundingSpheres
     * @return bounding spheres
     */
    const EntityBSphere& getBoundingSpheres();

    const std::vector<std::pair<glm::vec3, glm::vec3>>& getRoomSizes();

    bool m_debug{false};  /// toggle to enable / disable debug rendering

   private:
    /**
     * represents all info about a room
     */
    struct RoomInfo {
        int xSize{0};      /// x size of the room
        int zSize{0};      /// z size of the room
        int wallFil{0};    /// wall fill percent
        int floorFill{0};  /// floor fill percent
        int xOrigin{0};    /// x origin
        int zOrigin{0};    /// z origin
        DoorSet doors{};   /// doors

        RoomInfo() = default;
        RoomInfo(int, int, int, int, int, int, const DoorSet&);
    };

    /**
     * represents data for a door
     */
    struct DoorData {
        int x{0};                /// the relative x position of the door
        int z{0};                /// the relative z position of the door
        int connectingRoomX{0};  /// the x of the connecting door
        int connectingRoomZ{0};  /// the z of the connecting door
        RoomInfo info{};         /// info about the room the door belongs to

        DoorData() = default;
        DoorData(int, int, int, int, const RoomInfo&);
    };

    std::size_t m_numRooms{0};  /// the number of rooms to create on the map
    Resources m_resources;      /// engine resources for room creation
    int m_seed{0};              /// map seed
    std::vector<gameRoom> m_rooms{};         /// game rooms for the map
    std::vector<gameRoom> m_corridors{};     /// corridors for connecting rooms
    bool m_map[GM_X_MAX][GM_Z_MAX];          /// map array
    int m_seedOffset{0};                     /// seed offset
    std::vector<RoomInfo> m_roomInfo{};      /// info about all rooms in map
    std::vector<RoomInfo> m_corridorInfo{};  /// info about the corridors
    WallPoints m_wallPoints;                 /// wall points of main rooms
    WallPoints m_corridorWallPoints;         /// wall points of corridors
    EntityBSphere m_entityBSpheres;          /// entity data
    std::vector<std::pair<glm::vec3, glm::vec3>> m_roomSizes;
    gameRoom::RoomModels m_models;  /// models to use on main rooms
    gameRoom::RoomModels
        m_corridorModels;  /// models to use on corridors (wall[1] = nullptr so
                           /// doors dont draw

    /**
     * Reads all the models to use when creating a room
     * @param modelList the list with the models to read
     */
    void readModelFile(std::string& modelList);

    /**
     * generates the room info
     */
    void generateRooms();

    /**
     * generates the spawn room info
     * @return the info for the spawn room
     */
    RoomInfo generateSpawn();

    /**
     * Updates the main map with data about a new room
     * @param xSize the x size of the room
     * @param zSize the z size of the room
     * @param xOrigin the x origin
     * @param zOrigin the z origin
     * @return if the room was valid (not intersecting and with map bounds)
     */
    bool updateMap(int xSize, int zSize, int xOrigin, int zOrigin);

    /**
     * returns a random normal to be used when trying to spawn rooms
     * @return a random normal
     */
    glm::vec3 randomNormal();

    /**
     * Creates room objects from the room info generated
     */
    void createRooms();

    /**
     * Generates doors for a room that align with another room on the x & z axis
     */
    void generateDoors();

    /**
     * Based of the doors generated in generateDoors a single door is picked on
     * the x and z axis and creates a door on the room opposite. Creates the
     * door data for the room to generate.
     * @param roomInfo the info about this room
     * @param doorData the info about the door
     * @return the index of the door picked from door data
     */
    int insertDoors(RoomInfo& roomInfo, std::vector<DoorData>& doorData);

    /**
     * generates a corridor between two doors
     * @param doorData the door data used to create the corridor
     */
    void generateCorridor(const DoorData& doorData);

    /**
     * check all the corridor information generated for intersections and add
     * doors accordingly.
     */
    void checkCorridorIntersections();

    /**
     * Creates room objects from the corridor info generated. These rooms use
     * the special m_corridorModels.
     */
    void createCorridors();

    /**
     * Begins the map generation process
     * @param modelList the filename of the models to load
     */
    void mapGen(std::string& modelList);
};