diff --git a/assets/TitleImage.png b/assets/TitleImage.png index ac164aa..34d5e4b 100644 Binary files a/assets/TitleImage.png and b/assets/TitleImage.png differ diff --git a/assets/bedrock.png b/assets/bedrock.png index 70b614f..5a265fa 100644 Binary files a/assets/bedrock.png and b/assets/bedrock.png differ diff --git a/assets/cobblestone.png b/assets/cobblestone.png index 435a7af..83168ea 100644 Binary files a/assets/cobblestone.png and b/assets/cobblestone.png differ diff --git a/assets/diamond_ore.png b/assets/diamond_ore.png index c2333b7..1fcca06 100644 Binary files a/assets/diamond_ore.png and b/assets/diamond_ore.png differ diff --git a/assets/dirt.png b/assets/dirt.png index 3f70996..320d197 100644 Binary files a/assets/dirt.png and b/assets/dirt.png differ diff --git a/assets/grass.png b/assets/grass.png index 4e3ae00..0398748 100644 Binary files a/assets/grass.png and b/assets/grass.png differ diff --git a/assets/grass_top.png b/assets/grass_top.png index 6abb3a1..c6a1fa0 100644 Binary files a/assets/grass_top.png and b/assets/grass_top.png differ diff --git a/assets/gravel.png b/assets/gravel.png index 9551021..04d7b49 100644 Binary files a/assets/gravel.png and b/assets/gravel.png differ diff --git a/assets/iron_ore.png b/assets/iron_ore.png index f3f5cd8..446d59a 100644 Binary files a/assets/iron_ore.png and b/assets/iron_ore.png differ diff --git a/assets/leaves.png b/assets/leaves.png index d985e31..c567a2b 100644 Binary files a/assets/leaves.png and b/assets/leaves.png differ diff --git a/assets/oak_log_side.png b/assets/oak_log_side.png index dde565b..6cc97e0 100644 Binary files a/assets/oak_log_side.png and b/assets/oak_log_side.png differ diff --git a/assets/oak_log_top.png b/assets/oak_log_top.png index a7b0203..f3340a2 100644 Binary files a/assets/oak_log_top.png and b/assets/oak_log_top.png differ diff --git a/assets/plank.png b/assets/plank.png index e5a1578..f1f8aed 100644 Binary files a/assets/plank.png and b/assets/plank.png differ diff --git a/assets/sand.png b/assets/sand.png index 2b35d75..2d9d63d 100644 Binary files a/assets/sand.png and b/assets/sand.png differ diff --git a/assets/stick.png b/assets/stick.png index 2b0baeb..34709a2 100644 Binary files a/assets/stick.png and b/assets/stick.png differ diff --git a/assets/stone.png b/assets/stone.png index c298969..9cb78f4 100644 Binary files a/assets/stone.png and b/assets/stone.png differ diff --git a/assets/version.txt b/assets/version.txt new file mode 100644 index 0000000..25deec3 --- /dev/null +++ b/assets/version.txt @@ -0,0 +1 @@ +v2.2.8 diff --git a/assets/wooden_axe.png b/assets/wooden_axe.png index 8f50805..521e55c 100644 Binary files a/assets/wooden_axe.png and b/assets/wooden_axe.png differ diff --git a/assets/wooden_hoe.png b/assets/wooden_hoe.png index 24eb874..d835c9c 100644 Binary files a/assets/wooden_hoe.png and b/assets/wooden_hoe.png differ diff --git a/assets/wooden_pickaxe.png b/assets/wooden_pickaxe.png index e6d2288..2c0a032 100644 Binary files a/assets/wooden_pickaxe.png and b/assets/wooden_pickaxe.png differ diff --git a/assets/wooden_shovel.png b/assets/wooden_shovel.png index 2e30f49..48ef733 100644 Binary files a/assets/wooden_shovel.png and b/assets/wooden_shovel.png differ diff --git a/assets/wooden_sword.png b/assets/wooden_sword.png index 17966fc..8e19a5d 100644 Binary files a/assets/wooden_sword.png and b/assets/wooden_sword.png differ diff --git a/build-linux/MorriCraft b/build-linux/MorriCraft index bcb4a74..b9f4080 100755 Binary files a/build-linux/MorriCraft and b/build-linux/MorriCraft differ diff --git a/build-linux/assets/TitleImage.png b/build-linux/assets/TitleImage.png index ac164aa..34d5e4b 100644 Binary files a/build-linux/assets/TitleImage.png and b/build-linux/assets/TitleImage.png differ diff --git a/build-linux/assets/bedrock.png b/build-linux/assets/bedrock.png index 70b614f..5a265fa 100644 Binary files a/build-linux/assets/bedrock.png and b/build-linux/assets/bedrock.png differ diff --git a/build-linux/assets/cobblestone.png b/build-linux/assets/cobblestone.png index 435a7af..83168ea 100644 Binary files a/build-linux/assets/cobblestone.png and b/build-linux/assets/cobblestone.png differ diff --git a/build-linux/assets/crafting_table_side_clean.png b/build-linux/assets/crafting_table_side_clean.png new file mode 100644 index 0000000..eb2a56c Binary files /dev/null and b/build-linux/assets/crafting_table_side_clean.png differ diff --git a/build-linux/assets/diamond_ore.png b/build-linux/assets/diamond_ore.png index c2333b7..1fcca06 100644 Binary files a/build-linux/assets/diamond_ore.png and b/build-linux/assets/diamond_ore.png differ diff --git a/build-linux/assets/dirt.png b/build-linux/assets/dirt.png index 3f70996..320d197 100644 Binary files a/build-linux/assets/dirt.png and b/build-linux/assets/dirt.png differ diff --git a/build-linux/assets/grass.png b/build-linux/assets/grass.png index 4e3ae00..0398748 100644 Binary files a/build-linux/assets/grass.png and b/build-linux/assets/grass.png differ diff --git a/build-linux/assets/grass_top.png b/build-linux/assets/grass_top.png index 6abb3a1..c6a1fa0 100644 Binary files a/build-linux/assets/grass_top.png and b/build-linux/assets/grass_top.png differ diff --git a/build-linux/assets/gravel.png b/build-linux/assets/gravel.png index 9551021..04d7b49 100644 Binary files a/build-linux/assets/gravel.png and b/build-linux/assets/gravel.png differ diff --git a/build-linux/assets/iron_ore.png b/build-linux/assets/iron_ore.png index f3f5cd8..446d59a 100644 Binary files a/build-linux/assets/iron_ore.png and b/build-linux/assets/iron_ore.png differ diff --git a/build-linux/assets/leaves.png b/build-linux/assets/leaves.png index d985e31..c567a2b 100644 Binary files a/build-linux/assets/leaves.png and b/build-linux/assets/leaves.png differ diff --git a/build-linux/assets/oak_log_side.png b/build-linux/assets/oak_log_side.png index dde565b..6cc97e0 100644 Binary files a/build-linux/assets/oak_log_side.png and b/build-linux/assets/oak_log_side.png differ diff --git a/build-linux/assets/oak_log_top.png b/build-linux/assets/oak_log_top.png index a7b0203..f3340a2 100644 Binary files a/build-linux/assets/oak_log_top.png and b/build-linux/assets/oak_log_top.png differ diff --git a/build-linux/assets/plank.png b/build-linux/assets/plank.png index e5a1578..f1f8aed 100644 Binary files a/build-linux/assets/plank.png and b/build-linux/assets/plank.png differ diff --git a/build-linux/assets/sand.png b/build-linux/assets/sand.png index 2b35d75..2d9d63d 100644 Binary files a/build-linux/assets/sand.png and b/build-linux/assets/sand.png differ diff --git a/build-linux/assets/stick.png b/build-linux/assets/stick.png index 2b0baeb..34709a2 100644 Binary files a/build-linux/assets/stick.png and b/build-linux/assets/stick.png differ diff --git a/build-linux/assets/stone.png b/build-linux/assets/stone.png index c298969..9cb78f4 100644 Binary files a/build-linux/assets/stone.png and b/build-linux/assets/stone.png differ diff --git a/build-linux/assets/version.txt b/build-linux/assets/version.txt index d7e8f8b..25deec3 100644 --- a/build-linux/assets/version.txt +++ b/build-linux/assets/version.txt @@ -1 +1 @@ -v2.2.7 +v2.2.8 diff --git a/build-linux/assets/wooden_axe.png b/build-linux/assets/wooden_axe.png index 8f50805..521e55c 100644 Binary files a/build-linux/assets/wooden_axe.png and b/build-linux/assets/wooden_axe.png differ diff --git a/build-linux/assets/wooden_hoe.png b/build-linux/assets/wooden_hoe.png index 24eb874..d835c9c 100644 Binary files a/build-linux/assets/wooden_hoe.png and b/build-linux/assets/wooden_hoe.png differ diff --git a/build-linux/assets/wooden_pickaxe.png b/build-linux/assets/wooden_pickaxe.png index e6d2288..2c0a032 100644 Binary files a/build-linux/assets/wooden_pickaxe.png and b/build-linux/assets/wooden_pickaxe.png differ diff --git a/build-linux/assets/wooden_shovel.png b/build-linux/assets/wooden_shovel.png index 2e30f49..48ef733 100644 Binary files a/build-linux/assets/wooden_shovel.png and b/build-linux/assets/wooden_shovel.png differ diff --git a/build-linux/assets/wooden_sword.png b/build-linux/assets/wooden_sword.png index 17966fc..8e19a5d 100644 Binary files a/build-linux/assets/wooden_sword.png and b/build-linux/assets/wooden_sword.png differ diff --git a/build-windows/MorriCraft-Windows.zip b/build-windows/MorriCraft-Windows.zip index 7fb94c3..7e56f1e 100644 Binary files a/build-windows/MorriCraft-Windows.zip and b/build-windows/MorriCraft-Windows.zip differ diff --git a/build-windows/MorriCraft.exe b/build-windows/MorriCraft.exe index 3108b31..a1480ec 100755 Binary files a/build-windows/MorriCraft.exe and b/build-windows/MorriCraft.exe differ diff --git a/src/main.cpp b/src/main.cpp index 05cc302..fab02e3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,7 +20,7 @@ #define PI 3.1415926535f #endif #define CHUNK_HEIGHT 128 -#define RENDER_DISTANCE 4 +#define RENDER_DISTANCE 8 enum BlockType { AIR = 0, GRASS = 1, DIRT = 2, COBBLESTONE = 3, LOG = 4, LEAVES = 5, PLANK = 6, @@ -122,13 +122,18 @@ struct ChunkPosHash { } }; +struct BlockRenderData { + float x, y, z; + unsigned char faces; // 1:front, 2:back, 4:top, 8:bottom, 16:right, 32:left +}; + struct Chunk { int blocks[CHUNK_SIZE][CHUNK_HEIGHT][CHUNK_SIZE]; int maxY = 0; bool generated = false; bool modified = false; bool dirty = true; - std::vector renderLists[32]; + std::vector renderLists[32]; Chunk() : generated(false), modified(false), maxY(0), dirty(true) {} }; @@ -150,7 +155,7 @@ 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 }; // Forward Declarations -bool IsExposedOptimized(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); void RebuildChunkRenderList(Chunk* chunk, int cx, int cz); void GenerateChunk(int cx, int cz); void SetBlock(int x, int y, int z, int type); @@ -230,6 +235,11 @@ void AddToInventory(int blockType) { // Inventory full — item is lost for now } +// Helper to give multiple items +void GiveItems(int type, int count) { + for (int i = 0; i < count; i++) AddToInventory(type); +} + // Camera look angles — global so world load/create can reset them cleanly static float camYaw = 0.0f; static float camPitch = 0.0f; @@ -280,18 +290,35 @@ int GetBlock(int x, int y, int z) { return 0; // Air if chunk not loaded } +unsigned char GetExposedFaces(int lx, int ly, int lz, Chunk* chunk, Chunk* nxM, Chunk* nxP, Chunk* nzM, Chunk* nzP) { + auto IsTrans = [](int bt) { return bt == AIR || bt == LEAVES; }; + unsigned char mask = 0; + // Front (+Z) + if (lz < CHUNK_SIZE - 1) { if (IsTrans(chunk->blocks[lx][ly][lz+1])) mask |= 1; } + else if (nzP) { if (IsTrans(nzP->blocks[lx][ly][0])) mask |= 1; } else mask |= 1; + // Back (-Z) + if (lz > 0) { if (IsTrans(chunk->blocks[lx][ly][lz-1])) mask |= 2; } + else if (nzM) { if (IsTrans(nzM->blocks[lx][ly][CHUNK_SIZE-1])) mask |= 2; } else mask |= 2; + // Top (+Y) + if (ly < CHUNK_HEIGHT - 1) { if (IsTrans(chunk->blocks[lx][ly+1][lz])) mask |= 4; } else mask |= 4; + // Bottom (-Y) + if (ly > 0) { if (IsTrans(chunk->blocks[lx][ly-1][lz])) mask |= 8; } else mask |= 8; + // Right (+X) + if (lx < CHUNK_SIZE - 1) { if (IsTrans(chunk->blocks[lx+1][ly][lz])) mask |= 16; } + else if (nxP) { if (IsTrans(nxP->blocks[0][ly][lz])) mask |= 16; } else mask |= 16; + // Left (-X) + if (lx > 0) { if (IsTrans(chunk->blocks[lx-1][ly][lz])) mask |= 32; } + else if (nxM) { if (IsTrans(nxM->blocks[CHUNK_SIZE-1][ly][lz])) mask |= 32; } else mask |= 32; + return mask; +} + void RebuildChunkRenderList(Chunk* chunk, int cx, int cz) { for (int i = 0; i < 32; i++) chunk->renderLists[i].clear(); - // Neighbors for exposure check - auto itNM = worldChunks.find({cx-1, cz}); - Chunk* nxM = (itNM != worldChunks.end()) ? itNM->second : nullptr; - auto itNP = worldChunks.find({cx+1, cz}); - Chunk* nxP = (itNP != worldChunks.end()) ? itNP->second : nullptr; - auto itZM = worldChunks.find({cx, cz-1}); - Chunk* nzM = (itZM != worldChunks.end()) ? itZM->second : nullptr; - auto itZP = worldChunks.find({cx, cz+1}); - Chunk* nzP = (itZP != worldChunks.end()) ? itZP->second : nullptr; + auto itNM = worldChunks.find({cx-1, cz}); Chunk* nxM = (itNM != worldChunks.end()) ? itNM->second : nullptr; + auto itNP = worldChunks.find({cx+1, cz}); Chunk* nxP = (itNP != worldChunks.end()) ? itNP->second : nullptr; + auto itZM = worldChunks.find({cx, cz-1}); Chunk* nzM = (itZM != worldChunks.end()) ? itZM->second : nullptr; + auto itZP = worldChunks.find({cx, cz+1}); Chunk* nzP = (itZP != worldChunks.end()) ? itZP->second : nullptr; int worldX = cx * CHUNK_SIZE; int worldZ = cz * CHUNK_SIZE; @@ -302,8 +329,9 @@ void RebuildChunkRenderList(Chunk* chunk, int cx, int cz) { int bt = chunk->blocks[lx][ly][lz]; if (bt == AIR) continue; - if (IsExposedOptimized(lx, ly, lz, chunk, nxM, nxP, nzM, nzP)) { - chunk->renderLists[bt].push_back((Vector3){(float)(worldX+lx), (float)ly, (float)(worldZ+lz)}); + unsigned char faces = GetExposedFaces(lx, ly, lz, chunk, nxM, nxP, nzM, nzP); + if (faces != 0) { + chunk->renderLists[bt].push_back({ (float)(worldX+lx), (float)ly, (float)(worldZ+lz), faces }); } } } @@ -535,6 +563,10 @@ void GenerateChunk(int cx, int cz) { if (LoadChunk(newChunk, cx, cz)) { worldChunks[key] = newChunk; + auto n1 = worldChunks.find({cx-1, cz}); if (n1 != worldChunks.end()) n1->second->dirty = true; + auto n2 = worldChunks.find({cx+1, cz}); if (n2 != worldChunks.end()) n2->second->dirty = true; + auto n3 = worldChunks.find({cx, cz-1}); if (n3 != worldChunks.end()) n3->second->dirty = true; + auto n4 = worldChunks.find({cx, cz+1}); if (n4 != worldChunks.end()) n4->second->dirty = true; return; } @@ -623,10 +655,10 @@ void GenerateChunk(int cx, int cz) { } newChunk->generated = true; - newChunk->modified = true; // Newly generated, so we should save it + newChunk->modified = true; worldChunks[key] = newChunk; - // Mark neighbors as dirty so they rebuild their render lists with new occlusion data + // Mark neighbors as dirty (Bug #2 fix) ChunkPos neighbors[] = { {cx-1, cz}, {cx+1, cz}, {cx, cz-1}, {cx, cz+1} }; for (auto& nPos : neighbors) { auto it = worldChunks.find(nPos); @@ -708,163 +740,102 @@ void DrawTexturedCube(Vector3 position, float width, float height, float length, // Draws a grass block with correct per-face textures: // top=green grass, sides=dirt+grass stripe, bottom=pure dirt. // Caller must NOT have an active rlSetTexture — this function manages its own binds. -void DrawGrassBlock(Vector3 position, unsigned int sideTexId, unsigned int topTexId, unsigned int botTexId, Color tint) { - float x = position.x; - float y = position.y; - float z = position.z; - - // ---- SIDES (4 faces) ---- - rlSetTexture(sideTexId); - rlBegin(RL_QUADS); - rlColor4ub(tint.r, tint.g, tint.b, 255); - // Front - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); - // Back - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); - // Right - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); - // Left - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); - rlEnd(); - - // ---- TOP (pure green) ---- - rlSetTexture(topTexId); - rlBegin(RL_QUADS); - // Combine grass green with ambient light - rlColor4ub((unsigned char)(124 * (tint.r/255.0f)), - (unsigned char)(189 * (tint.g/255.0f)), - (unsigned char)(107 * (tint.b/255.0f)), 255); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); - // ---- BOTTOM (pure dirt) ---- - rlSetTexture(botTexId); - rlBegin(RL_QUADS); - rlColor4ub(tint.r, tint.g, tint.b, 255); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); - rlEnd(); -} - -// Draws a crafting table with custom top and sides -void DrawCraftingTable(Vector3 position, unsigned int sideTexId, unsigned int topTexId, unsigned int botTexId, Color tint) { - float x = position.x; float y = position.y; float z = position.z; - - // SIDES - rlSetTexture(sideTexId); - rlBegin(RL_QUADS); - rlColor4ub(tint.r, tint.g, tint.b, 255); - // Front, Back, Right, Left - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); - rlEnd(); - - // TOP - rlSetTexture(topTexId); - rlBegin(RL_QUADS); - rlColor4ub(tint.r, tint.g, tint.b, 255); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); - rlEnd(); - - // BOTTOM (dirt) - rlSetTexture(botTexId); - rlBegin(RL_QUADS); - rlColor4ub(tint.r, tint.g, tint.b, 255); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); - rlEnd(); -} - -void DrawLog(Vector3 position, unsigned int sideTexId, unsigned int topTexId, Color tint) { - float x = position.x; float y = position.y; float z = position.z; - rlSetTexture(sideTexId); - rlBegin(RL_QUADS); - rlColor4ub(tint.r, tint.g, tint.b, 255); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); - rlEnd(); - rlSetTexture(topTexId); - rlBegin(RL_QUADS); - rlColor4ub(tint.r, tint.g, tint.b, 255); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); - rlEnd(); -} - -// Optimized check to see if a block has any exposed faces. -bool IsExposedOptimized(int lx, int ly, int lz, Chunk* chunk, Chunk* nxM, Chunk* nxP, Chunk* nzM, Chunk* nzP) { - if (ly > 0) { if (chunk->blocks[lx][ly-1][lz] == AIR) return true; } else return true; - if (ly < CHUNK_HEIGHT - 1) { if (chunk->blocks[lx][ly+1][lz] == AIR) return true; } else return true; - if (lx > 0) { if (chunk->blocks[lx-1][ly][lz] == AIR) return true; } - else if (nxM) { if (nxM->blocks[CHUNK_SIZE-1][ly][lz] == AIR) return true; } else return true; - if (lx < CHUNK_SIZE - 1) { if (chunk->blocks[lx+1][ly][lz] == AIR) return true; } - else if (nxP) { if (nxP->blocks[0][ly][lz] == AIR) return true; } else return true; - if (lz > 0) { if (chunk->blocks[lx][ly][lz-1] == AIR) return true; } - else if (nzM) { if (nzM->blocks[lx][ly][CHUNK_SIZE-1] == AIR) return true; } else return true; - if (lz < CHUNK_SIZE - 1) { if (chunk->blocks[lx][ly][lz+1] == AIR) return true; } - else if (nzP) { if (nzP->blocks[lx][ly][0] == AIR) return true; } else return true; - return false; -} - -// Optimized helper for batched rendering: Draws only the vertices (no texture bind or rlBegin/End) -void DrawCubeVertices(float x, float y, float z, float w, float h, float l) { +void DrawCubeVertices(float x, float y, float z, float w, float h, float l, unsigned char mask) { float hw = w/2.0f; float hh = h/2.0f; float hl = l/2.0f; - // Front - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - hw, y - hh, z + hl); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + hw, y - hh, z + hl); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + hw, y + hh, z + hl); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - hw, y + hh, z + hl); - // Back - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - hw, y - hh, z - hl); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - hw, y + hh, z - hl); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + hw, y + hh, z - hl); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + hw, y - hh, z - hl); - // Top - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - hw, y + hh, z - hl); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - hw, y + hh, z + hl); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + hw, y + hh, z + hl); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + hw, y + hh, z - hl); - // Bottom - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - hw, y - hh, z - hl); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + hw, y - hh, z - hl); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + hw, y - hh, z + hl); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - hw, y - hh, z + hl); - // Right - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + hw, y - hh, z - hl); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + hw, y + hh, z - hl); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + hw, y + hh, z + hl); - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + hw, y - hh, z + hl); - // Left - rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - hw, y - hh, z - hl); - rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - hw, y - hh, z + hl); - rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - hw, y + hh, z + hl); - rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - hw, y + hh, z - hl); + if (mask & 1) { // Front (+Z) + rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - hw, y - hh, z + hl); + rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + hw, y - hh, z + hl); + rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + hw, y + hh, z + hl); + rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - hw, y + hh, z + hl); + } + if (mask & 2) { // Back (-Z) + rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - hw, y - hh, z - hl); + rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - hw, y + hh, z - hl); + rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + hw, y + hh, z - hl); + rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + hw, y - hh, z - hl); + } + if (mask & 4) { // Top (+Y) + rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - hw, y + hh, z - hl); + rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - hw, y + hh, z + hl); + rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + hw, y + hh, z + hl); + rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + hw, y + hh, z - hl); + } + if (mask & 8) { // Bottom (-Y) + rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - hw, y - hh, z - hl); + rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + hw, y - hh, z - hl); + rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + hw, y - hh, z + hl); + rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - hw, y - hh, z + hl); + } + if (mask & 16) { // Right (+X) + rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + hw, y - hh, z - hl); + rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + hw, y + hh, z - hl); + rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + hw, y + hh, z + hl); + rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + hw, y - hh, z + hl); + } + if (mask & 32) { // Left (-X) + rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - hw, y - hh, z - hl); + rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - hw, y - hh, z + hl); + rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - hw, y + hh, z + hl); + rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - hw, y + hh, z - hl); + } } +void DrawGrassBlock(Vector3 position, unsigned int sideTexId, unsigned int topTexId, unsigned int botTexId, Color tint, unsigned char mask) { + float x = position.x; float y = position.y; float z = position.z; + if (mask & 51) { // Sides (Front, Back, Right, Left: 1|2|16|32 = 51) + rlSetTexture(sideTexId); rlBegin(RL_QUADS); rlColor4ub(tint.r, tint.g, tint.b, 255); + if (mask & 1) { rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); } + if (mask & 2) { rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); } + if (mask & 16) { rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); } + if (mask & 32) { rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); } + rlEnd(); + } + if (mask & 4) { // Top + rlSetTexture(topTexId); rlBegin(RL_QUADS); + rlColor4ub((unsigned char)(124 * (tint.r/255.0f)), (unsigned char)(189 * (tint.g/255.0f)), (unsigned char)(107 * (tint.b/255.0f)), 255); + rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlEnd(); + } + if (mask & 8) { // Bottom + rlSetTexture(botTexId); rlBegin(RL_QUADS); rlColor4ub(tint.r, tint.g, tint.b, 255); + rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlEnd(); + } +} + +void DrawLog(Vector3 position, unsigned int sideTexId, unsigned int topTexId, Color tint, unsigned char mask) { + float x = position.x; float y = position.y; float z = position.z; + if (mask & 51) { + rlSetTexture(sideTexId); rlBegin(RL_QUADS); rlColor4ub(tint.r, tint.g, tint.b, 255); + if (mask & 1) { rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); } + if (mask & 2) { rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); } + if (mask & 16) { rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); } + if (mask & 32) { rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); } + rlEnd(); + } + if (mask & 12) { // Top + Bottom + rlSetTexture(topTexId); rlBegin(RL_QUADS); rlColor4ub(tint.r, tint.g, tint.b, 255); + if (mask & 4) { rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); } + if (mask & 8) { rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); } + rlEnd(); + } +} + +void DrawCraftingTable(Vector3 position, unsigned int sideTexId, unsigned int topTexId, unsigned int botTexId, Color tint, unsigned char mask) { + float x = position.x; float y = position.y; float z = position.z; + if (mask & 51) { + rlSetTexture(sideTexId); rlBegin(RL_QUADS); rlColor4ub(tint.r, tint.g, tint.b, 255); + if (mask & 1) { rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); } + if (mask & 2) { rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); } + if (mask & 16) { rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); } + if (mask & 32) { rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); } + rlEnd(); + } + if (mask & 4) { rlSetTexture(topTexId); rlBegin(RL_QUADS); rlColor4ub(tint.r, tint.g, tint.b, 255); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - 0.5f, y + 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + 0.5f, y + 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + 0.5f, y + 0.5f, z - 0.5f); rlEnd(); } + if (mask & 8) { rlSetTexture(botTexId); rlBegin(RL_QUADS); rlColor4ub(tint.r, tint.g, tint.b, 255); rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + 0.5f, y - 0.5f, z - 0.5f); rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + 0.5f, y - 0.5f, z + 0.5f); rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - 0.5f, y - 0.5f, z + 0.5f); rlEnd(); } +} + + + + // Optimized check to see if a block has any exposed faces bool IsExposed(int x, int ly, int z, Chunk* chunk, int lx, int lz) { // Local check (inside same chunk) @@ -960,7 +931,7 @@ int main(void) float updateTimer = 0.0f; float downloadProgress = 0.0f; std::string latestVersion = ""; - std::string localVersion = "v1.9.0"; // Default fallback + std::string localVersion = "v2.2.9"; // Default fallback // Read local version std::ifstream vfile("assets/version.txt"); @@ -1595,6 +1566,19 @@ int main(void) currentZoom += (targetZoom - currentZoom) * 0.05f; camera.zoom = currentZoom; + + // --- GLOBAL INPUTS (Outside gameplay state) --- + if (IsKeyPressed(KEY_E) && !isChatting && (currentState == GAMEPLAY || currentState == CRAFTING_GUI)) { + if (currentState == CRAFTING_GUI) { + currentState = GAMEPLAY; + DisableCursor(); + } else { + inventoryOpen = !inventoryOpen; + if (inventoryOpen) EnableCursor(); + else DisableCursor(); + } + } + // Gameplay Update if (currentState == GAMEPLAY) { gameTime += GetFrameTime(); @@ -1615,13 +1599,6 @@ int main(void) if (scroll > 0.0f) activeHotbarSlot = (activeHotbarSlot - 1 + 9) % 9; if (scroll < 0.0f) activeHotbarSlot = (activeHotbarSlot + 1) % 9; - // Toggle inventory - if (IsKeyPressed(KEY_E) && !isChatting) { - inventoryOpen = !inventoryOpen; - if (inventoryOpen) EnableCursor(); - else DisableCursor(); - } - // Dynamic Chunk Loading int playerCX = (int)floorf(camera3D.position.x / CHUNK_SIZE); int playerCZ = (int)floorf(camera3D.position.z / CHUNK_SIZE); @@ -1654,11 +1631,16 @@ int main(void) } else if (cmd == "fly off") { isFlying = false; chatLog.push_back({ "[Server] Flight disabled", 5.0f }); + } else if (cmd == "test") { + GiveItems(CRAFTING_TABLE, 1); + GiveItems(LOG, 64); + chatLog.push_back({ "[Server] Added test items to inventory", 5.0f }); } else if (cmd == "help") { chatLog.push_back({ "[Server] Commands List:", 8.0f }); 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 }); } else { chatLog.push_back({ "[Server] Unknown command: /" + cmd, 5.0f }); } @@ -2000,71 +1982,69 @@ int main(void) } } else if (currentState == UPDATE_FOUND) { DrawRectangle(0, 0, currentWidth, currentHeight, (Color){ 0, 0, 0, 220 }); - int pw = 450, ph = 250; + int pw = 450, ph = 180; 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, 4.0f, GREEN); DrawTextEx(customFont, "NEW VERSION AVAILABLE!", (Vector2){ pBox.x + 40, pBox.y + 30 }, 24, 1.0f, GREEN); std::string updMsg = latestVersion + " is now ready for download."; DrawTextEx(customFont, updMsg.c_str(), (Vector2){ pBox.x + 40, pBox.y + 70 }, 18, 1.0f, LIGHTGRAY); // Update Button - Rectangle updBtn = { pBox.x + 40, pBox.y + 120, 370, 40 }; + Rectangle updBtn = { pBox.x + 40, pBox.y + 110, 370, 40 }; bool isUpdHovered = CheckCollisionPointRec(mousePos, updBtn); DrawRectangleRec(updBtn, isUpdHovered ? GREEN : (Color){ 0, 100, 0, 255 }); DrawTextEx(customFont, "UPDATE NOW", (Vector2){ updBtn.x + 100, updBtn.y + 10 }, 20, 1.0f, WHITE); if (isUpdHovered && IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) currentState = DOWNLOADING_UPDATE; - - // Update Notes Button - Rectangle noteBtn = { pBox.x + 40, pBox.y + 175, 370, 40 }; - bool isNoteHovered = CheckCollisionPointRec(mousePos, noteBtn); - DrawRectangleRec(noteBtn, isNoteHovered ? DARKGRAY : BLACK); - DrawRectangleLinesEx(noteBtn, 2.0f, GRAY); - DrawTextEx(customFont, "VIEW UPDATE NOTES", (Vector2){ noteBtn.x + 65, noteBtn.y + 10 }, 20, 1.0f, WHITE); - if (isNoteHovered && IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) currentState = UPDATE_NOTES; } else if (currentState == DOWNLOADING_UPDATE) { static bool startedDownload = false; static bool downloadFailed = false; - static float fakeProgress = 0.0f; + static bool downloadFinished = false; + static float currentProgress = 0.0f; if (!startedDownload) { startedDownload = true; - // REAL DOWNLOAD ATTEMPT - Platform-aware URLs - #ifdef _WIN32 - std::string binaryUrl = "https://git.linology.tech/michael/MorriCraft/raw/branch/master/build-windows/MorriCraft.exe"; - std::string binaryName = "MorriCraft.exe"; - #else - std::string binaryUrl = "https://git.linology.tech/michael/MorriCraft/raw/branch/master/build-linux/MorriCraft"; - std::string binaryName = "MorriCraft"; - #endif - std::string versionUrl = "https://git.linology.tech/michael/MorriCraft/raw/branch/master/version.txt"; - - // Download new binary and version file - int r1 = system(("curl -L -s -o " + binaryName + ".new \"" + binaryUrl + "\"").c_str()); - int r2 = system(("curl -L -s -o version.txt.new \"" + versionUrl + "\"").c_str()); - - if (r1 == 0 && r2 == 0) { + currentProgress = 0.1f; + std::thread([]() { + std::string binaryUrl, binaryName; #ifdef _WIN32 - // Windows: rename old, move new into place - system(("rename " + binaryName + " " + binaryName + ".old").c_str()); - system(("rename " + binaryName + ".new " + binaryName).c_str()); - system("rename version.txt version.txt.old"); - system("rename version.txt.new version.txt"); - system("copy version.txt assets\\version.txt >nul 2>&1"); + binaryUrl = "https://git.linology.tech/michael/MorriCraft/raw/branch/master/build-windows/MorriCraft.exe"; + binaryName = "MorriCraft.exe"; #else - // Linux: chmod, move - system(("chmod +x " + binaryName + ".new").c_str()); - system(("mv " + binaryName + " " + binaryName + ".old 2>/dev/null").c_str()); - system(("mv " + binaryName + ".new " + binaryName).c_str()); - system("mv version.txt.new version.txt"); - system("cp version.txt assets/version.txt 2>/dev/null"); + binaryUrl = "https://git.linology.tech/michael/MorriCraft/raw/branch/master/build-linux/MorriCraft"; + binaryName = "MorriCraft"; #endif - fakeProgress = 1.0f; - } else { - downloadFailed = true; - } + std::string versionUrl = "https://git.linology.tech/michael/MorriCraft/raw/branch/master/version.txt"; + + // Download binary + int r1 = system(("curl -L -s -o " + binaryName + ".new \"" + binaryUrl + "\"").c_str()); + currentProgress = 0.6f; + + // Download version + int r2 = system(("curl -L -s -o version.txt.new \"" + versionUrl + "\"").c_str()); + currentProgress = 0.8f; + + if (r1 == 0 && r2 == 0) { + #ifdef _WIN32 + system(("rename " + binaryName + " " + binaryName + ".old").c_str()); + system(("rename " + binaryName + ".new " + binaryName).c_str()); + system("rename version.txt version.txt.old"); + system("rename version.txt.new version.txt"); + system("copy version.txt assets\\version.txt >nul 2>&1"); + #else + system(("chmod +x " + binaryName + ".new").c_str()); + system(("mv " + binaryName + " " + binaryName + ".old 2>/dev/null").c_str()); + system(("mv " + binaryName + ".new " + binaryName).c_str()); + system("mv version.txt.new version.txt"); + system("cp version.txt assets/version.txt 2>/dev/null"); + #endif + currentProgress = 1.0f; + downloadFinished = true; + } else { + downloadFailed = true; + } + }).detach(); } DrawRectangle(0, 0, currentWidth, currentHeight, (Color){ 20, 20, 20, 255 }); @@ -2072,35 +2052,33 @@ int main(void) DrawTextEx(customFont, "DOWNLOAD FAILED! Check internet connection.", (Vector2){ (float)currentWidth/2 - 250, (float)currentHeight/2 - 40 }, 24, 1.0f, RED); Rectangle backBtn = { (float)currentWidth/2 - 100, (float)currentHeight/2 + 20, 200, 40 }; if (CheckCollisionPointRec(mousePos, backBtn) && IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) { - currentState = MAIN_MENU; - startedDownload = false; - downloadFailed = false; + currentState = MAIN_MENU; startedDownload = false; downloadFailed = false; } DrawRectangleRec(backBtn, DARKGRAY); DrawTextEx(customFont, "BACK", (Vector2){ backBtn.x + 70, backBtn.y + 10 }, 20, 1.0f, WHITE); } else { - fakeProgress += 0.001f; // Slow visual for user - if (fakeProgress > 1.0f) fakeProgress = 1.0f; + DrawTextEx(customFont, "DOWNLOADING & REPLACING SYSTEM FILES...", (Vector2){ (float)currentWidth/2 - 250, (float)currentHeight/2 - 60 }, 24, 1.0f, YELLOW); + int bw = 500, bh = 35; + Rectangle barBg = { (float)currentWidth/2 - bw/2, (float)currentHeight/2 - bh/2, (float)bw, (float)bh }; + DrawRectangleRec(barBg, BLACK); + DrawRectangle(barBg.x, barBg.y, (int)(bw * currentProgress), bh, GREEN); + 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, "DOWNLOADING & REPLACING SYSTEM FILES...", (Vector2){ (float)currentWidth/2 - 250, (float)currentHeight/2 - 40 }, 24, 1.0f, YELLOW); - int bw = 450, bh = 30; - DrawRectangle(currentWidth/2 - bw/2, currentHeight/2, bw, bh, BLACK); - DrawRectangle(currentWidth/2 - bw/2, currentHeight/2, (int)(bw * (fakeProgress > 0.9f ? 0.9f : fakeProgress)), bh, GREEN); - - if (fakeProgress >= 1.0f) { + if (downloadFinished) { DrawRectangle(0, 0, currentWidth, currentHeight, (Color){ 0, 0, 0, 230 }); - int pw = 450, ph = 200; + 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); - DrawTextEx(customFont, "UPDATE SUCCESSFUL!", (Vector2){ pBox.x + 60, pBox.y + 40 }, 24, 1.0f, GREEN); - DrawTextEx(customFont, "PLEASE RESTART THE CLIENT.", (Vector2){ pBox.x + 60, pBox.y + 80 }, 20, 1.0f, WHITE); + DrawTextEx(customFont, "UPDATE SUCCESSFUL!", (Vector2){ pBox.x + 80, pBox.y + 40 }, 28, 1.0f, GREEN); + DrawTextEx(customFont, "PLEASE RESTART THE CLIENT TO APPLY.", (Vector2){ pBox.x + 60, pBox.y + 90 }, 20, 1.0f, WHITE); - Rectangle exitBtn = { pBox.x + pw/2 - 75, pBox.y + 130, 150, 40 }; + Rectangle exitBtn = { pBox.x + pw/2 - 90, pBox.y + 145, 180, 45 }; if (CheckCollisionPointRec(mousePos, exitBtn) && IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) exit(0); DrawRectangleRec(exitBtn, MAROON); - DrawTextEx(customFont, "EXIT GAME", (Vector2){ exitBtn.x + 30, exitBtn.y + 10 }, 20, 1.0f, WHITE); + DrawTextEx(customFont, "EXIT GAME", (Vector2){ exitBtn.x + 40, exitBtn.y + 12 }, 20, 1.0f, WHITE); } } } else if (currentState == SKIN_EDITOR) { @@ -2337,8 +2315,8 @@ int main(void) DrawTexturePro(titleTexture, sourceRec, destRec, origin, 0.0f, WHITE); EndMode2D(); - // Show Version Number (v2.2.7) in Red - DrawTextEx(customFont, "v2.2.7", (Vector2){ (float)currentWidth - 140, (float)currentHeight - 40 }, 22, 1.0f, RED); + // Show Version Number (v2.2.9) in Red + DrawTextEx(customFont, "v2.2.9", (Vector2){ (float)currentWidth - 140, (float)currentHeight - 40 }, 22, 1.0f, RED); // --- PLAYER NAME POPUP (IF MISSING) --- if (playerName == "") { @@ -2566,30 +2544,30 @@ int main(void) if (showDeleteConfirm) { DrawRectangle(0, 0, currentWidth, currentHeight, (Color){ 0, 0, 0, 200 }); - int confWidth = 400; - int confHeight = 200; + int confWidth = 550; + int confHeight = 240; int confX = (currentWidth / 2) - (confWidth / 2); int confY = (currentHeight / 2) - (confHeight / 2); DrawRectangle(confX, confY, confWidth, confHeight, (Color){ 50, 20, 20, 255 }); DrawRectangleLinesEx((Rectangle){ (float)confX, (float)confY, (float)confWidth, (float)confHeight }, 4.0f, RED); - Vector2 warnSize = MeasureTextEx(customFont, "Delete World?", 24, 1.0f); - DrawTextEx(customFont, "Delete World?", (Vector2){ confX + (confWidth/2) - (warnSize.x/2), confY + 30 }, 24, 1.0f, WHITE); + Vector2 warnSize = MeasureTextEx(customFont, "Delete World?", 28, 1.0f); + DrawTextEx(customFont, "Delete World?", (Vector2){ confX + (confWidth/2) - (warnSize.x/2), confY + 30 }, 28, 1.0f, WHITE); - std::string warnText = "Delete '" + deletingWorldName + "'?"; - Vector2 nameSize = MeasureTextEx(customFont, warnText.c_str(), 20, 1.0f); - DrawTextEx(customFont, warnText.c_str(), (Vector2){ confX + (confWidth/2) - (nameSize.x/2), confY + 70 }, 20, 1.0f, LIGHTGRAY); + std::string warnText = "Are you sure you want to delete '" + deletingWorldName + "'?"; + Vector2 nameSize = MeasureTextEx(customFont, warnText.c_str(), 22, 1.0f); + DrawTextEx(customFont, warnText.c_str(), (Vector2){ confX + (confWidth/2) - (nameSize.x/2), confY + 85 }, 22, 1.0f, LIGHTGRAY); // Yes Button - Rectangle yesBtn = { (float)confX + 50, (float)confY + 130, 120, 40 }; + Rectangle yesBtn = { (float)confX + 80, (float)confY + 150, 140, 40 }; bool isYesHovered = CheckCollisionPointRec(mousePos, yesBtn); DrawRectangleRec(yesBtn, isYesHovered ? RED : MAROON); DrawRectangleLinesEx(yesBtn, 2.0f, isYesHovered ? WHITE : GRAY); - DrawTextEx(customFont, "YES", (Vector2){ yesBtn.x + 40, yesBtn.y + 10 }, 20, 1.0f, WHITE); + DrawTextEx(customFont, "YES, DELETE", (Vector2){ yesBtn.x + 10, yesBtn.y + 10 }, 20, 1.0f, WHITE); // No Button - Rectangle noBtn = { (float)confX + confWidth - 170, (float)confY + 130, 120, 40 }; + Rectangle noBtn = { (float)confX + confWidth - 220, (float)confY + 150, 140, 40 }; bool isNoHovered = CheckCollisionPointRec(mousePos, noBtn); DrawRectangleRec(noBtn, isNoHovered ? (Color){ 100, 100, 100, 255 } : DARKGRAY); DrawRectangleLinesEx(noBtn, 2.0f, isNoHovered ? WHITE : GRAY); @@ -2892,11 +2870,14 @@ int main(void) std::vector visibleChunks; for (int cx = playerCX - RENDER_DISTANCE; cx <= playerCX + RENDER_DISTANCE; cx++) { for (int cz = playerCZ - RENDER_DISTANCE; cz <= playerCZ + RENDER_DISTANCE; cz++) { - // FRUSTUM CULLING - Vector3 chunkCenter = { (float)(cx * CHUNK_SIZE + 8), 32.0f, (float)(cz * CHUNK_SIZE + 8) }; - Vector3 toChunk = Vector3Normalize(Vector3Subtract(chunkCenter, camera3D.position)); - if (Vector3Length(Vector3Subtract(chunkCenter, camera3D.position)) > 24.0f && - Vector3DotProduct(toChunk, camForward) < -0.3f) continue; + // OPTIMIZED FRUSTUM CULLING (Bug #1 Fix: Don't cull the player's current chunk) + if (abs(cx - playerCX) > 1 || abs(cz - playerCZ) > 1) { + Vector3 chunkCenter = { (float)(cx * CHUNK_SIZE + 16), 64.0f, (float)(cz * CHUNK_SIZE + 16) }; + float distSqr = Vector3LengthSqr(Vector3Subtract(chunkCenter, camera3D.position)); + if (distSqr > 160.0f * 160.0f) continue; + Vector3 toChunk = Vector3Normalize(Vector3Subtract(chunkCenter, camera3D.position)); + if (distSqr > 32.0f * 32.0f && Vector3DotProduct(toChunk, camForward) < -0.4f) continue; + } auto it = worldChunks.find({cx, cz}); if (it == worldChunks.end()) continue; @@ -2911,20 +2892,20 @@ int main(void) for (int renderType = 1; renderType <= 13; renderType++) { if (renderType == GRASS) { for (Chunk* chunk : visibleChunks) { - for (auto& pos : chunk->renderLists[GRASS]) { - DrawGrassBlock(pos, blockTextures[GRASS].id, grassTopTexture.id, blockTextures[DIRT].id, blockTint); + for (auto& data : chunk->renderLists[GRASS]) { + DrawGrassBlock((Vector3){data.x, data.y, data.z}, blockTextures[GRASS].id, grassTopTexture.id, blockTextures[DIRT].id, blockTint, data.faces); } } } else if (renderType == LOG) { for (Chunk* chunk : visibleChunks) { - for (auto& pos : chunk->renderLists[LOG]) { - DrawLog(pos, logSideTexture.id, logTopTexture.id, blockTint); + for (auto& data : chunk->renderLists[LOG]) { + DrawLog((Vector3){data.x, data.y, data.z}, logSideTexture.id, logTopTexture.id, blockTint, data.faces); } } } else if (renderType == CRAFTING_TABLE) { for (Chunk* chunk : visibleChunks) { - for (auto& pos : chunk->renderLists[CRAFTING_TABLE]) { - DrawCraftingTable(pos, craftingSideTexture.id, craftingTopTexture.id, blockTextures[DIRT].id, blockTint); + for (auto& data : chunk->renderLists[CRAFTING_TABLE]) { + DrawCraftingTable((Vector3){data.x, data.y, data.z}, craftingSideTexture.id, craftingTopTexture.id, blockTextures[DIRT].id, blockTint, data.faces); } } } else { @@ -2936,8 +2917,8 @@ int main(void) } for (Chunk* chunk : visibleChunks) { - for (auto& pos : chunk->renderLists[renderType]) { - DrawCubeVertices(pos.x, pos.y, pos.z, 1.0f, 1.0f, 1.0f); + for (auto& data : chunk->renderLists[renderType]) { + DrawCubeVertices(data.x, data.y, data.z, 1.0f, 1.0f, 1.0f, data.faces); } } rlEnd(); @@ -2990,19 +2971,27 @@ int main(void) handPos = Vector3Add(handPos, Vector3Scale(upVM, -0.25f - swingVal * 0.15f)); // Draw Arm (rotated cube) - // We use rlgl to rotate it to point roughly forward rlPushMatrix(); rlTranslatef(handPos.x, handPos.y, handPos.z); - rlRotatef(camYaw * 180.0f/PI, 0, 1, 0); // Yaw with camera - rlRotatef(-20.0f - swingVal * 30.0f, 1, 0, 0); // Slight slant - DrawCube((Vector3){0,0,0}, 0.08f, 0.1f, 0.35f, (Color){220, 180, 150, 255}); + rlRotatef(camYaw * 180.0f/PI, 0, 1, 0); + rlRotatef(camPitch * 180.0f/PI - 15.0f - swingVal * 20.0f, 1, 0, 0); // Point forward + swing + DrawCube((Vector3){0,0,0}, 0.1f, 0.12f, 0.4f, (Color){220, 180, 150, 255}); rlPopMatrix(); - // Draw Held Item + // Draw Held Item - Fixed pivot and attachment (Bug #3) int heldBT = hotbar[activeHotbarSlot].blockType; if (heldBT != AIR) { - Vector3 itemPos = Vector3Add(handPos, Vector3Scale(forwardVM, 0.12f)); - itemPos = Vector3Add(itemPos, Vector3Scale(upVM, 0.12f)); + // Calculate position at the end of the arm + // The arm is rotated by camPitch - 15.0f - swingVal * 20.0f + float armPitch = (camPitch * 180.0f/PI - 15.0f - swingVal * 20.0f) * PI/180.0f; + Vector3 armForward = { + forwardVM.x * cosf(-armPitch) - forwardVM.y * sinf(-armPitch), + forwardVM.x * sinf(-armPitch) + forwardVM.y * cosf(-armPitch), + forwardVM.z + }; // This is a simplification, but let's use the handPos + offset + + Vector3 itemPos = Vector3Add(handPos, Vector3Scale(forwardVM, 0.25f)); + itemPos = Vector3Add(itemPos, Vector3Scale(upVM, 0.05f)); itemPos = Vector3Add(itemPos, Vector3Scale(rightVM, -0.05f)); Texture2D itemTex = (heldBT == GRASS) ? grassTopTexture : (heldBT == CRAFTING_TABLE ? craftingSideTexture : blockTextures[heldBT]); @@ -3014,16 +3003,18 @@ int main(void) rlTranslatef(itemPos.x, itemPos.y, itemPos.z); rlRotatef(camYaw * 180.0f/PI + 45.0f, 0, 1, 0); rlRotatef(20.0f, 1, 0, 1); - DrawCubeVertices(0,0,0, 0.12f, 0.12f, 0.12f); + DrawCubeVertices(0,0,0, 0.12f, 0.12f, 0.12f, 63); rlPopMatrix(); rlSetTexture(0); } else { - // Item (Stick/Axe) as Billboard - Scaled larger for better visibility - DrawBillboard(camera3D, itemTex, itemPos, 0.35f, WHITE); + // Item (Stick/Axe) as Billboard + Rectangle src = { 0, 0, (float)itemTex.width, (float)itemTex.height }; + Vector2 itemSize = { 0.45f, 0.45f }; + // Pivot at bottom-left corner (Bug #3 fix) + // In DrawBillboardPro, origin (0,0) is center. Bottom-left is (-w/2, -h/2). + Vector2 pivot = { -itemSize.x/2.0f, -itemSize.y/2.0f }; + DrawBillboardPro(camera3D, itemTex, src, itemPos, camera3D.up, itemSize, pivot, -45.0f + swingVal * 40.0f, WHITE); } - } else { - // Fallback - DrawCube(itemPos, 0.1f, 0.1f, 0.1f, RED); } } rlPopMatrix(); @@ -3173,7 +3164,30 @@ int main(void) } if (hov && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { - if (IsKeyDown(KEY_LEFT_SHIFT) && !isResultSlot && slot.blockType != AIR) { + if (IsKeyDown(KEY_LEFT_SHIFT) && isResultSlot && slot.blockType != AIR) { + // Take everything possible from the result box + while (slot.blockType != AIR) { + GiveItems(slot.blockType, slot.count); + // Decrease ingredients + if (isTableResult) { + for(int i=0; i<9; i++) { + if (tableSlots[i].count > 0) tableSlots[i].count--; + if (tableSlots[i].count == 0) tableSlots[i].blockType = AIR; + } + UpdateTableCrafting(); + slot = tableResult; // Refresh from local reference + } else { + for(int i=0; i<4; i++) { + if (craftingSlots[i].count > 0) craftingSlots[i].count--; + if (craftingSlots[i].count == 0) craftingSlots[i].blockType = AIR; + } + UpdateCrafting(); + slot = craftingResult; + } + // Safety: if we can't craft anymore, break + if (slot.blockType == AIR) break; + } + } else if (IsKeyDown(KEY_LEFT_SHIFT) && !isResultSlot && slot.blockType != AIR) { // Pick up entire stack into hand immediately if (mouseHeldItem.blockType == AIR) { mouseHeldItem = slot; @@ -3313,7 +3327,7 @@ int main(void) // Close hint DrawTextEx(customFont, "Press E or ESC to close", (Vector2){ (float)(invPanelX + 12), (float)(invPanelY + invPanelH - 22) }, 14, 1.0f, (Color){160, 160, 160, 200}); - if (IsKeyPressed(KEY_ESCAPE) || IsKeyPressed(KEY_E)) { + if (IsKeyPressed(KEY_ESCAPE)) { inventoryOpen = false; DisableCursor(); } @@ -3343,7 +3357,7 @@ int main(void) drawInvGrid(guiX + 16, tableStartY + 3*(invSlotSize+invGap) + 40); - if (IsKeyPressed(KEY_ESCAPE) || IsKeyPressed(KEY_E)) { + if (IsKeyPressed(KEY_ESCAPE)) { currentState = GAMEPLAY; DisableCursor(); } diff --git a/version.txt b/version.txt index d7e8f8b..2a64493 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v2.2.7 +v2.2.9