Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Structures refactor #4

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions include/gameLayer/structure.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ struct StructureData

//data is held outside

BlockType &unsafeGet(int x, int y, int z)
BlockType& unsafeGet(int x, int y, int z)
{
assert(x >= 0 && y >= 0 && z >= 0 && x < size.x && y < size.y && z < size.z);

return ((BlockType*)(this + 1))[y + z * size.y + x * size.y*size.z];
return ((BlockType*)(this + 1))[y + z * size.y + x * size.y * size.z];
}

BlockType &unsafeGetRotated(int x, int y, int z, int r)
BlockType& unsafeGetRotated(int x, int y, int z, int r)
{
if (r == 0)
{
Expand All @@ -41,7 +41,7 @@ struct StructureData

}

BlockType *safeGet(int x, int y, int z)
BlockType* safeGet(int x, int y, int z)
{
if (x < 0 || y < 0 || z < 0 || x >= size.x || y >= size.y || z >= size.z)
{
Expand All @@ -58,16 +58,17 @@ struct StructuresManager
{

bool loadAllStructures();

std::vector<StructureData *> trees;
std::vector<StructureData *> jungleTrees;
std::vector<StructureData *> palmTrees;
std::vector<StructureData *> treeHouses;
std::vector<StructureData *> smallPyramids;
std::vector<StructureData *> birchTrees;
std::vector<StructureData *> igloos;
std::vector<StructureData *> spruceTrees;
std::vector<const char*> structurePaths = {
RESOURCES_PATH "gameData/structures/trees",
RESOURCES_PATH "gameData/structures/jungleTrees",
RESOURCES_PATH "gameData/structures/palm",
RESOURCES_PATH "gameData/structures/treeHouses",
RESOURCES_PATH "gameData/structures/smallpyramid",
RESOURCES_PATH "gameData/structures/birch",
RESOURCES_PATH "gameData/structures/igloo",
RESOURCES_PATH "gameData/structures/spruce"
};
std::vector<std::vector<StructureData*>> allStructures;

void clear();
};

};
114 changes: 33 additions & 81 deletions src/gameLayer/multyPlayer/serverChunkStorer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -886,102 +886,54 @@ bool ServerChunkStorer::generateStructure(StructureToGenerate s,
}

bool ServerChunkStorer::generateStructure(StructureToGenerate s,
StructuresManager &structureManager,
std::unordered_set<glm::ivec2, Ivec2Hash> &newCreatedChunks,
std::vector<SendBlocksBack> &sendNewBlocksToPlayers,
std::vector<glm::ivec3> *controlBlocks)
StructuresManager& structureManager,
std::unordered_set<glm::ivec2, Ivec2Hash>& newCreatedChunks,
std::vector<SendBlocksBack>& sendNewBlocksToPlayers,
std::vector<glm::ivec3>* controlBlocks)
{
auto chooseRandomElement = [](float randVal, int elementCount)
{
return int(floor(randVal * elementCount));
};


if (s.type == Structure_Tree)
{

auto tree = structureManager.trees
[chooseRandomElement(s.randomNumber1, structureManager.trees.size())];

return generateStructure(s, tree,
chooseRandomElement(s.randomNumber2, 4), newCreatedChunks, sendNewBlocksToPlayers,
controlBlocks);
}
else
if (s.type == Structure_JungleTree)
{

auto tree = structureManager.jungleTrees
[chooseRandomElement(s.randomNumber1, structureManager.jungleTrees.size())];

return generateStructure(s, tree, chooseRandomElement(s.randomNumber2, 4), newCreatedChunks, sendNewBlocksToPlayers, controlBlocks);
}if (s.type == Structure_PalmTree)
{

auto tree = structureManager.palmTrees
[chooseRandomElement(s.randomNumber1, structureManager.palmTrees.size())];

return generateStructure(s, tree, chooseRandomElement(s.randomNumber2, 4), newCreatedChunks,
sendNewBlocksToPlayers, controlBlocks);

}if (s.type == Structure_TreeHouse)
{

auto tree = structureManager.treeHouses
[chooseRandomElement(s.randomNumber1, structureManager.treeHouses.size())];

return generateStructure(s, tree, chooseRandomElement(s.randomNumber2, 4), newCreatedChunks,
sendNewBlocksToPlayers, controlBlocks);

}if (s.type == Structure_Pyramid)
{

auto tree = structureManager.smallPyramids
[chooseRandomElement(s.randomNumber1, structureManager.smallPyramids.size())];

return generateStructure(s, tree, chooseRandomElement(s.randomNumber2, 4), newCreatedChunks,
sendNewBlocksToPlayers, controlBlocks);

}if (s.type == Structure_BirchTree)
{
auto tree = structureManager.birchTrees
[chooseRandomElement(s.randomNumber1, structureManager.birchTrees.size())];

return generateStructure(s, tree, chooseRandomElement(s.randomNumber2, 4),
newCreatedChunks, sendNewBlocksToPlayers, controlBlocks);

}if (s.type == Structure_Igloo)
{
auto tree = structureManager.igloos
[chooseRandomElement(s.randomNumber1, structureManager.igloos.size())];

return generateStructure(s, tree, chooseRandomElement(s.randomNumber2, 4),
newCreatedChunks, sendNewBlocksToPlayers, controlBlocks);

}
if (s.type == Structure_Spruce)
auto chooseRandomElement = [](float randVal, int elementCount)
{
auto tree = structureManager.spruceTrees
[chooseRandomElement(s.randomNumber1, structureManager.spruceTrees.size())];
static std::random_device rd;
static std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(0, elementCount - 1);
return dist(gen);
};

// Map structure types to indices in the allStructures vector
const std::unordered_map<int, size_t> typeToIndex = {
{Structure_Tree, 0},
{Structure_JungleTree, 1},
{Structure_PalmTree, 2},
{Structure_TreeHouse, 3},
{Structure_Pyramid, 4},
{Structure_BirchTree, 5},
{Structure_Igloo, 6},
{Structure_Spruce, 7}
};

if (s.randomNumber3 > 0.5)
{
auto it = typeToIndex.find(s.type);
if (it != typeToIndex.end()) {
size_t index = it->second;
const auto& structures = structureManager.allStructures[index];
if (!structures.empty()) {
auto tree = structures[chooseRandomElement(s.randomNumber1, structures.size())];
if (s.type == Structure_Spruce && s.randomNumber3 > 0.5) {
return generateStructure(s, tree, chooseRandomElement(s.randomNumber2, 4),
newCreatedChunks, sendNewBlocksToPlayers, controlBlocks, true,
BlockTypes::spruce_leaves, BlockTypes::spruce_leaves_red);
}
else
{
else {
return generateStructure(s, tree, chooseRandomElement(s.randomNumber2, 4),
newCreatedChunks, sendNewBlocksToPlayers, controlBlocks);
}

}
}


return 0;
return false;
}


Block *ServerChunkStorer::getBlockSafe(glm::ivec3 pos)
{
auto c = getChunkOrGetNull(divideChunk(pos.x), divideChunk(pos.z));
Expand Down
115 changes: 31 additions & 84 deletions src/gameLayer/structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,106 +4,53 @@

bool StructuresManager::loadAllStructures()
{

auto loadFolder = [](const char *path, std::vector<StructureData*> &structures)
for (const char* path : structurePaths)
{
auto it = std::filesystem::directory_iterator(path); //todo check errors
for (const auto &entry : it)
{
if (entry.is_regular_file())
{
size_t s = 0;
std::vector<StructureData*> structures;

sfs::getFileSize(entry.path().string().c_str(), s);
auto it = std::filesystem::directory_iterator(path);

if (s < sizeof(StructureData))
{
return 0;
}
for (const auto& entry : it)
{
if (!entry.is_regular_file())
continue;

unsigned char *sData = new unsigned char[s];
size_t s = 0;
sfs::getFileSize(entry.path().string().c_str(), s);

if (sfs::readEntireFile(sData, s, entry.path().string().c_str(), true) != sfs::noError)
{
return 0;
}
if (s < sizeof(StructureData))
return false;

structures.push_back((StructureData *)sData);
}
}
};
unsigned char* sData = new unsigned char[s];
if (sfs::readEntireFile(sData, s, entry.path().string().c_str(), true) != sfs::noError)
return false;

loadFolder(RESOURCES_PATH "gameData/structures/trees", trees);
loadFolder(RESOURCES_PATH "gameData/structures/jungleTrees", jungleTrees);
loadFolder(RESOURCES_PATH "gameData/structures/palm", palmTrees);
loadFolder(RESOURCES_PATH "gameData/structures/treeHouses", treeHouses);
loadFolder(RESOURCES_PATH "gameData/structures/smallpyramid", smallPyramids);
loadFolder(RESOURCES_PATH "gameData/structures/birch", birchTrees);
loadFolder(RESOURCES_PATH "gameData/structures/igloo", igloos);
loadFolder(RESOURCES_PATH "gameData/structures/spruce", spruceTrees);

structures.push_back((StructureData*)sData);
}
allStructures.push_back(std::move(structures));
}

if (trees.empty()) { return 0; }
if (jungleTrees.empty()) { return 0; }
if (palmTrees.empty()) { return 0; }
if (treeHouses.empty()) { return 0; }
if (smallPyramids.empty()) { return 0; }
if (birchTrees.empty()) { return 0; }
if (igloos.empty()) { return 0; }
if (spruceTrees.empty()) { return 0; }
for (const auto& structures : allStructures)
{
if (structures.empty())
return false;
}

return true;
}

void StructuresManager::clear()
{
for (auto &i : trees)
for (auto& structures : allStructures)
{
unsigned char *d = (unsigned char*)i;
delete[] d;
}

for (auto &i : jungleTrees)
{
unsigned char *d = (unsigned char *)i;
delete[] d;
}

for (auto &i : palmTrees)
{
unsigned char *d = (unsigned char *)i;
delete[] d;
}

for (auto &i : treeHouses)
{
unsigned char *d = (unsigned char *)i;
delete[] d;
}

for (auto &i : smallPyramids)
{
unsigned char *d = (unsigned char *)i;
delete[] d;
}

for (auto &i : birchTrees)
{
unsigned char *d = (unsigned char *)i;
delete[] d;
}

for (auto &i : igloos)
{
unsigned char *d = (unsigned char *)i;
delete[] d;
}

for (auto &i : spruceTrees)
{
unsigned char *d = (unsigned char *)i;
delete[] d;
for (auto& structure : structures)
{
unsigned char* d = reinterpret_cast<unsigned char*>(structure);
delete[] d;
}
structures.clear();
}
allStructures.clear();

*this = {};
}