diff options
Diffstat (limited to 'src/World.cpp')
-rw-r--r-- | src/World.cpp | 227 |
1 files changed, 133 insertions, 94 deletions
diff --git a/src/World.cpp b/src/World.cpp index 19eddbf..5b4bb03 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3,122 +3,128 @@ #include "DebugInfo.hpp" void World::ParseChunkData(std::shared_ptr<PacketChunkData> packet) { - StreamBuffer chunkData(packet->Data.data(), packet->Data.size()); - std::bitset<16> bitmask(packet->PrimaryBitMask); - for (int i = 0; i < 16; i++) { - if (bitmask[i]) { - Vector chunkPosition = Vector(packet->ChunkX, i, packet->ChunkZ); - Section section = ParseSection(&chunkData, chunkPosition); - + StreamBuffer chunkData(packet->Data.data(), packet->Data.size()); + std::bitset<16> bitmask(packet->PrimaryBitMask); + for (int i = 0; i < 16; i++) { + if (bitmask[i]) { + Vector chunkPosition = Vector(packet->ChunkX, i, packet->ChunkZ); + Section section = ParseSection(&chunkData, chunkPosition); + if (packet->GroundUpContinuous) { - if (!sections.insert(std::make_pair(chunkPosition, section)).second) { + if (!sections.insert(std::make_pair(chunkPosition, std::make_unique<Section>(section))).second) { LOG(ERROR) << "New chunk not created " << chunkPosition << " potential memory leak"; } - UpdateSectionList(); - } else { + UpdateSectionsList(); + } + else { using std::swap; - swap(sections.at(chunkPosition), section); + swap(*sections.at(chunkPosition).get(), section); } EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ chunkPosition }); } - } + } } Section World::ParseSection(StreamInput *data, Vector position) { - unsigned char bitsPerBlock = data->ReadUByte(); - - int paletteLength = data->ReadVarInt(); - std::vector<unsigned short> palette; - for (int i = 0; i < paletteLength; i++) { - palette.push_back(data->ReadVarInt()); - } - int dataArrayLength = data->ReadVarInt(); - auto dataArray = data->ReadByteArray(dataArrayLength * 8); - auto blockLight = data->ReadByteArray(2048); - std::vector<unsigned char> skyLight; - if (dimension == 0) - skyLight = data->ReadByteArray(2048); + unsigned char bitsPerBlock = data->ReadUByte(); + + int paletteLength = data->ReadVarInt(); + std::vector<unsigned short> palette; + for (int i = 0; i < paletteLength; i++) { + palette.push_back(data->ReadVarInt()); + } + int dataArrayLength = data->ReadVarInt(); + auto dataArray = data->ReadByteArray(dataArrayLength * 8); + auto blockLight = data->ReadByteArray(2048); + std::vector<unsigned char> skyLight; + if (dimension == 0) + skyLight = data->ReadByteArray(2048); long long *blockData = reinterpret_cast<long long*>(dataArray.data()); for (int i = 0; i < dataArray.size() / sizeof(long long); i++) endswap(blockData[i]); - std::vector<long long> blockArray (blockData, blockData + dataArray.size() / sizeof (long long)); + std::vector<long long> blockArray(blockData, blockData + dataArray.size() / sizeof(long long)); return Section(position, bitsPerBlock, std::move(palette), std::move(blockArray), std::move(blockLight), std::move(skyLight)); } World::~World() { - DebugInfo::totalSections = 0; } World::World() { } bool World::isPlayerCollides(double X, double Y, double Z) { - Vector PlayerChunk(floor(X / 16.0), floor(Y / 16.0), floor(Z / 16.0)); - if (sections.find(PlayerChunk) == sections.end() || sections.find(PlayerChunk - Vector(0,1,0)) == sections.end()) - return true; - std::vector<Vector> closestSectionsCoordinates = { - Vector(PlayerChunk.x, PlayerChunk.y, PlayerChunk.z), - Vector(PlayerChunk.x + 1, PlayerChunk.y, PlayerChunk.z), - Vector(PlayerChunk.x - 1, PlayerChunk.y, PlayerChunk.z), - Vector(PlayerChunk.x, PlayerChunk.y + 1, PlayerChunk.z), - Vector(PlayerChunk.x, PlayerChunk.y - 1, PlayerChunk.z), - Vector(PlayerChunk.x, PlayerChunk.y, PlayerChunk.z + 1), - Vector(PlayerChunk.x, PlayerChunk.y, PlayerChunk.z - 1), - }; - std::vector<Vector> closestSections; - for (auto &coord:closestSectionsCoordinates) { + Vector PlayerChunk(floor(X / 16.0), floor(Y / 16.0), floor(Z / 16.0)); + if (sections.find(PlayerChunk) == sections.end() || sections.find(PlayerChunk - Vector(0, 1, 0)) == sections.end()) + return false; + + std::vector<Vector> closestSectionsCoordinates = { + Vector(PlayerChunk.x, PlayerChunk.y, PlayerChunk.z), + Vector(PlayerChunk.x + 1, PlayerChunk.y, PlayerChunk.z), + Vector(PlayerChunk.x - 1, PlayerChunk.y, PlayerChunk.z), + Vector(PlayerChunk.x, PlayerChunk.y + 1, PlayerChunk.z), + Vector(PlayerChunk.x, PlayerChunk.y - 1, PlayerChunk.z), + Vector(PlayerChunk.x, PlayerChunk.y, PlayerChunk.z + 1), + Vector(PlayerChunk.x, PlayerChunk.y, PlayerChunk.z - 1), + }; + std::vector<Vector> closestSections; + for (auto &coord : closestSectionsCoordinates) { if (sections.find(coord) != sections.end()) closestSections.push_back(coord); - } - - for (auto &it:closestSections) { - - const double PlayerWidth = 0.6; - const double PlayerHeight = 1.82; - const double PlayerLength = 0.6; - - AABB playerColl; - playerColl.x = X - PlayerWidth / 2.0; - playerColl.w = PlayerWidth; - playerColl.y = Y; - playerColl.h = PlayerHeight; - playerColl.z = Z - PlayerLength / 2.0; - playerColl.l = PlayerLength; - - const Section §ion = *this->GetSection(it); - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - BlockId block = section.GetBlockId(Vector(x, y, z)); - if (block.id == 0 || block.id == 31) - continue; - AABB blockColl{(x + it.x * 16.0), - (y + it.y * 16.0), - (z + it.z * 16.0), 1, 1, 1}; - if (TestCollision(playerColl, blockColl)) - return true; - } - } - } - } - return false; -} - -const std::vector<Vector>& World::GetSectionsList() { - return sectionsList; + } + + for (auto &it : closestSections) { + + const double PlayerWidth = 0.6; + const double PlayerHeight = 1.82; + const double PlayerLength = 0.6; + + AABB playerColl; + playerColl.x = X - PlayerWidth / 2.0; + playerColl.w = PlayerWidth; + playerColl.y = Y; + playerColl.h = PlayerHeight; + playerColl.z = Z - PlayerLength / 2.0; + playerColl.l = PlayerLength; + + const Section §ion = this->GetSection(it); + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + BlockId block = section.GetBlockId(Vector(x, y, z)); + if (block.id == 0 || block.id == 31) + continue; + AABB blockColl{ (x + it.x * 16.0), + (y + it.y * 16.0), + (z + it.z * 16.0), 1, 1, 1 }; + if (TestCollision(playerColl, blockColl)) + return true; + } + } + } + } + return false; +} + +std::vector<Vector> World::GetSectionsList() { + sectionsListMutex.lock(); + auto vec = sectionsList; + sectionsListMutex.unlock(); + return vec; } static Section fallbackSection; -const Section* World::GetSection(Vector sectionPos) { +const Section &World::GetSection(Vector sectionPos) { auto result = sections.find(sectionPos); if (result == sections.end()) { - return nullptr; - } else { - return &result->second; + LOG(ERROR) << "Accessed not loaded section " << sectionPos; + return fallbackSection; + } + else { + return *result->second.get(); } } @@ -128,7 +134,7 @@ glm::vec3 World::Raycast(glm::vec3 position, glm::vec3 direction, float maxLengt void World::UpdatePhysics(float delta) { - //delta /= 5; + delta /= 5; entitiesMutex.lock(); for (auto& it : entities) { it.pos = it.pos + it.vel * delta; @@ -190,32 +196,32 @@ void World::DeleteEntity(unsigned int EntityId) } void World::ParseChunkData(std::shared_ptr<PacketBlockChange> packet) { - /*Block& block = this->GetBlock(packet->Position); - block = Block(packet->BlockId >> 4, packet->BlockId & 15, block.light, block.sky); + SetBlockId(packet->Position, BlockId{(unsigned short) (packet->BlockId >> 4),(unsigned char) (packet->BlockId & 0xF) }); + Vector sectionPos(std::floor(packet->Position.x / 16.0), std::floor(packet->Position.y / 16.0), std::floor(packet->Position.z / 16.0)); - EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ sectionPos });*/ + EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ sectionPos }); } void World::ParseChunkData(std::shared_ptr<PacketMultiBlockChange> packet) { - /*std::vector<Vector> changedSections; + std::vector<Vector> changedSections; for (auto& it : packet->Records) { int x = (it.HorizontalPosition >> 4 & 15) + (packet->ChunkX * 16); int y = it.YCoordinate; int z = (it.HorizontalPosition & 15) + (packet->ChunkZ * 16); Vector worldPos(x, y, z); - Block& block = GetBlock(worldPos); - block = Block(it.BlockId >> 4, it.BlockId & 15, block.light, block.sky); + SetBlockId(worldPos, BlockId{(unsigned short) (it.BlockId >> 4),(unsigned char) (it.BlockId & 0xF) }); Vector sectionPos(packet->ChunkX, std::floor(it.YCoordinate / 16.0), packet->ChunkZ); if (std::find(changedSections.begin(), changedSections.end(), sectionPos) == changedSections.end()) changedSections.push_back(sectionPos); } - for (auto& sectionPos: changedSections) - EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ sectionPos });*/ + + for (auto& sectionPos : changedSections) + EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ sectionPos }); } void World::ParseChunkData(std::shared_ptr<PacketUnloadChunk> packet) { - std::vector<std::map<Vector,Section>::iterator> toRemove; + std::vector<std::map<Vector, std::unique_ptr<Section>>::iterator> toRemove; for (auto it = sections.begin(); it != sections.end(); ++it) { if (it->first.x == packet->ChunkX && it->first.z == packet->ChunkZ) toRemove.push_back(it); @@ -224,12 +230,45 @@ void World::ParseChunkData(std::shared_ptr<PacketUnloadChunk> packet) { EventAgregator::PushEvent(EventType::ChunkDeleted, ChunkDeletedData{ it->first }); sections.erase(it); } - UpdateSectionList(); + UpdateSectionsList(); } -void World::UpdateSectionList() { +void World::UpdateSectionsList() { + sectionsListMutex.lock(); sectionsList.clear(); for (auto& it : sections) { sectionsList.push_back(it.first); } + sectionsListMutex.unlock(); +} + +BlockId World::GetBlockId(Vector pos) { + Vector sectionPos(std::floor(pos.x / 16.0), std::floor(pos.y / 16.0), std::floor(pos.z / 16.0)); + + Section* section = GetSectionPtr(sectionPos); + return section->GetBlockId(pos - (sectionPos * 16)); +} + +void World::SetBlockId(Vector pos, BlockId block) { + Vector sectionPos(std::floor(pos.x / 16.0), std::floor(pos.y / 16.0), std::floor(pos.z / 16.0)); + + Section* section = GetSectionPtr(sectionPos); + section->SetBlockId(pos - (sectionPos * 16), block); +} + +void World::SetBlockLight(Vector pos, unsigned char light) { + +} + +void World::SetBlockSkyLight(Vector pos, unsigned char light) { + +} + +Section *World::GetSectionPtr(Vector position) { + auto it = sections.find(position); + + if (it == sections.end()) + return nullptr; + + return it->second.get(); }
\ No newline at end of file |