From 75e17fb26b05814bebf18a2ff5e98ee2abcd61f9 Mon Sep 17 00:00:00 2001 From: Adolfo Reyna Date: Fri, 6 Feb 2026 22:45:16 -0500 Subject: [PATCH] Add friction to mindless clicking by disabling default action preselection in Monopoly menus --- games/monopoly/PropertyModalGame.h | 13 +++++++++---- games/monopoly/monopoly_game.cpp | 17 ++++++++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/games/monopoly/PropertyModalGame.h b/games/monopoly/PropertyModalGame.h index 18e6dc0..ad9e95c 100644 --- a/games/monopoly/PropertyModalGame.h +++ b/games/monopoly/PropertyModalGame.h @@ -26,11 +26,13 @@ class PropertyModalGame : public Game { public: PropertyModalGame(uint16_t width, uint16_t height, LowLevelRenderer* renderer, LowLevelGUI* gui, InputManager* input_manager, const BoardTile* prop, bool owned, const char* owner, int o_id, bool affordable, Player* p_list = nullptr, int p_count = 0, int obs_idx = -1) - : Game(width, height, renderer, gui, input_manager), property(prop), dismissed(false), is_owned(owned), owner_name(owner), owner_id(o_id), can_afford(affordable), selected_choice(0), buy_requested(false), rent_requested(false), players(p_list), players_count(p_count), observer_idx(obs_idx) { - if (is_owned || !can_afford) selected_choice = 1; + : Game(width, height, renderer, gui, input_manager), property(prop), dismissed(false), is_owned(owned), owner_name(owner), owner_id(o_id), can_afford(affordable), selected_choice(-1), buy_requested(false), rent_requested(false), players(p_list), players_count(p_count), observer_idx(obs_idx) { + if (is_owned || !can_afford) selected_choice = 0; } void init() override { - dismissed = false; buy_requested = false; rent_requested = false; selected_choice = 0; + dismissed = false; buy_requested = false; rent_requested = false; + selected_choice = -1; + if (is_owned || !can_afford) selected_choice = 0; ModalButtonHelper::set_monopoly_regions(input_manager, width, height); } Type get_type() const override { return Type::MONOPOLY_PROPERTY; } @@ -48,12 +50,14 @@ public: // Otherwise (Buy/Pass), use A to cycle and B to select if (event.type == INPUT_BUTTON_0) { // BUTTON A -> Change selection if (!is_owned && can_afford) { - selected_choice = (selected_choice + 1) % 2; + if (selected_choice == -1) selected_choice = 0; + else selected_choice = (selected_choice + 1) % 2; return true; } } if (event.type == INPUT_BUTTON_1) { // BUTTON B -> Select action if (!is_owned && can_afford) { + if (selected_choice == -1) return false; // Ignore if nothing selected if (selected_choice == 0) buy_requested = true; dismissed = true; return true; @@ -181,6 +185,7 @@ public: btn_y += 40; // Pass Button if (selected_choice == 1) renderer->draw_filled_rectangle(win_x + 20, btn_y, btn_w, btn_h, true, 1); + else renderer->draw_rectangle(win_x + 20, btn_y, btn_w, btn_h, true, 1); if (selected_choice == 1) renderer->set_text_color(false); snprintf(buf, sizeof(buf), "%sPASS", (selected_choice == 1 ? "> " : " ")); diff --git a/games/monopoly/monopoly_game.cpp b/games/monopoly/monopoly_game.cpp index 91fd347..db291e4 100644 --- a/games/monopoly/monopoly_game.cpp +++ b/games/monopoly/monopoly_game.cpp @@ -51,7 +51,7 @@ void MonopolyGame::init() { has_rolled = false; double_rolls = 0; just_sent_to_jail = false; - selected_action = 0; + selected_action = -1; srand(time(NULL)); shuffle_chance_deck(); shuffle_community_deck(); @@ -147,6 +147,7 @@ bool MonopolyGame::update(const InputEvent& event) { // We'll apply the effect when CommunityChestModal is dismissed } if (active_modal) active_modal->init(); + else selected_action = -1; return needs_redraw; } else if (chance_modal && chance_modal->is_dismissed()) { const ChanceCard* card = &CHANCE_DECK[last_drawn_chance_idx]; @@ -234,9 +235,9 @@ bool MonopolyGame::update(const InputEvent& event) { } bool can_afford = (p->balance >= landed->cost); active_modal = new PropertyModalGame(width, height, renderer, gui, input_manager, landed, is_owned, owner_name, owner_id, can_afford, players, players_count, current_player_idx); + if (active_modal) active_modal->init(); } } - return needs_redraw; } else if (community_modal && community_modal->is_dismissed()) { const CommunityCard* card = &COMMUNITY_DECK[last_drawn_community_idx]; last_drawn_community_idx = -1; @@ -299,9 +300,9 @@ bool MonopolyGame::update(const InputEvent& event) { } bool can_afford = (p->balance >= landed->cost); active_modal = new PropertyModalGame(width, height, renderer, gui, input_manager, landed, is_owned, owner_name, owner_id, can_afford, players, players_count, current_player_idx); + if (active_modal) active_modal->init(); } } - return needs_redraw; } else if (prop_modal && prop_modal->is_dismissed()) { if (prop_modal->wants_to_buy()) { const BoardTile* tile = &MONOPOLY_BOARD[p->position]; @@ -383,6 +384,10 @@ bool MonopolyGame::update(const InputEvent& event) { needs_redraw = true; ModalButtonHelper::set_monopoly_regions(input_manager, width, height); } + + if (active_modal == nullptr && needs_redraw) { + selected_action = -1; + } return needs_redraw; } @@ -392,11 +397,13 @@ bool MonopolyGame::update(const InputEvent& event) { needs_redraw = true; break; case INPUT_BUTTON_1: + if (selected_action == -1) return false; + if (p->is_in_jail && !has_rolled && selected_action == 1) { p->balance -= 50; p->is_in_jail = false; p->jail_turns = 0; - selected_action = 0; + selected_action = -1; needs_redraw = true; return true; } @@ -466,7 +473,7 @@ roll_dice_logic: needs_redraw = true; } else { current_player_idx = (current_player_idx + 1) % players_count; - has_rolled = false; double_rolls = 0; just_sent_to_jail = false; selected_action = 0; + has_rolled = false; double_rolls = 0; just_sent_to_jail = false; selected_action = -1; active_modal = new TurnModalGame(width, height, renderer, gui, input_manager, &players[current_player_idx]); needs_redraw = true; }