Complete roguelike tutorial using C++ and libtcod - part 5: preparing for combat
Complete roguelike tutorial using C++ and libtcod -originally written by Jice Text in this tutorial was released under the Creative Commons Attribution-ShareAlike 3.0 Unported and the GNU Free Documentation License (unversioned, with no invariant sections, front-cover texts, or back-cover texts) on 2015-09-21. |
---|
|
In this part, we'll do some refactoring to prepare the monster bashing. This includes detecting actor collisions (an actor trying to step on a tile where there already is an actor) and properly handling game turns.
Don't step on my shoes
First, we want to detect when the player tries to walk on a Tile occupied by another actor as this is the basis for melee combat. We keep the Map::isWall function but we add a Map::canWalk that handles both walls and actors.
In Map.hpp :
bool canWalk(int x, int y) const;
And the implementation in Map.cpp :
bool Map::canWalk(int x, int y) const { if (isWall(x,y)) { // this is a wall return false; } for (Actor **iterator=engine.actors.begin(); iterator!=engine.actors.end();iterator++) { Actor *actor=*iterator; if ( actor->x == x && actor->y == y ) { // there is an actor there. cannot walk return false; } } return true; }
First, the function checks if there is a wall. Else, it scans the actor list and returns false if there is an actor at given position.
Fill the rooms with monsters
Now we'll replace the inoffensive @ NPCs with ugly smelly orcs and trolls. Let's first define the maximum number of monsters per room.
static const int MAX_ROOM_MONSTERS = 3;
We add a createMonster function to place a new monster somewhere on the map :
Map.hpp :
void addMonster(int x, int y);
Map.cpp :
void Map::addMonster(int x, int y) { TCODRandom *rng=TCODRandom::getInstance(); if ( rng->getInt(0,100) < 80 ) { // create an orc engine.actors.push(new Actor(x,y,'o',"orc", TCODColor::desaturatedGreen)); } else { // create a troll engine.actors.push(new Actor(x,y,'T',"troll", TCODColor::darkerGreen)); } }
We create an orc in 80% of the cases, or a troll.
Now we change the createRoom function :
TCODRandom *rng=TCODRandom::getInstance(); int nbMonsters=rng->getInt(0,MAX_ROOM_MONSTERS); while (nbMonsters > 0) { int x=rng->getInt(x1,x2); int y=rng->getInt(y1,y2); if ( canWalk(x,y) ) { addMonster(x,y); } nbMonsters--; }
First we get a random number of monsters and for each one, get a random position inside the room. If the tile is empty (canWalk) we create a monster.