Kaynağa Gözat

many vibecode lmaoo

quantumde1 2 gün önce
ebeveyn
işleme
a49e87bc29

+ 3 - 1
conf/settings.conf

@@ -4,4 +4,6 @@ BACKWARD:S
 LEFT:A
 RIGHT:D
 DIALOG:K
-OPMENU:M
+OPMENU:M
+SCRIPT:scripts/SA00.lua
+FULLSCREEN:0

+ 1 - 11
source/app.d

@@ -21,15 +21,5 @@ void main(string[] args)
     } else {
         SetTraceLogLevel(7);
     }
-    int screenWidth = GetScreenWidth();
-    int screenHeight = GetScreenHeight();
-    luaExec = "scripts/00_script.lua";
-    if (args.length > 1) {
-        writeln("!!!If needed, there is first argument for choosing script to execute.!!!");
-        luaExec = getcwd().to!string ~ "/" ~ args[1];
-        engine_loader("tief blau", screenWidth, screenHeight);
-    }
-    else {
-        engine_loader("tief blau", screenWidth, screenHeight);
-    }
+    engine_loader();
 }

+ 232 - 83
source/dialogs/dialogbox.d

@@ -7,29 +7,134 @@ import std.conv;
 import std.uni;
 import std.typecons;
 import std.algorithm;
+import variables;
 
 int currentPage = 0;
 float textDisplayProgress = 0.0f;
 bool textFullyDisplayed = false;
 
