Roguelike Game in C++17
Placing enemies.
Slowly we get closer to something resembling a game. Player can move around, they don't see the whole map. There are random rooms, tunnels/hallways. But there is nothing else to do. This section solve that last problem, by adding entities to direct player's RAGEEEEEEEEEEE!
Goals
So breaking down the tasks for this section, we get
- Add randomized number of enemies in each room.
- Draw them only if Player can see them.
- Collision detection with enemies.
Demons of the world
To generate all the enemies, we will modify the game_entity
structure.
Gone are char
and TCODColor
member variables, and in comes entity_type
member variable. entity_type
is an enum class with 3 values for the moment.
- player
- ogre
- goblin
Logically speaking, there is nothing really special about the player. So I'll be treating them same as any other character in the game.
Additionally, there is now face
method within game_entity
structure. This method
will return a std::pair
of char
and TCODColor
from a file local std::array
object. Values in this array are placed in same order as entity_type
values, so
it can be indexed into. We have to also change console_layer::draw
method for entities
to use face
method to get info about how to draw a game_entity
, done via structured
binding.
Another new function being added is generate_enemies
, which will return a list of
game_entity
objects with type
member begin either ogre
or goblin
. It will take
in list of all the rooms in the map, and place these game_entity
objects within those
rooms. We are again use C++17 random header for random number generation. place_enemies_in_room
lambda will place between 0
and max_enemies_per_room
enemies in the room provided.
The distribution between goblins
and ogres
is 80/20, meaning 80% of the time it's goblins
rest is ogres.
Lastly, for this section, we modify the main
function. Removed the player specific game_entity
object, and added a call to generate_enemies
. After getting a list of enemies, we add a player
specific game_entity
object to the list of all entities, along with creating a reference to
the same player object in the all entities list.
To draw all of them, there is simple for loop that just goes over all entities
and calls console_layer::draw
.
In the darkness hides
We have all the entities in the world rendering, but it sort of gives away their position to the player, removing all the suspense.
So for this section, we will change how console_layer::draw
works with entities, by removing
draw method for a singular entity, and adding draw method to take whole entities list at once.
In order to hide any entity not in player's view, we will also pass in the fov_map
.
Then is a matter of simply looping through the entities list, and check if they are in player's
field of view. If they are, then draw them, else continue to next. Also removed is the for loop
in main
function that did the looping, instead it's just a single line call to our new draw
method.
Don't tread on my personal space
We now have enemies appearing only if they are in player's field of view, but they are bit ethreal. Player can simple walk over them, surely demons would object to such attitude.
In order to stop the player from doing this we'll change the do_action
function, it will
now also take in list of all the entities. In the move
switch case block, we now attempt
to find out if the position the player will move into is already occupied or not. If it's not
occupied, then player can continue to that point. However, if it is occupied then, we will
print a flavour text message to the console.
To support checking if point on the map is occupied, get_entity_at
function has been added
to game_entity[.cpp|.hpp]
. Also to support printing of flavour text to_string
function also
now exists in the same file.
Now when player attempts to walk over ogres and goblins, they won't be able to. And they'll also annoy the creature they bumped into.

Links
╣ GitHub Repo ╠═══
╣ Home ╠═══
╣ Prev: Player's field of view ╠═══
╣ Next: Combat ╠═══