diff --git a/src/Bob.cpp b/src/Bob.cpp index d9a0562..8a5744c 100644 --- a/src/Bob.cpp +++ b/src/Bob.cpp @@ -3,6 +3,7 @@ void Game::handle_event(SDL_Event *event) { static SDL_Point window_size; + std::string input; switch (event->type) { case (SDL_QUIT): @@ -15,6 +16,8 @@ void Game::handle_event(SDL_Event *event) { case SDL_WINDOWEVENT_SIZE_CHANGED: this->grid->update_dimensions({event->window.data1, event->window.data2}); + this->text_input_box->update_dimensions({0, event->window.data2 - 12, event->window.data1, + event->window.data2}); break; default: break; @@ -22,45 +25,84 @@ void Game::handle_event(SDL_Event *event) } break; case SDL_MOUSEMOTION: - grid->handle_event(event); - this->field_box->handle_event(event); - this->upgrade_box->handle_event(event); + if (!this->text_input_box->get_active()) + { + grid->handle_event(event); + this->field_box->handle_event(event); + this->upgrade_box->handle_event(event); + } break; case SDL_MOUSEWHEEL: - grid->handle_event(event); + if (!this->text_input_box->get_active()) + { + grid->handle_event(event); + } break; case SDL_MOUSEBUTTONDOWN: - this->grid->handle_event(event); - this->field_box->handle_event(event); - this->upgrade_box->handle_event(event); + if (!this->text_input_box->get_active()) + { + this->grid->handle_event(event); + this->field_box->handle_event(event); + this->upgrade_box->handle_event(event); + this->next_turn_button->handle_event(event); + } break; case SDL_KEYDOWN: switch (event->key.keysym.sym) { case SDLK_w: - this->move[0] = true; + if (!this->text_input_box->get_active()) + this->move[0] = true; break; case SDLK_a: - this->move[1] = true; + if (!this->text_input_box->get_active()) + this->move[1] = true; break; case SDLK_s: - this->move[2] = true; + if (!this->text_input_box->get_active()) + this->move[2] = true; break; case SDLK_d: - this->move[3] = true; + if (!this->text_input_box->get_active()) + this->move[3] = true; break; case SDLK_f: - window_size = this->window->toggle_fullscreen(); - this->grid->update_dimensions(window_size); - this->field_box->update_position({0, 20}); - this->upgrade_box->set_visible(false); + if (!this->text_input_box->get_active()) + { + window_size = this->window->toggle_fullscreen(); + this->grid->update_dimensions(window_size); + this->text_input_box->update_dimensions({0, window_size.y - window_size.x, 12}); + this->next_turn_button->update_position({window_size.x - 100, window_size.y - 100}); + this->upgrade_box->set_visible(false); + } break; case SDLK_ESCAPE: - this->quit = true; + if (this->text_input_box->get_active()) + { + this->text_input_box->stop(); + this->test_box->set_visible(false); + } + else + { + this->text_input_box->start(); + this->test_box->set_visible(true); + + } + break; + case SDLK_RETURN: + input = this->text_input_box->get_input(); + if (input == "/quit") + { + this->quit = true; + } break; default: break; } + if (this->text_input_box->get_active()) + { + this->text_input_box->handle_event(event); + } break; case SDL_KEYUP: switch (event->key.keysym.sym) @@ -81,6 +123,17 @@ void Game::handle_event(SDL_Event *event) break; } break; + case SDL_TEXTINPUT: + if (this->text_input_box->get_active()) + { + this->text_input_box->handle_event(event); + } + break; + case SDL_TEXTEDITING: + if (this->text_input_box->get_active()) + { + this->text_input_box->handle_event(event); + } default: if (event->type == BOB_MARKERUPDATE || event->type == BOB_NEXTROUNDEVENT @@ -92,18 +145,6 @@ void Game::handle_event(SDL_Event *event) this->field_box->handle_event(event); this->upgrade_box->handle_event(event); } - else - { - if (event->type == BOB_NEXTTURNEVENT) - { - this->current_player++; - if (Player::current_player == Player::players.end()) - { - Player::current_player = Player::players.begin(); - trigger_event(BOB_NEXTROUNDEVENT, 0x0, (void *) *(Player::current_player), nullptr); - } - } - } break; } } @@ -151,6 +192,8 @@ void Game::render() this->test_box->render(this->renderer); this->field_box->render(this->renderer); this->upgrade_box->render(this->renderer); + this->next_turn_button->render(this->renderer); + this->text_input_box->render(this->renderer); this->renderer->present(); } catch (const SDL_RendererException &err) @@ -189,7 +232,7 @@ int main(int, char **) } SDL_Rect bounds; SDL_GetDisplayBounds(0, &bounds); - SDL_Rect window_dimensions = {SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, bounds.w, bounds.h}; + SDL_Rect window_dimensions = {SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600}; Game *game = new Game(&window_dimensions, 20); int exit_status = 1; exit_status = game->game_loop(); diff --git a/src/Bob.hpp b/src/Bob.hpp index 3b4359e..6a167e7 100644 --- a/src/Bob.hpp +++ b/src/Bob.hpp @@ -29,10 +29,14 @@ public: } this->quit = false; SDL_Color fg = {0x00, 0x00, 0x00, 0xff}; + this->players = std::vector(); + Player *default_player = new Player(); + this->players.push_back(default_player); 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); + SDL_Point window_size = this->window->get_size(); this->renderer = new Renderer(this->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE); this->grid = new HexagonGrid(size, this->layout, this->renderer); @@ -41,6 +45,12 @@ public: this->upgrade_box = new UpgradeBox(this->renderer, {0, 0, 1, 1}, fg, this->font, center); this->test_box = new TextBox(this->renderer, {0, 0, 1, 1}, fg, this->font); this->test_box->set_visible(true); + this->next_turn_button = new NextTurnButtonBox(this->renderer, + {window_size.x - 100, window_size.y - 100, 1, 1}, fg, + this->font, &(this->players)); + this->text_input_box = new TextInputBox(this->renderer, {0, window_size.y - 12, window_size.x, 12}, fg, + this->font); + this->text_input_box->stop(); } catch (const SDL_Exception &sdl_except) { @@ -52,6 +62,12 @@ public: ~Game() { + for (auto player : this->players) + { + delete player; + } + delete text_input_box; + delete this->next_turn_button; delete this->test_box; delete this->upgrade_box; delete this->field_box; @@ -70,7 +86,9 @@ public: int game_loop(); private: - + TextInputBox *text_input_box; + std::vector players; + NextTurnButtonBox *next_turn_button; UpgradeBox *upgrade_box; FieldBox *field_box; TextBox *test_box; diff --git a/src/Events.cpp b/src/Events.cpp index 086cce4..90de0c5 100644 --- a/src/Events.cpp +++ b/src/Events.cpp @@ -6,6 +6,8 @@ const Uint32 BOB_FIELDUPDATEEVENT = register_events(1); const Uint32 BOB_FIELDSELECTEDEVENT = register_events(1); const Uint32 BOB_FIELDUPGRADEVENT = register_events(1); const Uint32 BOB_NEXTTURNEVENT = register_events(1); +const Uint32 BOB_ATTACKEVENTS = register_events(1); + bool Timer::MOUSE_LOCKED = false; diff --git a/src/Events.hpp b/src/Events.hpp index c996cf2..340394d 100644 --- a/src/Events.hpp +++ b/src/Events.hpp @@ -13,6 +13,7 @@ extern const Uint32 BOB_FIELDUPDATEEVENT; extern const Uint32 BOB_FIELDSELECTEDEVENT; extern const Uint32 BOB_FIELDUPGRADEVENT; extern const Uint32 BOB_NEXTTURNEVENT; +extern const Uint32 BOB_ATTACKEVENTS; #endif Uint32 register_events(Uint32 n); diff --git a/src/Gameplay.cpp b/src/Gameplay.cpp index e760f68..7a90f24 100644 --- a/src/Gameplay.cpp +++ b/src/Gameplay.cpp @@ -1,6 +1,6 @@ #include "Gameplay.hpp" -static std::vector::iterator Player::current_player = Player::players.end(); +Player *Player::current_player = nullptr; SDL_Point operator+(SDL_Point left, SDL_Point right) { @@ -315,6 +315,8 @@ void FieldMeta::load(SDL_Renderer *renderer, Layout *layout) } if (this->owner->get_id().is_nil()) color = {0x77, 0x77, 0x77, 0xff}; + if (this->fighting) + color = {0x0, 0x77, 0x77, 0xff}; filledPolygonRGBA(renderer, vx, vy, 6, color.r, color.g, color.b, 0x77); SDL_Color inverse; inverse.r = (Uint8) (color.r + 0x77); @@ -420,6 +422,8 @@ void HexagonGrid::render(Renderer *renderer) void HexagonGrid::handle_event(SDL_Event *event) { + Player *attacking; + Player *owner; SDL_Point mouse = {0, 0}; SDL_GetMouseState(&mouse.x, &mouse.y); int scroll = this->layout->size / 10 * event->wheel.y; @@ -472,7 +476,23 @@ void HexagonGrid::handle_event(SDL_Event *event) trigger_event(BOB_FIELDSELECTEDEVENT, 0, (void *) this->marker, nullptr); break; case SDL_BUTTON_LEFT: - trigger_event(BOB_FIELDSELECTEDEVENT, 1, (void *) this->marker, nullptr); + owner = this->marker->get_owner(); + if (*owner == *(Player::current_player)) + { + if (this->first_attack != nullptr) + { + this->first_attack->set_fighting(false); + } + this->first_attack = this->marker; + this->first_attack->set_fighting(true); + } + else if (this->first_attack != nullptr) + { + attacking = this->first_attack->get_owner(); + attacking->fight(this->marker); + this->first_attack->set_fighting(false); + this->first_attack = nullptr; + } break; default: break; diff --git a/src/Gameplay.hpp b/src/Gameplay.hpp index 961403a..303c6a0 100644 --- a/src/Gameplay.hpp +++ b/src/Gameplay.hpp @@ -543,8 +543,8 @@ public: return !(*this == rhs); } - static std::vector players; - static std::vector::iterator current_player; + static Player *current_player; + private: boost::uuids::uuid uuid; SDL_Color color; @@ -561,6 +561,7 @@ public: FieldMeta(HexagonGrid *grid_, Field field_, Player *owner_) : grid(grid_), field(field_), owner(owner_) { + this->fighting = false; this->upgrades = 0; static std::random_device rd; std::mt19937 rng(rd()); @@ -601,7 +602,11 @@ public: FieldMeta *get_neighbor(Uint8 direction); + bool get_fighting() { return this->fighting; } + + void set_fighting(bool state) { this->fighting = state; } private: + bool fighting; const Field field; HexagonGrid *grid; Player *owner; @@ -620,6 +625,7 @@ public: HexagonGrid(Sint16 grid_radius, Layout *layout_, Renderer *renderer_) : layout(layout_), radius(grid_radius), renderer(renderer_) { + this->first_attack = nullptr; this->texture = nullptr; this->panning = false; std::unordered_map fields = std::unordered_map(); @@ -681,6 +687,7 @@ public: private: bool changed; + FieldMeta *first_attack; Renderer *renderer; SDL_Texture *texture; std::unordered_map fields; diff --git a/src/Gui.cpp b/src/Gui.cpp index 35fe44c..73144f6 100644 --- a/src/Gui.cpp +++ b/src/Gui.cpp @@ -21,6 +21,7 @@ TTF_Font *load_font_from_file(std::string path_to_file, int size) bool TextBox::load_text(std::string text) { + this->renderer->set_draw_color({0, 0, 0, 0xff}); const char *displayed_text = text.c_str(); SDL_Surface *text_surface = TTF_RenderUTF8_Blended_Wrapped(this->font, displayed_text, this->color, 100); if (text_surface == nullptr) @@ -196,7 +197,10 @@ void UpgradeButtonBox::handle_event(const SDL_Event *event) if (inside_target(&(this->dimensions), &pos)) { FieldMeta *field = this->box->get_field(); - field->upgrade(this->upgrade); + if (*(Player::current_player) == *(field->get_owner())) + { + field->upgrade(this->upgrade); + } } } } @@ -276,4 +280,111 @@ void FieldBox::update_position(SDL_Point point) { this->dimensions.x = point.x; this->dimensions.y = point.y - this->dimensions.h - 6; +} + +void NextTurnButtonBox::handle_event(const SDL_Event *event) +{ + if (event->type == SDL_MOUSEBUTTONDOWN) + { + SDL_Point mouse; + SDL_GetMouseState(&(mouse.x), &(mouse.y)); + if (inside_target(&(this->dimensions), &mouse)) + { + Player *last_player = Player::current_player; + this->current_player = this->current_player + 1; + if (this->current_player == players->end()) + { + this->current_player = players->begin(); + trigger_event(BOB_NEXTROUNDEVENT, 0, last_player, Player::current_player); + } + else + { + trigger_event(BOB_NEXTTURNEVENT, 0, last_player, Player::current_player); + } + Player::current_player = *(this->current_player); + std::ostringstream text; + text << "NEXT TURN" << "\n\n" << Player::current_player->get_name(); + this->load_text(text.str()); + } + } +} + +void TextInputBox::start() +{ + this->visible = true; + SDL_StartTextInput(); +} + +void TextInputBox::stop() +{ + this->visible = false; + SDL_StopTextInput(); +} + +void TextInputBox::handle_event(const SDL_Event *event) +{ + bool changed = false; + if (event->type == SDL_KEYDOWN) + { + if (event->key.keysym.sym == SDLK_RETURN) + { + this->input = ""; + changed = true; + } + else if (event->key.keysym.sym == SDLK_BACKSPACE && this->input.length() > 0) + { + input.pop_back(); + changed = true; + } + else if (event->key.keysym.sym == SDLK_c && SDL_GetModState() & KMOD_CTRL) + { + SDL_SetClipboardText(input.c_str()); + changed = true; + } + else if (event->key.keysym.sym == SDLK_v && SDL_GetModState() & KMOD_CTRL) + { + input = SDL_GetClipboardText(); + + } + } + else if (event->type == SDL_TEXTINPUT) + { + if (!((event->text.text[0] == 'c' || event->text.text[0] == 'C') + && (event->text.text[0] == 'v' || event->text.text[0] == 'V') && SDL_GetModState() & KMOD_CTRL)) + { + input += event->text.text; + changed = true; + } + } + else if (event->type == SDL_TEXTEDITING) + { + // nothin atm + } + if (changed) + { + std::string foo = input; // because SDL_ttf will complain if not + foo += " "; + this->load_text(foo); + } +} + +void TextInputBox::render(Renderer *ext_renderer) +{ + if (this->texture != nullptr && this->visible) + { + ext_renderer->set_draw_color({0xff, 0xff, 0xff, 0x00}); + SDL_RenderFillRect(ext_renderer->get_renderer(), &(bg_dimensions)); + ext_renderer->copy(this->texture, nullptr, &(this->dimensions)); + } +} + +void TextInputBox::update_dimensions(SDL_Rect rect) +{ + this->bg_dimensions = rect; + this->dimensions = bg_dimensions; +} + +bool TextInputBox::get_active() +{ + return SDL_IsTextInputActive() == SDL_TRUE; } \ No newline at end of file diff --git a/src/Gui.hpp b/src/Gui.hpp index a81941a..1a21426 100644 --- a/src/Gui.hpp +++ b/src/Gui.hpp @@ -61,6 +61,35 @@ protected: TTF_Font *font; }; +class TextInputBox : TextBox +{ +public: + TextInputBox(Renderer *renderer_, SDL_Rect dimensions_, SDL_Color color_, TTF_Font *font_) + : TextBox(renderer_, dimensions_, color_, font_), bg_dimensions(dimensions_), input("") + { + this->visible = false; + this->load_text(" "); + } + + void start(); + + void stop(); + + bool get_active(); + + void handle_event(const SDL_Event *event); + + void render(Renderer *ext_renderer); + + void update_dimensions(SDL_Rect rect); + + std::string get_input() { return this->input; } + +private: + SDL_Rect bg_dimensions; + std::string input; +}; + class FieldBox : public TextBox { public: @@ -98,10 +127,29 @@ private: bool active; // this upgrade has been unlocked }; -/*class NextTurnButtonBox : public TextBox +class NextTurnButtonBox : public TextBox { +public: + NextTurnButtonBox(Renderer *renderer, SDL_Rect dimensions, SDL_Color color, TTF_Font *font_, + std::vector *players_) + : TextBox(renderer, dimensions, color, font_), players(players_) + { + this->current_player = this->players->begin(); + Player::current_player = *(this->current_player); + std::ostringstream text; + // Warning, next line looks ugly @.@ + text << "NEXT TURN" << "\n\n" << (*(this->current_player))->get_name(); + this->load_text(text.str()); + this->visible = true; + } + + void handle_event(const SDL_Event *event); + +private: + std::vector *players; + std::vector::iterator current_player; }; - */ + class UpgradeBox : public Box {