From 64f61759d75c767c250efa612b7da70645071d95 Mon Sep 17 00:00:00 2001 From: Adolfo Reyna Date: Fri, 6 Feb 2026 23:13:32 -0500 Subject: [PATCH] Fix emulator compilation and crash, and implement Monopoly payment modal --- basic1.cpp | 8 +- emulator/Makefile | 4 +- emulator/basic1_emulator | Bin 164672 -> 184416 bytes emulator/input_manager.h | 52 +++++++++- emulator/main.cpp | 6 ++ games/monopoly/DiceModalGame.h | 6 +- games/monopoly/ModalButtonHelper.h | 52 ++++++---- games/monopoly/PaymentModalGame.h | 159 +++++++++++++++++++++++++++++ games/monopoly/monopoly_game.cpp | 85 ++++++++------- lib/game.h | 3 +- 10 files changed, 309 insertions(+), 66 deletions(-) create mode 100644 games/monopoly/PaymentModalGame.h diff --git a/basic1.cpp b/basic1.cpp index 7501e71..73b8c2c 100644 --- a/basic1.cpp +++ b/basic1.cpp @@ -306,8 +306,8 @@ int main() // Initialize renderer and GUI system LowLevelRenderer renderer(bit_buffer, V_WIDTH, V_HEIGHT); - renderer.set_font(&font_5x5_obj); - LowLevelGUI gui = LowLevelGUI(&renderer, font_BMplain_obj); + renderer.set_font(&font_homespun_obj); + LowLevelGUI gui = LowLevelGUI(&renderer, font_homespun_obj); // Initialize touch screen using abstraction FIRST (before InputManager needs it) touch = LowLevelTouch::create((TouchType)TOUCH_TYPE_SELECTED, V_WIDTH, V_HEIGHT, @@ -353,7 +353,9 @@ int main() launcher.register_game("Monopoly", "Classic property trading game", [](uint16_t w, uint16_t h, LowLevelRenderer* r, LowLevelGUI* g, InputManager* im) -> Game* { - return new MonopolyGame(w, h, r, g, im); + // For Feather TFT (480x320), reduce width to 430 to make room for sidebar buttons + uint16_t game_w = (w == 480) ? 430 : w; + return new MonopolyGame(game_w, h, r, g, im); }); launcher.register_game("Demo Game", "Simple test game", diff --git a/emulator/Makefile b/emulator/Makefile index 37e4686..d38cb80 100644 --- a/emulator/Makefile +++ b/emulator/Makefile @@ -8,11 +8,11 @@ CXXFLAGS = -std=c++17 -Wall # Paths for Homebrew on macOS (Silicon/M1/M2/M3) ifeq ($(OS), Darwin) SFML_DIR = $(shell brew --prefix sfml@2) - INCLUDES = -I. -I$(SFML_DIR)/include -I../display -I../fonts -I../games + INCLUDES = -I. -I.. -I$(SFML_DIR)/include -I../display -I../fonts -I../games LIBS = -L$(SFML_DIR)/lib -lsfml-graphics -lsfml-window -lsfml-system else # Standard Linux paths - INCLUDES = -I. -I../display -I../fonts -I../games + INCLUDES = -I. -I.. -I../display -I../fonts -I../games LIBS = -lsfml-graphics -lsfml-window -lsfml-system endif diff --git a/emulator/basic1_emulator b/emulator/basic1_emulator index 32583355dc96b12071e3651a56551687f839ddcd..8bcdc5a3220c1cf1290f2d65a570e03323803fd8 100755 GIT binary patch delta 67345 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 HJp6wE=3d0@ delta 45063 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 diff --git a/emulator/input_manager.h b/emulator/input_manager.h index ee397fd..7e9fa2d 100644 --- a/emulator/input_manager.h +++ b/emulator/input_manager.h @@ -1,6 +1,56 @@ -#pragma once +#ifndef INPUT_MANAGER_H +#define INPUT_MANAGER_H + +#include +#include "input_event.h" + // Minimal stub for emulator build class InputManager { public: bool has_buttons() const { return false; } + bool has_touch() const { return false; } + + void get_virtual_button_regions(int* a_rect, int* b_rect) const { + for (int i = 0; i < 4; i++) { + a_rect[i] = v_button_a[i]; + b_rect[i] = v_button_b[i]; + } + } + void set_virtual_button_regions(int ax, int ay, int aw, int ah, int bx, int by, int bw, int bh) { + v_button_a[0] = ax; v_button_a[1] = ay; v_button_a[2] = aw; v_button_a[3] = ah; + v_button_b[0] = bx; v_button_b[1] = by; v_button_b[2] = bw; v_button_b[3] = bh; + v_buttons_active = true; + } + void clear_virtual_button_regions() { + v_buttons_active = false; + for (int i = 0; i < 4; i++) { + v_button_a[i] = 0; + v_button_b[i] = 0; + } + } + + bool check_virtual_buttons(int16_t x, int16_t y, InputType& out_type) const { + if (!v_buttons_active) return false; + + if (x >= v_button_a[0] && x <= v_button_a[0] + v_button_a[2] && + y >= v_button_a[1] && y <= v_button_a[1] + v_button_a[3]) { + out_type = INPUT_BUTTON_0; + return true; + } + + if (x >= v_button_b[0] && x <= v_button_b[0] + v_button_b[2] && + y >= v_button_b[1] && y <= v_button_b[1] + v_button_b[3]) { + out_type = INPUT_BUTTON_1; + return true; + } + + return false; + } + +private: + int v_button_a[4] = {0, 0, 0, 0}; + int v_button_b[4] = {0, 0, 0, 0}; + bool v_buttons_active = false; }; + +#endif diff --git a/emulator/main.cpp b/emulator/main.cpp index b7ec687..f44873b 100644 --- a/emulator/main.cpp +++ b/emulator/main.cpp @@ -64,6 +64,12 @@ int main() { event.x = sfEvent.mouseButton.x; event.y = sfEvent.mouseButton.y; event.valid = true; + + // Check for virtual buttons + InputType virtual_type; + if (input_manager.check_virtual_buttons(event.x, event.y, virtual_type)) { + event.type = virtual_type; + } } else if (sfEvent.type == sf::Event::KeyPressed) { if (sfEvent.key.code == sf::Keyboard::Space) { event.type = INPUT_BUTTON_0; diff --git a/games/monopoly/DiceModalGame.h b/games/monopoly/DiceModalGame.h index e6e5424..ab1f6b4 100644 --- a/games/monopoly/DiceModalGame.h +++ b/games/monopoly/DiceModalGame.h @@ -104,10 +104,10 @@ public: char move_buf[64]; if (from_tile && to_tile) { snprintf(move_buf, sizeof(move_buf), "FROM: %s", from_tile->name); - renderer->draw_string_scaled(ix + 10, info_y, move_buf, 1); - info_y += 12; + renderer->draw_string_scaled(ix + 10, info_y, move_buf, 2); + info_y += 24; snprintf(move_buf, sizeof(move_buf), "TO: %s", to_tile->name); - renderer->draw_string_scaled(ix + 10, info_y, move_buf, 1); + renderer->draw_string_scaled(ix + 10, info_y, move_buf, 2); } // Button diff --git a/games/monopoly/ModalButtonHelper.h b/games/monopoly/ModalButtonHelper.h index 496618f..907bb25 100644 --- a/games/monopoly/ModalButtonHelper.h +++ b/games/monopoly/ModalButtonHelper.h @@ -11,23 +11,32 @@ public: static void set_monopoly_regions(InputManager* input_manager, uint16_t width, uint16_t height) { if (!input_manager) return; - // --- BUTTON CONFIGURATION --- - // Adjust these variables to move the virtual buttons easily - int btn_w = 60; - int btn_h = 60; - int margin_right = 135; // Positioned for the inner board area (W - 135 = 345) - int start_y = 80; // Vertical start position - int spacing = 30; // Gap between buttons - - int btn_x = width - margin_right; - int btn_a_y = start_y; - int btn_b_y = btn_a_y + btn_h + spacing; + if (width < 480) { + // Sidebar mode for 480x320 screen (Buttons at 400-480) + int sidebar_x = width; + int sidebar_w = 480 - width; + int btn_h = height / 2; + input_manager->set_virtual_button_regions( + sidebar_x, 0, sidebar_w, btn_h, // Button A (Top half) + sidebar_x, btn_h, sidebar_w, btn_h // Button B (Bottom half) + ); + } else { + // Inner dashboard mode (fallback) + int btn_w = 60; + int btn_h = 60; + int margin_right = 135; // Positioned for the inner board area (W - 135 = 345) + int start_y = 80; // Vertical start position + int spacing = 30; // Gap between buttons + + int btn_x = width - margin_right; + int btn_a_y = start_y; + int btn_b_y = btn_a_y + btn_h + spacing; - // Apply regions to input manager - input_manager->set_virtual_button_regions( - btn_x, btn_a_y, btn_w, btn_h, // Button A (Top) - btn_x, btn_b_y, btn_w, btn_h // Button B (Bottom) - ); + input_manager->set_virtual_button_regions( + btn_x, btn_a_y, btn_w, btn_h, + btn_x, btn_b_y, btn_w, btn_h + ); + } } /** @@ -42,17 +51,20 @@ public: // Save current color bool original_color = renderer->get_current_text_color(); - // Draw Button A (Top) + // Draw Button A renderer->draw_filled_rectangle(a[0], a[1], a[2], a[3], false, 0); // White back renderer->draw_rectangle(a[0], a[1], a[2], a[3], true, 2); // Black border renderer->set_text_color(true); - renderer->draw_string_scaled(a[0] + (a[2] - 12) / 2, a[1] + (a[3] - 16) / 2, "A", 2); + // Use larger font scaling if buttons are big (sidebar mode) + int scale_a = (a[3] > 100) ? 4 : 2; + renderer->draw_string_scaled(a[0] + (a[2] - 6 * scale_a) / 2, a[1] + (a[3] - 8 * scale_a) / 2, "A", scale_a); - // Draw Button B (Under A) + // Draw Button B renderer->draw_filled_rectangle(b[0], b[1], b[2], b[3], false, 0); // White back renderer->draw_rectangle(b[0], b[1], b[2], b[3], true, 2); // Black border renderer->set_text_color(true); - renderer->draw_string_scaled(b[0] + (b[2] - 12) / 2, b[1] + (b[3] - 16) / 2, "B", 2); + int scale_b = (b[3] > 100) ? 4 : 2; + renderer->draw_string_scaled(b[0] + (b[2] - 6 * scale_b) / 2, b[1] + (b[3] - 8 * scale_b) / 2, "B", scale_b); // Restore color renderer->set_text_color(original_color); diff --git a/games/monopoly/PaymentModalGame.h b/games/monopoly/PaymentModalGame.h new file mode 100644 index 0000000..fb69f3b --- /dev/null +++ b/games/monopoly/PaymentModalGame.h @@ -0,0 +1,159 @@ +// 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; } +}; diff --git a/games/monopoly/monopoly_game.cpp b/games/monopoly/monopoly_game.cpp index db291e4..f720dfa 100644 --- a/games/monopoly/monopoly_game.cpp +++ b/games/monopoly/monopoly_game.cpp @@ -23,6 +23,7 @@ extern "C" { #include "ChanceModalGame.h" #include "CommunityChestModalGame.h" #include "TurnModalGame.h" +#include "PaymentModalGame.h" #include "ModalButtonHelper.h" #include "sprites.h" #include "MonopolyBoardRenderer.h" @@ -55,6 +56,7 @@ void MonopolyGame::init() { srand(time(NULL)); shuffle_chance_deck(); shuffle_community_deck(); + //renderer->set_font(&font_tama_mini02_obj); if (active_modal) { delete active_modal; active_modal = nullptr; } active_modal = new TurnModalGame(width, height, renderer, gui, input_manager, &players[current_player_idx]); // TODO: Reset all board state, property ownership, etc. @@ -113,6 +115,16 @@ bool MonopolyGame::update(const InputEvent& event) { ChanceModalGame* chance_modal = (active_modal->get_type() == Game::Type::MONOPOLY_CHANCE) ? static_cast(active_modal) : nullptr; CommunityChestModalGame* community_modal = (active_modal->get_type() == Game::Type::MONOPOLY_COMMUNITY_CHEST) ? static_cast(active_modal) : nullptr; TurnModalGame* turn_modal = (active_modal->get_type() == Game::Type::MONOPOLY_TURN) ? static_cast(active_modal) : nullptr; + PaymentModalGame* pay_modal = (active_modal->get_type() == Game::Type::MONOPOLY_PAYMENT) ? static_cast(active_modal) : nullptr; + + if (pay_modal && pay_modal->is_dismissed()) { + delete active_modal; + active_modal = nullptr; + selected_action = -1; + needs_redraw = true; + ModalButtonHelper::set_monopoly_regions(input_manager, width, height); + return needs_redraw; + } if (dice_modal && dice_modal->is_dismissed()) { delete active_modal; @@ -165,7 +177,8 @@ bool MonopolyGame::update(const InputEvent& event) { p->balance += card->value; break; case CHANCE_SPEND: - p->balance -= card->value; + active_modal = new PaymentModalGame(width, height, renderer, gui, input_manager, p, nullptr, card->value, "CHANCE CARD"); + if (active_modal) active_modal->init(); break; case CHANCE_ADVANCE: { int target = card->value; @@ -211,12 +224,12 @@ bool MonopolyGame::update(const InputEvent& event) { break; } - delete active_modal; - active_modal = nullptr; needs_redraw = true; ModalButtonHelper::set_monopoly_regions(input_manager, width, height); - if (position_changed) { + if (active_modal) { + active_modal->init(); + } else if (position_changed) { // If we moved, check if we landed on a property const BoardTile* landed = &MONOPOLY_BOARD[p->position]; if (landed->type == TILE_PROPERTY || landed->type == TILE_RAILROAD || landed->type == TILE_UTILITY) { @@ -250,7 +263,8 @@ bool MonopolyGame::update(const InputEvent& event) { p->balance += card->value; break; case COMMUNITY_SPEND: - p->balance -= card->value; + active_modal = new PaymentModalGame(width, height, renderer, gui, input_manager, p, nullptr, card->value, "COMMUNITY CHEST"); + if (active_modal) active_modal->init(); break; case COMMUNITY_ADVANCE: p->position = card->value; @@ -277,12 +291,12 @@ bool MonopolyGame::update(const InputEvent& event) { break; } - delete active_modal; - active_modal = nullptr; needs_redraw = true; ModalButtonHelper::set_monopoly_regions(input_manager, width, height); - if (position_changed) { + if (active_modal) { + active_modal->init(); + } else if (position_changed) { const BoardTile* landed = &MONOPOLY_BOARD[p->position]; if (landed->type == TILE_PROPERTY || landed->type == TILE_RAILROAD || landed->type == TILE_UTILITY) { bool is_owned = false; @@ -304,28 +318,30 @@ bool MonopolyGame::update(const InputEvent& event) { } } } else if (prop_modal && prop_modal->is_dismissed()) { - if (prop_modal->wants_to_buy()) { + bool wants_buy = prop_modal->wants_to_buy(); + bool wants_rent = prop_modal->wants_to_pay_rent(); + int owner_id_from_modal = prop_modal->get_owner_id(); + + delete active_modal; + active_modal = nullptr; + + if (wants_buy) { const BoardTile* tile = &MONOPOLY_BOARD[p->position]; if (p->balance >= tile->cost) { - p->balance -= tile->cost; + active_modal = new PaymentModalGame(width, height, renderer, gui, input_manager, p, nullptr, tile->cost, "BUY PROPERTY"); p->properties_owned[p->property_count++] = p->position; } - } else if (prop_modal->wants_to_pay_rent()) { + } else if (wants_rent) { const BoardTile* tile = &MONOPOLY_BOARD[p->position]; int rent = 0; if (tile->type == TILE_PROPERTY) { - // Logic for rent: If owner has all properties of group, rent is doubled (base only) - // For now, let's just use rent[0] as requested, but we should probably eventually - // check for houses. Let's stick to rent[0] to match the modal's display. rent = tile->rent[0]; } else if (tile->type == TILE_RAILROAD) { - // Utility logic for Railroads: 1:25, 2:50, 3:100, 4:200 - int owner_id = prop_modal->get_owner_id(); int rr_count = 0; - if (owner_id != -1) { - for (int i = 0; i < players[owner_id].property_count; ++i) { - if (MONOPOLY_BOARD[players[owner_id].properties_owned[i]].type == TILE_RAILROAD) { + if (owner_id_from_modal != -1) { + for (int i = 0; i < players[owner_id_from_modal].property_count; ++i) { + if (MONOPOLY_BOARD[players[owner_id_from_modal].properties_owned[i]].type == TILE_RAILROAD) { rr_count++; } } @@ -334,18 +350,14 @@ bool MonopolyGame::update(const InputEvent& event) { else if (rr_count == 2) rent = 50; else if (rr_count == 3) rent = 100; else if (rr_count == 4) rent = 200; - else rent = 25; // Fallback + else rent = 25; } else if (tile->type == TILE_UTILITY) { - // Utility: 4x dice if 1 owned, 10x if both. - // Since we don't have the dice roll here, let's use a fixed 40 for now - // or calculate it from last_dice1 + last_dice2. int total_dice = last_dice1 + last_dice2; - int owner_id = prop_modal->get_owner_id(); int utility_count = 0; - if (owner_id != -1) { - for (int i = 0; i < players[owner_id].property_count; ++i) { - if (MONOPOLY_BOARD[players[owner_id].properties_owned[i]].type == TILE_UTILITY) { + if (owner_id_from_modal != -1) { + for (int i = 0; i < players[owner_id_from_modal].property_count; ++i) { + if (MONOPOLY_BOARD[players[owner_id_from_modal].properties_owned[i]].type == TILE_UTILITY) { utility_count++; } } @@ -359,20 +371,17 @@ bool MonopolyGame::update(const InputEvent& event) { rent *= rent_multiplier; - int o_id = prop_modal->get_owner_id(); - if (o_id != -1 && (int)current_player_idx != o_id) { - p->balance -= rent; - players[o_id].balance += rent; + if (owner_id_from_modal != -1 && (int)current_player_idx != owner_id_from_modal) { + active_modal = new PaymentModalGame(width, height, renderer, gui, input_manager, p, &players[owner_id_from_modal], rent, "RENT"); } } // Reset multipliers rent_multiplier = 1; force_utility_10x = false; - delete active_modal; - active_modal = nullptr; needs_redraw = true; ModalButtonHelper::set_monopoly_regions(input_manager, width, height); + if (active_modal) active_modal->init(); } else if (board_modal && board_modal->is_dismissed()) { delete active_modal; active_modal = nullptr; @@ -400,7 +409,8 @@ bool MonopolyGame::update(const InputEvent& event) { if (selected_action == -1) return false; if (p->is_in_jail && !has_rolled && selected_action == 1) { - p->balance -= 50; + active_modal = new PaymentModalGame(width, height, renderer, gui, input_manager, p, nullptr, 50, "JAIL BAIL"); + if (active_modal) active_modal->init(); p->is_in_jail = false; p->jail_turns = 0; selected_action = -1; @@ -423,7 +433,9 @@ roll_dice_logic: } else { p->jail_turns++; if (p->jail_turns >= 3) { - p->balance -= 50; p->is_in_jail = false; p->jail_turns = 0; + active_modal = new PaymentModalGame(width, height, renderer, gui, input_manager, p, nullptr, 50, "JAIL BAIL (FORCED)"); + if (active_modal) active_modal->init(); + p->is_in_jail = false; p->jail_turns = 0; } else { has_rolled = true; last_dice1 = d1; last_dice2 = d2; @@ -468,7 +480,8 @@ roll_dice_logic: current_community_idx = (current_community_idx + 1) % COMMUNITY_DECK_SIZE; if (current_community_idx == 0) shuffle_community_deck(); } else if (lnd->type == TILE_TAX) { - p->balance -= lnd->cost; + active_modal = new PaymentModalGame(width, height, renderer, gui, input_manager, p, nullptr, lnd->cost, "TAXES"); + if (active_modal) active_modal->init(); } needs_redraw = true; } else { diff --git a/lib/game.h b/lib/game.h index ee3f53f..53bc866 100644 --- a/lib/game.h +++ b/lib/game.h @@ -35,7 +35,8 @@ public: MONOPOLY_BOARD, MONOPOLY_CHANCE, MONOPOLY_COMMUNITY_CHEST, - MONOPOLY_TURN + MONOPOLY_TURN, + MONOPOLY_PAYMENT }; /**