Fix emulator compilation and crash, and implement Monopoly payment modal
This commit is contained in:
159
games/monopoly/PaymentModalGame.h
Normal file
159
games/monopoly/PaymentModalGame.h
Normal file
@@ -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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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; }
|
||||
};
|
||||
Reference in New Issue
Block a user