v2.2.24 - UI Fixes, Command Updates, and Release Packaging
This commit is contained in:
parent
7c136d758f
commit
a2c7bacc94
Binary file not shown.
13
README.md
13
README.md
|
|
@ -106,10 +106,15 @@ A pre-built `MorriCraft-Windows.zip` is available in the repository root.
|
|||
|
||||
## 📜 Version History
|
||||
|
||||
### v2.2.22 - World Generation Polish (Current)
|
||||
- **Spawn Plateau**: Implemented a terrain smoothing algorithm around the spawn point (0,0). This ensures new players start on a flat, safe area and prevents "cliff spawns" or starting inside walls.
|
||||
- **Larger Biomes**: Biome scale has been increased by 4x. Deserts, forests, and rocky regions are now much more expansive and realistic.
|
||||
- **Improved Spawning**: Refined the surface-finding logic to ensure players always start precisely 0.1 blocks above the grass.
|
||||
### v2.2.24 - UI & Command Fixes (Current)
|
||||
- **'E' Key Bug Fix**: Resolved an issue where the inventory overlay would get out of sync with container/cheat GUIs, preventing the menu from staying open or resulting in a missing cursor.
|
||||
- **/test Command**: Refined the `/test` command to grant exactly 1x Crafting Table and 64x Oak Logs with descriptive feedback.
|
||||
- **Help Command**: Updated `/help` to include all debug commands (`/test`, `/cheat`, `/fly`, `/seed`).
|
||||
- **/fly Command**: Added a simple toggle behavior to the `/fly` command.
|
||||
|
||||
### v2.2.23 - Persistence & Viewmodel Fixes
|
||||
|
||||
### v2.2.22 - World Generation Polish
|
||||
|
||||
### v2.2.21 - Save Fix & Updater Polish
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 748 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 779 KiB |
|
|
@ -1 +1 @@
|
|||
v2.2.8
|
||||
v2.2.24
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 748 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 779 KiB |
|
|
@ -1 +1 @@
|
|||
v2.2.8
|
||||
v2.2.23
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 748 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 779 KiB |
|
|
@ -1 +1 @@
|
|||
v2.2.8
|
||||
v2.2.23
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
v2.2.22
|
||||
v2.2.24
|
||||
|
|
|
|||
84
src/main.cpp
84
src/main.cpp
|
|
@ -380,7 +380,7 @@ void RebuildChunkRenderList(Chunk* chunk, int cx, int cz) {
|
|||
|
||||
unsigned char faces = GetExposedFaces(lx, ly, lz, chunk, nxM, nxP, nzM, nzP);
|
||||
if (faces != 0) {
|
||||
// Simple Torch Lighting (v2.2.22)
|
||||
// Simple Torch Lighting (v2.2.23)
|
||||
float blockLight = 0.0f;
|
||||
Vector3 bPos = {(float)(worldX+lx), (float)ly, (float)(worldZ+lz)};
|
||||
for (const auto& tp : torchPositions) {
|
||||
|
|
@ -638,7 +638,8 @@ float FindSpawnY(int spawnX, int spawnZ) {
|
|||
// Feet land at top of block (y + 0.5).
|
||||
// We use +0.6f + 1.6f to ensure we start slightly ABOVE the block
|
||||
// to avoid getting stuck in collision on frame 1.
|
||||
return (float)y + 0.6f + 1.6f;
|
||||
// v2.2.23: Spawn higher (feet at y + 1.5, eyes at y + 3.1) to avoid ground-clipping
|
||||
return (float)y + 1.5f + 1.6f;
|
||||
}
|
||||
}
|
||||
return 64.0f; // Safer fallback (above typical y=32 ground)
|
||||
|
|
@ -678,7 +679,7 @@ void GenerateChunk(int cx, int cz) {
|
|||
// Combine: broad hills (±12) + local detail (±4) = up to ±16 around Y=32
|
||||
int height = 32 + (int)(continentNoise * 12.0f) + (int)(detailNoise * 4.0f);
|
||||
|
||||
// Spawn Plateau (v2.2.22): Smoothly flatten area around (0,0)
|
||||
// Spawn Plateau (v2.2.23): Smoothly flatten area around (0,0)
|
||||
float distToSpawn = sqrtf(worldX * worldX + worldZ * worldZ);
|
||||
if (distToSpawn < 12.0f) {
|
||||
float plateauStrength = 1.0f - (distToSpawn / 12.0f);
|
||||
|
|
@ -690,7 +691,7 @@ void GenerateChunk(int cx, int cz) {
|
|||
if (height < 10) height = 10;
|
||||
if (height >= CHUNK_HEIGHT - 2) height = CHUNK_HEIGHT - 2;
|
||||
|
||||
// Biome noise: determines surface type (v2.2.22: 4x larger biomes)
|
||||
// Biome noise: determines surface type (v2.2.23: 4x larger biomes)
|
||||
float biomeNoise = fbm(worldX * 0.002f, worldZ * 0.002f, globalSeedHash + 77777);
|
||||
|
||||
for (int y = 0; y <= height; y++) {
|
||||
|
|
@ -975,7 +976,7 @@ 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 v2.2.22");
|
||||
InitWindow(screenWidth, screenHeight, "MorriCraft v2.2.23");
|
||||
LoadConfig();
|
||||
SetExitKey(KEY_NULL); // Prevent ESC from closing the window
|
||||
|
||||
|
|
@ -1039,7 +1040,7 @@ int main(void)
|
|||
float updateTimer = 0.0f;
|
||||
float downloadProgress = 0.0f;
|
||||
std::string latestVersion = "";
|
||||
std::string localVersion = "v2.2.22"; // Default fallback
|
||||
std::string localVersion = "v2.2.23"; // Default fallback
|
||||
|
||||
// Read local version
|
||||
std::ifstream vfile("assets/version.txt");
|
||||
|
|
@ -1646,7 +1647,7 @@ int main(void)
|
|||
|
||||
|
||||
// --- GLOBAL TIME & AUDIO MANAGEMENT ---
|
||||
float cycleLength = 600.0f; // Slower day cycle (v2.2.22: cut speed in half)
|
||||
float cycleLength = 600.0f; // Slower day cycle (v2.2.23: cut speed in half)
|
||||
if (currentState == GAMEPLAY) gameTime += GetFrameTime();
|
||||
float timeOfDay = fmodf(gameTime, cycleLength) / cycleLength;
|
||||
float sunAngle = timeOfDay * 2.0f * 3.14159f - 3.14159f/2.0f;
|
||||
|
|
@ -1682,6 +1683,7 @@ int main(void)
|
|||
if (currentState == CRAFTING_GUI || currentState == CHEST_GUI || currentState == CHEAT_GUI) {
|
||||
if (currentState == CHEST_GUI) PlaySound(chestCloseSound);
|
||||
currentState = GAMEPLAY;
|
||||
inventoryOpen = false;
|
||||
DisableCursor();
|
||||
} else {
|
||||
inventoryOpen = !inventoryOpen;
|
||||
|
|
@ -1736,16 +1738,17 @@ int main(void)
|
|||
|
||||
if (cmd == "seed") {
|
||||
chatLog.push_back({ "[Server] World seed: " + std::to_string(globalSeedHash), 8.0f });
|
||||
} else if (cmd == "fly on") {
|
||||
isFlying = true;
|
||||
chatLog.push_back({ "[Server] Flight enabled (Noclip ON)", 5.0f });
|
||||
} else if (cmd == "fly off") {
|
||||
isFlying = false;
|
||||
chatLog.push_back({ "[Server] Flight disabled", 5.0f });
|
||||
} else if (cmd == "fly" || cmd == "fly on" || cmd == "fly off") {
|
||||
if (cmd == "fly on") isFlying = true;
|
||||
else if (cmd == "fly off") isFlying = false;
|
||||
else isFlying = !isFlying;
|
||||
|
||||
if (isFlying) chatLog.push_back({ "[Server] Flight enabled (Noclip ON)", 5.0f });
|
||||
else chatLog.push_back({ "[Server] Flight disabled", 5.0f });
|
||||
} else if (cmd == "test") {
|
||||
AddToInventory(CRAFTING_TABLE);
|
||||
for(int i=0; i<64; i++) AddToInventory(LOG);
|
||||
chatLog.push_back({"[System] Granted testing items.", 5.0f});
|
||||
GiveItems(CRAFTING_TABLE, 1);
|
||||
GiveItems(LOG, 64);
|
||||
chatLog.push_back({"[System] Granted 1x Crafting Table and 64x Oak Logs.", 5.0f});
|
||||
} else if (cmd == "cheat") {
|
||||
currentState = CHEAT_GUI;
|
||||
EnableCursor();
|
||||
|
|
@ -1755,7 +1758,7 @@ int main(void)
|
|||
chatLog.push_back({ " /help - Shows this list", 8.0f });
|
||||
chatLog.push_back({ " /seed - Shows the world seed", 8.0f });
|
||||
chatLog.push_back({ " /fly [on|off] - Toggle flight mode", 8.0f });
|
||||
chatLog.push_back({ " /test - Give basic crafting materials", 8.0f });
|
||||
chatLog.push_back({ " /test - Give testing materials (1x Table, 64x Logs)", 8.0f });
|
||||
chatLog.push_back({ " /cheat - Open creative menu", 8.0f });
|
||||
} else {
|
||||
chatLog.push_back({ "[Server] Unknown command: /" + cmd, 5.0f });
|
||||
|
|
@ -2000,7 +2003,7 @@ int main(void)
|
|||
AddToInventory(targetBlock);
|
||||
NetSetBlock(hitX, hitY, hitZ, AIR);
|
||||
|
||||
// Tool Durability Logic (v2.2.22)
|
||||
// Tool Durability Logic (v2.2.23)
|
||||
InventorySlot* slot = &hotbar[activeHotbarSlot];
|
||||
if (slot->maxDurability > 0) {
|
||||
slot->durability--;
|
||||
|
|
@ -2175,7 +2178,7 @@ int main(void)
|
|||
std::string versionUrl = "https://git.linology.tech/michael/MorriCraft/raw/branch/master/release/version.txt";
|
||||
|
||||
// Download binary
|
||||
// v2.2.22: Download directly to the expected zip name
|
||||
// v2.2.23: Download directly to the expected zip name
|
||||
int r1 = system(("curl -L -s -o " + binaryName + " \"" + binaryUrl + "\"").c_str());
|
||||
currentProgress = 0.7f;
|
||||
|
||||
|
|
@ -2223,7 +2226,7 @@ int main(void)
|
|||
DrawTextEx(customFont, "Installing update...", (Vector2){ (float)currentWidth/2 - 80, (float)currentHeight/2 - 60 }, 24, 1.0f, GREEN);
|
||||
} else {
|
||||
DrawTextEx(customFont, "Downloading update...", (Vector2){ (float)currentWidth/2 - 90, (float)currentHeight/2 - 60 }, 24, 1.0f, YELLOW);
|
||||
// Dynamic progress pulse (v2.2.22)
|
||||
// Dynamic progress pulse (v2.2.23)
|
||||
if (currentProgress < 0.7f) currentProgress += 0.001f;
|
||||
}
|
||||
int bw = 500, bh = 35;
|
||||
|
|
@ -2497,8 +2500,8 @@ int main(void)
|
|||
DrawTexturePro(titleTexture, sourceRec, destRec, origin, 0.0f, WHITE);
|
||||
EndMode2D();
|
||||
|
||||
// Show Version Number (v2.2.22) in Red
|
||||
DrawTextEx(customFont, "v2.2.22", (Vector2){ 20, (float)currentHeight - 30 }, 22, 1.0f, RED);
|
||||
// Show Version Number (v2.2.23) in Red
|
||||
DrawTextEx(customFont, "v2.2.23", (Vector2){ 20, (float)currentHeight - 30 }, 22, 1.0f, RED);
|
||||
|
||||
// --- PLAYER NAME POPUP (IF MISSING) ---
|
||||
if (playerName == "") {
|
||||
|
|
@ -2669,14 +2672,14 @@ int main(void)
|
|||
// Load seed and player position from world.dat
|
||||
std::ifstream worldFile("saves/" + currentWorldName + "/world.dat");
|
||||
if (worldFile.is_open()) {
|
||||
worldFile >> globalSeedHash >> spawnSavedX >> spawnSavedY >> spawnSavedZ;
|
||||
worldFile >> globalSeedHash >> spawnSavedX >> spawnSavedY >> spawnSavedZ >> gameTime;
|
||||
worldFile.close();
|
||||
} else {
|
||||
globalSeedHash = 12345;
|
||||
spawnSavedX = 0; spawnSavedY = -1; spawnSavedZ = 0;
|
||||
}
|
||||
|
||||
// Load Chests (v2.2.22)
|
||||
// Load Chests (v2.2.23)
|
||||
chestInventories.clear();
|
||||
std::ifstream cf("saves/" + currentWorldName + "/chests.dat", std::ios::binary);
|
||||
if (cf.is_open()) {
|
||||
|
|
@ -2694,7 +2697,7 @@ int main(void)
|
|||
cf.close();
|
||||
}
|
||||
|
||||
// Load Torches (v2.2.22)
|
||||
// Load Torches (v2.2.23)
|
||||
torchPositions.clear();
|
||||
std::ifstream tf("saves/" + currentWorldName + "/torches.dat", std::ios::binary);
|
||||
if (tf.is_open()) {
|
||||
|
|
@ -2978,7 +2981,7 @@ int main(void)
|
|||
snprintf(worldName, sizeof(worldName), "%s", currentWorldName.c_str());
|
||||
worldNameLen = strlen(worldName);
|
||||
|
||||
gameTime = 150.0f; // Start new world at 7:00 AM (v2.2.22 adjusted for slower cycle)
|
||||
gameTime = 150.0f; // Start new world at 7:00 AM (v2.2.23 adjusted for slower cycle)
|
||||
|
||||
if (serverMode) {
|
||||
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
|
@ -3125,7 +3128,7 @@ int main(void)
|
|||
} else if (renderType == TORCH) {
|
||||
for (Chunk* chunk : visibleChunks) {
|
||||
for (auto& data : chunk->renderLists[TORCH]) {
|
||||
// 3D Flickering Torch (v2.2.22)
|
||||
// 3D Flickering Torch (v2.2.23)
|
||||
float flicker = sinf(GetTime() * 12.0f) * 0.03f;
|
||||
float h = 0.6f + flicker;
|
||||
float w = 0.12f;
|
||||
|
|
@ -3263,8 +3266,8 @@ int main(void)
|
|||
Rectangle src = { 0, 0, (float)itemTex.width, (float)itemTex.height };
|
||||
Vector2 itemSize = { 0.35f, 0.35f };
|
||||
Vector2 pivot = { -itemSize.x/2.0f, -itemSize.y/2.0f };
|
||||
// Back to 135 degrees
|
||||
DrawBillboardPro(camera3D, itemTex, src, itemPos, camera3D.up, itemSize, pivot, 135.0f + swingVal * 40.0f, WHITE);
|
||||
// v2.2.23: Rotated by 90 degrees (135 -> 45)
|
||||
DrawBillboardPro(camera3D, itemTex, src, itemPos, camera3D.up, itemSize, pivot, 45.0f + swingVal * 40.0f, WHITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3369,7 +3372,7 @@ int main(void)
|
|||
(Vector2){ (float)(sx + (slotSize/2) - (countSize.x/2)), (float)(hotbarY + slotSize - 14) },
|
||||
12, 1.0f, WHITE);
|
||||
|
||||
// Draw Hotbar Durability Bar (v2.2.22)
|
||||
// Draw Hotbar Durability Bar (v2.2.23)
|
||||
if (hotbar[s].maxDurability > 0 && hotbar[s].durability < hotbar[s].maxDurability) {
|
||||
float durP = (float)hotbar[s].durability / hotbar[s].maxDurability;
|
||||
int barW = slotSize - 10;
|
||||
|
|
@ -3400,7 +3403,7 @@ int main(void)
|
|||
DrawRectangleRec(slotRect, hov ? (Color){90,90,90,255} : (Color){60,60,60,255});
|
||||
DrawRectangleLinesEx(slotRect, 2.0f, hov ? WHITE : (Color){100,100,100,200});
|
||||
|
||||
// Draw Durability Bar (v2.2.22)
|
||||
// Draw Durability Bar (v2.2.23)
|
||||
if (slot.maxDurability > 0 && slot.durability < slot.maxDurability) {
|
||||
float durPercent = (float)slot.durability / slot.maxDurability;
|
||||
int barW = slotRect.width - 10;
|
||||
|
|
@ -3628,6 +3631,7 @@ int main(void)
|
|||
|
||||
if (IsKeyPressed(KEY_ESCAPE)) {
|
||||
currentState = GAMEPLAY;
|
||||
inventoryOpen = false;
|
||||
DisableCursor();
|
||||
}
|
||||
}
|
||||
|
|
@ -3676,7 +3680,7 @@ int main(void)
|
|||
}
|
||||
}
|
||||
if (hov && IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) {
|
||||
// Right click: pick up/place one (v2.2.22)
|
||||
// Right click: pick up/place one (v2.2.23)
|
||||
if (mouseHeldItem.blockType == AIR) {
|
||||
if (chestInv[i].blockType != AIR && chestInv[i].count > 0) {
|
||||
mouseHeldItem = InventorySlot(chestInv[i].blockType, 1);
|
||||
|
|
@ -3723,7 +3727,7 @@ int main(void)
|
|||
}
|
||||
}
|
||||
if (hov && IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) {
|
||||
// Right click logic for player inv in chest GUI (v2.2.22)
|
||||
// Right click logic for player inv in chest GUI (v2.2.23)
|
||||
if (mouseHeldItem.blockType == AIR) {
|
||||
if (inventory[i].blockType != AIR && inventory[i].count > 0) {
|
||||
mouseHeldItem = InventorySlot(inventory[i].blockType, 1);
|
||||
|
|
@ -3744,7 +3748,7 @@ int main(void)
|
|||
}
|
||||
|
||||
if (IsKeyPressed(KEY_ESCAPE)) {
|
||||
currentState = GAMEPLAY; DisableCursor(); PlaySound(chestCloseSound);
|
||||
currentState = GAMEPLAY; inventoryOpen = false; DisableCursor(); PlaySound(chestCloseSound);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3795,7 +3799,7 @@ int main(void)
|
|||
DrawTextEx(customFont, "Click item to set to active hotbar slot", (Vector2){ (float)guiX + 20, (float)guiY + panelH - 30 }, 18, 1.0f, LIGHTGRAY);
|
||||
|
||||
if (IsKeyPressed(KEY_ESCAPE) || IsKeyPressed(KEY_E)) {
|
||||
currentState = GAMEPLAY; DisableCursor();
|
||||
currentState = GAMEPLAY; inventoryOpen = false; DisableCursor();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3857,6 +3861,7 @@ int main(void)
|
|||
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) {
|
||||
if (i == 0) { // Resume
|
||||
currentState = GAMEPLAY;
|
||||
inventoryOpen = false;
|
||||
DisableCursor();
|
||||
} else if (i == 1) { // Open to LAN
|
||||
if (serverSocket == INVALID_SOCKET_VAL) {
|
||||
|
|
@ -3882,13 +3887,14 @@ int main(void)
|
|||
currentState = MAIN_MENU;
|
||||
inventoryOpen = false;
|
||||
|
||||
// Save player position to world.dat
|
||||
// Save player position and gameTime to world.dat
|
||||
std::ofstream wf("saves/" + currentWorldName + "/world.dat");
|
||||
if (wf.is_open()) {
|
||||
wf << globalSeedHash << " "
|
||||
<< camera3D.position.x << " "
|
||||
<< camera3D.position.y << " "
|
||||
<< camera3D.position.z;
|
||||
<< camera3D.position.z << " "
|
||||
<< gameTime;
|
||||
wf.close();
|
||||
}
|
||||
// Save inventory
|
||||
|
|
@ -3900,7 +3906,7 @@ int main(void)
|
|||
invf.close();
|
||||
}
|
||||
|
||||
// Save Chests (v2.2.22)
|
||||
// Save Chests (v2.2.23)
|
||||
std::ofstream cf("saves/" + currentWorldName + "/chests.dat", std::ios::binary);
|
||||
if (cf.is_open()) {
|
||||
uint32_t count = (uint32_t)chestInventories.size();
|
||||
|
|
@ -3916,7 +3922,7 @@ int main(void)
|
|||
cf.close();
|
||||
}
|
||||
|
||||
// Save Torches (v2.2.22)
|
||||
// Save Torches (v2.2.23)
|
||||
std::ofstream tf("saves/" + currentWorldName + "/torches.dat", std::ios::binary);
|
||||
if (tf.is_open()) {
|
||||
uint32_t count = (uint32_t)torchPositions.size();
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
v2.2.22
|
||||
v2.2.24
|
||||
|
|
|
|||
Loading…
Reference in New Issue