v2.2.24 Patch: Fixed grass block held item, Improved update system with restart button and extraction progress, and Optimized spawn points for biome stability.
This commit is contained in:
parent
a2c7bacc94
commit
d5b58fd2fd
Binary file not shown.
Binary file not shown.
|
|
@ -1 +1 @@
|
||||||
v2.2.23
|
v2.2.24
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1 +1 @@
|
||||||
v2.2.23
|
v2.2.24
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
163
src/main.cpp
163
src/main.cpp
|
|
@ -173,7 +173,7 @@ static float playerHealth = 16.0f;
|
||||||
static uint32_t localPlayerID = 0;
|
static uint32_t localPlayerID = 0;
|
||||||
static Sound hitSound;
|
static Sound hitSound;
|
||||||
|
|
||||||
enum MenuState { MAIN_MENU, OPTIONS_MENU, CREATE_WORLD_MENU, LOAD_WORLD_MENU, GAMEPLAY, PAUSE_MENU, CRAFTING_GUI, CHECKING_UPDATES, UPDATE_NOTES, UPDATE_FOUND, DOWNLOADING_UPDATE, CONNECT_MENU, SKIN_EDITOR, WORLD_CREATION_PROGRESS, CHEST_GUI, CHEAT_GUI };
|
enum MenuState { MAIN_MENU, OPTIONS_MENU, CREATE_WORLD_MENU, LOAD_WORLD_MENU, GAMEPLAY, PAUSE_MENU, CRAFTING_GUI, CHECKING_UPDATES, UPDATE_NOTES, UPDATE_FOUND, DOWNLOADING_UPDATE, EXTRACTING_UPDATE, CONNECT_MENU, SKIN_EDITOR, WORLD_CREATION_PROGRESS, CHEST_GUI, CHEAT_GUI };
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
unsigned char GetExposedFaces(int lx, int ly, int lz, Chunk* chunk, Chunk* nxM, Chunk* nxP, Chunk* nzM, Chunk* nzP);
|
unsigned char GetExposedFaces(int lx, int ly, int lz, Chunk* chunk, Chunk* nxM, Chunk* nxP, Chunk* nzM, Chunk* nzP);
|
||||||
|
|
@ -627,6 +627,35 @@ float fbm(float x, float y, unsigned int seed) {
|
||||||
// Forward-declare so FindSpawnY can call GenerateChunk
|
// Forward-declare so FindSpawnY can call GenerateChunk
|
||||||
void GenerateChunk(int cx, int cz);
|
void GenerateChunk(int cx, int cz);
|
||||||
|
|
||||||
|
// Find a spawn point near (0,0) that is far from biome edges
|
||||||
|
Vector2 FindIdealSpawn() {
|
||||||
|
float bestScore = -1.0f;
|
||||||
|
Vector2 bestPos = { 0, 0 };
|
||||||
|
// Scan a spiral to find the most "stable" biome point
|
||||||
|
for (int r = 0; r < 500; r += 16) {
|
||||||
|
for (float a = 0; a < 2.0f * PI; a += 0.4f) {
|
||||||
|
float x = cosf(a) * r;
|
||||||
|
float z = sinf(a) * r;
|
||||||
|
float bn = fbm(x * 0.002f, z * 0.002f, globalSeedHash + 77777);
|
||||||
|
|
||||||
|
// Score based on distance from the transition thresholds (-0.3, 0.3)
|
||||||
|
// We want points that are deeply in a biome (e.g. bn = 0.0, 0.7, or -0.7)
|
||||||
|
float distToEdge = fminf(fabsf(bn - 0.3f), fabsf(bn + 0.3f));
|
||||||
|
|
||||||
|
// Also prioritize points closer to origin if scores are similar
|
||||||
|
float finalScore = distToEdge - (r * 0.0001f);
|
||||||
|
|
||||||
|
if (finalScore > bestScore) {
|
||||||
|
bestScore = finalScore;
|
||||||
|
bestPos = { x, z };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we found a very stable point (dist > 0.2 from edge), stop early
|
||||||
|
if (bestScore > 0.2f) break;
|
||||||
|
}
|
||||||
|
return bestPos;
|
||||||
|
}
|
||||||
|
|
||||||
// Generate the spawn chunk and scan downward to find the first solid surface.
|
// Generate the spawn chunk and scan downward to find the first solid surface.
|
||||||
// Returns the player eye-level Y (surface block top + 1.6 camera height).
|
// Returns the player eye-level Y (surface block top + 1.6 camera height).
|
||||||
float FindSpawnY(int spawnX, int spawnZ) {
|
float FindSpawnY(int spawnX, int spawnZ) {
|
||||||
|
|
@ -1036,6 +1065,12 @@ int main(void)
|
||||||
MenuState currentState = CHECKING_UPDATES;
|
MenuState currentState = CHECKING_UPDATES;
|
||||||
MenuState optionsReturnState = MAIN_MENU;
|
MenuState optionsReturnState = MAIN_MENU;
|
||||||
|
|
||||||
|
bool startedDownload = false;
|
||||||
|
bool downloadFailed = false;
|
||||||
|
bool isInstalling = false;
|
||||||
|
bool downloadFinished = false;
|
||||||
|
float currentProgress = 0.0f;
|
||||||
|
|
||||||
bool updateReady = false;
|
bool updateReady = false;
|
||||||
float updateTimer = 0.0f;
|
float updateTimer = 0.0f;
|
||||||
float downloadProgress = 0.0f;
|
float downloadProgress = 0.0f;
|
||||||
|
|
@ -2157,16 +2192,10 @@ int main(void)
|
||||||
currentState = MAIN_MENU;
|
currentState = MAIN_MENU;
|
||||||
}
|
}
|
||||||
} else if (currentState == DOWNLOADING_UPDATE) {
|
} else if (currentState == DOWNLOADING_UPDATE) {
|
||||||
static bool startedDownload = false;
|
|
||||||
static bool downloadFailed = false;
|
|
||||||
static bool isInstalling = false;
|
|
||||||
static bool downloadFinished = false;
|
|
||||||
static float currentProgress = 0.0f;
|
|
||||||
|
|
||||||
if (!startedDownload) {
|
if (!startedDownload) {
|
||||||
startedDownload = true;
|
startedDownload = true;
|
||||||
currentProgress = 0.1f;
|
currentProgress = 0.1f;
|
||||||
std::thread([]() {
|
std::thread([&]() {
|
||||||
std::string binaryUrl, binaryName;
|
std::string binaryUrl, binaryName;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
binaryUrl = "https://git.linology.tech/michael/MorriCraft/raw/branch/master/release/MorriCraft-Windows.zip";
|
binaryUrl = "https://git.linology.tech/michael/MorriCraft/raw/branch/master/release/MorriCraft-Windows.zip";
|
||||||
|
|
@ -2178,27 +2207,34 @@ int main(void)
|
||||||
std::string versionUrl = "https://git.linology.tech/michael/MorriCraft/raw/branch/master/release/version.txt";
|
std::string versionUrl = "https://git.linology.tech/michael/MorriCraft/raw/branch/master/release/version.txt";
|
||||||
|
|
||||||
// Download binary
|
// Download binary
|
||||||
// v2.2.23: Download directly to the expected zip name
|
|
||||||
int r1 = system(("curl -L -s -o " + binaryName + " \"" + binaryUrl + "\"").c_str());
|
int r1 = system(("curl -L -s -o " + binaryName + " \"" + binaryUrl + "\"").c_str());
|
||||||
currentProgress = 0.7f;
|
currentProgress = 0.85f; // Most of the way done after binary
|
||||||
|
|
||||||
// Download version
|
// Download version
|
||||||
int r2 = system(("curl -L -s -o version.txt.new \"" + versionUrl + "\"").c_str());
|
int r2 = system(("curl -L -s -o version.txt.new \"" + versionUrl + "\"").c_str());
|
||||||
currentProgress = 0.9f;
|
currentProgress = 1.0f;
|
||||||
|
|
||||||
if (r1 == 0 && r2 == 0) {
|
if (r1 == 0 && r2 == 0) {
|
||||||
|
// Switch to extraction phase
|
||||||
|
currentState = EXTRACTING_UPDATE;
|
||||||
isInstalling = true;
|
isInstalling = true;
|
||||||
|
currentProgress = 0.0f; // Reset for extraction phase
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Windows Update: Move exe, unzip assets
|
// Windows Update: Move exe, unzip assets
|
||||||
system("move MorriCraft.exe MorriCraft.old >nul 2>&1");
|
system("move MorriCraft.exe MorriCraft.old >nul 2>&1");
|
||||||
|
currentProgress = 0.3f;
|
||||||
system(("powershell -Command \"Expand-Archive -Path " + binaryName + " -DestinationPath . -Force\"").c_str());
|
system(("powershell -Command \"Expand-Archive -Path " + binaryName + " -DestinationPath . -Force\"").c_str());
|
||||||
|
currentProgress = 0.8f;
|
||||||
system("move version.txt.new version.txt >nul 2>&1");
|
system("move version.txt.new version.txt >nul 2>&1");
|
||||||
system("copy version.txt assets\\version.txt >nul 2>&1");
|
system("copy version.txt assets\\version.txt >nul 2>&1");
|
||||||
system(("del " + binaryName).c_str());
|
system(("del " + binaryName).c_str());
|
||||||
#else
|
#else
|
||||||
// Linux Update: Move binary, unzip assets
|
// Linux Update: Move binary, unzip assets
|
||||||
system("mv MorriCraft MorriCraft.old 2>/dev/null");
|
system("mv MorriCraft MorriCraft.old 2>/dev/null");
|
||||||
|
currentProgress = 0.3f;
|
||||||
system(("unzip -o " + binaryName).c_str());
|
system(("unzip -o " + binaryName).c_str());
|
||||||
|
currentProgress = 0.8f;
|
||||||
system("chmod +x MorriCraft");
|
system("chmod +x MorriCraft");
|
||||||
system("mv version.txt.new version.txt 2>/dev/null");
|
system("mv version.txt.new version.txt 2>/dev/null");
|
||||||
system("cp version.txt assets/version.txt 2>/dev/null");
|
system("cp version.txt assets/version.txt 2>/dev/null");
|
||||||
|
|
@ -2222,33 +2258,52 @@ int main(void)
|
||||||
DrawRectangleRec(backBtn, DARKGRAY);
|
DrawRectangleRec(backBtn, DARKGRAY);
|
||||||
DrawTextEx(customFont, "BACK", (Vector2){ backBtn.x + 70, backBtn.y + 10 }, 20, 1.0f, WHITE);
|
DrawTextEx(customFont, "BACK", (Vector2){ backBtn.x + 70, backBtn.y + 10 }, 20, 1.0f, WHITE);
|
||||||
} else {
|
} else {
|
||||||
if (isInstalling) {
|
DrawTextEx(customFont, "Downloading update...", (Vector2){ (float)currentWidth/2 - 90, (float)currentHeight/2 - 60 }, 24, 1.0f, YELLOW);
|
||||||
DrawTextEx(customFont, "Installing update...", (Vector2){ (float)currentWidth/2 - 80, (float)currentHeight/2 - 60 }, 24, 1.0f, GREEN);
|
// Dynamic progress pulse (v2.2.23)
|
||||||
} else {
|
if (currentProgress < 0.7f) currentProgress += 0.001f;
|
||||||
DrawTextEx(customFont, "Downloading update...", (Vector2){ (float)currentWidth/2 - 90, (float)currentHeight/2 - 60 }, 24, 1.0f, YELLOW);
|
|
||||||
// Dynamic progress pulse (v2.2.23)
|
|
||||||
if (currentProgress < 0.7f) currentProgress += 0.001f;
|
|
||||||
}
|
|
||||||
int bw = 500, bh = 35;
|
int bw = 500, bh = 35;
|
||||||
Rectangle barBg = { (float)currentWidth/2 - bw/2, (float)currentHeight/2 - bh/2, (float)bw, (float)bh };
|
Rectangle barBg = { (float)currentWidth/2 - bw/2, (float)currentHeight/2 - bh/2, (float)bw, (float)bh };
|
||||||
DrawRectangleRec(barBg, BLACK);
|
DrawRectangleRec(barBg, BLACK);
|
||||||
DrawRectangle(barBg.x, barBg.y, (int)(bw * currentProgress), bh, GREEN);
|
DrawRectangle(barBg.x, barBg.y, (int)(bw * currentProgress), bh, GREEN);
|
||||||
DrawRectangleLinesEx(barBg, 2.0f, GRAY);
|
DrawRectangleLinesEx(barBg, 2.0f, GRAY);
|
||||||
DrawTextEx(customFont, TextFormat("%i%%", (int)(currentProgress * 100)), (Vector2){ barBg.x + bw + 15, barBg.y + 5 }, 20, 1.0f, WHITE);
|
DrawTextEx(customFont, TextFormat("%i%%", (int)(currentProgress * 100)), (Vector2){ barBg.x + bw + 15, barBg.y + 5 }, 20, 1.0f, WHITE);
|
||||||
|
}
|
||||||
|
} else if (currentState == EXTRACTING_UPDATE) {
|
||||||
|
DrawRectangle(0, 0, currentWidth, currentHeight, (Color){ 20, 20, 20, 255 });
|
||||||
|
DrawTextEx(customFont, "Extracting and Installing Update...", (Vector2){ (float)currentWidth/2 - 150, (float)currentHeight/2 - 60 }, 24, 1.0f, GREEN);
|
||||||
|
|
||||||
|
int bw = 500, bh = 35;
|
||||||
|
Rectangle barBg = { (float)currentWidth/2 - bw/2, (float)currentHeight/2 - bh/2, (float)bw, (float)bh };
|
||||||
|
DrawRectangleRec(barBg, BLACK);
|
||||||
|
// We use the thread's progress for the extraction bar too
|
||||||
|
DrawRectangle(barBg.x, barBg.y, (int)(bw * 1.0f), bh, (Color){0, 228, 48, 150}); // Faded green background
|
||||||
|
DrawRectangle(barBg.x, barBg.y, (int)(bw * 1.0f), bh, GREEN);
|
||||||
|
DrawRectangleLinesEx(barBg, 2.0f, GRAY);
|
||||||
|
DrawTextEx(customFont, "Applying files...", (Vector2){ barBg.x, barBg.y + bh + 10 }, 18, 1.0f, GRAY);
|
||||||
|
|
||||||
|
if (downloadFinished) {
|
||||||
|
DrawRectangle(0, 0, currentWidth, currentHeight, (Color){ 0, 0, 0, 230 });
|
||||||
|
int pw = 500, ph = 220;
|
||||||
|
Rectangle pBox = { (float)currentWidth/2 - pw/2, (float)currentHeight/2 - ph/2, (float)pw, (float)ph };
|
||||||
|
DrawRectangleRec(pBox, (Color){ 30, 30, 30, 255 });
|
||||||
|
DrawRectangleLinesEx(pBox, 4.0f, GREEN);
|
||||||
|
|
||||||
if (downloadFinished) {
|
DrawTextEx(customFont, "UPDATE SUCCESSFUL!", (Vector2){ pBox.x + 80, pBox.y + 40 }, 28, 1.0f, GREEN);
|
||||||
DrawRectangle(0, 0, currentWidth, currentHeight, (Color){ 0, 0, 0, 230 });
|
DrawTextEx(customFont, "THE GAME NEEDS TO RESTART TO APPLY.", (Vector2){ pBox.x + 60, pBox.y + 90 }, 20, 1.0f, WHITE);
|
||||||
int pw = 500, ph = 220;
|
|
||||||
Rectangle pBox = { (float)currentWidth/2 - pw/2, (float)currentHeight/2 - ph/2, (float)pw, (float)ph };
|
Rectangle restartBtn = { pBox.x + pw/2 - 90, pBox.y + 145, 180, 45 };
|
||||||
DrawRectangleRec(pBox, (Color){ 30, 30, 30, 255 });
|
bool hRestart = CheckCollisionPointRec(mousePos, restartBtn);
|
||||||
|
DrawRectangleRec(restartBtn, hRestart ? GREEN : DARKGREEN);
|
||||||
DrawTextEx(customFont, "UPDATE SUCCESSFUL!", (Vector2){ pBox.x + 80, pBox.y + 40 }, 28, 1.0f, GREEN);
|
DrawTextEx(customFont, "RESTART", (Vector2){ restartBtn.x + 45, restartBtn.y + 12 }, 20, 1.0f, WHITE);
|
||||||
DrawTextEx(customFont, "PLEASE RESTART THE CLIENT TO APPLY.", (Vector2){ pBox.x + 60, pBox.y + 90 }, 20, 1.0f, WHITE);
|
|
||||||
|
if (hRestart && IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) {
|
||||||
Rectangle exitBtn = { pBox.x + pw/2 - 90, pBox.y + 145, 180, 45 };
|
#ifdef _WIN32
|
||||||
if (CheckCollisionPointRec(mousePos, exitBtn) && IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) exit(0);
|
system("start MorriCraft.exe");
|
||||||
DrawRectangleRec(exitBtn, MAROON);
|
#else
|
||||||
DrawTextEx(customFont, "EXIT GAME", (Vector2){ exitBtn.x + 40, exitBtn.y + 12 }, 20, 1.0f, WHITE);
|
system("./MorriCraft &");
|
||||||
|
#endif
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (currentState == CHEAT_GUI) {
|
} else if (currentState == CHEAT_GUI) {
|
||||||
|
|
@ -2438,9 +2493,10 @@ int main(void)
|
||||||
if (chunksGeneratedCount >= totalChunksToPreGen) {
|
if (chunksGeneratedCount >= totalChunksToPreGen) {
|
||||||
// FINALIZE: Place player and save world data
|
// FINALIZE: Place player and save world data
|
||||||
if (isNewWorldGeneration) {
|
if (isNewWorldGeneration) {
|
||||||
float spawnY = FindSpawnY(0, 0);
|
Vector2 idealSpawn = FindIdealSpawn();
|
||||||
camera3D.position = (Vector3){ 0.0f, spawnY, 0.0f };
|
float spawnY = FindSpawnY((int)idealSpawn.x, (int)idealSpawn.y);
|
||||||
camera3D.target = (Vector3){ 0.0f, spawnY, 1.0f };
|
camera3D.position = (Vector3){ idealSpawn.x, spawnY, idealSpawn.y };
|
||||||
|
camera3D.target = (Vector3){ idealSpawn.x, spawnY, idealSpawn.y + 1.0f };
|
||||||
|
|
||||||
std::ofstream worldFile2("saves/" + currentWorldName + "/world.dat");
|
std::ofstream worldFile2("saves/" + currentWorldName + "/world.dat");
|
||||||
if (worldFile2.is_open()) {
|
if (worldFile2.is_open()) {
|
||||||
|
|
@ -3246,27 +3302,36 @@ int main(void)
|
||||||
itemPos = Vector3Add(itemPos, Vector3Scale(upVM, 0.05f));
|
itemPos = Vector3Add(itemPos, Vector3Scale(upVM, 0.05f));
|
||||||
itemPos = Vector3Add(itemPos, Vector3Scale(rightVM, -0.05f));
|
itemPos = Vector3Add(itemPos, Vector3Scale(rightVM, -0.05f));
|
||||||
|
|
||||||
Texture2D itemTex = (heldBT == GRASS) ? grassTopTexture : (heldBT == CRAFTING_TABLE ? craftingSideTexture : blockTextures[heldBT]);
|
if (heldBT < STICK) {
|
||||||
if (itemTex.id > 0) {
|
// 3D Block in hand
|
||||||
if (heldBT < STICK) {
|
rlPushMatrix();
|
||||||
// 3D Block in hand
|
rlTranslatef(itemPos.x, itemPos.y, itemPos.z);
|
||||||
rlSetTexture(itemTex.id);
|
rlRotatef(camYaw * 180.0f/PI + 45.0f, 0, 1, 0);
|
||||||
rlPushMatrix();
|
rlRotatef(20.0f, 1, 0, 1);
|
||||||
rlTranslatef(itemPos.x, itemPos.y, itemPos.z);
|
rlScalef(0.15f, 0.15f, 0.15f);
|
||||||
rlRotatef(camYaw * 180.0f/PI + 45.0f, 0, 1, 0);
|
|
||||||
rlRotatef(20.0f, 1, 0, 1);
|
if (heldBT == GRASS) {
|
||||||
|
DrawGrassBlock((Vector3){0,0,0}, blockTextures[GRASS].id, grassTopTexture.id, blockTextures[DIRT].id, WHITE, 63);
|
||||||
|
} else if (heldBT == LOG) {
|
||||||
|
DrawLog((Vector3){0,0,0}, logSideTexture.id, logTopTexture.id, WHITE, 63);
|
||||||
|
} else if (heldBT == CRAFTING_TABLE) {
|
||||||
|
DrawCraftingTable((Vector3){0,0,0}, craftingSideTexture.id, craftingTopTexture.id, blockTextures[DIRT].id, WHITE, 63);
|
||||||
|
} else {
|
||||||
|
rlSetTexture(blockTextures[heldBT].id);
|
||||||
rlBegin(RL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
rlColor4ub(255, 255, 255, 255);
|
rlColor4ub(255, 255, 255, 255);
|
||||||
DrawCubeVertices(0,0,0, 0.15f, 0.15f, 0.15f, 63);
|
DrawCubeVertices(0,0,0, 1.0f, 1.0f, 1.0f, 63);
|
||||||
rlEnd();
|
rlEnd();
|
||||||
rlPopMatrix();
|
}
|
||||||
rlSetTexture(0);
|
rlPopMatrix();
|
||||||
} else {
|
rlSetTexture(0);
|
||||||
// Item (Stick/Axe) as Billboard
|
} else {
|
||||||
|
// Item (Stick/Axe) as Billboard
|
||||||
|
Texture2D itemTex = blockTextures[heldBT];
|
||||||
|
if (itemTex.id > 0) {
|
||||||
Rectangle src = { 0, 0, (float)itemTex.width, (float)itemTex.height };
|
Rectangle src = { 0, 0, (float)itemTex.width, (float)itemTex.height };
|
||||||
Vector2 itemSize = { 0.35f, 0.35f };
|
Vector2 itemSize = { 0.35f, 0.35f };
|
||||||
Vector2 pivot = { -itemSize.x/2.0f, -itemSize.y/2.0f };
|
Vector2 pivot = { -itemSize.x/2.0f, -itemSize.y/2.0f };
|
||||||
// v2.2.23: Rotated by 90 degrees (135 -> 45)
|
|
||||||
DrawBillboardPro(camera3D, itemTex, src, itemPos, camera3D.up, itemSize, pivot, 45.0f + swingVal * 40.0f, WHITE);
|
DrawBillboardPro(camera3D, itemTex, src, itemPos, camera3D.up, itemSize, pivot, 45.0f + swingVal * 40.0f, WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue