#include "Gui.h" #include "Engine.h" #include "Actor.h" #include "Map.h" #include "Destructible.h" static const int PANEL_HEIGHT = 7; static const int BAR_WIDTH = 20; static const int MSG_X = BAR_WIDTH + 2; 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; } Gui::~Gui() { log.clearAndDelete(); } void Gui::render() { // clear the GUI console con.clear(); renderBar(1, 1, BAR_WIDTH, "HP", engine->player->destructible->hp, engine->player->destructible->maxHp, TCOD_ColorRGB(255,100,100), TCOD_ColorRGB(100, 0, 0)); // draw the message log int y = 1; float colorCoef = 0.4f; for (Message** it = log.begin(); it != log.end(); it++) { Message* message = *it; tcod::print(con, { MSG_X, y }, message->text, TCOD_ColorRGB(message->col.r * colorCoef, message->col.g * colorCoef, message->col.b * colorCoef), std::nullopt); y++; if (colorCoef < 1.0f) { colorCoef += 0.3f; } } renderMouseLook(); tcod::blit(*root, con, { 0, engine->screenHeight - PANEL_HEIGHT }, { 0, 0, engine->screenWidth, PANEL_HEIGHT }); } void Gui::renderBar(int x, int y, int width, std::string name, float value, float maxValue, const TCOD_ColorRGB& barColor, const TCOD_ColorRGB& backColor) { tcod::draw_rect(con, { x, y, width, 1 }, ' ', std::nullopt, backColor); int barWidth = (int)(value / maxValue * width); if (barWidth > 0) { // draw the bar tcod::draw_rect(con, { x, y, barWidth, 1 }, ' ', std::nullopt, barColor); } tcod::print(con, { x + width / 2, y }, name + " : " + std::to_string((int)value) + "/" + std::to_string((int)maxValue), TCOD_ColorRGB(255, 255, 255), std::nullopt, TCOD_CENTER); } Gui::Message::Message(std::string text, const TCOD_ColorRGB& col) : text(text), col(col) { } Gui::Message::~Message() { } void Gui::message(const TCOD_ColorRGB& col, const char* text, ...) { // build the text va_list ap; char buf[128]; va_start(ap, text); vsprintf(buf, text, ap); va_end(ap); char* lineBegin = buf; char* lineEnd; if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0'; do { // make room for the new message if (log.size() == MSG_HEIGHT) { Message* toRemove = log.get(0); log.remove(toRemove); delete toRemove; } lineEnd = strchr(lineBegin, '\n'); if (lineEnd) { *lineEnd = '\0'; } Message* msg = new Message(lineBegin, col); log.push(msg); // go to next line lineBegin = lineEnd + 1; } while (lineEnd); } void Gui::renderMouseLook() { if (!engine->map->isInFov(engine->mouse.cx, engine->mouse.cy)) { // if mouse is out of fov, nothing to render return; } char buf[128] = ""; bool first = true; for (Actor** it = engine->actors.begin(); it != engine->actors.end(); it++) { Actor* actor = *it; // find actors under the mouse cursor if (actor->x == engine->mouse.cx && actor->y == engine->mouse.cy) { if (!first) { strcat(buf, ", "); } else { first = false; } strcat(buf, actor->name.c_str()); } } tcod::print(con, { 1, 0 }, buf, TCOD_ColorRGB(200, 200, 200), std::nullopt); }