Difference between revisions of "Complete roguelike tutorial using C++ and libtcod - part 5: preparing for combat"

From RogueBasin
Jump to navigation Jump to search
Line 30: Line 30:


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.
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.




[[Category:Developing]]
[[Category:Developing]]

Revision as of 15:07, 6 October 2015

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.