diff --git a/src/Game.cpp b/src/Game.cpp index 4e37772..d64dc3d 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -66,12 +66,30 @@ Game::initPlayer() { Weapon::WeaponType::PISTOL, Weapon::WeaponType::KNIFE, Gadget::GadgetType::NONE, Gadget::GadgetType::NONE }; - mGenerator.generateCurrentAreaIfNeeded(Vector2f(), playerItems); + auto enemySpawns = mGenerator.generateCurrentAreaIfNeeded(Vector2f()); mPlayer = std::shared_ptr(new Player(mWorld, mPathfinder, mGenerator.getPlayerSpawn(), playerItems)); mWorld.insertCharacter(mPlayer); + insertEnemies(enemySpawns); } +/** + * Inserts enemies at the given positions, if they are more than + * Character::VISION_DISTANCE away from the player's postion. + */ +void +Game::insertEnemies(const std::vector& positions) { + for (const auto& spawn : positions) { + if (thor::length(spawn - mPlayer->getPosition()) > + Character::VISION_DISTANCE) + mWorld.insertCharacter(std::make_shared(mWorld, + mPathfinder, spawn, mPlayer->getEquippedItems())); + } +} + +/** + * Initializes the lights held by the player and sets light system parameters. + */ void Game::initLight() { Yaml config("light.yaml"); @@ -132,7 +150,8 @@ Game::loop() { render(); - mGenerator.generateCurrentAreaIfNeeded(mPlayer->getPosition(), mPlayer->getEquippedItems()); + auto enemySpawns = mGenerator.generateCurrentAreaIfNeeded(mPlayer->getPosition()); + insertEnemies(enemySpawns); } } diff --git a/src/Game.h b/src/Game.h index 41e7c43..848d4fe 100644 --- a/src/Game.h +++ b/src/Game.h @@ -43,6 +43,7 @@ private: void updateGui(); void initPlayer(); void initLight(); + void insertEnemies(const std::vector& positions); private: static const int FPS_GOAL = 60; diff --git a/src/generator/Generator.cpp b/src/generator/Generator.cpp index e5d2697..0487d60 100644 --- a/src/generator/Generator.cpp +++ b/src/generator/Generator.cpp @@ -39,15 +39,17 @@ Generator::Generator(World& world, Pathfinder& pathfinder, /** * Generates tiles near player position (maximum distance is determined by * GENERATE_AREA_SIZE and GENERATE_AREA_RANGE). + * + * @return Potential spawn points for enemies. Guaranteed to be on floor tiles. */ -void -Generator::generateCurrentAreaIfNeeded(const Vector2f& playerPosition, - const Character::EquippedItems& playerItems) { +std::vector +Generator::generateCurrentAreaIfNeeded(const Vector2f& position) { + std::vector enemySpawns; std::map open; std::set closed; - Vector2i start((int) floor(playerPosition.x / Tile::TILE_SIZE.x), - (int) floor(playerPosition.y / Tile::TILE_SIZE.y)); + Vector2i start((int) floor(position.x / Tile::TILE_SIZE.x), + (int) floor(position.y / Tile::TILE_SIZE.y)); start /= mAreaSize; auto makePair = [&start](const Vector2i& point) { return std::make_pair(point, thor::length(Vector2f(point - start))); @@ -65,12 +67,8 @@ Generator::generateCurrentAreaIfNeeded(const Vector2f& playerPosition, Vector2i(mAreaSize, mAreaSize) / 2, Vector2i(mAreaSize, mAreaSize)); generateTiles(area); - for (const auto& spawn : getEnemySpawns(area)) { - float distance = thor::length(spawn - playerPosition); - if (distance > Character::VISION_DISTANCE) - mWorld.insertCharacter(std::shared_ptr(new Enemy( - mWorld, mPathfinder, spawn, playerItems))); - } + auto spawnTemp = getEnemySpawns(area); + enemySpawns.insert(enemySpawns.end(), spawnTemp.begin(), spawnTemp.end()); } if (mGenerated[current.x][current.y] && distance <= mMaxRange) { if (closed.find(Vector2i(current.x + 1, current.y)) == closed.end()) @@ -83,6 +81,7 @@ Generator::generateCurrentAreaIfNeeded(const Vector2f& playerPosition, open.insert(makePair(Vector2i(current.x, current.y - 1))); } } + return enemySpawns; } /** diff --git a/src/generator/Generator.h b/src/generator/Generator.h index 4dbdab4..025cb30 100644 --- a/src/generator/Generator.h +++ b/src/generator/Generator.h @@ -28,10 +28,8 @@ class Generator : public sf::Drawable { public: explicit Generator(World& world, Pathfinder& pathfinder, ltbl::LightSystem& lightSystem, const Yaml& config); - void generateCurrentAreaIfNeeded(const Vector2f& position, - const Character::EquippedItems& playerItems); + std::vector generateCurrentAreaIfNeeded(const Vector2f& position); Vector2f getPlayerSpawn() const; - std::vector getEnemySpawns(const sf::IntRect& area); private: typedef std::map > array; @@ -43,6 +41,7 @@ private: std::vector createMinimalSpanningTree( const Vector2i& start, const float limit); void connectRooms(const Vector2i& start); + std::vector getEnemySpawns(const sf::IntRect& area); void draw(sf::RenderTarget& target, sf::RenderStates states) const; private: