// PaymentModalGame.h #pragma once #include "../../lib/game.h" #include "../../display/low_level_render.h" #include "../../display/low_level_gui.h" #include "input_manager.h" #include "player.h" #include "MonopolyBoardRenderer.h" #include "ModalButtonHelper.h" #include #include class PaymentModalGame : public Game { Player* payer; Player* recipient; // nullptr if Bank int amount; int options[3]; bool option_visible[3]; int correct_answer; int selected_choice; bool dismissed; const char* reason; bool show_error; public: PaymentModalGame(uint16_t width, uint16_t height, LowLevelRenderer* renderer, LowLevelGUI* gui, InputManager* input_manager, Player* p, Player* r, int amt, const char* reas) : Game(width, height, renderer, gui, input_manager), payer(p), recipient(r), amount(amt), reason(reas), selected_choice(-1), dismissed(false), show_error(false) { correct_answer = payer->balance - amount; for (int i = 0; i < 3; i++) option_visible[i] = true; // Generate two fake answers int fake1 = correct_answer + (rand() % 4 + 1) * 10; int fake2 = correct_answer - (rand() % 4 + 1) * 10; if (fake2 < 0 && correct_answer > 10) fake2 = correct_answer - 5; if (fake2 == correct_answer || fake2 == fake1) fake2 = fake1 + 10; int rand_pos = rand() % 3; if (rand_pos == 0) { options[0] = correct_answer; options[1] = fake1; options[2] = fake2; } else if (rand_pos == 1) { options[0] = fake1; options[1] = correct_answer; options[2] = fake2; } else { options[0] = fake1; options[1] = fake2; options[2] = correct_answer; } } void init() override { dismissed = false; selected_choice = -1; show_error = false; for (int i = 0; i < 3; i++) option_visible[i] = true; ModalButtonHelper::set_monopoly_regions(input_manager, width, height); } Type get_type() const override { return Type::MONOPOLY_PAYMENT; } bool update(const InputEvent& event) override { if (event.type == INPUT_BUTTON_0) { // Select // Find next visible option do { selected_choice = (selected_choice + 1) % 3; } while (!option_visible[selected_choice]); show_error = false; return true; } if (event.type == INPUT_BUTTON_1) { // Execute if (selected_choice == -1) return false; if (!option_visible[selected_choice]) return false; if (options[selected_choice] == correct_answer) { payer->balance -= amount; if (recipient) recipient->balance += amount; dismissed = true; } else { option_visible[selected_choice] = false; show_error = true; // De-select the hidden option selected_choice = -1; } return true; } return false; } void draw() override { renderer->clear_buffer(); // Draw board background if possible (simplified here) int win_w = width - 2 * (width / 8); int win_h = height - 2 * (height / 8); int win_x = (width - win_w) / 2; int win_y = (height - win_h) / 2; renderer->draw_filled_rectangle(win_x, win_y, win_w, win_h, false, 0); renderer->draw_rectangle(win_x, win_y, win_w, win_h, true, 2); renderer->draw_rectangle(win_x + 3, win_y + 3, win_w - 6, win_h - 6, true, 1); // Header renderer->draw_filled_rectangle(win_x + 4, win_y + 4, win_w - 8, 35, true, 1); renderer->set_text_color(false); renderer->draw_string_scaled(win_x + (win_w - 12 * 10) / 2, win_y + 10, "PAYMENT DUE", 2); renderer->set_text_color(true); char buf[128]; int content_y = win_y + 50; snprintf(buf, sizeof(buf), "Paying: $%d from $%d", amount, payer->balance); renderer->draw_string_scaled(win_x + 20, content_y, buf, 2); content_y += 25; snprintf(buf, sizeof(buf), "To: %s", recipient ? recipient->name : "The Bank"); renderer->draw_string_scaled(win_x + 20, content_y, buf, 2); content_y += 25; snprintf(buf, sizeof(buf), "Reason: %s", reason); renderer->draw_string_scaled(win_x + 20, content_y, buf, 1); content_y += 30; renderer->draw_line(win_x + 10, content_y, win_x + win_w - 10, content_y, true); content_y += 15; renderer->draw_string_scaled(win_x + 20, content_y, "What is your new balance?", 1); content_y += 25; // Options for (int i = 0; i < 3; i++) { if (!option_visible[i]) { content_y += 25; continue; } snprintf(buf, sizeof(buf), "%s $%d", (selected_choice == i ? ">" : " "), options[i]); if (selected_choice == i) renderer->draw_filled_rectangle(win_x + 15, content_y - 2, 120, 22, true, 1); if (selected_choice == i) renderer->set_text_color(false); renderer->draw_string_scaled(win_x + 20, content_y, buf, 2); renderer->set_text_color(true); content_y += 25; } if (show_error) { renderer->set_text_color(true); renderer->draw_string_scaled(win_x + 20, content_y + 10, "TRY AGAIN!", 2); } ModalButtonHelper::draw_virtual_buttons(renderer, input_manager); } bool is_dismissed() const { return dismissed; } };