finished tutorial
This commit is contained in:
parent
89b4bce734
commit
843606bcbf
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
Actor::Actor(int x, int y, std::string_view ch, std::string name, const TCOD_ColorRGB& col) :
|
Actor::Actor(int x, int y, std::string_view ch, std::string name, const TCOD_ColorRGB& col) :
|
||||||
x(x), y(y), ch(ch), col(col), name(name),
|
x(x), y(y), ch(ch), col(col), name(name),
|
||||||
blocks(true), attacker(nullptr), destructible(nullptr), ai(nullptr), pickable(nullptr), container(nullptr) {
|
blocks(true), attacker(nullptr), destructible(nullptr), ai(nullptr), pickable(nullptr), container(nullptr), fovOnly(true) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
Actor.h
1
Actor.h
@ -17,6 +17,7 @@ public:
|
|||||||
TCOD_ColorRGB col; // color
|
TCOD_ColorRGB col; // color
|
||||||
std::string name;
|
std::string name;
|
||||||
bool blocks;
|
bool blocks;
|
||||||
|
bool fovOnly; // only display when in fov
|
||||||
Attacker* attacker;
|
Attacker* attacker;
|
||||||
Destructible* destructible;
|
Destructible* destructible;
|
||||||
Ai* ai;
|
Ai* ai;
|
||||||
|
51
Ai.cpp
51
Ai.cpp
@ -10,10 +10,43 @@
|
|||||||
#include "Pickable.h"
|
#include "Pickable.h"
|
||||||
#include "Container.h"
|
#include "Container.h"
|
||||||
|
|
||||||
|
PlayerAi::PlayerAi() : xpLevel(1) {
|
||||||
|
}
|
||||||
|
|
||||||
|
const int LEVEL_UP_BASE = 200;
|
||||||
|
const int LEVEL_UP_FACTOR = 150;
|
||||||
|
|
||||||
|
int PlayerAi::getNextLevelXp() {
|
||||||
|
return LEVEL_UP_BASE + xpLevel * LEVEL_UP_FACTOR;
|
||||||
|
}
|
||||||
|
|
||||||
void PlayerAi::update(Actor* owner) {
|
void PlayerAi::update(Actor* owner) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
int dx = 0, dy = 0;
|
int dx = 0, dy = 0;
|
||||||
|
int levelUpXp = getNextLevelXp();
|
||||||
|
if (owner->destructible->xp >= levelUpXp) {
|
||||||
|
xpLevel++;
|
||||||
|
owner->destructible->xp -= levelUpXp;
|
||||||
|
engine->gui->message(TCOD_ColorRGB(255, 255, 100), "Your battle skills grow stronger! You reached level %d", xpLevel);
|
||||||
|
engine->gui->menu.clear();
|
||||||
|
engine->gui->menu.addItem(Menu::CONSTITUTION, "Constitution (+20HP)");
|
||||||
|
engine->gui->menu.addItem(Menu::STRENGTH, "Strength (+1 attack)");
|
||||||
|
engine->gui->menu.addItem(Menu::AGILITY, "Agility (+1 defense)");
|
||||||
|
Menu::MenuItemCode menuItem = engine->gui->menu.pick(engine->context, engine->console, Menu::PAUSE);
|
||||||
|
switch (menuItem) {
|
||||||
|
case Menu::CONSTITUTION:
|
||||||
|
owner->destructible->maxHp += 20;
|
||||||
|
owner->destructible->hp += 20;
|
||||||
|
break;
|
||||||
|
case Menu::STRENGTH:
|
||||||
|
owner->attacker->power += 1;
|
||||||
|
break;
|
||||||
|
case Menu::AGILITY:
|
||||||
|
owner->destructible->defense += 1;
|
||||||
|
break;
|
||||||
|
default:break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (owner->destructible && owner->destructible->isDead()) {
|
if (owner->destructible && owner->destructible->isDead()) {
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
@ -56,9 +89,7 @@ void PlayerAi::update(Actor* owner) {
|
|||||||
engine->gameStatus = Engine::PAUSE;
|
engine->gameStatus = Engine::PAUSE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (event.key.key >= SDLK_A && event.key.key <= SDLK_Z) {
|
handleActionKey(owner, event.key.key, event.key.mod);
|
||||||
handleActionKey(owner, event.key.key);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -78,7 +109,7 @@ void PlayerAi::update(Actor* owner) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerAi::handleActionKey(Actor* owner, int sdlkey) {
|
void PlayerAi::handleActionKey(Actor* owner, int sdlkey, int mod) {
|
||||||
switch (sdlkey) {
|
switch (sdlkey) {
|
||||||
case SDLK_G: // pickup item
|
case SDLK_G: // pickup item
|
||||||
{
|
{
|
||||||
@ -126,6 +157,16 @@ void PlayerAi::handleActionKey(Actor* owner, int sdlkey) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SDLK_PERIOD:
|
||||||
|
if (mod & SDL_KMOD_SHIFT) {
|
||||||
|
if (engine->stairs->x == owner->x && engine->stairs->y == owner->y) {
|
||||||
|
engine->nextLevel();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
engine->gui->message(TCOD_ColorRGB(200, 200, 200), "There are no stairs here.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
Ai.h
6
Ai.h
@ -20,9 +20,13 @@ public:
|
|||||||
void update(Actor* owner);
|
void update(Actor* owner);
|
||||||
void load(TCODZip& zip);
|
void load(TCODZip& zip);
|
||||||
void save(TCODZip& zip);
|
void save(TCODZip& zip);
|
||||||
|
int xpLevel;
|
||||||
|
PlayerAi();
|
||||||
|
int getNextLevelXp();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool moveOrAttack(Actor* owner, int targetx, int targety);
|
bool moveOrAttack(Actor* owner, int targetx, int targety);
|
||||||
void handleActionKey(Actor* owner, int sdlkey);
|
void handleActionKey(Actor* owner, int sdlkey, int mod);
|
||||||
Actor* choseFromInventory(Actor* owner);
|
Actor* choseFromInventory(Actor* owner);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
#include "Engine.h"
|
#include "Engine.h"
|
||||||
#include "Gui.h"
|
#include "Gui.h"
|
||||||
|
|
||||||
Destructible::Destructible(float maxHp, float defense, std::string corpseName) :
|
Destructible::Destructible(float maxHp, float defense, std::string corpseName, int xp) :
|
||||||
maxHp(maxHp), hp(maxHp), defense(defense), corpseName(corpseName) {
|
maxHp(maxHp), hp(maxHp), defense(defense), corpseName(corpseName), xp(xp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float Destructible::takeDamage(Actor* owner, float damage) {
|
float Destructible::takeDamage(Actor* owner, float damage) {
|
||||||
@ -39,12 +39,12 @@ void Destructible::die(Actor* owner) {
|
|||||||
engine->sendToBack(owner);
|
engine->sendToBack(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
MonsterDestructible::MonsterDestructible(float maxHp, float defense, std::string corpseName) :
|
MonsterDestructible::MonsterDestructible(float maxHp, float defense, std::string corpseName, int xp) :
|
||||||
Destructible(maxHp, defense, corpseName) {
|
Destructible(maxHp, defense, corpseName, xp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerDestructible::PlayerDestructible(float maxHp, float defense, std::string corpseName) :
|
PlayerDestructible::PlayerDestructible(float maxHp, float defense, std::string corpseName) :
|
||||||
Destructible(maxHp, defense, corpseName) {
|
Destructible(maxHp, defense, corpseName, 1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerDestructible::save(TCODZip& zip) {
|
void PlayerDestructible::save(TCODZip& zip) {
|
||||||
@ -60,7 +60,10 @@ void MonsterDestructible::save(TCODZip& zip) {
|
|||||||
void MonsterDestructible::die(Actor* owner) {
|
void MonsterDestructible::die(Actor* owner) {
|
||||||
// transform it into a nasty corpse! it doesn't block, can't be
|
// transform it into a nasty corpse! it doesn't block, can't be
|
||||||
// attacked and doesn't move
|
// attacked and doesn't move
|
||||||
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s is dead\n", owner->name.c_str());
|
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s is dead. You gain %d xp",
|
||||||
|
owner->name.c_str(), xp);
|
||||||
|
engine->player->destructible->xp += xp;
|
||||||
|
|
||||||
Destructible::die(owner);
|
Destructible::die(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +78,7 @@ void Destructible::load(TCODZip& zip) {
|
|||||||
hp = zip.getFloat();
|
hp = zip.getFloat();
|
||||||
defense = zip.getFloat();
|
defense = zip.getFloat();
|
||||||
corpseName = zip.getString();
|
corpseName = zip.getString();
|
||||||
|
xp = zip.getInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Destructible::save(TCODZip& zip) {
|
void Destructible::save(TCODZip& zip) {
|
||||||
@ -82,13 +86,14 @@ void Destructible::save(TCODZip& zip) {
|
|||||||
zip.putFloat(hp);
|
zip.putFloat(hp);
|
||||||
zip.putFloat(defense);
|
zip.putFloat(defense);
|
||||||
zip.putString(corpseName.c_str());
|
zip.putString(corpseName.c_str());
|
||||||
|
zip.putInt(xp);
|
||||||
}
|
}
|
||||||
|
|
||||||
Destructible* Destructible::create(TCODZip& zip) {
|
Destructible* Destructible::create(TCODZip& zip) {
|
||||||
DestructibleType type = (DestructibleType)zip.getInt();
|
DestructibleType type = (DestructibleType)zip.getInt();
|
||||||
Destructible* destructible = NULL;
|
Destructible* destructible = NULL;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MONSTER: destructible = new MonsterDestructible(0, 0, ""); break;
|
case MONSTER: destructible = new MonsterDestructible(0, 0, "", 0); break;
|
||||||
case PLAYER: destructible = new PlayerDestructible(0, 0, ""); break;
|
case PLAYER: destructible = new PlayerDestructible(0, 0, ""); break;
|
||||||
}
|
}
|
||||||
destructible->load(zip);
|
destructible->load(zip);
|
||||||
|
@ -13,7 +13,7 @@ public:
|
|||||||
float defense; // hit points deflected
|
float defense; // hit points deflected
|
||||||
std::string corpseName; // the actor's name once dead/destroyed
|
std::string corpseName; // the actor's name once dead/destroyed
|
||||||
|
|
||||||
Destructible(float maxHp, float defense, std::string corpseName);
|
Destructible(float maxHp, float defense, std::string corpseName, int xp);
|
||||||
virtual ~Destructible() {};
|
virtual ~Destructible() {};
|
||||||
inline bool isDead() { return hp <= 0; }
|
inline bool isDead() { return hp <= 0; }
|
||||||
float takeDamage(Actor* owner, float damage);
|
float takeDamage(Actor* owner, float damage);
|
||||||
@ -23,6 +23,7 @@ public:
|
|||||||
void load(TCODZip& zip);
|
void load(TCODZip& zip);
|
||||||
void save(TCODZip& zip);
|
void save(TCODZip& zip);
|
||||||
static Destructible* create(TCODZip& zip);
|
static Destructible* create(TCODZip& zip);
|
||||||
|
int xp; // XP gained when killing this monster (or player xp)
|
||||||
protected:
|
protected:
|
||||||
enum DestructibleType {
|
enum DestructibleType {
|
||||||
MONSTER, PLAYER
|
MONSTER, PLAYER
|
||||||
@ -31,7 +32,7 @@ protected:
|
|||||||
|
|
||||||
class MonsterDestructible : public Destructible {
|
class MonsterDestructible : public Destructible {
|
||||||
public:
|
public:
|
||||||
MonsterDestructible(float maxHp, float defense, std::string corpseName);
|
MonsterDestructible(float maxHp, float defense, std::string corpseName, int xp);
|
||||||
void save(TCODZip& zip);
|
void save(TCODZip& zip);
|
||||||
void die(Actor* owner);
|
void die(Actor* owner);
|
||||||
};
|
};
|
||||||
|
46
Engine.cpp
46
Engine.cpp
@ -14,6 +14,7 @@ Engine::Engine(int screenWidth, int screenHeight, tcod::Context *context, tcod::
|
|||||||
this->console = console;
|
this->console = console;
|
||||||
this->screenWidth = screenWidth;
|
this->screenWidth = screenWidth;
|
||||||
this->screenHeight = screenHeight;
|
this->screenHeight = screenHeight;
|
||||||
|
this->level = 1;
|
||||||
gui = nullptr;
|
gui = nullptr;
|
||||||
map = nullptr;
|
map = nullptr;
|
||||||
player = nullptr;
|
player = nullptr;
|
||||||
@ -32,13 +33,36 @@ void Engine::init() {
|
|||||||
player->ai = new PlayerAi();
|
player->ai = new PlayerAi();
|
||||||
player->container = new Container(26);
|
player->container = new Container(26);
|
||||||
actors.push(player);
|
actors.push(player);
|
||||||
map = new Map(80, 45);
|
stairs = new Actor(0, 0, ">", "stairs", TCOD_ColorRGB(255,255,255));
|
||||||
|
stairs->blocks = false;
|
||||||
|
stairs->fovOnly = false;
|
||||||
|
actors.push(stairs);
|
||||||
|
map = new Map(80, 43);
|
||||||
map->init(true);
|
map->init(true);
|
||||||
gui->message(TCOD_ColorRGB(150,0,0),
|
gui->message(TCOD_ColorRGB(150,0,0),
|
||||||
"Welcome stranger!\nPrepare to perish in the Tombs of Andrew's Dunegon.");
|
"Welcome stranger!\nPrepare to perish in the Tombs of Andrew's Dunegon.");
|
||||||
gameStatus = STARTUP;
|
gameStatus = STARTUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Engine::nextLevel() {
|
||||||
|
level++;
|
||||||
|
gui->message(TCOD_ColorRGB(255, 100, 255), "You take a moment to rest, and recover your strength.");
|
||||||
|
player->destructible->heal(player->destructible->maxHp / 2);
|
||||||
|
gui->message(TCOD_ColorRGB(255, 100, 100), "After a rare moment of peace, you descend\ndeeper into the heart of the dungeon...");
|
||||||
|
delete map;
|
||||||
|
// delete all actors but player and stairs
|
||||||
|
for (Actor** it = actors.begin(); it != actors.end(); it++) {
|
||||||
|
if (*it != player && *it != stairs) {
|
||||||
|
delete* it;
|
||||||
|
it = actors.remove(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// create a new map
|
||||||
|
map = new Map(80, 43);
|
||||||
|
map->init(true);
|
||||||
|
gameStatus = STARTUP;
|
||||||
|
}
|
||||||
|
|
||||||
void Engine::term() {
|
void Engine::term() {
|
||||||
actors.clearAndDelete();
|
actors.clearAndDelete();
|
||||||
if (map) delete map;
|
if (map) delete map;
|
||||||
@ -84,7 +108,9 @@ void Engine::render(bool present) {
|
|||||||
for (Actor** iterator = actors.begin();
|
for (Actor** iterator = actors.begin();
|
||||||
iterator != actors.end(); iterator++) {
|
iterator != actors.end(); iterator++) {
|
||||||
Actor* actor = *iterator;
|
Actor* actor = *iterator;
|
||||||
if (actor != player && map->isInFov(actor->x, actor->y)) {
|
if (actor != player && ((!actor->fovOnly && map->isExplored(actor->x, actor->y))
|
||||||
|
|| map->isInFov(actor->x, actor->y))) {
|
||||||
|
|
||||||
actor->render(*console);
|
actor->render(*console);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,8 +167,8 @@ bool Engine::pickATile(int* x, int* y, float maxRange) {
|
|||||||
engine->context->convert_event_coordinates(event);
|
engine->context->convert_event_coordinates(event);
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case SDL_EVENT_MOUSE_MOTION:
|
case SDL_EVENT_MOUSE_MOTION:
|
||||||
engine->mouse.cx = event.motion.x;
|
engine->mouse.cx = (int)event.motion.x;
|
||||||
engine->mouse.cy = event.motion.y;
|
engine->mouse.cy = (int)event.motion.y;
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||||
engine->mouse.lbutton_pressed = event.button.button == SDL_BUTTON_LEFT;
|
engine->mouse.lbutton_pressed = event.button.button == SDL_BUTTON_LEFT;
|
||||||
@ -189,15 +215,18 @@ void Engine::save() {
|
|||||||
else {
|
else {
|
||||||
TCODZip zip;
|
TCODZip zip;
|
||||||
// save the map first
|
// save the map first
|
||||||
|
zip.putInt(level);
|
||||||
zip.putInt(map->width);
|
zip.putInt(map->width);
|
||||||
zip.putInt(map->height);
|
zip.putInt(map->height);
|
||||||
map->save(zip);
|
map->save(zip);
|
||||||
// then the player
|
// then the player
|
||||||
player->save(zip);
|
player->save(zip);
|
||||||
|
// then the stairs
|
||||||
|
stairs->save(zip);
|
||||||
// then all the other actors
|
// then all the other actors
|
||||||
zip.putInt(actors.size() - 1);
|
zip.putInt(actors.size() - 2);
|
||||||
for (Actor** it = actors.begin(); it != actors.end(); it++) {
|
for (Actor** it = actors.begin(); it != actors.end(); it++) {
|
||||||
if (*it != player) {
|
if (*it != player && *it != stairs) {
|
||||||
(*it)->save(zip);
|
(*it)->save(zip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,6 +261,7 @@ void Engine::load() {
|
|||||||
term();
|
term();
|
||||||
zip.loadFromFile("game.sav");
|
zip.loadFromFile("game.sav");
|
||||||
// load the map
|
// load the map
|
||||||
|
level = zip.getInt();
|
||||||
int width = zip.getInt();
|
int width = zip.getInt();
|
||||||
int height = zip.getInt();
|
int height = zip.getInt();
|
||||||
map = new Map(width, height);
|
map = new Map(width, height);
|
||||||
@ -240,6 +270,10 @@ void Engine::load() {
|
|||||||
player = new Actor(0, 0, "?", "", TCOD_ColorRGB(255, 255, 255));
|
player = new Actor(0, 0, "?", "", TCOD_ColorRGB(255, 255, 255));
|
||||||
player->load(zip);
|
player->load(zip);
|
||||||
actors.push(player);
|
actors.push(player);
|
||||||
|
// the stairs
|
||||||
|
stairs = new Actor(0, 0, "?", "", TCOD_ColorRGB(255, 255, 255));
|
||||||
|
stairs->load(zip);
|
||||||
|
actors.push(stairs);
|
||||||
// then all other actors
|
// then all other actors
|
||||||
int nbActors = zip.getInt();
|
int nbActors = zip.getInt();
|
||||||
while (nbActors > 0) {
|
while (nbActors > 0) {
|
||||||
|
3
Engine.h
3
Engine.h
@ -22,6 +22,9 @@ public:
|
|||||||
TCOD_mouse_t mouse;
|
TCOD_mouse_t mouse;
|
||||||
TCODList<Actor*> actors;
|
TCODList<Actor*> actors;
|
||||||
Actor* player;
|
Actor* player;
|
||||||
|
Actor* stairs;
|
||||||
|
int level;
|
||||||
|
void nextLevel();
|
||||||
Map* map;
|
Map* map;
|
||||||
Gui* gui;
|
Gui* gui;
|
||||||
int fovRadius;
|
int fovRadius;
|
||||||
|
36
Gui.cpp
36
Gui.cpp
@ -1,9 +1,11 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
#include "libtcod.hpp"
|
||||||
#include "Gui.h"
|
#include "Gui.h"
|
||||||
#include "Engine.h"
|
#include "Engine.h"
|
||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
#include "Destructible.h"
|
#include "Destructible.h"
|
||||||
|
#include "Ai.h"
|
||||||
|
|
||||||
static const int PANEL_HEIGHT = 7;
|
static const int PANEL_HEIGHT = 7;
|
||||||
static const int BAR_WIDTH = 20;
|
static const int BAR_WIDTH = 20;
|
||||||
@ -30,6 +32,13 @@ void Gui::render() {
|
|||||||
renderBar(1, 1, BAR_WIDTH, "HP", engine->player->destructible->hp,
|
renderBar(1, 1, BAR_WIDTH, "HP", engine->player->destructible->hp,
|
||||||
engine->player->destructible->maxHp,
|
engine->player->destructible->maxHp,
|
||||||
TCOD_ColorRGB(255,100,100), TCOD_ColorRGB(100, 0, 0));
|
TCOD_ColorRGB(255,100,100), TCOD_ColorRGB(100, 0, 0));
|
||||||
|
// draw the XP bar
|
||||||
|
PlayerAi* ai = (PlayerAi*)engine->player->ai;
|
||||||
|
renderBar(1, 5, BAR_WIDTH, "XP(" + std::to_string(ai->xpLevel) + ")", engine->player->destructible->xp,
|
||||||
|
ai->getNextLevelXp(),
|
||||||
|
TCOD_ColorRGB(255, 100, 255), TCOD_ColorRGB(100,0,100));
|
||||||
|
|
||||||
|
tcod::print(con, { 3, 3 }, "Dungeon level " + std::to_string(engine->level), TCOD_ColorRGB(255, 255, 255), std::nullopt);
|
||||||
|
|
||||||
// draw the message log
|
// draw the message log
|
||||||
int y = 1;
|
int y = 1;
|
||||||
@ -158,20 +167,36 @@ void Menu::addItem(MenuItemCode code, std::string label) {
|
|||||||
item->label = label;
|
item->label = label;
|
||||||
items.push(item);
|
items.push(item);
|
||||||
}
|
}
|
||||||
|
const int PAUSE_MENU_WIDTH = 30;
|
||||||
|
const int PAUSE_MENU_HEIGHT = 15;
|
||||||
|
Menu::MenuItemCode Menu::pick(tcod::Context *ctx, tcod::Console *con, DisplayMode mode) {
|
||||||
|
|
||||||
Menu::MenuItemCode Menu::pick(tcod::Context *ctx, tcod::Console *con) {
|
|
||||||
static TCODImage img("menu_background1.png");
|
|
||||||
int selectedItem = 0;
|
int selectedItem = 0;
|
||||||
|
int menux, menuy;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (mode == PAUSE) {
|
||||||
|
menux = engine->screenWidth / 2 - PAUSE_MENU_WIDTH / 2;
|
||||||
|
menuy = engine->screenHeight / 2 - PAUSE_MENU_HEIGHT / 2;
|
||||||
|
TCOD_ColorRGB fg(200, 180, 50);
|
||||||
|
TCOD_ColorRGB bg(0, 0, 0);
|
||||||
|
tcod::print_frame(*con, { menux, menuy, PAUSE_MENU_WIDTH, PAUSE_MENU_HEIGHT }, "Inventory", &fg, &bg, TCOD_BKGND_OVERLAY);
|
||||||
|
menux += 2;
|
||||||
|
menuy += 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
static TCODImage img("menu_background1.png");
|
||||||
img.blit2x(*con, 0, 0);
|
img.blit2x(*con, 0, 0);
|
||||||
|
menux = 10;
|
||||||
|
menuy = con->get_height() / 3;
|
||||||
|
}
|
||||||
|
|
||||||
int currentItem = 0;
|
int currentItem = 0;
|
||||||
for (MenuItem** it = items.begin(); it != items.end(); it++) {
|
for (MenuItem** it = items.begin(); it != items.end(); it++) {
|
||||||
if (currentItem == selectedItem) {
|
if (currentItem == selectedItem) {
|
||||||
tcod::print(*con, { 10, 10 + currentItem * 3 }, (*it)->label,TCOD_ColorRGB(255, 100, 255), std::nullopt);
|
tcod::print(*con, { menux, menuy + currentItem * 3 }, (*it)->label,TCOD_ColorRGB(255, 100, 255), std::nullopt);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tcod::print(*con, { 10, 10 + currentItem * 3 }, (*it)->label, TCOD_ColorRGB(200, 200, 200), std::nullopt);
|
tcod::print(*con, { menux, menuy + currentItem * 3 }, (*it)->label, TCOD_ColorRGB(200, 200, 200), std::nullopt);
|
||||||
}
|
}
|
||||||
currentItem++;
|
currentItem++;
|
||||||
}
|
}
|
||||||
@ -208,3 +233,4 @@ Menu::MenuItemCode Menu::pick(tcod::Context *ctx, tcod::Console *con) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
Gui.h
11
Gui.h
@ -9,12 +9,19 @@ public:
|
|||||||
NONE,
|
NONE,
|
||||||
NEW_GAME,
|
NEW_GAME,
|
||||||
CONTINUE,
|
CONTINUE,
|
||||||
EXIT
|
EXIT,
|
||||||
|
CONSTITUTION,
|
||||||
|
STRENGTH,
|
||||||
|
AGILITY
|
||||||
|
};
|
||||||
|
enum DisplayMode {
|
||||||
|
MAIN,
|
||||||
|
PAUSE
|
||||||
};
|
};
|
||||||
~Menu();
|
~Menu();
|
||||||
void clear();
|
void clear();
|
||||||
void addItem(MenuItemCode code, std::string label);
|
void addItem(MenuItemCode code, std::string label);
|
||||||
MenuItemCode pick(tcod::Context* ctx, tcod::Console* con);
|
MenuItemCode pick(tcod::Context* ctx, tcod::Console* con, DisplayMode mode = MAIN);
|
||||||
protected:
|
protected:
|
||||||
struct MenuItem {
|
struct MenuItem {
|
||||||
MenuItemCode code;
|
MenuItemCode code;
|
||||||
|
7
Map.cpp
7
Map.cpp
@ -175,6 +175,9 @@ void Map::createRoom(bool first, int x1, int y1, int x2, int y2, bool withActors
|
|||||||
nbItems--;
|
nbItems--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// set stairs position
|
||||||
|
engine->stairs->x = (x1 + x2) / 2;
|
||||||
|
engine->stairs->y = (y1 + y2) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::addMonster(int x, int y) {
|
void Map::addMonster(int x, int y) {
|
||||||
@ -183,7 +186,7 @@ void Map::addMonster(int x, int y) {
|
|||||||
// create an orc
|
// create an orc
|
||||||
Actor* orc = new Actor(x, y, "o", "orc",
|
Actor* orc = new Actor(x, y, "o", "orc",
|
||||||
TCOD_ColorRGB(0, 100, 0));
|
TCOD_ColorRGB(0, 100, 0));
|
||||||
orc->destructible = new MonsterDestructible(10, 0, "dead orc");
|
orc->destructible = new MonsterDestructible(10, 0, "dead orc", 5);
|
||||||
orc->attacker = new Attacker(3);
|
orc->attacker = new Attacker(3);
|
||||||
orc->ai = new MonsterAi();
|
orc->ai = new MonsterAi();
|
||||||
engine->actors.push(orc);
|
engine->actors.push(orc);
|
||||||
@ -192,7 +195,7 @@ void Map::addMonster(int x, int y) {
|
|||||||
// create a troll
|
// create a troll
|
||||||
Actor* troll = new Actor(x, y, "T", "troll",
|
Actor* troll = new Actor(x, y, "T", "troll",
|
||||||
TCOD_ColorRGB(0, 255, 0));
|
TCOD_ColorRGB(0, 255, 0));
|
||||||
troll->destructible = new MonsterDestructible(16, 1, "troll carcass");
|
troll->destructible = new MonsterDestructible(16, 1, "troll carcass", 10);
|
||||||
troll->attacker = new Attacker(4);
|
troll->attacker = new Attacker(4);
|
||||||
troll->ai = new MonsterAi();
|
troll->ai = new MonsterAi();
|
||||||
engine->actors.push(troll);
|
engine->actors.push(troll);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user