diff --git a/src/main.cpp b/src/main.cpp index f2bd2f3..b156283 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -79,12 +79,16 @@ struct Chunk { std::unordered_map worldChunks; static unsigned int globalSeedHash = 0; static std::string currentWorldName = ""; +static std::string playerName = "Player"; +static bool serverMode = false; // Forward Declarations bool IsExposedOptimized(int lx, int ly, int lz, Chunk* chunk, Chunk* nxM, Chunk* nxP, Chunk* nzM, Chunk* nzP); void RebuildChunkRenderList(Chunk* chunk, int cx, int cz); void GenerateChunk(int cx, int cz); void SetBlock(int x, int y, int z, int type); +void SaveConfig(); +void LoadConfig(); // ---- Inventory System ---- struct InventorySlot { @@ -232,6 +236,34 @@ void SetBlock(int x, int y, int z, int type) { } } +void SaveConfig() { + std::ofstream file("config.cfg"); + if (file.is_open()) { + file << "playerName=" << playerName << "\n"; + file << "serverMode=" << (serverMode ? "true" : "false") << "\n"; + file.close(); + } +} + +void LoadConfig() { + std::ifstream file("config.cfg"); + if (file.is_open()) { + std::string line; + while (std::getline(file, line)) { + size_t sep = line.find('='); + if (sep != std::string::npos) { + std::string key = line.substr(0, sep); + std::string val = line.substr(sep + 1); + if (key == "playerName") playerName = val; + else if (key == "serverMode") serverMode = (val == "true"); + } + } + file.close(); + } else { + playerName = ""; // Trigger popup + } +} + void GenerateTrees(Chunk* chunk, int cx, int cz) { for (int x = 0; x < CHUNK_SIZE; x++) { for (int z = 0; z < CHUNK_SIZE; z++) { @@ -639,7 +671,8 @@ int main(void) // By default, windows have minimize, maximize, and close buttons on the top bar. SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_VSYNC_HINT); - InitWindow(screenWidth, screenHeight, "MorriCraft - Title Screen"); + InitWindow(screenWidth, screenHeight, "MorriCraft v1.8.0"); + LoadConfig(); SetExitKey(KEY_NULL); // Prevent ESC from closing the window // Initialize audio device @@ -851,11 +884,21 @@ int main(void) SetMusicVolume(titleMusic, titleLoopFade * masterMusicVolume * (1.0f - crossfade)); - // Gameplay volume crossfade between day and night - // We use dayFactor (calculated later in loop) or calculate it here - float dayNnightFactor = 1.0f; // Default - // We'll move the music volume setting after dayFactor is calculated for accuracy - // But for now, let's just make sure nightMusic is updated + // --- GLOBAL MUSIC VOLUME MANAGEMENT --- + float sunAngle = timeOfDay * 2.0f * PI - PI/2.0f; + float dayFactor = (sinf(sunAngle) + 1.0f) / 2.0f; + float quickMix = (dayFactor - 0.5f) * 5.0f + 0.5f; + if (quickMix > 1.0f) quickMix = 1.0f; + if (quickMix < 0.0f) quickMix = 0.0f; + + SetMusicVolume(gameplayMusic, masterMusicVolume * crossfade * quickMix); + SetMusicVolume(nightMusic, masterMusicVolume * crossfade * (1.0f - quickMix)); + + // Ensure streams are playing when crossfaded in + if (crossfade > 0.01f) { + if (!IsMusicStreamPlaying(gameplayMusic)) PlayMusicStream(gameplayMusic); + if (!IsMusicStreamPlaying(nightMusic)) PlayMusicStream(nightMusic); + } // Handle window resize dynamically int currentWidth = GetScreenWidth(); @@ -1148,8 +1191,41 @@ int main(void) DrawTexturePro(titleTexture, sourceRec, destRec, origin, 0.0f, WHITE); EndMode2D(); - // Show Version Number (v1.7.1) in Red - DrawTextEx(customFont, "v1.7.1", (Vector2){ (float)currentWidth - 140, (float)currentHeight - 40 }, 22, 1.0f, RED); + // Show Version Number (v1.8.0) in Red + DrawTextEx(customFont, "v1.8.0", (Vector2){ (float)currentWidth - 140, (float)currentHeight - 40 }, 22, 1.0f, RED); + + // --- PLAYER NAME POPUP (IF MISSING) --- + if (playerName == "") { + DrawRectangle(0, 0, currentWidth, currentHeight, (Color){ 0, 0, 0, 200 }); + int pw = 400, ph = 200; + Rectangle pBox = { (float)currentWidth/2 - pw/2, (float)currentHeight/2 - ph/2, (float)pw, (float)ph }; + DrawRectangleRec(pBox, (Color){ 40, 40, 40, 255 }); + DrawRectangleLinesEx(pBox, 2.0f, WHITE); + DrawTextEx(customFont, "Enter Your Name", (Vector2){ pBox.x + 20, pBox.y + 20 }, 24, 1.0f, WHITE); + + static char inputName[32] = {0}; + int c = GetCharPressed(); + while (c > 0) { + if (c >= 32 && c <= 125 && strlen(inputName) < 30) { + int len = strlen(inputName); + inputName[len] = (char)c; + inputName[len+1] = '\0'; + } + c = GetCharPressed(); + } + if (IsKeyPressed(KEY_BACKSPACE)) { + int len = strlen(inputName); + if (len > 0) inputName[len-1] = '\0'; + } + + DrawRectangle(pBox.x + 20, pBox.y + 60, pw - 40, 40, BLACK); + DrawTextEx(customFont, inputName, (Vector2){ pBox.x + 30, pBox.y + 70 }, 20, 1.0f, WHITE); + + if (IsKeyPressed(KEY_ENTER) && strlen(inputName) > 0) { + playerName = inputName; + SaveConfig(); + } + } } Vector2 mousePos = GetMousePosition(); @@ -1192,6 +1268,8 @@ int main(void) currentState = CREATE_WORLD_MENU; } else if (i == 1) { // Load World button currentState = LOAD_WORLD_MENU; + } else if (i == 2) { // Connect button + // Future: Open Direct Connect UI } else if (i == 3) { // Options button optionsReturnState = MAIN_MENU; currentState = OPTIONS_MENU; @@ -1422,6 +1500,18 @@ int main(void) DrawRectangleRec(soundHandle, LIGHTGRAY); DrawRectangleLinesEx(soundHandle, 2.0f, WHITE); + // Multiplayer Options + DrawTextEx(customFont, "Multiplayer", (Vector2){ (float)panelX + 40, (float)panelY + 290 }, 20, 1.0f, LIGHTGRAY); + Rectangle serverCheck = { (float)panelX + 40, (float)panelY + 320, 20, 20 }; + bool isServerHovered = CheckCollisionPointRec(mousePos, serverCheck); + DrawRectangleRec(serverCheck, serverMode ? GREEN : DARKGRAY); + DrawRectangleLinesEx(serverCheck, 2.0f, isServerHovered ? WHITE : GRAY); + DrawTextEx(customFont, "Server Mode (Experimental)", (Vector2){ serverCheck.x + 35, serverCheck.y }, 18, 1.0f, WHITE); + if (isServerHovered && IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) { + serverMode = !serverMode; + SaveConfig(); + } + // Done Button int backBtnWidth = 200; int backBtnHeight = 50; @@ -1588,14 +1678,6 @@ int main(void) float dayFactor = (sinf(sunAngle) + 1.0f) / 2.0f; // 0 (night) to 1 (day) - // Rapid Music Crossfade Logic - float quickMix = (dayFactor - 0.5f) * 5.0f + 0.5f; // Steeper transition centered at 0.5 - if (quickMix > 1.0f) quickMix = 1.0f; - if (quickMix < 0.0f) quickMix = 0.0f; - - // Update Music Volumes based on time of day - SetMusicVolume(gameplayMusic, masterMusicVolume * crossfade * quickMix); - SetMusicVolume(nightMusic, masterMusicVolume * crossfade * (1.0f - quickMix)); float lightLevel = 0.2f + 0.8f * dayFactor; // Ambient light multiplier Color blockTint = { (unsigned char)(255 * lightLevel), (unsigned char)(255 * lightLevel), (unsigned char)(255 * lightLevel), 255 };