#include #include #include #include #include "scenes.h" #include "../resources/resources.h" #include "../ui_elements/UI.h" typedef struct { Puzzle *PuzzlePtr; TextArea *EditorInfo; Button *submitButton; int scroll; // Time until the next distraction puzzle in seconds size_t distraction_timer; // Miliseconds elapsed float time_acc; } puzzleSceneData; const int HEADER_FONT_SIZE = 50; const int EDITOR_PADDING = 3; const int BORDER = 2; const int FOOTER_HEIGHT = 30; // Time in seconds const size_t BASE_TIME_LEFT = 1; // 5 * 60; void DrawPuzzleName(char *name) { Vector2 width = MeasureTextEx(*GetMainFont(), name, 50, 1); int screen_width = GetScreenWidth(); Vector2 pos = { .y = 20, .x = (screen_width - width.x) / 2, }; DrawTextEx(*GetMainFont(), name, pos, HEADER_FONT_SIZE, 1, COLORSCHEME_BROWN); } void DrawControls(Scene *self, Rectangle rect) { DrawRecBordered(rect, WHITE, COLORSCHEME_ORANGE, BORDER); puzzleSceneData *data = ((Scene *)self)->data; Rectangle panel = { .x = rect.x + BORDER * 2, .y = rect.y + BORDER * 2, .width = rect.width - BORDER * 4, .height = rect.height - BORDER * 4, }; int acc = panel.width - panel.height + BORDER * 4; if (data->submitButton != NULL) { Rectangle submit_trg = { .x = acc, .y = panel.y, .width = panel.height, .height = panel.height, }; // Hacky. Should find a way to update in update() DrawButton(data->submitButton, &submit_trg); acc -= (panel.height + PADDING); } } Rectangle GetBodyRect() { int HeaderOffset = PADDING * 2 + HEADER_FONT_SIZE; Rectangle outp = { .x = PADDING, .y = HeaderOffset, .width = GetScreenWidth() - PADDING * 2, .height = GetScreenHeight() - HeaderOffset - PADDING * 3 - FOOTER_HEIGHT, }; return outp; } bool drawPuzzleScene(void *self) { puzzleSceneData *data = ((Scene *)self)->data; DrawBackground(); DrawPuzzleName(data->PuzzlePtr->Name); Rectangle body = GetBodyRect(); // DrawRecBordered(body, WHITE, COLORSCHEME_ORANGE, BORDER); // DrawTextArea(data->EditorInfo, body, GetMonoFont(), 20, 2, &data->editor_scroll); // return true; Rectangle pane1, pane2; GetPanesSplit(&pane1, &pane2, body, 0.35, 0.4); DrawRecBordered(pane1, WHITE, COLORSCHEME_ORANGE, BORDER); DrawRecBordered(pane2, WHITE, COLORSCHEME_ORANGE, BORDER); DrawTextInRec(pane1, data->PuzzlePtr->Description, GetMainFont(), 20, COLORSCHEME_BROWN, 3, &data->scroll); Rectangle editor_rect = { .x = pane2.x + EDITOR_PADDING, .y = pane2.y + EDITOR_PADDING, .width = pane2.width - EDITOR_PADDING * 2, .height = pane2.height - EDITOR_PADDING * 2, }; DrawTextArea(data->EditorInfo, editor_rect); Rectangle controls_rect = { .x = PADDING, .y = body.y + body.height + PADDING, .width = body.width, .height = FOOTER_HEIGHT, }; DrawControls(self, controls_rect); return true; } void SubmitPuzzle(Scene *self) { puzzleSceneData *data = ((Scene *)self)->data; char *script = GetText(data->EditorInfo); SubmitionResult *res = SubmitSolution(data->PuzzlePtr, script); if (res != NULL) AddScene(CreateResultView(res)); } void AddTime(Scene *self, size_t additionalTime) { puzzleSceneData *data = ((Scene *)self)->data; data->distraction_timer += additionalTime; } void createDistraction() { AddScene(CreateDistractionScene(GetRandomDistraction(), AddTime)); } bool updatePuzzleScene(void *self) { puzzleSceneData *data = ((Scene *)self)->data; Rectangle body = GetBodyRect(); Rectangle pane1, pane2; GetPanesSplit(&pane1, &pane2, body, 0.35, 0.4); UpdateTextArea(data->EditorInfo, pane2); if (IsKeyPressed(KEY_F5)) SubmitPuzzle(self); if (data->submitButton != NULL) UpdateButton(data->submitButton); data->time_acc += GetFrameTime(); while (data->time_acc >= 1) { data->distraction_timer -= 1; data->time_acc -= 1; // TraceLog(LOG_INFO, "Time left: %u", data->distraction_timer); if (data->distraction_timer == 0) { createDistraction(); return true; } } return true; } void deinitPuzzleScene(void *self) { puzzleSceneData *data = ((Scene *)self)->data; TraceLog(LOG_INFO, "Deleting a puzzle scene"); FreeTextArea(data->EditorInfo); if (data->submitButton != NULL) free(data->submitButton); free(data); free((Scene *)self); } Scene *CreatePuzzleScene(Puzzle *puzzle) { Scene *outp = malloc(sizeof(Scene)); outp->Update = updatePuzzleScene; outp->Draw = drawPuzzleScene; outp->Deint = deinitPuzzleScene; outp->IsTransparent = false; puzzleSceneData *data = malloc(sizeof(puzzleSceneData)); data->PuzzlePtr = puzzle; data->scroll = 0; TextAreaDisplayParams *EditorDisplayParams = malloc(sizeof(TextAreaDisplayParams)); if (EditorDisplayParams != NULL) { EditorDisplayParams->font = GetMonoFont(); EditorDisplayParams->spacing = 1; EditorDisplayParams->font_size = 20; // this will change EditorDisplayParams->scroll_h = 0; EditorDisplayParams->scroll_v = 0; } Button *submitButton = malloc(sizeof(Button)); if (submitButton != NULL) { submitButton->parent = outp; submitButton->OnClick = SubmitPuzzle; submitButton->atlas = GetButtonsAtlas(); submitButton->textrueLocation = (Rectangle) { .x = 0, .y = 0, .width = 32, .height = 32, }; } data->submitButton = submitButton; data->distraction_timer = BASE_TIME_LEFT; data->time_acc = 0; if (puzzle->InitialCode != NULL) { data->EditorInfo = CreateTextAreaFromText(EditorDisplayParams, puzzle->InitialCode); } else { data->EditorInfo = CreateTextArea(EditorDisplayParams); } outp->data = data; return outp; }