#include "Chunk.h" #include "Constants.h" #include "Globals.h" #include "Registries.h" Chunk::Chunk(Framework::Punkt location) : ReferenceCounter(), location(location), isLoading(0) {} Chunk::Chunk(Framework::Punkt location, Framework::StreamReader* zReader) : Chunk(location) { load(zReader); } Chunk::~Chunk() {} void Chunk::api(char* message) { // TODO: implement api } Block* Chunk::zBlockAt(Framework::Vec3 location) { cs.lock(); for (Block* b : blocks) { if (Framework::Vec3((int)floor(b->getPos().x), (int)floor(b->getPos().y), (int)floor(b->getPos().z)) == location) { cs.unlock(); return b; } } cs.unlock(); return 0; } void Chunk::setBlock(Block* block) { cs.lock(); Framework::Vec3 pos = (Framework::Vec3)block->getPos(); for (Framework::Iterator iterator = blocks.begin(); iterator; iterator++) { if (pos == (Framework::Vec3)iterator->getPos()) { iterator->release(); iterator.set(block); cs.unlock(); return; } } blocks.add(block); cs.unlock(); if (!isLoading) updateVisibility(); } void Chunk::removeBlock(Block* zBlock) { cs.lock(); int index = 0; for (Framework::Iterator iterator = blocks.begin(); iterator; iterator++, index++) { if (zBlock == (Block*)iterator) { blocks.remove(index); cs.unlock(); if (!isLoading) updateVisibility(); return; } } cs.unlock(); } void Chunk::load(Framework::StreamReader* zReader) { isLoading = 1; Framework::Vec3 pos = { 0, 0, 0 }; unsigned short id; zReader->lese((char*)&id, 2); while (id) { zReader->lese((char*)&pos.x, 4); zReader->lese((char*)&pos.y, 4); zReader->lese((char*)&pos.z, 4); if (blockTypes[id]->doesNeedInstance()) setBlock(blockTypes[id]->createBlock({ pos.x + location.x - CHUNK_SIZE / 2, pos.y + location.y - CHUNK_SIZE / 2, pos.z })); zReader->lese((char*)&id, 2); } isLoading = 0; updateVisibility(); } Framework::Punkt Chunk::getCenter() const { return location; } Framework::Vec3 Chunk::getMin() const { return { location.x - CHUNK_SIZE / 2, location.y - CHUNK_SIZE / 2, 0 }; } Framework::Vec3 Chunk::getMax() const { return { location.x + CHUNK_SIZE / 2, location.y + CHUNK_SIZE / 2, WORLD_HEIGHT }; } void Chunk::forAll(std::function f) { cs.lock(); for (Block* b : blocks) f(b); cs.unlock(); } void Chunk::updateVisibility() { cs.lock(); for (Block* b : blocks) { Framework::Vec3 pos = Framework::Vec3((int)floor(b->getPos().x), (int)floor(b->getPos().y), (int)floor(b->getPos().z)); for (int i = 0; i < 6; i++) { Block* c = zBlockAt(pos + getDirection(getDirectionFromIndex(i))); b->setSideVisible(getDirectionFromIndex(i), !c || c->isTransparent()); } } cs.unlock(); }