diff --git a/card.c b/card.c index 2b22217..fc7e8cc 100644 --- a/card.c +++ b/card.c @@ -103,7 +103,7 @@ void add_to_hand(Hand *h, Card *c) { } c->move.curve = CURVE_EASE_IN_OUT; c->move.current_time = 0.; - c->move.end_time = 0.5; + c->move.end_time = 0.2; h->count++; } diff --git a/dialog.c b/dialog.c new file mode 100644 index 0000000..0753c42 --- /dev/null +++ b/dialog.c @@ -0,0 +1,108 @@ +#include +#include +#include + +#include + +#include "dialog.h" + +Dialog dialogs[2]; + +void handle_click_cancel_yes(Game *g) { + g->state = GAME_STATE_CHOOSING_FROM_HAND; +} + +void handle_click_cancel_no(Game *g) { + g->state = GAME_STATE_CHOOSING_FROM_HAND; +} + +void init_dialogs(Game *g) { + Dialog *cancel_dialog = &dialogs[0]; + cancel_dialog->text = malloc(200); + strcpy(cancel_dialog->text, "Would you like to cancel?"); + cancel_dialog->text_color = BLACK; + cancel_dialog->options_count = 2; + cancel_dialog->game = g; + + cancel_dialog->options[0].text = malloc(50); + strcpy(cancel_dialog->options[0].text, "Yes"); + cancel_dialog->options[0].color = GREEN; + cancel_dialog->options[0].handle = &handle_click_cancel_yes; + + cancel_dialog->options[1].text = malloc(50); + strcpy(cancel_dialog->options[1].text, "No"); + cancel_dialog->options[1].color = RED; + cancel_dialog->options[1].handle = &handle_click_cancel_no; + + + Dialog *shoubu_dialog = &dialogs[1]; + shoubu_dialog->text = malloc(200); + strcpy(shoubu_dialog->text, "You have dekiyaku! Sage or shoubu?"); + shoubu_dialog->text_color = BLACK; + shoubu_dialog->options_count = 2; + shoubu_dialog->game = g; + + shoubu_dialog->options[0].text = malloc(50); + strcpy(shoubu_dialog->options[0].text, "Sage"); + shoubu_dialog->options[0].color = GREEN; + shoubu_dialog->options[0].handle = NULL; + + shoubu_dialog->options[1].text = malloc(50); + strcpy(shoubu_dialog->options[1].text, "Shoubu"); + shoubu_dialog->options[1].color = RED; + shoubu_dialog->options[1].handle = NULL; +} + +Dialog *cancel_dialog() { return &dialogs[0]; } +Dialog *shoubu_dialog() { return &dialogs[1]; } + +Rectangle dialog_option_outer_rectangle(Dialog *d, int i) { + return (Rectangle) { + ((960 * (i + 1)) / (d->options_count + 1)) - 10 + 200, + 500, + MeasureText(d->options[i].text, DIALOG_OPTION_FONT_SIZE) + 20, + 40, + }; +} + +Rectangle dialog_option_inner_rectangle(Dialog *d, int i) { + Rectangle outer = dialog_option_outer_rectangle(d, i); + return (Rectangle) { + outer.x + 3, + outer.y + 3, + outer.width - 6, + outer.height - 6, + }; +} + +void dialog_draw(Dialog *d) { + int text_width; + DrawRectangleRec(DIALOG_OUTER_RECTANGLE, BLACK); + DrawRectangleRec(DIALOG_INNER_RECTANGLE, WHITE); + text_width = MeasureText(d->text, DIALOG_TEXT_FONT_SIZE); + DrawText(d->text, 700 - (text_width / 2), 400, DIALOG_TEXT_FONT_SIZE, d->text_color); + + for (int i = 0; i < d->options_count; i++) { + DialogOption *o = &d->options[i]; + Rectangle outer = dialog_option_outer_rectangle(d, i); + Rectangle inner = dialog_option_inner_rectangle(d, i); + DrawRectangleRec(outer, BLACK); + DrawRectangleRec(inner, o->color); + DrawText(o->text, inner.x + 3, inner.y + 3, DIALOG_OPTION_FONT_SIZE, BLACK); + } +} + +void dialog_handle_input(Dialog *d) { + if (IsMouseButtonPressed(0)) { + Vector2 mouse_pos = GetMousePosition(); + for (int i = 0; i < d->options_count; i++) { + DialogOption *o = &d->options[i]; + Rectangle outer = dialog_option_outer_rectangle(d, i); + if (CheckCollisionPointRec(mouse_pos, outer)) { + o->handle(d->game); + d->game->dialog = NULL; + break; + } + } + } +} diff --git a/dialog.h b/dialog.h new file mode 100644 index 0000000..d762313 --- /dev/null +++ b/dialog.h @@ -0,0 +1,34 @@ +#ifndef _HF_DIALOG_ +#define _HF_DIALOG_ + +typedef struct DialogOption DialogOption; +typedef struct Dialog Dialog; + +#include "game.h" + +#define DIALOG_OUTER_RECTANGLE (Rectangle) { 200, 200, 1000, 500 } +#define DIALOG_INNER_RECTANGLE (Rectangle) { 220, 220, 960, 460 } +#define DIALOG_TEXT_FONT_SIZE 60 +#define DIALOG_OPTION_FONT_SIZE 30 + +struct DialogOption { + char *text; + Color color; + void (*handle) (Game *g); +}; + +struct Dialog { + char *text; + Color text_color; + DialogOption options[3]; + int options_count; + Game *game; +}; + +void init_dialogs(Game *g); +Dialog *cancel_dialog(); +Dialog *shoubu_dialog(); +void dialog_draw(Dialog *d); +void dialog_handle_input(Dialog *d); + +#endif diff --git a/game.c b/game.c index 32f1484..5587c3b 100644 --- a/game.c +++ b/game.c @@ -8,6 +8,7 @@ #include "field_multiplier.h" #include "special_cases.h" #include "play.h" +#include "dialog.h" Vector2 mouse_pos; char teyaku_calculation[400]; @@ -28,7 +29,9 @@ void initialize_game(Game *g) { g->kan_value = 12; g->current_play_from_hand = NULL; g->current_play_target = NULL; - g->turn_number = 0; + g->turn_number = -1; + g->dialog = NULL; + init_dialogs(g); for (int i = 0; i < 48; i++) { CardType t = CHAFF; @@ -132,6 +135,7 @@ bool is_player_turn(Game *g) { bool stale_calculation = true; void handle_input(Game *g) { if (!is_player_turn(g)) return; + if (g->dialog) return dialog_handle_input(g->dialog); switch (g->state) { case GAME_STATE_CHOOSING_FROM_HAND: @@ -267,6 +271,9 @@ void run_frame_start_of_turn(Game *g) { } void run_frame_checking_for_cancel(Game *g) { + if (g->dialog) return; + if (is_player_turn(g)) { g->dialog = cancel_dialog(); return; } + if (current_player(g)->dekiyaku_action == DEKIYAKU_ACTION_SAGE) { if (is_player_turn(g)) { // check for player canceling @@ -520,6 +527,10 @@ void draw_frame(Game *g) { } } + if (g->dialog) { + dialog_draw(g->dialog); + } + EndDrawing(); } diff --git a/game.h b/game.h index 8da0a0d..e209e4c 100644 --- a/game.h +++ b/game.h @@ -11,6 +11,7 @@ typedef struct Game Game; #include "dekiyaku.h" #include "points.h" #include "player.h" +#include "dialog.h" typedef enum GameState { GAME_STATE_INITIALIZING, @@ -40,6 +41,7 @@ struct Game { Player player, right, left; int temp_points; int turn_number; + Dialog *dialog; }; void initialize_game(Game *g);