357 lines
8.3 KiB
C
357 lines
8.3 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
#include <math.h>
|
|
|
|
#include <raylib.h>
|
|
#include <raymath.h>
|
|
|
|
#include "types.h"
|
|
#include "game.h"
|
|
#include "draw.h"
|
|
#include "ui.h"
|
|
#include "config.h"
|
|
|
|
char _ver_str[256];
|
|
char *VERSION_STR = _ver_str;
|
|
|
|
GUIInfo gui_info;
|
|
|
|
#define color_main_brown (Color){247, 239, 206, 255}
|
|
#define color_main_brown1 (Color){161, 151, 112, 255}
|
|
|
|
void draw_text_centered(char *str, int y, int font_size, Color color){
|
|
int width = MeasureText(str, font_size);
|
|
DrawText(str, 640-width/2, y, font_size, color);
|
|
}
|
|
|
|
void draw_buttons(Widget *widget){
|
|
for(int i = 0; i < widget->button_n; i++){
|
|
Button *butt = &widget->buttons[i];
|
|
DrawRectangleRounded(butt->box, 0.1, 3, butt->color_0);
|
|
Color outline_color = butt->curr_select ? SKYBLUE : butt->color_1;
|
|
DrawRectangleRoundedLines(butt->box, 0.1, 3, 2, outline_color);
|
|
int font_size = 0.75*butt->box.height;
|
|
int width = MeasureText(butt->txt, font_size);
|
|
int text_x = butt->box.x + butt->box.width/2 - width/2;
|
|
int text_y = butt->box.y + butt->box.height/5;
|
|
DrawText(butt->txt, text_x, text_y, font_size, butt->color_txt);
|
|
}
|
|
}
|
|
|
|
void buttons_do_event(Widget *widget, Game *game, MTEvent event){
|
|
if(event.type != EV_Mouse || event.click != MOUSE_BUTTON_LEFT)
|
|
return;
|
|
for(int i = 0; i < widget->button_n; i++){
|
|
Button *butt = &widget->buttons[i];
|
|
if(CheckCollisionPointRec(event.pos, butt->box) && butt->handler)
|
|
butt->handler(game);
|
|
}
|
|
}
|
|
|
|
void main_menu_draw(Widget *widget, Game *game){
|
|
ClearBackground(color_main_brown);
|
|
|
|
draw_text_centered("Mineur Tycoon", 50, 100, BLACK);
|
|
draw_text_centered(VERSION_STR, 160, 30, BLACK);
|
|
|
|
DrawRectangleRounded((Rectangle){500, 200, 280, 260}, 0.1, 3,
|
|
color_main_brown1);
|
|
|
|
draw_buttons(widget);
|
|
}
|
|
|
|
void widget_draw_game(Widget *widget, Game *game){
|
|
draw_game(game);
|
|
}
|
|
|
|
void game_exit(Game *game){
|
|
game->exit = true;
|
|
}
|
|
|
|
void main_menu_new_game(Game *game){
|
|
gui_info.widget_active[0] = true;
|
|
gui_info.widget_active[1] = false;
|
|
game->paused = false;
|
|
}
|
|
|
|
Widget main_menu = {
|
|
.box = {.x = 0, .y = 0, .width = -1, .height = -1},
|
|
.draw = main_menu_draw,
|
|
.do_event = buttons_do_event,
|
|
.capt_flags = CF_Mouse | CF_Keyb,
|
|
.buttons = {
|
|
{.box = {520,220,240,40},
|
|
.color_0 = WHITE,
|
|
.color_1 = BLACK,
|
|
.color_txt = BLACK,
|
|
.txt = "New game",
|
|
.handler = main_menu_new_game
|
|
},
|
|
{.box = {520,270,240,40},
|
|
.color_0 = WHITE,
|
|
.color_1 = BLACK,
|
|
.color_txt = GRAY,
|
|
.txt = "Load game",
|
|
.handler = NULL
|
|
},
|
|
{.box = {520,320,240,40},
|
|
.color_0 = WHITE,
|
|
.color_1 = BLACK,
|
|
.color_txt = GRAY,
|
|
.txt = "Settings",
|
|
.handler = NULL
|
|
},
|
|
{.box = {520,400,240,40},
|
|
.color_0 = WHITE,
|
|
.color_1 = BLACK,
|
|
.color_txt = BLACK,
|
|
.txt = "Exit",
|
|
.handler = game_exit
|
|
},
|
|
},
|
|
.button_n = 4
|
|
};
|
|
|
|
void pause_menu_draw(Widget *widget, Game *game){
|
|
DrawRectangleRounded((Rectangle){500, 150, 280, 380}, 0.1, 3,
|
|
color_main_brown1);
|
|
|
|
draw_buttons(widget);
|
|
}
|
|
|
|
void pause_menu_resume(Game *game){
|
|
gui_info.widget_active[4] = false;
|
|
gui_info.widget_active[0] = true;
|
|
game->paused = false;
|
|
}
|
|
|
|
void pause_menu_new_game(Game *game){
|
|
clean_game(game);
|
|
init_game(game);
|
|
pause_menu_resume(game);
|
|
}
|
|
|
|
Widget pause_menu = {
|
|
.box = {.x = 0, .y = 0, .width = -1, .height = -1},
|
|
.draw = pause_menu_draw,
|
|
.do_event = buttons_do_event,
|
|
.capt_flags = CF_Mouse | CF_Keyb,
|
|
.buttons = {
|
|
{.box = {520,170,240,40},
|
|
.color_0 = WHITE,
|
|
.color_1 = BLACK,
|
|
.color_txt = BLACK,
|
|
.txt = "Resume",
|
|
.handler = pause_menu_resume
|
|
},
|
|
{.box = {520,240,240,40},
|
|
.color_0 = WHITE,
|
|
.color_1 = BLACK,
|
|
.color_txt = BLACK,
|
|
.txt = "New game",
|
|
.handler = pause_menu_new_game
|
|
},
|
|
{.box = {520,290,240,40},
|
|
.color_0 = WHITE,
|
|
.color_1 = BLACK,
|
|
.color_txt = GRAY,
|
|
.txt = "Save game",
|
|
.handler = NULL
|
|
},
|
|
{.box = {520,340,240,40},
|
|
.color_0 = WHITE,
|
|
.color_1 = BLACK,
|
|
.color_txt = GRAY,
|
|
.txt = "Load game",
|
|
.handler = NULL
|
|
},
|
|
{.box = {520,390,240,40},
|
|
.color_0 = WHITE,
|
|
.color_1 = BLACK,
|
|
.color_txt = GRAY,
|
|
.txt = "Settings",
|
|
.handler = NULL
|
|
},
|
|
{.box = {520,470,240,40},
|
|
.color_0 = WHITE,
|
|
.color_1 = BLACK,
|
|
.color_txt = BLACK,
|
|
.txt = "Exit",
|
|
.handler = game_exit
|
|
}
|
|
},
|
|
.button_n = 6
|
|
};
|
|
|
|
void worker_widget_draw(Widget *widget, Game *game){
|
|
DrawRectangleRounded(widget->box, 0.1, 3, color_main_brown);
|
|
}
|
|
|
|
void worker_widget_do_event(Widget *widget, Game *game, MTEvent event){
|
|
if(event.click == MOUSE_BUTTON_LEFT)
|
|
gui_info.widget_active[2] = false;
|
|
}
|
|
|
|
Widget worker_widget = {
|
|
.box = {.x = 40, .y = 40, .width = 300, .height = 600},
|
|
.draw = worker_widget_draw,
|
|
.do_event = worker_widget_do_event,
|
|
.capt_flags = CF_Mouse,
|
|
.buttons = {
|
|
|
|
},
|
|
.button_n = 0
|
|
};
|
|
|
|
Widget machine_widget = {
|
|
|
|
};
|
|
|
|
Widget game_widget = {
|
|
.box = {0,0,0,0},
|
|
.draw = widget_draw_game,
|
|
.do_event = NULL,
|
|
.capt_flags = 0,
|
|
.buttons = {},
|
|
.button_n = 0
|
|
};
|
|
|
|
void init_ui(){
|
|
snprintf(_ver_str, 256, "v%d.%d-%d", VERSION_MAJ, VERSION_MIN,
|
|
VERSION_PATCH);
|
|
|
|
// Android exclusive key -> no exit key
|
|
SetExitKey(KEY_MENU);
|
|
|
|
gui_info = (GUIInfo){{&game_widget, &main_menu, &worker_widget, &machine_widget, &pause_menu},
|
|
{false, true, false, false, false},
|
|
NULL};
|
|
}
|
|
|
|
void draw_widgets(Game *game){
|
|
for(int i = 0; i < WIDGET_N; i++){
|
|
if(!gui_info.widget_active[i])
|
|
continue;
|
|
Widget *w = gui_info.widgets[i];
|
|
if(w->draw)
|
|
w->draw(w, game);
|
|
}
|
|
}
|
|
|
|
bool widget_coll(Rectangle widget, V2d point){
|
|
if(widget.width < 0)
|
|
widget.width = SCREEN_W;
|
|
if(widget.height < 0)
|
|
widget.height = SCREEN_H;
|
|
return CheckCollisionPointRec(point, widget);
|
|
}
|
|
|
|
bool widgets_treat_event(Game *game, MTEvent event){
|
|
bool treated = true;
|
|
for(int i = WIDGET_N-1; i >= 0 && treated; i--){
|
|
if(!gui_info.widget_active[i])
|
|
continue;
|
|
Widget *w = gui_info.widgets[i];
|
|
if(!w || !w->do_event)
|
|
continue;
|
|
if(!widget_coll(w->box, event.pos))
|
|
continue;
|
|
// Only actually call do_key if the event type matches event flags
|
|
switch(event.type){
|
|
default:
|
|
continue;
|
|
case EV_Mouse:
|
|
if(w->capt_flags & CF_Mouse)
|
|
break;
|
|
continue;
|
|
case EV_Keyb:
|
|
if(w->capt_flags & CF_Keyb)
|
|
break;
|
|
continue;
|
|
}
|
|
treated = false;
|
|
w->do_event(w, game, event);
|
|
}
|
|
return treated;
|
|
}
|
|
|
|
bool ui_do_key(Game *game, int key){
|
|
MTEvent event = {.type = EV_Keyb, {.key = key}};
|
|
return widgets_treat_event(game, event);
|
|
}
|
|
|
|
bool ui_do_mouse(Game *game, V2d pos, int click){
|
|
MTEvent event = {.type = EV_Mouse, {.click = click}, .pos = pos};
|
|
return widgets_treat_event(game, event);
|
|
}
|
|
|
|
void try_interface(Game *game, V2d pos){
|
|
|
|
DrawRectangleV(pos, (V2d){16,16},PINK);
|
|
|
|
Machine *mach = get_machine_from_pos(&game->machines, pos);
|
|
|
|
if(mach){
|
|
printf("found machine %d\n",mach->id);
|
|
return;
|
|
}
|
|
|
|
Worker *work = get_worker_from_pos(&game->workers, pos);
|
|
|
|
if(!work)
|
|
return;
|
|
|
|
printf("found worker\n");
|
|
gui_info.widget_active[2] = true;
|
|
|
|
return;
|
|
}
|
|
|
|
bool keydown(int key){
|
|
return IsKeyDown(key);
|
|
}
|
|
|
|
void goto_pause_menu(Game *game){
|
|
if(gui_info.widget_active[1])
|
|
return;
|
|
memset(gui_info.widget_active, false, sizeof(bool)*WIDGET_N);
|
|
gui_info.widget_active[4] = true;
|
|
game->paused = true;
|
|
}
|
|
|
|
int get_mouse(){
|
|
for(int i = 0; i < MOUSE_BUTTON_NULL; i++){
|
|
if(IsMouseButtonPressed(i))
|
|
return i;
|
|
}
|
|
return MOUSE_BUTTON_NULL;
|
|
}
|
|
|
|
void get_keys(Game *game){
|
|
V2d mouse_pos = GetMousePosition();
|
|
int mouse_click = get_mouse();
|
|
if(ui_do_mouse(game, mouse_pos, mouse_click)){
|
|
if(mouse_click == MOUSE_BUTTON_LEFT)
|
|
try_interface(game, GetScreenToWorld2D(mouse_pos,game->camera));
|
|
}
|
|
|
|
if(keydown(KEY_W))
|
|
game->camera.target.y -= 3;
|
|
if(keydown(KEY_S))
|
|
game->camera.target.y += 3;
|
|
if(keydown(KEY_A))
|
|
game->camera.target.x -= 3;
|
|
if(keydown(KEY_D))
|
|
game->camera.target.x += 3;
|
|
if(keydown(KEY_UP))
|
|
game->camera.zoom *= 1.025;
|
|
if(keydown(KEY_DOWN))
|
|
game->camera.zoom *= 1/1.025;
|
|
if(IsKeyPressed(KEY_P))
|
|
game->paused = !game->paused;
|
|
if(IsKeyPressed(KEY_ESCAPE))
|
|
goto_pause_menu(game);
|
|
}
|