#include "ArcanistLevel.h" #include <algorithm> #include <random> ArcanistLevel::~ArcanistLevel() { for (auto& m_allObstacle : m_allObstacles) { delete m_allObstacle; } } const Room& ArcanistLevel::getRoom(std::size_t i) const { if (i < m_rooms.size() && i > 0) { return m_rooms[i]; } throw std::invalid_argument( "ArchanistLevel::getRoom, Index out of bounds.\n"); } const std::vector<Room>& ArcanistLevel::getRooms() const { return m_rooms; } const Room& ArcanistLevel::getNearestRoom(const glm::vec2& position) const { auto room = std::find_if(m_rooms.begin(), m_rooms.end(), [position](const Room& room) { if (position.x >= room.min.x && position.y >= room.min.y && position.x <= room.max.x && position.y <= room.max.y) { return true; } return false; }); if (room != m_rooms.end()) { return *room; } else { throw std::runtime_error("getNearestRoom out of bound position\n"); } } bool ArcanistLevel::isInBounds(const glm::vec2& position) const { auto room = std::find_if(m_rooms.begin(), m_rooms.end(), [position](const Room& room) { if (position.x >= room.min.x + 0.25f && position.y >= room.min.y + 0.25f && position.x <= room.max.x - 1.25f && position.y <= room.max.y - 1.25f) { return true; } return false; }); if (room != m_rooms.end()) { return true; } return false; } bool ArcanistLevel::isInBoundsTight(const glm::vec2& position) const { auto room = std::find_if(m_rooms.begin(), m_rooms.end(), [position](const Room& room) { if (position.x >= room.min.x + 0.5f && position.y >= room.min.y + 0.5f && position.x <= room.max.x - 1.5f && position.y <= room.max.y - 1.5f) { return true; } return false; }); if (room != m_rooms.end()) { return true; } return false; } void ArcanistLevel::updateAllWalls() { m_allWalls.clear(); std::for_each(m_rooms.begin(), m_rooms.end(), [this](const Room& room) { std::copy(room.walls.begin(), room.walls.end(), std::back_inserter(m_allWalls)); }); } void ArcanistLevel::updateAllEntities() { m_allObstacles.clear(); std::for_each(m_rooms.begin(), m_rooms.end(), [this](const Room& room) { std::copy(room.obstacles.begin(), room.obstacles.end(), std::back_inserter(m_allObstacles)); }); } const std::vector<WallType>& ArcanistLevel::getAllWalls() const { return m_allWalls; } const std::vector<BasicEntity*>& ArcanistLevel::getAllObstacles() const { return m_allObstacles; } glm::vec2 ArcanistLevel::getRandomSpawn() { // Pick random room that isn't spawn or a corridor std::random_device rd{}; /// obtain a random number from hardware std::mt19937 gen{rd()}; /// seed the generator std::uniform_int_distribution<> distribution{1, (int)m_numOfRooms - 1}; /// define the range auto& room = m_rooms[distribution(gen)]; return getRandomSpawn(room); } glm::vec2 ArcanistLevel::getRandomSpawn(int seed) { // Pick random room that isn't spawn or a corridor std::mt19937 gen{static_cast<std::random_device::result_type>( seed)}; /// seed the generator std::uniform_int_distribution<> distribution{1, (int)m_numOfRooms - 1}; /// define the range const auto& room = m_rooms[distribution(gen)]; return getRandomSpawn(room, seed); } glm::vec2 ArcanistLevel::getRandomSpawn(const Room& room) { std::random_device rd{}; /// obtain a random number from hardware std::mt19937 gen{rd()}; /// seed the generator std::uniform_int_distribution<> xDist{(int)room.min.x + 1, (int)room.max.x - 2}; /// define the range std::uniform_int_distribution<> yDist{(int)room.min.y + 1, (int)room.max.y - 2}; return glm::vec2{(float)xDist(gen), (float)yDist(gen)}; } glm::vec2 ArcanistLevel::getRandomSpawn(const Room& room, int seed) { std::mt19937 gen{static_cast<std::random_device::result_type>(seed)}; std::uniform_int_distribution<> xDist{(int)room.min.x + 1, (int)room.max.x - 2}; /// define the range std::uniform_int_distribution<> yDist{(int)room.min.y + 1, (int)room.max.y - 2}; return glm::vec2{(float)xDist(gen), (float)yDist(gen)}; }