From 78c33d84b64581ba55714b33e5df3f769fc610d5 Mon Sep 17 00:00:00 2001 From: Tim Schubert Date: Tue, 26 Jan 2016 00:33:48 +0100 Subject: [PATCH] Display upgrade information. --- src/Bob.cpp | 16 +++-- src/Bob.hpp | 21 ++++-- src/CMakeLists.txt | 2 +- src/Events.cpp | 1 + src/Events.hpp | 1 + src/Gameplay.cpp | 63 ++++++++++++++---- src/Gameplay.hpp | 42 ++++++++++-- src/Gui.cpp | 160 ++++++++++++++++++++++++++++++++++++++++----- src/Gui.hpp | 101 +++++++++++++++++++++------- 9 files changed, 340 insertions(+), 67 deletions(-) diff --git a/src/Bob.cpp b/src/Bob.cpp index 942fcd7..1b32f64 100644 --- a/src/Bob.cpp +++ b/src/Bob.cpp @@ -23,12 +23,16 @@ void Game::handle_event(SDL_Event *event) break; case SDL_MOUSEMOTION: grid->handle_event(event); + this->side_bar->handle_event(event); + this->upgrade_box->handle_event(event); break; case SDL_MOUSEWHEEL: grid->handle_event(event); break; case SDL_MOUSEBUTTONDOWN: - grid->handle_event(event); + this->grid->handle_event(event); + this->side_bar->handle_event(event); + this->upgrade_box->handle_event(event); break; case SDL_KEYDOWN: switch (event->key.keysym.sym) @@ -48,7 +52,8 @@ void Game::handle_event(SDL_Event *event) case SDLK_f: window_size = this->window->toggle_fullscreen(); this->grid->update_dimensions(window_size); - this->side_bar->update_dimensions(window_size); + this->field_box->update_position({0, 20}); + this->upgrade_box->set_visible(false); break; case SDLK_ESCAPE: this->quit = true; @@ -78,10 +83,11 @@ void Game::handle_event(SDL_Event *event) break; default: if (event->type == BOB_MARKERUPDATE || event->type == BOB_NEXTTURNEVENT || - event->type == BOB_FIELDUPDATEEVENT) + event->type == BOB_FIELDUPDATEEVENT || event->type == BOB_FIELDSELECTED) { this->grid->handle_event(event); this->side_bar->handle_event(event); + this->upgrade_box->handle_event(event); } break; } @@ -127,6 +133,7 @@ void Game::render() this->renderer->clear(); this->grid->render(this->renderer->get_renderer()); this->side_bar->render(this->renderer); + this->upgrade_box->render(this->renderer); this->renderer->present(); } catch (const SDL_RendererException &err) @@ -165,7 +172,8 @@ int main(int, char **) } SDL_Rect window_dimensions = {SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGTH}; Game *game = new Game(&window_dimensions, 2); - int exit_status = game->game_loop(); + int exit_status = 1; + exit_status = game->game_loop(); delete game; TTF_Quit(); SDL_Quit(); diff --git a/src/Bob.hpp b/src/Bob.hpp index 48a6ecc..55a2d52 100644 --- a/src/Bob.hpp +++ b/src/Bob.hpp @@ -32,29 +32,39 @@ public: this->move[i] = false; } this->quit = false; - SDL_Color fg = {0x00, 0xff, 0x00, 0xff}; + SDL_Color fg = {0xff, 0xff, 0xff, 0xff}; try { this->font = load_font_from_file("/usr/share/fonts/dejavu/DejaVuSans.ttf", 12); this->window = new Window(TITLE, window_dimensions, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); this->renderer = new Renderer(this->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE); + FieldMeta *center = this->grid->get_field({0, 0, 0}); SDL_Rect side_bar_dimensions = {window_dimensions->x - SIDEBAR_WIDTH, 0, SIDEBAR_WIDTH, window_dimensions->y}; this->side_bar = new Container(this->window, this->renderer, side_bar_dimensions); this->field_box = new FieldBox(this->renderer, - {0, 20, SIDEBAR_WIDTH, SCREEN_HEIGTH}, + {0, 20, 0, 0}, fg, this->font, - this->grid->point_to_field({0.0, 0.0}) + center + ); + this->upgrade_box = new UpgradeBox(this->renderer, + {0, 0, 210, 140}, + fg, + this->font, + center ); this->test_box = new TextBox(this->renderer, {0, 0, SIDEBAR_WIDTH, SCREEN_HEIGTH}, - fg, this->font + fg, + this->font ); + this->test_box->set_visible(true); this->side_bar->add(test_box); this->side_bar->add(field_box); - this->side_bar->set_visible(true); + //this->side_bar->add(upgrade_box); + //this->side_bar->set_visible(true); } catch (const SDL_Exception &sdl_except) { @@ -85,6 +95,7 @@ public: int game_loop(); private: + UpgradeBox *upgrade_box; FieldBox *field_box; TextBox *test_box; TTF_Font *font; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5a7fa8e..6d6e8c2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,2 +1,2 @@ -add_executable(Bob Bob.cpp Bob.hpp Gameplay.cpp Gameplay.hpp Gui.hpp Gui.cpp Events.cpp Exceptions.hpp) +add_executable(Bob Bob.cpp Bob.hpp Gameplay.cpp Gameplay.hpp Gui.hpp Gui.cpp Events.cpp Exceptions.hpp Pixelmask.h) target_link_libraries(Bob ${SDL2_LIB} ${SDL2_GFX_LIB} ${SDL2_TTF_LIB} ${Boost_LIBRARIES}) \ No newline at end of file diff --git a/src/Events.cpp b/src/Events.cpp index a1c4f41..a8a4f11 100644 --- a/src/Events.cpp +++ b/src/Events.cpp @@ -3,6 +3,7 @@ const Uint32 BOB_NEXTTURNEVENT = register_events(1); const Uint32 BOB_MARKERUPDATE = register_events(1); const Uint32 BOB_FIELDUPDATEEVENT = register_events(1); +const Uint32 BOB_FIELDSELECTED = register_events(1); void Timer::start_timer() { diff --git a/src/Events.hpp b/src/Events.hpp index fc49d34..61b6506 100644 --- a/src/Events.hpp +++ b/src/Events.hpp @@ -10,6 +10,7 @@ extern const Uint32 BOB_NEXTTURNEVENT; extern const Uint32 BOB_MARKERUPDATE; extern const Uint32 BOB_FIELDUPDATEEVENT; +extern const Uint32 BOB_FIELDSELECTED; #endif Uint32 register_events(Uint32 n); diff --git a/src/Gameplay.cpp b/src/Gameplay.cpp index 0b4efbf..03ccf41 100644 --- a/src/Gameplay.cpp +++ b/src/Gameplay.cpp @@ -183,6 +183,17 @@ void FieldMeta::render(SDL_Renderer *renderer, Layout *layout) } } +void FieldMeta::trigger_event(Uint32 type, Sint32 code) +{ + SDL_Event event; + SDL_memset(&event, 0, sizeof(event)); /* or SDL_zero(event) */ + event.type = type; + event.user.code = code; + event.user.data1 = static_cast(this); + event.user.data2 = 0; + SDL_PushEvent(&event); +} + void FieldMeta::regenerate_resources() { this->resources = resources_base; @@ -192,6 +203,7 @@ void FieldMeta::regenerate_resources() this->resources *= 2; if (this->upgrades[Regeneration_3]) this->resources *= 2; + this->trigger_event(BOB_FIELDUPDATEEVENT, 0); } Resource HexagonGrid::get_resources_of_cluster(Cluster *cluster) @@ -208,21 +220,24 @@ Resource HexagonGrid::get_resources_of_cluster(Cluster *cluster) bool FieldMeta::upgrade(Upgrade upgrade) { // check available resources for cluster and consume resources - Cluster *cluster = new Cluster(); - this->grid->get_cluster(this); - Resource cluster_resources = this->grid->get_resources_of_cluster(cluster); + if (this->upgrades[upgrade]) + return this->upgrades[upgrade]; + Cluster cluster = this->grid->get_cluster(this); + Resource cluster_resources = this->grid->get_resources_of_cluster(&cluster); auto pair = UPGRADE_COSTS.find(upgrade); if (pair != UPGRADE_COSTS.end()) { Resource costs = pair->second; - Resource remaining_costs = this->grid->consume_resources_of_cluster(cluster, costs); + if (costs > cluster_resources) // too expensive for you + return this->upgrades[upgrade]; + Resource remaining_costs = this->grid->consume_resources_of_cluster(&cluster, costs); static const Resource neutral = {0, 0, 0}; if (remaining_costs == neutral) { this->upgrades[upgrade] = true; } } - delete cluster; + this->trigger_event(BOB_FIELDUPDATEEVENT, 0); return this->upgrades[upgrade]; } @@ -265,6 +280,12 @@ Cluster HexagonGrid::get_cluster(FieldMeta *field) return visited; } +void FieldMeta::consume_resources(Resource costs) +{ + this->resources -= costs; + this->trigger_event(BOB_FIELDUPDATEEVENT, 0); +} + Resource HexagonGrid::consume_resources_of_cluster(Cluster *cluster, Resource costs) { for (FieldMeta *meta : *cluster) @@ -388,6 +409,12 @@ void HexagonGrid::handle_event(SDL_Event *event) case SDL_BUTTON_MIDDLE: this->panning = !(this->panning); break; + case SDL_BUTTON_RIGHT: + this->marker->trigger_event(BOB_FIELDSELECTED, 0); + break; + //case SDL_BUTTON_LEFT: + // this->marker->trigger_event(BOB_FIELDSELECTED, 1); + // break; default: break; } @@ -421,13 +448,11 @@ void HexagonGrid::update_marker() if (n_marker != nullptr) { this->marker = n_marker; - SDL_Event event; - SDL_memset(&event, 0, sizeof(event)); /* or SDL_zero(event) */ - event.type = BOB_MARKERUPDATE; - event.user.code = 0x0; - event.user.data1 = static_cast(n_marker); - event.user.data2 = 0; - SDL_PushEvent(&event); + n_marker->trigger_event(BOB_MARKERUPDATE, 0); + } + else + { + marker->trigger_event(BOB_MARKERUPDATE, 1); } } @@ -442,6 +467,15 @@ FieldMeta *HexagonGrid::point_to_field(const Point p) } +FieldMeta *HexagonGrid::get_field(Field field) +{ + FieldMeta *meta = nullptr; + auto pair = this->fields.find(field); + if (pair != this->fields.end()) + meta = pair->second; + return meta; +} + bool HexagonGrid::on_rectangle(SDL_Rect *rect) { // check if center inside rect for ANY field @@ -465,3 +499,8 @@ void HexagonGrid::update_dimensions(SDL_Point dimensions) this->layout->box.w = dimensions.x; this->layout->box.h = dimensions.y; } + +Point HexagonGrid::field_to_point(FieldMeta *field) +{ + return field->get_field().field_to_point(this->layout); +} \ No newline at end of file diff --git a/src/Gameplay.hpp b/src/Gameplay.hpp index 824fdea..f689229 100644 --- a/src/Gameplay.hpp +++ b/src/Gameplay.hpp @@ -23,8 +23,6 @@ #include #include "Events.hpp" -#define NUM_UPGRADES 10 - SDL_Point operator+(SDL_Point left, SDL_Point right); SDL_Point operator-(SDL_Point left, SDL_Point right); @@ -339,8 +337,6 @@ inline std::ostream &operator<<(std::ostream &os, const Field &rhs) return os; } -typedef std::bitset UpgradeFlags; - struct Resource { Uint8 circle; @@ -441,7 +437,6 @@ struct Resource enum Upgrade { - First_Upgrade = 0, Regeneration_1, Regeneration_2, Regeneration_3, @@ -450,6 +445,13 @@ enum Upgrade Reproduction_3 }; +const std::vector UPGRADES = {Regeneration_1, Regeneration_2, Regeneration_3, Reproduction_1, Reproduction_2, + Reproduction_3}; + +const int NUM_UPGRADES = 6; + +typedef std::bitset UpgradeFlags; + namespace std { template<> @@ -475,6 +477,28 @@ const std::unordered_map UPGRADE_COSTS( } ); +const std::unordered_map UPGRADE_NAMES( + { + {Regeneration_1, "Regeneration 1"}, + {Regeneration_2, "Regeneration 2"}, + {Regeneration_3, "Regeneration 3"}, + {Reproduction_1, "Reproduction 1"}, + {Reproduction_2, "Reproduction 2"}, + {Reproduction_3, "Reproduction 3"} + } +); + +const std::unordered_map UPGRADE_TEXTS( + { + {Regeneration_1, "Resources yield 2x their base resources per turn."}, + {Regeneration_2, "Resources yield 4x their base resources per turn."}, + {Regeneration_3, "Resources yield 8x their base resources per turn."}, + {Reproduction_1, "Not used yet!"}, + {Reproduction_2, "Not used yet!"}, + {Reproduction_3, "Not used yet!"} + } +); + class FieldMeta; class Player @@ -562,7 +586,7 @@ public: UpgradeFlags get_upgrades() { return this->upgrades; } - void consume_resources(Resource costs) { this->resources -= costs; } + void consume_resources(Resource costs); void regenerate_resources(); @@ -572,6 +596,8 @@ public: FieldMeta *get_neighbor(Uint8 direction); + void trigger_event(Uint32 type, Sint32 code); + private: const Field field; HexagonGrid *grid; @@ -639,6 +665,10 @@ public: FieldMeta *point_to_field(const Point p); + Point field_to_point(FieldMeta *field); + + FieldMeta *get_field(Field field); + void handle_event(SDL_Event *event); private: diff --git a/src/Gui.cpp b/src/Gui.cpp index 08758bc..325f503 100644 --- a/src/Gui.cpp +++ b/src/Gui.cpp @@ -22,17 +22,17 @@ TTF_Font *load_font_from_file(std::string path_to_file, int size) bool TextBox::load_text(std::string text) { const char *displayed_text = text.c_str(); - SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped(this->font, displayed_text, {0xff, 0xff, 0xff, 0xff}, - this->dimensions.w); + SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped(this->font, displayed_text, this->color, 100); if (surface == nullptr) { SDL_FreeSurface(surface); throw SDL_TTFException(); } - else if (surface->w > this->dimensions.w || surface->h > this->dimensions.h) + /*else if (surface->w > this->dimensions.w || surface->h > this->dimensions.h) { std::cerr << "Overfull TextBox!" << std::endl; } + */ this->dimensions.w = surface->w; this->dimensions.h = surface->h; if (this->texture != nullptr) @@ -73,11 +73,10 @@ SDL_Point Window::toggle_fullscreen() return window_size; } -bool Window::position_inside_window(SDL_Point position) +bool inside_target(const SDL_Rect *target, const SDL_Point *position) { - SDL_DisplayMode dm; - SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(this->window), &dm); - return position.x > 0 && position.x < dm.w && position.y > 0 && position.y < dm.h; + return target->x < position->x && target->x + target->w > position->x && target->y < position->y && + target->y + target->h > position->y; } int Window::get_window_id() @@ -108,17 +107,20 @@ void Container::handle_event(SDL_Event *event) void FieldBox::handle_event(const SDL_Event *event) { - Field *field_update; if (event->type == BOB_FIELDUPDATEEVENT) { - field_update = reinterpret_cast(event->user.data1); - if (*field_update == this->field->get_field()) + FieldMeta *field_update = reinterpret_cast(event->user.data1); + if (field_update == this->field) { this->update(); } } else if (event->type == BOB_MARKERUPDATE) { + if (event->user.code == 0) + this->visible = true; + else + this->visible = false; this->field = static_cast(event->user.data1); this->update(); } @@ -138,12 +140,112 @@ void FieldBox::update() this->load_text(output.str()); } -void ButtonInfoBox::handle_event(const SDL_Event *event) +void UpgradeButtonBox::set_active(bool state) { -}; + this->active = state; + if (state) + { + this->color = {0x0, 0x0, 0xff, this->color.a}; + this->load_text(UPGRADE_NAMES.at(this->upgrade)); + } +} void UpgradeBox::handle_event(const SDL_Event *event) { + if (event->type == SDL_MOUSEBUTTONDOWN && this->visible) + { + SDL_Point m_pos; + SDL_GetMouseState(&m_pos.x, &m_pos.y); + if (inside_target(&(this->dimensions), &m_pos)) + { + if (marked_upgrade != nullptr) + { + this->marked_upgrade->handle_event(event); + } + } + else + { + this->set_visible(false); + } + } + else if (event->type == BOB_FIELDSELECTED) + { + FieldMeta *selected = static_cast(event->user.data1); + if (selected != nullptr && event->user.code == 0x0) + { + this->set_visible(true); + this->field = selected; + Point p_pos = selected->get_grid()->field_to_point(selected); + SDL_Point point = {(int) p_pos.x, (int) p_pos.y}; + this->update_position(point); + } + else + { + this->set_visible(false); + } + } + else if (event->type == BOB_FIELDUPDATEEVENT) + { + // mark updates active / inactive + this->field = static_cast(event->user.data1); + UpgradeFlags updated_upgrades = this->field->get_upgrades(); + for (auto upgrade : this->upgrades) + { + upgrade->set_active(updated_upgrades[upgrade->get_upgrade()]); + } + } + else if (event->type == SDL_MOUSEMOTION && this->visible) + { + SDL_Point pos; + SDL_GetMouseState(&(pos.x), &(pos.y)); + // update the info text field for the selected update + for (auto box : this->upgrades) + { + SDL_Rect target = box->get_dimensions(); + if (this->marked_upgrade != box && inside_target(&target, &pos)) + { + this->marked_upgrade = box; + Resource costs = UPGRADE_COSTS.at(box->get_upgrade()); + std::ostringstream output; + output //<< UPGRADE_NAMES.at(box->get_upgrade()) << "\n" + << "● " << (int) costs.circle << "\n" + << "▲ " << (int) costs.triangle << "\n" + << "■ " << (int) costs.square << "\n" + << UPGRADE_TEXTS.at(box->get_upgrade()); + this->upgrade_info->load_text(output.str()); + } + } + } +} + +void UpgradeButtonBox::handle_event(const SDL_Event *event) +{ + SDL_Point pos; + SDL_GetMouseState(&(pos.x), &(pos.y)); + if (event->type == SDL_MOUSEBUTTONDOWN && this->visible) + { + if (inside_target(&(this->dimensions), &pos)) + { + this->box->get_field()->upgrade(this->upgrade); + } + } +} + +void UpgradeBox::render(Renderer *ext_renderer) +{ + if (this->visible && this->texture != nullptr) + { + // copy background + if (SDL_RenderCopy(ext_renderer->get_renderer(), this->texture, nullptr, &(this->dimensions)) < 0) + { + throw SDL_RendererException(); + } + this->upgrade_info->render(ext_renderer); + for (auto box : this->upgrades) + { + box->render(ext_renderer); + } + } } void Container::render(Renderer *renderer) @@ -173,13 +275,37 @@ void Container::set_visible(bool visible) } } -void Container::update_dimensions(SDL_Point dimensions) +void Container::update_position(SDL_Point dimensions) { for (auto box : this->elements) - box->update_dimensions(dimensions); + box->update_position(dimensions); } -void Box::update_dimensions(SDL_Point dimensions) +void Box::update_position(SDL_Point pos) { - this->dimensions.x = 0; -} \ No newline at end of file + this->dimensions.x = pos.x; + this->dimensions.y = pos.y; +} + +void UpgradeBox::update_position(SDL_Point pos) +{ + SDL_Point d_pos = pos; + this->dimensions.x = pos.x; + this->dimensions.y = pos.y; + for (auto box : this->upgrades) + { + box->update_position(d_pos); + d_pos.y += 20; + } + this->upgrade_info->update_position({pos.x + 110, pos.y}); +} + +void UpgradeBox::set_visible(bool status) +{ + this->visible = status; + this->upgrade_info->set_visible(status); + for (UpgradeButtonBox *box : this->upgrades) + { + box->set_visible(status); + } +} diff --git a/src/Gui.hpp b/src/Gui.hpp index c058e02..fe44ad3 100644 --- a/src/Gui.hpp +++ b/src/Gui.hpp @@ -12,6 +12,7 @@ #include "Exceptions.hpp" #include "Gameplay.hpp" #include "Events.hpp" +#include "Pixelmask.h" SDL_Color operator!(const SDL_Color &color); @@ -43,8 +44,6 @@ public: SDL_Point toggle_fullscreen(); - bool position_inside_window(SDL_Point position); - int get_window_id(); }; @@ -88,19 +87,21 @@ public: this->visible = false; } - ~Box() + virtual ~Box() { SDL_DestroyTexture(this->texture); } - void update_dimensions(SDL_Point dimensions); + virtual void update_position(SDL_Point dimensions); virtual void render(Renderer *renderer); - void set_visible(bool visibility) { this->visible = visibility; } + virtual void set_visible(bool visibility) { this->visible = visibility; } SDL_Rect get_dimensions() { return this->dimensions; } + void set_dimensions(SDL_Rect dimensions) { this->dimensions = dimensions; } + virtual void handle_event(const SDL_Event *event) = 0; protected: Renderer *renderer; @@ -118,7 +119,7 @@ public: virtual bool load_text(std::string text); - virtual void handle_event(const SDL_Event *event) { }; + virtual void handle_event(const SDL_Event *event) { } protected: TTF_Font *font; @@ -132,32 +133,88 @@ public: void handle_event(const SDL_Event *event); - void update(); + virtual void update(); -private: +protected: FieldMeta *field; }; -class UpgradeBox : public TextBox +class UpgradeBox; + +class UpgradeButtonBox : public TextBox { public: - UpgradeBox(Renderer *renderer, SDL_Rect dimensions, FieldMeta *field_, SDL_Color color, TTF_Font *font) - : TextBox(renderer, dimensions, color, font) { } + UpgradeButtonBox(Renderer *renderer, SDL_Rect dimensions, SDL_Color color, TTF_Font *font, UpgradeBox *box_, + Upgrade upgrade) + : TextBox(renderer, dimensions, color, font), box(box_), upgrade(upgrade) { } + + Upgrade get_upgrade() { return this->upgrade; } void handle_event(const SDL_Event *event); -}; -class ButtonInfoBox : public TextBox -{ -public: - ButtonInfoBox(Renderer *renderer, SDL_Rect dimensions, FieldMeta *field_, SDL_Color color, TTF_Font *font, - UpgradeBox *upgrade_box_) - : TextBox(renderer, dimensions, color, font), upgrade_box(upgrade_box_) { } - - void handle_event(const SDL_Event *event); + void set_active(bool state); private: - UpgradeBox *upgrade_box; + UpgradeBox *box; + Upgrade upgrade; + bool active; // this upgrade has been unlocked +}; + +class UpgradeBox : public Box +{ +public: + UpgradeBox(Renderer *renderer, SDL_Rect dimensions, SDL_Color color, TTF_Font *font, FieldMeta *field_) + : Box(renderer, dimensions, color), field(field_) + { + ; + this->texture = SDL_CreateTexture(renderer->get_renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, + dimensions.w, dimensions.h); + int y = dimensions.y; + for (Upgrade upgrade : UPGRADES) + { + UpgradeButtonBox *box = new UpgradeButtonBox(renderer, {0, y, 0, 0}, color, font, this, upgrade); + box->load_text(UPGRADE_NAMES.at(upgrade)); + y += 20; + this->marked_upgrade = box; + this->upgrades.push_back(box); + } + this->upgrade_info = new TextBox(renderer, {0, 0, 0, 0}, color, font); + renderer->set_draw_color({0x77, 0x77, 0x77, 0x77}); + SDL_SetRenderTarget(renderer->get_renderer(), this->texture); + const SDL_Rect bg = dimensions; + if (SDL_RenderFillRect(renderer->get_renderer(), &bg) < 0) + { + SDL_DestroyTexture(this->texture); + SDL_SetRenderTarget(renderer->get_renderer(), nullptr); + throw SDL_RendererException(); + } + SDL_SetRenderTarget(renderer->get_renderer(), nullptr); + } + + ~UpgradeBox() + { + for (auto box : upgrades) + { + delete box; + } + delete upgrade_info; + } + + void handle_event(const SDL_Event *event); + + void render(Renderer *renderer); + + FieldMeta *get_field() { return this->field; } + + void update_position(SDL_Point pos); + + void set_visible(bool status); + +private: + std::vector upgrades; + UpgradeButtonBox *marked_upgrade; + TextBox *upgrade_info; + FieldMeta *field; }; class Container @@ -177,7 +234,7 @@ public: void handle_event(SDL_Event *event); - void update_dimensions(SDL_Point dimensions); + void update_position(SDL_Point dimensions); private: Window *window;