Improvements
This commit is contained in:
parent
843606bcbf
commit
ef522be8ef
3
ADG5.cpp
3
ADG5.cpp
@ -14,7 +14,8 @@ int main(int argc, char **argv)
|
||||
{
|
||||
auto console = tcod::Console(80, 50);
|
||||
auto params = TCOD_ContextParams{};
|
||||
|
||||
auto tileset = tcod::load_tilesheet("terminal10x16_gs_ro.png", { 16, 16 }, tcod::CHARMAP_CP437);
|
||||
params.tileset = tileset.get();
|
||||
params.console = console.get();
|
||||
params.window_title = "Andrew's Dungeon Game 5";
|
||||
params.sdl_window_flags = SDL_WINDOW_RESIZABLE;
|
||||
|
@ -16,7 +16,12 @@ Actor::Actor(int x, int y, std::string_view ch, std::string name, const TCOD_Col
|
||||
}
|
||||
|
||||
void Actor::render(TCOD_Console& cons) const {
|
||||
tcod::print(cons, { x, y }, ch, col, std::nullopt);
|
||||
int offset_x = engine->player->x - Engine::VIEW_WIDTH / 2;
|
||||
int offset_y = engine->player->y - Engine::VIEW_HEIGHT / 2;
|
||||
if (offset_x > x || Engine::VIEW_WIDTH + offset_x < x || offset_y > y || Engine::VIEW_HEIGHT + offset_y < y) {
|
||||
return;
|
||||
}
|
||||
tcod::print(cons, { x - offset_x, y - offset_y}, ch, col, std::nullopt);
|
||||
}
|
||||
|
||||
void Actor::update() {
|
||||
|
12
Ai.cpp
12
Ai.cpp
@ -27,7 +27,7 @@ void PlayerAi::update(Actor* owner) {
|
||||
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->message(engine->gui->lightYellow, "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)");
|
||||
@ -120,18 +120,18 @@ void PlayerAi::handleActionKey(Actor* owner, int sdlkey, int mod) {
|
||||
if (actor->pickable && actor->x == owner->x && actor->y == owner->y) {
|
||||
if (actor->pickable->pick(actor, owner)) {
|
||||
found = true;
|
||||
engine->gui->message(TCOD_ColorRGB(200,200,200), "You pick up the %s.",
|
||||
engine->gui->message(engine->gui->lightGrey, "You pick up the %s.",
|
||||
actor->name.c_str());
|
||||
break;
|
||||
}
|
||||
else if (!found) {
|
||||
found = true;
|
||||
engine->gui->message(TCOD_ColorRGB(255,0,0), "Your inventory is full.");
|
||||
engine->gui->message(engine->gui->red, "Your inventory is full.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
engine->gui->message(TCOD_ColorRGB(200,200,200), "There's nothing here that you can pick up.");
|
||||
engine->gui->message(engine->gui->lightGrey, "There's nothing here that you can pick up.");
|
||||
}
|
||||
if (engine->gameStatus != Engine::QUIT)
|
||||
engine->gameStatus = Engine::NEW_TURN;
|
||||
@ -163,7 +163,7 @@ void PlayerAi::handleActionKey(Actor* owner, int sdlkey, int mod) {
|
||||
engine->nextLevel();
|
||||
}
|
||||
else {
|
||||
engine->gui->message(TCOD_ColorRGB(200, 200, 200), "There are no stairs here.");
|
||||
engine->gui->message(engine->gui->lightGrey, "There are no stairs here.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -189,7 +189,7 @@ bool PlayerAi::moveOrAttack(Actor* owner, int targetx, int targety) {
|
||||
|| actor->pickable;
|
||||
if (corpseOrItem
|
||||
&& actor->x == targetx && actor->y == targety) {
|
||||
engine->gui->message(TCOD_ColorRGB(200,200,200), "There's a %s here.", actor->name.c_str());
|
||||
engine->gui->message(engine->gui->lightGrey, "There's a %s here.", actor->name.c_str());
|
||||
}
|
||||
}
|
||||
owner->x = targetx;
|
||||
|
@ -10,16 +10,16 @@ Attacker::Attacker(float power) : power(power) {
|
||||
void Attacker::attack(Actor* owner, Actor* target) {
|
||||
if (target->destructible && !target->destructible->isDead()) {
|
||||
if (power - target->destructible->defense > 0) {
|
||||
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s attacks %s for %g hit points.\n", owner->name.c_str(), target->name.c_str(),
|
||||
engine->gui->message(engine->gui->lightGrey, "%s attacks %s for %g hit points.\n", owner->name.c_str(), target->name.c_str(),
|
||||
power - target->destructible->defense);
|
||||
}
|
||||
else {
|
||||
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s attacks %s but it has no effect!\n", owner->name.c_str(), target->name.c_str());
|
||||
engine->gui->message(engine->gui->lightGrey, "%s attacks %s but it has no effect!\n", owner->name.c_str(), target->name.c_str());
|
||||
}
|
||||
target->destructible->takeDamage(target, power);
|
||||
}
|
||||
else {
|
||||
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s attacks %s in vain.\n", owner->name.c_str(), target->name.c_str());
|
||||
engine->gui->message(engine->gui->lightGrey, "%s attacks %s in vain.\n", owner->name.c_str(), target->name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ Confuser::Confuser(int nbTurns, float range)
|
||||
: nbTurns(nbTurns), range(range) {
|
||||
}
|
||||
bool Confuser::use(Actor* owner, Actor* wearer) {
|
||||
engine->gui->message(TCOD_ColorRGB(0, 255, 255), "Left-click an enemy to confuse it,\nor right-click to cancel.");
|
||||
engine->gui->message(engine->gui->lightBlue, "Left-click an enemy to confuse it,\nor right-click to cancel.");
|
||||
int x, y;
|
||||
if (!engine->pickATile(&x, &y, range)) {
|
||||
return false;
|
||||
@ -22,7 +22,7 @@ bool Confuser::use(Actor* owner, Actor* wearer) {
|
||||
// confuse the monster for <nbTurns> turns
|
||||
Ai* confusedAi = new ConfusedMonsterAi(nbTurns, actor->ai);
|
||||
actor->ai = confusedAi;
|
||||
engine->gui->message(TCOD_ColorRGB(100, 255, 100), "The eyes of the %s look vacant,\nas he starts to stumble around!",
|
||||
engine->gui->message(engine->gui->lightGreen, "The eyes of the %s look vacant,\nas he starts to stumble around!",
|
||||
actor->name.c_str());
|
||||
return Pickable::use(owner, wearer);
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ void MonsterDestructible::save(TCODZip& zip) {
|
||||
void MonsterDestructible::die(Actor* owner) {
|
||||
// transform it into a nasty corpse! it doesn't block, can't be
|
||||
// attacked and doesn't move
|
||||
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s is dead. You gain %d xp",
|
||||
engine->gui->message(engine->gui->lightGrey, "%s is dead. You gain %d xp",
|
||||
owner->name.c_str(), xp);
|
||||
engine->player->destructible->xp += xp;
|
||||
|
||||
@ -68,7 +68,7 @@ void MonsterDestructible::die(Actor* owner) {
|
||||
}
|
||||
|
||||
void PlayerDestructible::die(Actor* owner) {
|
||||
engine->gui->message(TCOD_ColorRGB(150, 0, 0), "You died!\n");
|
||||
engine->gui->message(engine->gui->red, "You died!\n");
|
||||
Destructible::die(owner);
|
||||
engine->gameStatus = Engine::DEFEAT;
|
||||
}
|
||||
|
10
Engine.cpp
10
Engine.cpp
@ -27,7 +27,7 @@ Engine::Engine(int screenWidth, int screenHeight, tcod::Context *context, tcod::
|
||||
}
|
||||
|
||||
void Engine::init() {
|
||||
player = new Actor(40, 25, "@", "player", TCOD_ColorRGB(255, 255, 255));
|
||||
player = new Actor(40, 25, "@", "player", engine->gui->white);
|
||||
player->destructible = new PlayerDestructible(30, 2, "player corpse");
|
||||
player->attacker = new Attacker(5);
|
||||
player->ai = new PlayerAi();
|
||||
@ -37,7 +37,7 @@ void Engine::init() {
|
||||
stairs->blocks = false;
|
||||
stairs->fovOnly = false;
|
||||
actors.push(stairs);
|
||||
map = new Map(80, 43);
|
||||
map = new Map(200, 100);
|
||||
map->init(true);
|
||||
gui->message(TCOD_ColorRGB(150,0,0),
|
||||
"Welcome stranger!\nPrepare to perish in the Tombs of Andrew's Dunegon.");
|
||||
@ -46,9 +46,9 @@ void Engine::init() {
|
||||
|
||||
void Engine::nextLevel() {
|
||||
level++;
|
||||
gui->message(TCOD_ColorRGB(255, 100, 255), "You take a moment to rest, and recover your strength.");
|
||||
gui->message(engine->gui->lightPurple, "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...");
|
||||
gui->message(engine->gui->lightRed, "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++) {
|
||||
@ -58,7 +58,7 @@ void Engine::nextLevel() {
|
||||
}
|
||||
}
|
||||
// create a new map
|
||||
map = new Map(80, 43);
|
||||
map = new Map(200, 100);
|
||||
map->init(true);
|
||||
gameStatus = STARTUP;
|
||||
}
|
||||
|
2
Engine.h
2
Engine.h
@ -7,6 +7,8 @@ class Gui;
|
||||
|
||||
class Engine {
|
||||
public:
|
||||
const static int VIEW_WIDTH = 80;
|
||||
const static int VIEW_HEIGHT = 43;
|
||||
enum GameStatus {
|
||||
STARTUP,
|
||||
IDLE,
|
||||
|
@ -10,18 +10,18 @@ Fireball::Fireball(float range, float damage)
|
||||
}
|
||||
|
||||
bool Fireball::use(Actor* owner, Actor* wearer) {
|
||||
engine->gui->message(TCOD_ColorRGB(0, 255, 255), "Left-click a target tile for the fireball,\nor right-click to cancel.");
|
||||
engine->gui->message(engine->gui->lightBlue, "Left-click a target tile for the fireball,\nor right-click to cancel.");
|
||||
int x, y;
|
||||
if (!engine->pickATile(&x, &y)) {
|
||||
return false;
|
||||
}
|
||||
engine->gui->message(TCOD_ColorRGB(255, 255, 100), "The fireball explodes, burning everything within %g tiles!", range);
|
||||
engine->gui->message(engine->gui->lightYellow, "The fireball explodes, burning everything within %g tiles!", range);
|
||||
for (Actor** iterator = engine->actors.begin();
|
||||
iterator != engine->actors.end(); iterator++) {
|
||||
Actor* actor = *iterator;
|
||||
if (actor->destructible && !actor->destructible->isDead()
|
||||
&& actor->getDistance(x, y) <= range) {
|
||||
engine->gui->message(TCOD_ColorRGB(255, 255, 100), "The %s gets burned for %g hit points.",
|
||||
engine->gui->message(engine->gui->lightYellow, "The %s gets burned for %g hit points.",
|
||||
actor->name.c_str(), damage);
|
||||
actor->destructible->takeDamage(actor, damage);
|
||||
}
|
||||
|
20
Gui.cpp
20
Gui.cpp
@ -15,6 +15,20 @@ static const int MSG_HEIGHT = PANEL_HEIGHT - 1;
|
||||
Gui::Gui(tcod::Context *ctx, tcod::Console *root) {
|
||||
con = ctx->new_console(engine->screenWidth, PANEL_HEIGHT);
|
||||
this->root = root;
|
||||
darkGrey = TCOD_ColorRGB(100,100,100);
|
||||
lightGrey = TCOD_ColorRGB(200,200,200);
|
||||
white = TCOD_ColorRGB(255,255,255);
|
||||
red = TCOD_ColorRGB(100, 50, 50);
|
||||
green = TCOD_ColorRGB(50, 100, 50);
|
||||
blue = TCOD_ColorRGB(50, 50, 100);
|
||||
yellow = TCOD_ColorRGB(100, 100, 50);
|
||||
black = TCOD_ColorRGB(0, 0, 0);
|
||||
lightBlue = TCOD_ColorRGB(100, 100, 255);
|
||||
lightGreen = TCOD_ColorRGB(100, 255, 100);
|
||||
lightRed = TCOD_ColorRGB(255, 100, 100);
|
||||
lightYellow = TCOD_ColorRGB(255, 255, 100);
|
||||
lightPurple = TCOD_ColorRGB(255, 100, 255);
|
||||
purple = TCOD_ColorRGB(100, 50, 100);
|
||||
}
|
||||
|
||||
void Gui::clear() {
|
||||
@ -186,8 +200,10 @@ Menu::MenuItemCode Menu::pick(tcod::Context *ctx, tcod::Console *con, DisplayMod
|
||||
else {
|
||||
static TCODImage img("menu_background1.png");
|
||||
img.blit2x(*con, 0, 0);
|
||||
menux = 10;
|
||||
menuy = con->get_height() / 3;
|
||||
TCOD_ColorRGB fg(200, 180, 50);
|
||||
TCOD_ColorRGB bg(0, 0, 0);
|
||||
menux = 7;
|
||||
menuy = 30;
|
||||
}
|
||||
|
||||
int currentItem = 0;
|
||||
|
15
Gui.h
15
Gui.h
@ -5,6 +5,7 @@
|
||||
|
||||
class Menu {
|
||||
public:
|
||||
|
||||
enum MenuItemCode {
|
||||
NONE,
|
||||
NEW_GAME,
|
||||
@ -32,6 +33,20 @@ protected:
|
||||
|
||||
class Gui : public Persistent {
|
||||
public:
|
||||
TCOD_ColorRGB darkGrey;
|
||||
TCOD_ColorRGB lightGrey;
|
||||
TCOD_ColorRGB white;
|
||||
TCOD_ColorRGB red;
|
||||
TCOD_ColorRGB green;
|
||||
TCOD_ColorRGB blue;
|
||||
TCOD_ColorRGB yellow;
|
||||
TCOD_ColorRGB black;
|
||||
TCOD_ColorRGB lightBlue;
|
||||
TCOD_ColorRGB lightGreen;
|
||||
TCOD_ColorRGB lightRed;
|
||||
TCOD_ColorRGB lightYellow;
|
||||
TCOD_ColorRGB lightPurple;
|
||||
TCOD_ColorRGB purple;
|
||||
Gui(tcod::Context *ctx, tcod::Console *root);
|
||||
~Gui();
|
||||
void render();
|
||||
|
@ -11,11 +11,11 @@ LightningBolt::LightningBolt(float range, float damage)
|
||||
bool LightningBolt::use(Actor* owner, Actor* wearer) {
|
||||
Actor* closestMonster = engine->getClosestMonster(wearer->x, wearer->y, range);
|
||||
if (!closestMonster) {
|
||||
engine->gui->message(TCOD_ColorRGB(200,200,200), "No enemy is close enough to strike.");
|
||||
engine->gui->message(engine->gui->white, "No enemy is close enough to strike.");
|
||||
return false;
|
||||
}
|
||||
// hit closest monster for <damage> hit points
|
||||
engine->gui->message(TCOD_ColorRGB(100, 255, 100),
|
||||
engine->gui->message(engine->gui->lightBlue,
|
||||
"A lighting bolt strikes the %s with a crack of thunder!\n"
|
||||
"The damage is %g hit points.",
|
||||
closestMonster->name.c_str(), damage);
|
||||
|
24
Map.cpp
24
Map.cpp
@ -9,6 +9,7 @@
|
||||
#include "Lightningbolt.h"
|
||||
#include "Fireball.h"
|
||||
#include "Confuser.h"
|
||||
#include "Gui.h"
|
||||
|
||||
static const int ROOM_MAX_SIZE = 12;
|
||||
static const int ROOM_MIN_SIZE = 6;
|
||||
@ -114,13 +115,16 @@ void Map::render(TCOD_Console& cons) const {
|
||||
static const TCOD_ColorRGB lightGround(200, 180, 50);
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int offset_x = engine->player->x - Engine::VIEW_WIDTH / 2;
|
||||
int offset_y = engine->player->y - Engine::VIEW_HEIGHT / 2;
|
||||
if (offset_x > x || Engine::VIEW_WIDTH + offset_x < x || offset_y > y || Engine::VIEW_HEIGHT + offset_y < y) {
|
||||
continue;
|
||||
}
|
||||
if (isInFov(x, y)) {
|
||||
tcod::print(cons, { x, y }, " ", std::nullopt, isWall(x, y) ? lightWall : lightGround);
|
||||
tcod::print(cons, { x - offset_x, y - offset_y }, " ", std::nullopt, isWall(x, y) ? lightWall : lightGround);
|
||||
}
|
||||
else if (isExplored(x, y)) {
|
||||
tcod::print(cons, { x, y }, " ", std::nullopt, isWall(x, y) ? darkWall : darkGround);
|
||||
|
||||
|
||||
tcod::print(cons, { x- offset_x, y - offset_y }, " ", std::nullopt, isWall(x, y) ? darkWall : darkGround);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -185,7 +189,7 @@ void Map::addMonster(int x, int y) {
|
||||
if (rng->getInt(0, 100) < 80) {
|
||||
// create an orc
|
||||
Actor* orc = new Actor(x, y, "o", "orc",
|
||||
TCOD_ColorRGB(0, 100, 0));
|
||||
engine->gui->green);
|
||||
orc->destructible = new MonsterDestructible(10, 0, "dead orc", 5);
|
||||
orc->attacker = new Attacker(3);
|
||||
orc->ai = new MonsterAi();
|
||||
@ -194,7 +198,7 @@ void Map::addMonster(int x, int y) {
|
||||
else {
|
||||
// create a troll
|
||||
Actor* troll = new Actor(x, y, "T", "troll",
|
||||
TCOD_ColorRGB(0, 255, 0));
|
||||
engine->gui->lightGreen);
|
||||
troll->destructible = new MonsterDestructible(16, 1, "troll carcass", 10);
|
||||
troll->attacker = new Attacker(4);
|
||||
troll->ai = new MonsterAi();
|
||||
@ -208,7 +212,7 @@ void Map::addItem(int x, int y) {
|
||||
if (dice < 70) {
|
||||
// create a health potion
|
||||
Actor* healthPotion = new Actor(x, y, "!", "health potion",
|
||||
TCOD_ColorRGB(128, 0, 128));
|
||||
engine->gui->purple);
|
||||
healthPotion->blocks = false;
|
||||
healthPotion->pickable = new Healer(4);
|
||||
engine->actors.push(healthPotion);
|
||||
@ -216,7 +220,7 @@ void Map::addItem(int x, int y) {
|
||||
else if (dice < 70 + 10) {
|
||||
// create a scroll of lightning bolt
|
||||
Actor* scrollOfLightningBolt = new Actor(x, y, "#", "scroll of lightning bolt",
|
||||
TCOD_ColorRGB(255, 100, 100));
|
||||
engine->gui->lightRed);
|
||||
scrollOfLightningBolt->blocks = false;
|
||||
scrollOfLightningBolt->pickable = new LightningBolt(5, 20);
|
||||
engine->actors.push(scrollOfLightningBolt);
|
||||
@ -225,7 +229,7 @@ void Map::addItem(int x, int y) {
|
||||
else if (dice < 70 + 10 + 10) {
|
||||
// create a scroll of fireball
|
||||
Actor* scrollOfFireball = new Actor(x, y, "#", "scroll of fireball",
|
||||
TCOD_ColorRGB(255, 100, 100));
|
||||
engine->gui->lightRed);
|
||||
scrollOfFireball->blocks = false;
|
||||
scrollOfFireball->pickable = new Fireball(3, 12);
|
||||
engine->actors.push(scrollOfFireball);
|
||||
@ -233,7 +237,7 @@ void Map::addItem(int x, int y) {
|
||||
else {
|
||||
// create a scroll of confusion
|
||||
Actor* scrollOfConfusion = new Actor(x, y, "#", "scroll of confusion",
|
||||
TCOD_ColorRGB(255, 100, 100));
|
||||
engine->gui->lightRed);
|
||||
scrollOfConfusion->blocks = false;
|
||||
scrollOfConfusion->pickable = new Confuser(10, 8);
|
||||
engine->actors.push(scrollOfConfusion);
|
||||
|
@ -32,7 +32,7 @@ void Pickable::drop(Actor* owner, Actor* wearer) {
|
||||
engine->actors.push(owner);
|
||||
owner->x = wearer->x;
|
||||
owner->y = wearer->y;
|
||||
engine->gui->message(TCOD_ColorRGB(200,200,200), "%s drops a %s.",
|
||||
engine->gui->message(engine->gui->lightGrey, "%s drops a %s.",
|
||||
wearer->name.c_str(), owner->name.c_str());
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 14 KiB |
BIN
terminal10x16_gs_ro.png
Normal file
BIN
terminal10x16_gs_ro.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
Loading…
x
Reference in New Issue
Block a user