+// Texture variables
+bool texturesLoaded = false;
+float circleRotationAngle = 0.0f;
+
+// Border sizes for 9-slice scaling
+const int DIALOG_BORDER = 32; // Border size that won't be stretched
+const int CHOICE_BORDER = 32;  // Border size for choice window
+
+void draw9SliceTexture(Texture2D tex, Rectangle dest, int borderSize, Color tint) {
+    // Source rectangle is the whole texture
+    Rectangle src = Rectangle(0, 0, tex.width, tex.height);
+    
+    // Prevent division by zero
+    if (borderSize <= 0) borderSize = 1;
+    if (borderSize * 2 >= src.width) borderSize = cast(int)src.width / 3;
+    if (borderSize * 2 >= src.height) borderSize = cast(int)src.height / 3;
+    
+    // Calculate inner source rectangle (without borders)
+    Rectangle innerSrc = Rectangle(
+        borderSize, 
+        borderSize, 
+        src.width - borderSize * 2, 
+        src.height - borderSize * 2
+    );
+    
+    // Calculate inner destination rectangle
+    Rectangle innerDest = Rectangle(
+        dest.x + borderSize, 
+        dest.y + borderSize, 
+        dest.width - borderSize * 2, 
+        dest.height - borderSize * 2
+    );
+    
+    // Draw 9 parts:
+    // 1. Top-left corner
+    DrawTexturePro(tex, 
+        Rectangle(src.x, src.y, borderSize, borderSize),
+        Rectangle(dest.x, dest.y, borderSize, borderSize),
+        Vector2(0, 0), 0, tint);
+    
+    // 2. Top edge
+    DrawTexturePro(tex, 
+        Rectangle(src.x + borderSize, src.y, innerSrc.width, borderSize),
+        Rectangle(dest.x + borderSize, dest.y, innerDest.width, borderSize),
+        Vector2(0, 0), 0, tint);
+    
+    // 3. Top-right corner
+    DrawTexturePro(tex, 
+        Rectangle(src.x + src.width - borderSize, src.y, borderSize, borderSize),
+        Rectangle(dest.x + dest.width - borderSize, dest.y, borderSize, borderSize),
+        Vector2(0, 0), 0, tint);
+    
+    // 4. Left edge
+    DrawTexturePro(tex, 
+        Rectangle(src.x, src.y + borderSize, borderSize, innerSrc.height),
+        Rectangle(dest.x, dest.y + borderSize, borderSize, innerDest.height),
+        Vector2(0, 0), 0, tint);
+    
+    // 5. Center (stretched)
+    DrawTexturePro(tex, 
+        innerSrc,
+        innerDest,
+        Vector2(0, 0), 0, tint);
+    
+    // 6. Right edge
+    DrawTexturePro(tex, 
+        Rectangle(src.x + src.width - borderSize, src.y + borderSize, borderSize, innerSrc.height),
+        Rectangle(dest.x + dest.width - borderSize, dest.y + borderSize, borderSize, innerDest.height),
+        Vector2(0, 0), 0, tint);
+    
+    // 7. Bottom-left corner
+    DrawTexturePro(tex, 
+        Rectangle(src.x, src.y + src.height - borderSize, borderSize, borderSize),
+        Rectangle(dest.x, dest.y + dest.height - borderSize, borderSize, borderSize),
+        Vector2(0, 0), 0, tint);
+    
+    // 8. Bottom edge
+    DrawTexturePro(tex, 
+        Rectangle(src.x + borderSize, src.y + src.height - borderSize, innerSrc.width, borderSize),
+        Rectangle(dest.x + borderSize, dest.y + dest.height - borderSize, innerDest.width, borderSize),
+        Vector2(0, 0), 0, tint);
+    
+    // 9. Bottom-right corner
+    DrawTexturePro(tex, 
+        Rectangle(src.x + src.width - borderSize, src.y + src.height - borderSize, borderSize, borderSize),
+        Rectangle(dest.x + dest.width - borderSize, dest.y + dest.height - borderSize, borderSize, borderSize),
+        Vector2(0, 0), 0, tint);
+}
+
 void displayDialog(string[] pages, string[] choices, ref int selectedChoice, int choicePage, Font dialogFont, 
-bool *showDialog, float textSpeed) {
+bool *showDialog, ref float textSpeed, Color dialogColor, 
+Texture2D circle, Texture2D dialogBackgroundTex, Texture2D choiceWindowTex) {
+
     int pagesLength = cast(int)pages.length;
     int screenWidth = GetScreenWidth();
     int screenHeight = GetScreenHeight();
     
-    DrawRectangle(
-        0,
-        screenHeight - screenHeight / 3,
-        screenWidth,
-        screenHeight / 3,
-        Color(20, 20, 20, 220)
+    const int screenPadding = 10;
+    
+    // Dialog background rectangle с отступами
+    Rectangle dialogRect = Rectangle(
+        screenPadding, // X с отступом
+        screenHeight - screenHeight / 3 - screenPadding, // Y с отступом
+        screenWidth - 2 * screenPadding, // Ширина с учетом отступов
+        screenHeight / 3 // Высота (без изменения)
+    );
+    
+    // Draw dialog background with 9-slice scaling
+    draw9SliceTexture(
+        dialogBackgroundTex,
+        dialogRect,
+        DIALOG_BORDER,
+        Color(255, 255, 255, 220) // Slightly transparent
     );
     
-    float marginLeft = screenWidth/6.5f;
+    const float textLeftMargin = 33.0f;
+    const float textTopMargin = 20.0f;
+    
+    float marginLeft = dialogRect.x + textLeftMargin; // Отступ от левого края фона
     float marginRight = screenWidth/6.5f;
-    float marginTop = screenHeight - screenHeight/3.3f;
-    float textWidth = screenWidth - marginLeft - marginRight;
+    float marginTop = dialogRect.y + textTopMargin; // Отступ от верхнего края фона
+    float textWidth = dialogRect.width - textLeftMargin - marginRight;
     float fontSize = 40.0f;
     float spacing = 1.0f;
     
@@ -93,9 +198,16 @@ bool *showDialog, float textSpeed) {
         remainingText = remainingText[fitChars..$];
     }
     
-    // Draw each line of text
     float lineHeight = MeasureTextEx(dialogFont, "A", fontSize, spacing).y * 1.4;
     for (int i = 0; i < lines.length; i++) {
+        DrawTextEx(
+            dialogFont,
+            lines[i].toStringz(),
+            Vector2(marginLeft+3, 3+(marginTop + i * lineHeight)),
+            fontSize,
+            spacing,
+            Colors.BLACK
+        );
         DrawTextEx(
             dialogFont,
             lines[i].toStringz(),
@@ -106,95 +218,132 @@ bool *showDialog, float textSpeed) {
         );
     }
     
-    if (textFullyDisplayed) {
-        drawSnakeAnimation(
-            0,
-            screenHeight - screenHeight / 3,
-            screenWidth,
-            screenHeight / 3
+    if (textFullyDisplayed && lines.length > 0) {
+        // Обновляем угол вращения (например, 45 градусов в секунду)
+        circleRotationAngle += 45.0f * GetFrameTime();
+        if (circleRotationAngle >= 360.0f) {
+            circleRotationAngle -= 360.0f;
+        }
+
+        // Получаем позицию и размер последней строки текста
+        float lastLineWidth = 10 + MeasureTextEx(dialogFont, lines[$-1].toStringz(), fontSize, spacing).x;
+        float lastLineY = marginTop + 20 + (lines.length - 1) * lineHeight;
+        
+        // Позиция круга справа от последней строки
+        float circleX = marginLeft + lastLineWidth + 10; // 10 - отступ от текста
+        float circleY = lastLineY;
+        
+        // Размер круга (можете настроить)
+        float circleSize = 30.0f;
+        
+        Rectangle destRect = Rectangle(circleX, circleY, circleSize, circleSize);
+        Rectangle sourceRect = Rectangle(0, 0, circle.width, circle.height);
+        Vector2 origin = Vector2(circleSize/2, circleSize/2);
+        DrawTexturePro(
+            circle,
+            sourceRect,
+            destRect,
+            origin,
+            circleRotationAngle,
+            Colors.WHITE
         );
     }
-    if (currentPage == choicePage) {
-        
-        // Обработка выбора ответа (вверх/вниз)
-        if (IsKeyPressed(KeyboardKey.KEY_DOWN)) {
-            selectedChoice = cast(int)((selectedChoice + 1) % choices.length);
-        }
-        if (IsKeyPressed(KeyboardKey.KEY_UP)) {
-            selectedChoice = cast(int)((selectedChoice - 1 + choices.length) % choices.length);
-        }
     
+   if (currentPage == choicePage) {
+        int verticalPadding = 30;
+        int choiceHeight = 50;
+        int choiceSpacing = 10;
+
+        int choiceWindowWidth = screenWidth / 2;
+        int choiceWindowHeight = cast(int)(verticalPadding * 2 + choices.length * choiceHeight + (choices.length - 1) * choiceSpacing);
+
+        int choiceWindowX = (screenWidth - choiceWindowWidth) / 2;
+        int choiceWindowY = (screenHeight - choiceWindowHeight) / 2;
+
+        // Draw choice window with 9-slice scaling
+        draw9SliceTexture(
+            choiceWindowTex,
+            Rectangle(choiceWindowX, choiceWindowY, choiceWindowWidth, choiceWindowHeight),
+            CHOICE_BORDER,
+            Colors.WHITE
+        );
+
+        Vector2 mousePos = GetMousePosition();
+        bool mouseClicked = IsMouseButtonPressed(MouseButton.MOUSE_BUTTON_LEFT);
+        
         for (int i = 0; i < choices.length; i++) {
-            Color color = (i == selectedChoice) ? Colors.YELLOW : Colors.WHITE; 
+            Rectangle choiceRect = Rectangle(
+                choiceWindowX + 40,
+                choiceWindowY + verticalPadding + i * (choiceHeight + choiceSpacing),
+                choiceWindowWidth - 80,
+                choiceHeight
+            );
+            
+            bool isHovered = CheckCollisionPointRec(mousePos, choiceRect);
+            
+            if (isHovered) {
+                selectedChoice = i;
+                if (mouseClicked) {
+                    currentPage += 1;
+                    textDisplayProgress = 0.0f;
+                    textFullyDisplayed = false;
+                }
+            }
+            
+            Color color = (i == selectedChoice) ? Colors.YELLOW : (isHovered ? Colors.LIGHTGRAY : Colors.WHITE);
+            
+            if (isHovered || i == selectedChoice) {
+                DrawRectangleRec(choiceRect, Color(60, 60, 60, 200));
+            }
+            
+            Vector2 textSize = MeasureTextEx(dialogFont, choices[i].toStringz(), 39, spacing);
+            Vector2 textPos = Vector2(
+                choiceRect.x + (choiceRect.width - textSize.x) / 2,
+                choiceRect.y + (choiceRect.height - textSize.y) / 2
+            );
             DrawTextEx(
                 dialogFont,
-                toStringz(choices[i]),
-                Vector2(marginLeft, 60 + marginTop + i * 40),
-                fontSize,
+                choices[i].toStringz(),
+                Vector2(textPos.x+3, textPos.y+3),
+                39,
+                spacing,
+                Colors.BLACK
+            );
+            
+            DrawTextEx(
+                dialogFont,
+                choices[i].toStringz(),
+                textPos,
+                39,
                 spacing,
                 color
             );
         }
+        
+        if (IsKeyPressed(KeyboardKey.KEY_DOWN)) {
+            selectedChoice = cast(int)((selectedChoice + 1) % choices.length);
+        }
+        if (IsKeyPressed(KeyboardKey.KEY_UP)) {
+            selectedChoice = cast(int)((selectedChoice - 1 + choices.length) % choices.length);
+        }
+        if (IsMouseButtonPressed(MouseButton.MOUSE_BUTTON_LEFT)) {
+            currentPage += 1;
+            textDisplayProgress = 0.0f;
+            textFullyDisplayed = false;
+        }
+    }
+    
+    if ((IsKeyDown(KeyboardKey.KEY_LEFT_CONTROL) || IsKeyDown(KeyboardKey.KEY_RIGHT_CONTROL)) 
+    && currentPage != choicePage && currentPage < pages.length) {
+        currentPage += 1;
     }
     if (currentPage >= pagesLength) {
         currentPage = 0;
         textDisplayProgress = 0.0f;
         textFullyDisplayed = false;
         pages = [];
+        textSpeed = 0.6f;
         *showDialog = false;
         return;
     }
-}
-
-void drawSnakeAnimation(int rectX, int rectY, int rectWidth, int rectHeight) {
-    static float animTimer = 0.0f;
-    animTimer += GetFrameTime();
-    if (animTimer > 0.1f) animTimer = 0.0f;
-    
-    int animWidth = 300;
-    int animHeight = 100;
-    int animX = rectX + rectWidth - animWidth - 20;
-    int animY = rectY + rectHeight - animHeight - 20;
-    
-    int cubeSize = 5;
-    int cubesInRow = 5;
-    int spacing = 1;
-    
-    int centerX = animX + animWidth/2 - (cubesInRow*cubeSize + (cubesInRow-1)*spacing)/2;
-    int centerY = animY + animHeight/2 - (cubesInRow*cubeSize + (cubesInRow-1)*spacing)/2;
-    
-    for (int y = 0; y < cubesInRow; y++) {
-        for (int x = 0; x < cubesInRow; x++) {
-            DrawRectangle(
-                centerX + x*(cubeSize + spacing),
-                centerY + y*(cubeSize + spacing),
-                cubeSize, cubeSize, Color(50, 50, 50, 255)
-            );
-        }
-    }
-    
-    static int snakePosition = 0;
-    if (animTimer == 0.0f) snakePosition = (snakePosition + 1) % 16;
-    
-    Tuple!(int, int)[] snakePath = [
-        tuple(2, 0), tuple(3, 0), tuple(4, 0), tuple(4, 1),
-        tuple(4, 2), tuple(4, 3), tuple(4, 4), tuple(3, 4),
-        tuple(2, 4), tuple(1, 4), tuple(0, 4), tuple(0, 3),
-        tuple(0, 2), tuple(0, 1), tuple(0, 0), tuple(1, 0)
-    ];
-    
-    for (int i = 0; i < snakePath.length; i++) {
-        int relPos = cast(int)((i + snakePosition) % snakePath.length);
-        int x = snakePath[relPos][0];
-        int y = snakePath[relPos][1];
-        
-        float t = cast(float)i / snakePath.length;
-        Color cubeColor = Color(0, cast(ubyte)(50 + 70 * (1 - t)), 0, 255); 
-        
-        DrawRectangle(
-            centerX + x*(cubeSize + spacing),
-            centerY + y*(cubeSize + spacing),
-            cubeSize, cubeSize, cubeColor
-        );
-    }
 }

+ 17 - 6
source/graphics/engine.d

@@ -35,15 +35,19 @@ import system.cleanup;
 import core.stdc.stdlib;
 import core.stdc.time;
 
-void engine_loader(string window_name, int screenWidth, int screenHeight)
+void engine_loader()
 {
+    int screenWidth = GetScreenWidth();
+    int screenHeight = GetScreenHeight();
     // Initialization
     debug debugWriteln("Engine version: ", ver);
     SetExitKey(0);
+    Image icon = LoadImage("res/icon.png");
     // Window and Audio Initialization
-    InitWindow(screenWidth, screenHeight, cast(char*) window_name);
-    DisableCursor();
-    ToggleFullscreen();
+    InitWindow(screenWidth, screenHeight, "Remember11 - Self Chapter");
+    SetWindowIcon(icon);
+    UnloadImage(icon);
+    //ToggleFullscreen();
     SetTargetFPS(60);
     textFont = LoadFont("res/font_en.png");
     // Fade In and Out Effects
@@ -67,36 +71,43 @@ void engine_loader(string window_name, int screenWidth, int screenHeight)
         case GameState.InGame:
 
             gameInit();
+            luaExec = systemSettings.script_path;
             while (!WindowShouldClose())
             {
                 SetExitKey(0);
                 if (luaReload) {
                     int luaExecutionCode = luaInit(luaExec);
                     if (luaExecutionCode != EngineExitCodes.EXIT_OK) {
-                        debugWriteln("Engine stops execution according to error code: ", 
+                        writeln("[ERROR] Engine stops execution according to error code: ", 
                         luaExecutionCode.to!EngineExitCodes);
                         currentGameState = GameState.Exit;
                         break;
                     }
                     luaReload = false;
                 }
-                luaEventLoop();
+                if (IsKeyPressed(KeyboardKey.KEY_F11)) {
+                    ToggleFullscreen();
+                }
                 BeginDrawing();
                 ClearBackground(Colors.BLACK);
                 // main logic
                 BeginMode2D(camera);
                 backgroundLogic();
+                characterLogic();
                 // effects logic
                 effectsLogic();
                 EndMode2D();
                 //drawing dialogs
                 dialogLogic();
+                luaEventLoop();
                 EndDrawing();
             }
             break;
         case GameState.Exit:
             EndDrawing();
             unloadResourcesLogic();
+            CloseAudioDevice();
+            CloseWindow();
             return;
 
         default:

+ 61 - 15
source/graphics/gamelogic.d

@@ -23,18 +23,15 @@ import std.file;
  
 void gameInit()
 {
+    circle = LoadTexture("res/misc/circle.png");
+    dialogBackgroundTex = LoadTexture("res/misc/TEX#win_01d.PNG");
+    choiceWindowTex = LoadTexture("res/misc/TEX#win_00d.PNG");
+    texturesLoaded = true;
     if (WindowShouldClose()) {
         currentGameState = GameState.Exit;
     } else {
         debugWriteln("Game initializing.");
         systemSettings = loadSettingsFromConfigFile();
-        if (sfxEnabled == false) {
-            UnloadSound(audio.menuMoveSound);
-            UnloadSound(audio.acceptSound);
-            UnloadSound(audio.menuChangeSound);
-            UnloadSound(audio.declineSound);
-            UnloadSound(audio.nonSound);
-        }
     }
 }
 
@@ -57,35 +54,84 @@ void effectsLogic()
 }
 
 void backgroundLogic() {
+    if (backgroundFades.length < backgroundTextures.length) {
+        backgroundFades.length = backgroundTextures.length;
+    }
+
     for (int i = 0; i < backgroundTextures.length; i++) {
-        if (backgroundTextures[i].drawTexture == true) {
+        if (backgroundTextures[i].drawTexture) {
+            if (backgroundFades[i].alpha < 1.0f) {
+                backgroundFades[i].alpha += GetFrameTime() * backgroundFades[i].fadeSpeed;
+                if (backgroundFades[i].alpha > 1.0f) backgroundFades[i].alpha = 1.0f;
+            }
+        } else {
+            if (backgroundFades[i].alpha > 0.0f) {
+                backgroundFades[i].alpha -= GetFrameTime() * backgroundFades[i].fadeSpeed;
+                if (backgroundFades[i].alpha < 0.0f) backgroundFades[i].alpha = 0.0f;
+            }
+        }
+
+        if (backgroundFades[i].alpha > 0.0f) {
             float centeredX = backgroundTextures[i].x - (backgroundTextures[i].width * backgroundTextures[i].scale / 2);
             float centeredY = backgroundTextures[i].y - (backgroundTextures[i].height * backgroundTextures[i].scale / 2);
+            
+            Color tint = Colors.WHITE;
+            tint.a = cast(ubyte)(255 * backgroundFades[i].alpha);
+            
             DrawTextureEx(backgroundTextures[i].texture,
-            Vector2(centeredX, centeredY),
-            0.0,
-            backgroundTextures[i].scale,
-            Colors.WHITE
+                Vector2(centeredX, centeredY),
+                0.0,
+                backgroundTextures[i].scale,
+                tint
             );
         }
     }
+}
+
+void characterLogic() {
+    if (characterFades.length < characterTextures.length) {
+        characterFades.length = characterTextures.length;
+    }
 
     for (int i = 0; i < characterTextures.length; i++) {
-        if (characterTextures[i].drawTexture == true) {
+        if (characterTextures[i].drawTexture) {
+            if (characterTextures[i].justDrawn) {
+                characterFades[i].alpha = 0.0f;
+                characterTextures[i].justDrawn = false;
+            }
+            
+            if (characterFades[i].alpha < 1.0f) {
+                characterFades[i].alpha += GetFrameTime() * characterFades[i].fadeSpeed;
+                if (characterFades[i].alpha > 1.0f) characterFades[i].alpha = 1.0f;
+            }
+        } else {
+            if (characterFades[i].alpha > 0.0f) {
+                characterFades[i].alpha -= GetFrameTime() * characterFades[i].fadeSpeed;
+                if (characterFades[i].alpha < 0.0f) {
+                    characterFades[i].alpha = 0.0f;
+                }
+            }
+        }
+
+        if (characterFades[i].alpha > 0.0f) {
             float centeredX = characterTextures[i].x - (characterTextures[i].width * characterTextures[i].scale / 2);
             float centeredY = characterTextures[i].y - (characterTextures[i].height * characterTextures[i].scale / 2);
             
+            Color tint = Colors.WHITE;
+            tint.a = cast(ubyte)(255 * characterFades[i].alpha);
+            
             DrawTextureEx(characterTextures[i].texture,
                         Vector2(centeredX, centeredY), 
                         0.0, 
                         characterTextures[i].scale, 
-                        Colors.WHITE);
+                        tint);
         }
     }
 }
 
 void dialogLogic() {
     if (showDialog) {
-        displayDialog(messageGlobal, choices, selectedChoice, choicePage, textFont, &showDialog, typingSpeed);
+        displayDialog(messageGlobal, choices, selectedChoice, choicePage, textFont, &showDialog, typingSpeed, 
+        dialogColor, circle, dialogBackgroundTex, choiceWindowTex);
     }
 }

+ 138 - 13
source/scripts/lua.d

@@ -41,7 +41,7 @@ extern (C) nothrow int luaL_dialogBox(lua_State* L)
     int textTableLength = cast(int) lua_objlen(L, 1);
     messageGlobal = new string[](textTableLength); 
 
-    for (int i = 0; i < textTableLength; i++) {
+    foreach (i; 0..textTableLength) {
         lua_rawgeti(L, 1, i + 1);
         messageGlobal[i] = luaL_checkstring(L, -1).to!string;
         backlogText ~= messageGlobal[i];
@@ -52,24 +52,53 @@ extern (C) nothrow int luaL_dialogBox(lua_State* L)
     luaL_checktype(L, 2, LUA_TTABLE);
     int choicesLength = cast(int) lua_objlen(L, 2);
     choices = new string[choicesLength];
-    for (int i = 0; i < choicesLength; i++)
+    foreach (i; 0..choicesLength)
     {
         lua_rawgeti(L, 2, i + 1);
         choices[i] = luaL_checkstring(L, -1).to!string;
         lua_pop(L, 1);
     }
-
+    dialogColor = Colors.GREEN;
+    int colorArgPos = -1;
 
     //if provided, get page on which choices must be shown
-    if (lua_gettop(L) == 3) {
+    if (lua_gettop(L) >= 3) {
         choicePage = cast(int)luaL_checkinteger(L, 3);
     }
 
-    //if provided, change speed of showing text
-    if (lua_gettop(L) == 4) {
-        typingSpeed = cast(float) luaL_checknumber(L, 7);
+    if (lua_gettop(L) >= 4 && !lua_istable(L, 4)) {
+        typingSpeed = cast(float) luaL_checknumber(L, 4);
+    }
+    
+    //if 4 argument is a table - it must be a color
+    if (lua_gettop(L) >= 4 && lua_istable(L, 4)) {
+        colorArgPos = 4;
+    }
+    //else if 5 argument is a table its a color
+    else if (lua_gettop(L) >= 5 && lua_istable(L, 5)) {
+        colorArgPos = 5;
     }
 
+    if (colorArgPos != -1) {
+        lua_getfield(L, colorArgPos, "r");
+        dialogColor.r = cast(ubyte)lua_tointeger(L, -1);
+        lua_pop(L, 1);
+        
+        lua_getfield(L, colorArgPos, "g");
+        dialogColor.g = cast(ubyte)lua_tointeger(L, -1);
+        lua_pop(L, 1);
+        
+        lua_getfield(L, colorArgPos, "b");
+        dialogColor.b = cast(ubyte)lua_tointeger(L, -1);
+        lua_pop(L, 1);
+        
+        lua_getfield(L, colorArgPos, "a");
+        //if a empty, reset to default
+        if (!lua_isnil(L, -1)) {
+            dialogColor.a = cast(ubyte)lua_tointeger(L, -1);
+        }
+        lua_pop(L, 1);
+    }
     return 0;
 }
 
@@ -100,8 +129,12 @@ extern (C) nothrow int luaL_load2Dbackground(lua_State* L)
         if (count >= backgroundTextures.length) {
             backgroundTextures.length = count + 1;
         }
+        if (backgroundTextures[count].texture.id != 0) {
+            UnloadTexture(backgroundTextures[count].texture);
+        }
         char* filename = cast(char*)luaL_checkstring(L, 1);
         backgroundTextures[count].texture = LoadTexture(filename);
+        SetTextureFilter(backgroundTextures[count].texture, TextureFilter.TEXTURE_FILTER_BILINEAR);
     }
     catch (Exception e)
     {
@@ -120,7 +153,7 @@ extern (C) nothrow int luaL_draw2Dbackground(lua_State* L)
         backgroundTextures[count].width = backgroundTextures[count].texture.width;
         backgroundTextures[count].x = luaL_checknumber(L, 1);
         backgroundTextures[count].y = luaL_checknumber(L, 2);
-        backgroundTextures[count].scale = cast(int)luaL_checknumber(L, 3);
+        backgroundTextures[count].scale = luaL_checknumber(L, 3);
         backgroundTextures[count].drawTexture = true;
         debugWriteln(backgroundTextures[count]);
     }
@@ -136,7 +169,11 @@ extern (C) nothrow int luaL_stopDraw2Dbackground(lua_State* L)
     try
     {
         int count = cast(int)luaL_checkinteger(L, 1);
-        backgroundTextures[count].drawTexture = false;
+        if (count >= backgroundTextures.length) {
+            debugWriteln("stop draw not loaded background unavailable");
+        } else {
+            backgroundTextures[count].drawTexture = false;
+        }
     }
     catch (Exception e)
     {
@@ -148,7 +185,12 @@ extern (C) nothrow int luaL_stopDraw2Dbackground(lua_State* L)
 extern (C) nothrow int luaL_unload2Dbackground(lua_State* L)
 {
     int count = cast(int)luaL_checkinteger(L, 1);
-    UnloadTexture(backgroundTextures[count].texture);
+    if (count >= backgroundTextures.length) {
+        debugWriteln("Unloading non-loaded background unavailable");
+    } else {
+        backgroundTextures[count].drawTexture = false;
+        UnloadTexture(backgroundTextures[count].texture);
+    }
     return 0;
 }
 
@@ -162,7 +204,11 @@ extern (C) nothrow int luaL_load2Dcharacter(lua_State *L) {
         if (count >= characterTextures.length) {
             characterTextures.length = count + 1;
         }
+        if (count < characterTextures.length && characterTextures[count].texture.id != 0) {
+            UnloadTexture(characterTextures[count].texture);
+        }
         characterTextures[count].texture = LoadTexture(luaL_checkstring(L, 1));
+        SetTextureFilter(characterTextures[count].texture, TextureFilter.TEXTURE_FILTER_BILINEAR);
         characterTextures[count].width = characterTextures[count].texture.width;
         characterTextures[count].height = characterTextures[count].texture.height;
         characterTextures[count].drawTexture = false;
@@ -182,6 +228,7 @@ extern (C) nothrow int luaL_draw2Dcharacter(lua_State* L)
         characterTextures[count].y = cast(int) luaL_checkinteger(L, 2);
         characterTextures[count].x = cast(int) luaL_checkinteger(L, 1);
         characterTextures[count].drawTexture = true;
+        characterTextures[count].justDrawn = true;
         debugWriteln("Count: ", count, " drawTexture cond: ", characterTextures[count].drawTexture);
     } catch (Exception e) {
         debugWriteln(e.msg);
@@ -192,13 +239,22 @@ extern (C) nothrow int luaL_draw2Dcharacter(lua_State* L)
 extern (C) nothrow int luaL_stopDraw2Dcharacter(lua_State* L)
 {
     int count = cast(int) luaL_checkinteger(L, 1);
-    characterTextures[count].drawTexture = false;
+    if (count >= characterTextures.length) {
+        debugWriteln("error stop draw not loaded character");
+    } else {
+        characterTextures[count].drawTexture = false;
+    }
     return 0;
 }
 
 extern (C) nothrow int luaL_unload2Dcharacter(lua_State *L) {
     int count = cast(int) luaL_checkinteger(L, 1);
-    UnloadTexture(characterTextures[count].texture);
+    if (count >= characterTextures.length) {
+        debugWriteln("error unloading not loaded character");
+    } else {
+        characterTextures[count].drawTexture = false;
+        UnloadTexture(characterTextures[count].texture);
+    }
     return 0;
 }
 
@@ -273,6 +329,7 @@ extern (C) nothrow int luaL_moveCamera(lua_State *L) {
         float targetY = cast(float) luaL_checknumber(L, 2);
         float zoom = cast(float) luaL_optnumber(L, 3, 1.0f);
         float speed = cast(float) luaL_optnumber(L, 4, 5.0f);
+        debugWriteln(targetX, targetY, zoom, speed);
         cameraTargetX = targetX;
         cameraTargetY = targetY;
         cameraTargetZoom = zoom;
@@ -389,17 +446,76 @@ extern (C) nothrow int luaL_getTime(lua_State* L)
     return 1;
 }
 
+extern (C) nothrow int luaL_getDeltaTime(lua_State* L)
+{
+    //getDeltaTime
+    lua_pushnumber(L, GetFrameTime());
+    return 1;
+}
+
+float lastKeyPressTime = 0.0;
+immutable float keyPressCooldown = 0.2;
+
 extern (C) nothrow int luaL_isKeyPressed(lua_State* L)
 {
     try
     {
         int keyCode = cast(int)luaL_checkinteger(L, 1);
-        lua_pushboolean(L, IsKeyPressed(keyCode).to!bool);
+        bool isPressed = IsKeyPressed(keyCode).to!bool;
+
+        double currentTime = GetTime();
+        if (isPressed && (currentTime - lastKeyPressTime) < keyPressCooldown)
+        {
+            lua_pushboolean(L, false);
+        }
+        else if (isPressed)
+        {
+            lastKeyPressTime = currentTime;
+            lua_pushboolean(L, true);
+        }
+        else
+        {
+            lua_pushboolean(L, false);
+        }
+
         return 1;
     }
     catch (Exception e)
     {
         debugWriteln(e.msg);
+        lua_pushboolean(L, false);
+        return 1;
+    }
+}
+
+extern (C) nothrow int luaL_isMouseButtonPressed(lua_State* L)
+{
+    try
+    {
+        int keyCode = cast(int)luaL_checkinteger(L, 1);
+        bool isPressed = IsMouseButtonPressed(keyCode);
+
+        double currentTime = GetTime();
+        if (isPressed && (currentTime - lastKeyPressTime) < keyPressCooldown)
+        {
+            lua_pushboolean(L, false);
+        }
+        else if (isPressed)
+        {
+            lastKeyPressTime = currentTime;
+            lua_pushboolean(L, true);
+        }
+        else
+        {
+            lua_pushboolean(L, false);
+        }
+
+        return 1;
+    }
+    catch (Exception e)
+    {
+        debugWriteln(e.msg);
+        lua_pushboolean(L, false);
         return 1;
     }
 }
@@ -458,6 +574,12 @@ extern (C) nothrow int luaL_textureGC(lua_State *L) {
     return 0;
 }
 
+extern (C) nothrow int luaL_unloadTexture(lua_State *L) {
+    Texture2D* texture = cast(Texture2D*)luaL_checkudata(L, 1, "Texture");
+    UnloadTexture(*texture);
+    return 0;
+}
+
 extern (C) nothrow int luaL_drawTexture(lua_State *L) {
     Texture2D* texture = cast(Texture2D*)luaL_checkudata(L, 1, "Texture");
     int x = cast(int)luaL_checkinteger(L, 2);
@@ -601,17 +723,20 @@ extern (C) nothrow void luaL_loader(lua_State* L)
     lua_register(L, "stopDrawBackground", &luaL_stopDraw2Dbackground);
     lua_register(L, "unloadBackground", &luaL_unload2Dbackground);
     lua_register(L, "getTime", &luaL_getTime);
+    lua_register(L, "getDeltaTime", &luaL_getDeltaTime);
     lua_register(L, "loadScript", &luaL_loadScript);
     lua_register(L, "setFont", &luaL_setGameFont);
     lua_register(L, "getScreenHeight", &luaL_getScreenHeight);
     lua_register(L, "getScreenWidth", &luaL_getScreenWidth);
     lua_register(L, "isKeyPressed", &luaL_isKeyPressed);
+    lua_register(L, "isMouseButtonPressed", &luaL_isMouseButtonPressed);
     lua_register(L, "getLanguage", &luaL_getUsedLanguage);
     lua_register(L, "setGameState", &luaL_setGameState);
     //raylib direct bindings
     lua_register(L, "loadTexture", &luaL_loadTexture);
     lua_register(L, "drawTexture", &luaL_drawTexture);
     lua_register(L, "drawTextureEx", &luaL_drawTextureEx);
+    lua_register(L, "unloadTexture", &luaL_unloadTexture);
     lua_register(L, "drawText", &luaL_drawText);
     lua_register(L, "measureTextX", &luaL_measureTextX);
     lua_register(L, "measureTextY", &luaL_measureTextY);

+ 5 - 12
source/system/cleanup.d

@@ -9,22 +9,15 @@ void unloadResourcesLogic()
 {
     debugWriteln("Exiting. See ya'!");
     EndDrawing();
-    if (sfxEnabled) {
-        UnloadSound(audio.menuMoveSound);
-        UnloadSound(audio.acceptSound);
-        UnloadSound(audio.menuChangeSound);
-        UnloadSound(audio.declineSound);
-        UnloadSound(audio.nonSound);
+    for (int i = cast(int)framesUI.length; i < framesUI.length; i++) {
+        debugWriteln("unloading animations");
+        UnloadTexture(framesUI[i]);
     }
     UnloadFont(textFont);
-    for (int i = cast(int) characterTextures.length; i < characterTextures.length; i++)
-    {
+    for (int i = cast(int)characterTextures.length; i < characterTextures.length; i++) {
         UnloadTexture(characterTextures[i].texture);
     }
-    for (int i = cast(int) backgroundTextures.length; i < backgroundTextures.length; i++)
-    {
+    for (int i = cast(int)backgroundTextures.length; i < backgroundTextures.length; i++) {
         UnloadTexture(backgroundTextures[i].texture);
     }
-    CloseAudioDevice();
-    CloseWindow();
 }

+ 29 - 14
source/system/config.d

@@ -8,14 +8,13 @@ import variables;
 import std.conv;
 import system.abstraction;
 
-nothrow char parseConf(string filename, string type)
+nothrow auto parseConf(string type)(string filename)
 {
     try
     {
         auto file = File(filename);
         auto config = file.byLineCopy();
         
-        //mappings
         auto typeMap = [
             "sound": "SOUND:",
             "backward": "BACKWARD:",
@@ -23,7 +22,8 @@ nothrow char parseConf(string filename, string type)
             "right": "RIGHT:",
             "left": "LEFT:",
             "dialog": "DIALOG:",
-            "opmenu": "OPMENU:"
+            "opmenu": "OPMENU:",
+            "script": "SCRIPT:"
         ];
 
         if (type in typeMap)
@@ -34,9 +34,16 @@ nothrow char parseConf(string filename, string type)
                 auto trimmedLine = strip(line);
                 if (trimmedLine.startsWith(prefix))
                 {
-                    auto button = trimmedLine[prefix.length .. $].strip();
-                    debug debugWriteln("Value for ", type, ": ", button);
-                    return button.front.to!char;
+                    auto value = trimmedLine[prefix.length .. $].strip();
+                    debug debugWriteln("Value for ", type, ": ", value);
+                    
+                    static if (type == "sound") {
+                        return value.to!int();
+                    } else static if (type == "script") {
+                        return value;
+                    } else {
+                        return value.front.to!char();
+                    }
                 }
             }
         }
@@ -45,18 +52,26 @@ nothrow char parseConf(string filename, string type)
     {
         debugWriteln(e.msg);
     }
-    return 'E';
+    
+    static if (type == "sound") {
+        return 0;
+    } else static if (type == "script") {
+        return "";
+    } else {
+        return 'E';
+    }
 }
 
 SystemSettings loadSettingsFromConfigFile()
 {
     return SystemSettings(
-        parseConf("conf/settings.conf", "right"),
-        parseConf("conf/settings.conf", "left"),
-        parseConf("conf/settings.conf", "backward"),
-        parseConf("conf/settings.conf", "forward"),
-        parseConf("conf/settings.conf", "dialog"),
-        parseConf("conf/settings.conf", "opmenu"),
-        parseConf("conf/settings.conf", "sound")
+        parseConf!"sound"("conf/settings.conf"),      // int
+        parseConf!"right"("conf/settings.conf"),     // char
+        parseConf!"left"("conf/settings.conf"),       // char
+        parseConf!"backward"("conf/settings.conf"),   // char
+        parseConf!"forward"("conf/settings.conf"),    // char
+        parseConf!"dialog"("conf/settings.conf"),     // char
+        parseConf!"opmenu"("conf/settings.conf"),     // char
+        parseConf!"script"("conf/settings.conf")     // string
     );
 }

+ 10 - 35
source/ui/menu.d

@@ -14,19 +14,7 @@ import std.file;
 import scripts.lua;
 import std.conv;
 import graphics.gamelogic;
-
-enum
-{
-    MENU_ITEM_START = 0,
-    MENU_ITEM_SOUND = 1,
-    MENU_ITEM_SFX = 2,
-    MENU_ITEM_FULLSCREEN = 3,
-    MENU_ITEM_EXIT = 4,
-
-    FADE_SPEED_IN = 0.02f,
-    FADE_SPEED_OUT = 0.04f,
-    INACTIVITY_TIMEOUT = 20.0f
-}
+import system.cleanup;
 
 void fadeEffect(float alpha, bool fadeIn, void delegate(float alpha) renderer)
 {
@@ -50,20 +38,6 @@ void renderText(float alpha, immutable(char)* text)
     );
 }
 
-void renderLogo(float alpha, immutable(char)* name, bool fullscreen)
-{
-    Texture2D companyLogo = LoadTexture(name);
-    if (fullscreen) {
-        DrawTexturePro(companyLogo,
-            Rectangle(0, 0, cast(float) companyLogo.width, cast(float) companyLogo.height),
-            Rectangle(0, 0, cast(float) GetScreenWidth(), cast(float) GetScreenHeight()),
-            Vector2(0, 0), 0.0, Fade(Colors.WHITE, alpha));
-    }
-    else {
-        DrawTexture(companyLogo, GetScreenWidth() / 2, GetScreenHeight() / 2, Colors.WHITE);
-    }
-}
-
 void helloScreen()
 {
     debug
@@ -72,10 +46,8 @@ void helloScreen()
         debugWriteln("hello screen showing");
         if (play == false) {
             videoFinished = true;
-            goto debug_lab;
         }
-    }
-    else {
+    } else {
         fadeEffect(0.0f, true, (float alpha) {
             renderText(alpha, "powered by\n\nHimmel Engine");
         });
@@ -95,23 +67,22 @@ void helloScreen()
         // Play Opening Video
         BeginDrawing();
         debug debugWriteln("searching for video");
-        if (std.file.exists(getcwd() ~ "/res/videos/soul_OP.moflex.mp4"))
+        if (std.file.exists(getcwd() ~ "/res/videos/op.mp4"))
         {
             debug debugWriteln("video found, playing");
-            playVideo("/res/videos/soul_OP.moflex.mp4");
+            playVideo("/res/videos/op.mp4");
         }
         else {
             debug debugWriteln("video not found, skipping");
             videoFinished = true;
         }
     }
-    debug_lab:
 }
 
 int showMainMenu() {
     int luaExecutionCode = luaInit("scripts/menu.lua");
     if (luaExecutionCode != EngineExitCodes.EXIT_OK) {
-        debugWriteln("Engine stops execution according to error code: ", 
+        writeln("[ERROR] Engine stops execution according to error code: ", 
         luaExecutionCode.to!EngineExitCodes);
         currentGameState = GameState.Exit;
         return luaExecutionCode;
@@ -119,7 +90,11 @@ int showMainMenu() {
     luaReload = false;
     while (currentGameState == GameState.MainMenu)
     {
+        if (IsKeyPressed(KeyboardKey.KEY_F11)) {
+            ToggleFullscreen();
+        }
         UpdateMusicStream(music);
+        effectsLogic();
         luaEventLoop();
         BeginDrawing();
         BeginMode2D(camera);
@@ -130,5 +105,5 @@ int showMainMenu() {
     StopMusicStream(music);
     UnloadMusicStream(music);
     luaReload = true;
-    return 0;
+    return EngineExitCodes.EXIT_OK;
 }

+ 31 - 10
source/variables.d

@@ -11,12 +11,29 @@ extern (C) char* get_file_data_from_archive(const char *input_file, const char *
 void resetAllScriptValues() {
     debugWriteln("Resetting all values!");
     selectedChoice = 0;
+    foreach (i; 0..characterTextures.length)
+    {
+        characterTextures[i].drawTexture = false;
+        UnloadTexture(characterTextures[i].texture);
+    }
+    foreach (i; 0..backgroundTextures.length)
+    {
+        backgroundTextures[i].drawTexture = false;
+        UnloadTexture(backgroundTextures[i].texture);
+    }
     characterTextures = [];
     backgroundTextures = [];
 }
 
 /* system */
 
+struct FadeEffect {
+    float alpha = 0.0f;
+    float targetAlpha = 0.0f;
+    float fadeSpeed = 9.0f;
+    bool isFading = false;
+}
+
 struct SystemSettings {
     int sound_state;
     char right_button;
@@ -25,10 +42,12 @@ struct SystemSettings {
     char forward_button;
     char dialog_button;
     char opmenu_button;
+    string script_path;
 }
 
 struct TextureEngine {
     bool drawTexture;
+    bool justDrawn;
     float width;
     float height;
     float x;
@@ -37,14 +56,6 @@ struct TextureEngine {
     float scale;
 }
 
-struct InterfaceAudio {
-    Sound menuMoveSound;
-    Sound menuChangeSound;
-    Sound acceptSound;
-    Sound declineSound;
-    Sound nonSound;
-}
-
 enum GameState {
     MainMenu = 1,
     InGame = 2,
@@ -65,14 +76,19 @@ TextureEngine[] backgroundTextures;
 
 SystemSettings systemSettings;
 
-InterfaceAudio audio;
-
 int currentGameState = 1;
 
 Font textFont;
 
 Music music;
 
+Color dialogColor;
+
+FadeEffect[] characterFades;
+
+FadeEffect[] backgroundFades;
+
+FadeEffect dialogFade;
 
 /* booleans */
 
@@ -137,6 +153,11 @@ float typingSpeed = 0.6f;
 
 Texture2D[] framesUI;
 
+Texture2D dialogBackgroundTex;
+
+Texture2D choiceWindowTex;
+
+Texture2D circle;
 
 /* integer values */