format fix

This commit is contained in:
MihailRis 2024-05-17 21:37:02 +03:00
parent a93906d0f1
commit 7957a12b84

View File

@ -16,62 +16,67 @@
#include <limits.h> #include <limits.h>
#include <vector> #include <vector>
Chunks::Chunks(uint32_t w, uint32_t d, Chunks::Chunks(
int32_t ox, int32_t oz, uint32_t w, uint32_t d,
WorldFiles* wfile, int32_t ox, int32_t oz,
LevelEvents* events, WorldFiles* wfile,
const Content* content) LevelEvents* events,
: contentIds(content->getIndices()), const Content* content
chunks(w*d), ) : contentIds(content->getIndices()),
chunksSecond(w*d), chunks(w*d),
w(w), d(d), ox(ox), oz(oz), chunksSecond(w*d),
worldFiles(wfile), w(w), d(d), ox(ox), oz(oz),
events(events) { worldFiles(wfile),
volume = (size_t)w*(size_t)d; events(events)
chunksCount = 0; {
volume = static_cast<size_t>(w)*static_cast<size_t>(d);
chunksCount = 0;
} }
voxel* Chunks::get(int32_t x, int32_t y, int32_t z) { voxel* Chunks::get(int32_t x, int32_t y, int32_t z) {
x -= ox * CHUNK_W; x -= ox * CHUNK_W;
z -= oz * CHUNK_D; z -= oz * CHUNK_D;
int cx = floordiv(x, CHUNK_W); int cx = floordiv(x, CHUNK_W);
int cy = floordiv(y, CHUNK_H); int cy = floordiv(y, CHUNK_H);
int cz = floordiv(z, CHUNK_D); int cz = floordiv(z, CHUNK_D);
if (cx < 0 || cy < 0 || cz < 0 || cx >= int(w) || cy >= 1 || cz >= int(d)) if (cx < 0 || cy < 0 || cz < 0 || cx >= int(w) || cy >= 1 || cz >= int(d)) {
return nullptr; return nullptr;
auto& chunk = chunks[cz * w + cx]; // not thread safe }
if (chunk == nullptr) auto& chunk = chunks[cz * w + cx]; // not thread safe
return nullptr; if (chunk == nullptr) {
int lx = x - cx * CHUNK_W; return nullptr;
int ly = y - cy * CHUNK_H; }
int lz = z - cz * CHUNK_D; int lx = x - cx * CHUNK_W;
return &chunk->voxels[(ly * CHUNK_D + lz) * CHUNK_W + lx]; int ly = y - cy * CHUNK_H;
int lz = z - cz * CHUNK_D;
return &chunk->voxels[(ly * CHUNK_D + lz) * CHUNK_W + lx];
} }
const AABB* Chunks::isObstacleAt(float x, float y, float z){ const AABB* Chunks::isObstacleAt(float x, float y, float z){
int ix = floor(x); int ix = floor(x);
int iy = floor(y); int iy = floor(y);
int iz = floor(z); int iz = floor(z);
voxel* v = get(ix, iy, iz); voxel* v = get(ix, iy, iz);
if (v == nullptr) { if (v == nullptr) {
if (iy >= CHUNK_H) { if (iy >= CHUNK_H) {
return nullptr; return nullptr;
} else { } else {
static const AABB empty; static const AABB empty;
return &empty; return &empty;
}
}
const Block* def = contentIds->getBlockDef(v->id);
if (def->obstacle) {
const auto& boxes = def->rotatable
? def->rt.hitboxes[v->rotation()]
: def->hitboxes;
for (const auto& hitbox : boxes) {
if (hitbox.contains({x - ix, y - iy, z - iz}))
return &hitbox;
} }
} }
return nullptr; const Block* def = contentIds->getBlockDef(v->id);
if (def->obstacle) {
const auto& boxes = def->rotatable
? def->rt.hitboxes[v->rotation()]
: def->hitboxes;
for (const auto& hitbox : boxes) {
if (hitbox.contains({x - ix, y - iy, z - iz})) {
return &hitbox;
}
}
}
return nullptr;
} }
bool Chunks::isSolidBlock(int32_t x, int32_t y, int32_t z) { bool Chunks::isSolidBlock(int32_t x, int32_t y, int32_t z) {
@ -89,159 +94,166 @@ bool Chunks::isReplaceableBlock(int32_t x, int32_t y, int32_t z) {
} }
bool Chunks::isObstacleBlock(int32_t x, int32_t y, int32_t z) { bool Chunks::isObstacleBlock(int32_t x, int32_t y, int32_t z) {
voxel* v = get(x, y, z); voxel* v = get(x, y, z);
if (v == nullptr) if (v == nullptr)
return false; return false;
return contentIds->getBlockDef(v->id)->obstacle; return contentIds->getBlockDef(v->id)->obstacle;
} }
ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel){ ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel){
x -= ox * CHUNK_W; x -= ox * CHUNK_W;
z -= oz * CHUNK_D; z -= oz * CHUNK_D;
int cx = floordiv(x, CHUNK_W); int cx = floordiv(x, CHUNK_W);
int cy = floordiv(y, CHUNK_H); int cy = floordiv(y, CHUNK_H);
int cz = floordiv(z, CHUNK_D); int cz = floordiv(z, CHUNK_D);
if (cx < 0 || cy < 0 || cz < 0 || cx >= int(w) || cy >= 1 || cz >= int(d)) if (cx < 0 || cy < 0 || cz < 0 || cx >= int(w) || cy >= 1 || cz >= int(d)) {
return 0; return 0;
const auto& chunk = chunks[(cy * d + cz) * w + cx]; }
if (chunk == nullptr) const auto& chunk = chunks[(cy * d + cz) * w + cx];
return 0; if (chunk == nullptr) {
int lx = x - cx * CHUNK_W; return 0;
int ly = y - cy * CHUNK_H; }
int lz = z - cz * CHUNK_D; int lx = x - cx * CHUNK_W;
return chunk->lightmap.get(lx, ly, lz, channel); int ly = y - cy * CHUNK_H;
int lz = z - cz * CHUNK_D;
return chunk->lightmap.get(lx, ly, lz, channel);
} }
light_t Chunks::getLight(int32_t x, int32_t y, int32_t z){ light_t Chunks::getLight(int32_t x, int32_t y, int32_t z){
x -= ox * CHUNK_W; x -= ox * CHUNK_W;
z -= oz * CHUNK_D; z -= oz * CHUNK_D;
int cx = floordiv(x, CHUNK_W); int cx = floordiv(x, CHUNK_W);
int cy = floordiv(y, CHUNK_H); int cy = floordiv(y, CHUNK_H);
int cz = floordiv(z, CHUNK_D); int cz = floordiv(z, CHUNK_D);
if (cx < 0 || cy < 0 || cz < 0 || cx >= int(w) || cy >= 1 || cz >= int(d)) if (cx < 0 || cy < 0 || cz < 0 || cx >= int(w) || cy >= 1 || cz >= int(d)) {
return 0; return 0;
const auto& chunk = chunks[(cy * d + cz) * w + cx]; }
if (chunk == nullptr) const auto& chunk = chunks[(cy * d + cz) * w + cx];
return 0; if (chunk == nullptr) {
int lx = x - cx * CHUNK_W; return 0;
int ly = y - cy * CHUNK_H; }
int lz = z - cz * CHUNK_D; int lx = x - cx * CHUNK_W;
return chunk->lightmap.get(lx,ly,lz); int ly = y - cy * CHUNK_H;
int lz = z - cz * CHUNK_D;
return chunk->lightmap.get(lx,ly,lz);
} }
Chunk* Chunks::getChunkByVoxel(int32_t x, int32_t y, int32_t z){ Chunk* Chunks::getChunkByVoxel(int32_t x, int32_t y, int32_t z) {
if (y < 0 || y >= CHUNK_H) if (y < 0 || y >= CHUNK_H)
return nullptr; return nullptr;
x -= ox * CHUNK_W; x -= ox * CHUNK_W;
z -= oz * CHUNK_D; z -= oz * CHUNK_D;
int cx = floordiv(x, CHUNK_W); int cx = floordiv(x, CHUNK_W);
int cz = floordiv(z, CHUNK_D); int cz = floordiv(z, CHUNK_D);
if (cx < 0 || cz < 0 || cx >= int(w) || cz >= int(d)) if (cx < 0 || cz < 0 || cx >= int(w) || cz >= int(d))
return nullptr; return nullptr;
return chunks[cz * w + cx].get(); return chunks[cz * w + cx].get();
} }
Chunk* Chunks::getChunk(int x, int z){ Chunk* Chunks::getChunk(int x, int z){
x -= ox; x -= ox;
z -= oz; z -= oz;
if (x < 0 || z < 0 || x >= int(w) || z >= int(d)) if (x < 0 || z < 0 || x >= int(w) || z >= int(d))
return nullptr; return nullptr;
return chunks[z * w + x].get(); return chunks[z * w + x].get();
} }
void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, uint8_t states){ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, uint8_t states) {
if (y < 0 || y >= CHUNK_H) if (y < 0 || y >= CHUNK_H)
return; return;
x -= ox * CHUNK_W; x -= ox * CHUNK_W;
z -= oz * CHUNK_D; z -= oz * CHUNK_D;
int cx = floordiv(x, CHUNK_W); int cx = floordiv(x, CHUNK_W);
int cz = floordiv(z, CHUNK_D); int cz = floordiv(z, CHUNK_D);
if (cx < 0 || cz < 0 || cx >= int(w) || cz >= int(d)) if (cx < 0 || cz < 0 || cx >= int(w) || cz >= int(d))
return; return;
Chunk* chunk = chunks[cz * w + cx].get(); Chunk* chunk = chunks[cz * w + cx].get();
if (chunk == nullptr) if (chunk == nullptr)
return; return;
int lx = x - cx * CHUNK_W; int lx = x - cx * CHUNK_W;
int lz = z - cz * CHUNK_D; int lz = z - cz * CHUNK_D;
voxel& vox = chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx]; voxel& vox = chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx];
auto def = contentIds->getBlockDef(vox.id); auto def = contentIds->getBlockDef(vox.id);
if (def->inventorySize == 0) if (def->inventorySize == 0)
chunk->removeBlockInventory(lx, y, lz); chunk->removeBlockInventory(lx, y, lz);
vox.id = id; vox.id = id;
vox.states = states; vox.states = states;
chunk->setUnsaved(true); chunk->setUnsaved(true);
chunk->setModified(true); chunk->setModified(true);
if (y < chunk->bottom) chunk->bottom = y; if (y < chunk->bottom) chunk->bottom = y;
else if (y + 1 > chunk->top) chunk->top = y + 1; else if (y + 1 > chunk->top) chunk->top = y + 1;
else if (id == 0) chunk->updateHeights(); else if (id == 0) chunk->updateHeights();
if (lx == 0 && (chunk = getChunk(cx+ox-1, cz+oz))) if (lx == 0 && (chunk = getChunk(cx+ox-1, cz+oz)))
chunk->setModified(true); chunk->setModified(true);
if (lz == 0 && (chunk = getChunk(cx+ox, cz+oz-1))) if (lz == 0 && (chunk = getChunk(cx+ox, cz+oz-1)))
chunk->setModified(true); chunk->setModified(true);
if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cz+oz))) if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cz+oz)))
chunk->setModified(true); chunk->setModified(true);
if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cz+oz+1))) if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cz+oz+1)))
chunk->setModified(true); chunk->setModified(true);
} }
voxel* Chunks::rayCast(glm::vec3 start, voxel* Chunks::rayCast(
glm::vec3 dir, glm::vec3 start,
float maxDist, glm::vec3 dir,
glm::vec3& end, float maxDist,
glm::ivec3& norm, glm::vec3& end,
glm::ivec3& iend) { glm::ivec3& norm,
float px = start.x; glm::ivec3& iend
float py = start.y; ) {
float pz = start.z; float px = start.x;
float py = start.y;
float pz = start.z;
float dx = dir.x; float dx = dir.x;
float dy = dir.y; float dy = dir.y;
float dz = dir.z; float dz = dir.z;
float t = 0.0f; float t = 0.0f;
int ix = floor(px); int ix = floor(px);
int iy = floor(py); int iy = floor(py);
int iz = floor(pz); int iz = floor(pz);
int stepx = (dx > 0.0f) ? 1 : -1; int stepx = (dx > 0.0f) ? 1 : -1;
int stepy = (dy > 0.0f) ? 1 : -1; int stepy = (dy > 0.0f) ? 1 : -1;
int stepz = (dz > 0.0f) ? 1 : -1; int stepz = (dz > 0.0f) ? 1 : -1;
constexpr float infinity = std::numeric_limits<float>::infinity(); constexpr float infinity = std::numeric_limits<float>::infinity();
float txDelta = (dx == 0.0f) ? infinity : abs(1.0f / dx); float txDelta = (dx == 0.0f) ? infinity : abs(1.0f / dx);
float tyDelta = (dy == 0.0f) ? infinity : abs(1.0f / dy); float tyDelta = (dy == 0.0f) ? infinity : abs(1.0f / dy);
float tzDelta = (dz == 0.0f) ? infinity : abs(1.0f / dz); float tzDelta = (dz == 0.0f) ? infinity : abs(1.0f / dz);
float xdist = (stepx > 0) ? (ix + 1 - px) : (px - ix); float xdist = (stepx > 0) ? (ix + 1 - px) : (px - ix);
float ydist = (stepy > 0) ? (iy + 1 - py) : (py - iy); float ydist = (stepy > 0) ? (iy + 1 - py) : (py - iy);
float zdist = (stepz > 0) ? (iz + 1 - pz) : (pz - iz); float zdist = (stepz > 0) ? (iz + 1 - pz) : (pz - iz);
float txMax = (txDelta < infinity) ? txDelta * xdist : infinity; float txMax = (txDelta < infinity) ? txDelta * xdist : infinity;
float tyMax = (tyDelta < infinity) ? tyDelta * ydist : infinity; float tyMax = (tyDelta < infinity) ? tyDelta * ydist : infinity;
float tzMax = (tzDelta < infinity) ? tzDelta * zdist : infinity; float tzMax = (tzDelta < infinity) ? tzDelta * zdist : infinity;
int steppedIndex = -1; int steppedIndex = -1;
while (t <= maxDist){ while (t <= maxDist){
voxel* voxel = get(ix, iy, iz); voxel* voxel = get(ix, iy, iz);
if (voxel == nullptr){ return nullptr; } if (voxel == nullptr){
return nullptr;
const Block* def = contentIds->getBlockDef(voxel->id); }
if (def->selectable){ const Block* def = contentIds->getBlockDef(voxel->id);
end.x = px + t * dx; if (def->selectable){
end.y = py + t * dy; end.x = px + t * dx;
end.z = pz + t * dz; end.y = py + t * dy;
iend.x = ix; end.z = pz + t * dz;
iend.y = iy; iend.x = ix;
iend.z = iz; iend.y = iy;
iend.z = iz;
if (!def->rt.solid) {
if (!def->rt.solid) {
const std::vector<AABB>& hitboxes = def->rotatable const std::vector<AABB>& hitboxes = def->rotatable
? def->rt.hitboxes[voxel->rotation()] ? def->rt.hitboxes[voxel->rotation()]
: def->hitboxes; : def->hitboxes;
@ -253,7 +265,7 @@ voxel* Chunks::rayCast(glm::vec3 start,
for (const auto& box : hitboxes) { for (const auto& box : hitboxes) {
scalar_t boxDistance; scalar_t boxDistance;
glm::ivec3 boxNorm; glm::ivec3 boxNorm;
if (ray.intersectAABB(iend, box, maxDist, boxNorm, boxDistance) > RayRelation::None && boxDistance < distance) { if (ray.intersectAABB(iend, box, maxDist, boxNorm, boxDistance) > RayRelation::None && boxDistance < distance) {
hit = true; hit = true;
distance = boxDistance; distance = boxDistance;
@ -263,94 +275,95 @@ voxel* Chunks::rayCast(glm::vec3 start,
} }
if (hit) return voxel; if (hit) return voxel;
} else { } else {
iend.x = ix; iend.x = ix;
iend.y = iy; iend.y = iy;
iend.z = iz; iend.z = iz;
norm.x = norm.y = norm.z = 0; norm.x = norm.y = norm.z = 0;
if (steppedIndex == 0) norm.x = -stepx; if (steppedIndex == 0) norm.x = -stepx;
if (steppedIndex == 1) norm.y = -stepy; if (steppedIndex == 1) norm.y = -stepy;
if (steppedIndex == 2) norm.z = -stepz; if (steppedIndex == 2) norm.z = -stepz;
return voxel; return voxel;
} }
} }
if (txMax < tyMax) { if (txMax < tyMax) {
if (txMax < tzMax) { if (txMax < tzMax) {
ix += stepx; ix += stepx;
t = txMax; t = txMax;
txMax += txDelta; txMax += txDelta;
steppedIndex = 0; steppedIndex = 0;
} else { } else {
iz += stepz; iz += stepz;
t = tzMax; t = tzMax;
tzMax += tzDelta; tzMax += tzDelta;
steppedIndex = 2; steppedIndex = 2;
} }
} else { } else {
if (tyMax < tzMax) { if (tyMax < tzMax) {
iy += stepy; iy += stepy;
t = tyMax; t = tyMax;
tyMax += tyDelta; tyMax += tyDelta;
steppedIndex = 1; steppedIndex = 1;
} else { } else {
iz += stepz; iz += stepz;
t = tzMax; t = tzMax;
tzMax += tzDelta; tzMax += tzDelta;
steppedIndex = 2; steppedIndex = 2;
} }
} }
} }
iend.x = ix; iend.x = ix;
iend.y = iy; iend.y = iy;
iend.z = iz; iend.z = iz;
end.x = px + t * dx; end.x = px + t * dx;
end.y = py + t * dy; end.y = py + t * dy;
end.z = pz + t * dz; end.z = pz + t * dz;
norm.x = norm.y = norm.z = 0; norm.x = norm.y = norm.z = 0;
return nullptr; return nullptr;
} }
glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDist) { glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDist) {
float px = start.x; float px = start.x;
float py = start.y; float py = start.y;
float pz = start.z; float pz = start.z;
float dx = dir.x; float dx = dir.x;
float dy = dir.y; float dy = dir.y;
float dz = dir.z; float dz = dir.z;
float t = 0.0f; float t = 0.0f;
int ix = floor(px); int ix = floor(px);
int iy = floor(py); int iy = floor(py);
int iz = floor(pz); int iz = floor(pz);
int stepx = (dx > 0.0f) ? 1 : -1; int stepx = (dx > 0.0f) ? 1 : -1;
int stepy = (dy > 0.0f) ? 1 : -1; int stepy = (dy > 0.0f) ? 1 : -1;
int stepz = (dz > 0.0f) ? 1 : -1; int stepz = (dz > 0.0f) ? 1 : -1;
constexpr float infinity = std::numeric_limits<float>::infinity(); constexpr float infinity = std::numeric_limits<float>::infinity();
float txDelta = (dx == 0.0f) ? infinity : abs(1.0f / dx); float txDelta = (dx == 0.0f) ? infinity : abs(1.0f / dx);
float tyDelta = (dy == 0.0f) ? infinity : abs(1.0f / dy); float tyDelta = (dy == 0.0f) ? infinity : abs(1.0f / dy);
float tzDelta = (dz == 0.0f) ? infinity : abs(1.0f / dz); float tzDelta = (dz == 0.0f) ? infinity : abs(1.0f / dz);
float xdist = (stepx > 0) ? (ix + 1 - px) : (px - ix); float xdist = (stepx > 0) ? (ix + 1 - px) : (px - ix);
float ydist = (stepy > 0) ? (iy + 1 - py) : (py - iy); float ydist = (stepy > 0) ? (iy + 1 - py) : (py - iy);
float zdist = (stepz > 0) ? (iz + 1 - pz) : (pz - iz); float zdist = (stepz > 0) ? (iz + 1 - pz) : (pz - iz);
float txMax = (txDelta < infinity) ? txDelta * xdist : infinity; float txMax = (txDelta < infinity) ? txDelta * xdist : infinity;
float tyMax = (tyDelta < infinity) ? tyDelta * ydist : infinity; float tyMax = (tyDelta < infinity) ? tyDelta * ydist : infinity;
float tzMax = (tzDelta < infinity) ? tzDelta * zdist : infinity; float tzMax = (tzDelta < infinity) ? tzDelta * zdist : infinity;
while (t <= maxDist) { while (t <= maxDist) {
voxel* voxel = get(ix, iy, iz); voxel* voxel = get(ix, iy, iz);
if (voxel == nullptr) { return glm::vec3(px + t * dx, py + t * dy, pz + t * dz); } if (voxel == nullptr) {
return glm::vec3(px + t * dx, py + t * dy, pz + t * dz);
const Block* def = contentIds->getBlockDef(voxel->id); }
if (def->obstacle) { const Block* def = contentIds->getBlockDef(voxel->id);
if (!def->rt.solid) { if (def->obstacle) {
if (!def->rt.solid) {
const std::vector<AABB>& hitboxes = def->rotatable const std::vector<AABB>& hitboxes = def->rotatable
? def->rt.hitboxes[voxel->rotation()] ? def->rt.hitboxes[voxel->rotation()]
: def->modelBoxes; : def->modelBoxes;
@ -365,98 +378,98 @@ glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDis
return start + (dir * glm::vec3(distance)); return start + (dir * glm::vec3(distance));
} }
} }
} }
else { else {
return glm::vec3(px + t * dx, py + t * dy, pz + t * dz); return glm::vec3(px + t * dx, py + t * dy, pz + t * dz);
} }
} }
if (txMax < tyMax) { if (txMax < tyMax) {
if (txMax < tzMax) { if (txMax < tzMax) {
ix += stepx; ix += stepx;
t = txMax; t = txMax;
txMax += txDelta; txMax += txDelta;
} }
else { else {
iz += stepz; iz += stepz;
t = tzMax; t = tzMax;
tzMax += tzDelta; tzMax += tzDelta;
} }
} }
else { else {
if (tyMax < tzMax) { if (tyMax < tzMax) {
iy += stepy; iy += stepy;
t = tyMax; t = tyMax;
tyMax += tyDelta; tyMax += tyDelta;
} }
else { else {
iz += stepz; iz += stepz;
t = tzMax; t = tzMax;
tzMax += tzDelta; tzMax += tzDelta;
} }
} }
} }
return glm::vec3(px + maxDist * dx, py + maxDist * dy, pz + maxDist * dz); return glm::vec3(px + maxDist * dx, py + maxDist * dy, pz + maxDist * dz);
} }
void Chunks::setCenter(int32_t x, int32_t z) { void Chunks::setCenter(int32_t x, int32_t z) {
int cx = floordiv(x, CHUNK_W); int cx = floordiv(x, CHUNK_W);
int cz = floordiv(z, CHUNK_D); int cz = floordiv(z, CHUNK_D);
cx -= ox + w / 2; cx -= ox + w / 2;
cz -= oz + d / 2; cz -= oz + d / 2;
if (cx | cz) { if (cx | cz) {
translate(cx,cz); translate(cx,cz);
} }
} }
void Chunks::translate(int32_t dx, int32_t dz) { void Chunks::translate(int32_t dx, int32_t dz) {
auto& regions = worldFiles->getRegions(); auto& regions = worldFiles->getRegions();
for (uint i = 0; i < volume; i++){ for (uint i = 0; i < volume; i++){
chunksSecond[i] = nullptr; chunksSecond[i] = nullptr;
} }
for (uint32_t z = 0; z < d; z++){ for (uint32_t z = 0; z < d; z++) {
for (uint32_t x = 0; x < w; x++){ for (uint32_t x = 0; x < w; x++) {
auto chunk = chunks[z * w + x]; auto chunk = chunks[z * w + x];
int nx = x - dx; int nx = x - dx;
int nz = z - dz; int nz = z - dz;
if (chunk == nullptr) if (chunk == nullptr)
continue; continue;
if (nx < 0 || nz < 0 || nx >= int(w) || nz >= int(d)){ if (nx < 0 || nz < 0 || nx >= int(w) || nz >= int(d)) {
events->trigger(EVT_CHUNK_HIDDEN, chunk.get()); events->trigger(EVT_CHUNK_HIDDEN, chunk.get());
regions.put(chunk.get()); regions.put(chunk.get());
chunksCount--; chunksCount--;
continue; continue;
} }
chunksSecond[nz * w + nx] = chunk; chunksSecond[nz * w + nx] = chunk;
} }
} }
std::swap(chunks, chunksSecond); std::swap(chunks, chunksSecond);
ox += dx; ox += dx;
oz += dz; oz += dz;
} }
void Chunks::resize(uint32_t newW, uint32_t newD) { void Chunks::resize(uint32_t newW, uint32_t newD) {
if (newW < w) { if (newW < w) {
int delta = w - newW; int delta = w - newW;
translate(delta / 2, 0); translate(delta / 2, 0);
translate(-delta, 0); translate(-delta, 0);
translate(delta, 0); translate(delta, 0);
} }
if (newD < d) { if (newD < d) {
int delta = d - newD; int delta = d - newD;
translate(0, delta / 2); translate(0, delta / 2);
translate(0, -delta); translate(0, -delta);
translate(0, delta); translate(0, delta);
} }
const int newVolume = newW * newD; const int newVolume = newW * newD;
std::vector<std::shared_ptr<Chunk>> newChunks(newVolume); std::vector<std::shared_ptr<Chunk>> newChunks(newVolume);
std::vector<std::shared_ptr<Chunk>> newChunksSecond(newVolume); std::vector<std::shared_ptr<Chunk>> newChunksSecond(newVolume);
for (int z = 0; z < int(d) && z < int(newD); z++) { for (int z = 0; z < int(d) && z < int(newD); z++) {
for (int x = 0; x < int(w) && x < int(newW); x++) { for (int x = 0; x < int(w) && x < int(newW); x++) {
newChunks[z * newW + x] = chunks[z * w + x]; newChunks[z * newW + x] = chunks[z * w + x];
} }
} }
w = newW; w = newW;
d = newD; d = newD;
volume = newVolume; volume = newVolume;
@ -465,35 +478,35 @@ void Chunks::resize(uint32_t newW, uint32_t newD) {
} }
void Chunks::_setOffset(int32_t x, int32_t z) { void Chunks::_setOffset(int32_t x, int32_t z) {
ox = x; ox = x;
oz = z; oz = z;
} }
bool Chunks::putChunk(std::shared_ptr<Chunk> chunk) { bool Chunks::putChunk(std::shared_ptr<Chunk> chunk) {
int x = chunk->x; int x = chunk->x;
int z = chunk->z; int z = chunk->z;
x -= ox; x -= ox;
z -= oz; z -= oz;
if (x < 0 || z < 0 || x >= int(w) || z >= int(d)) if (x < 0 || z < 0 || x >= int(w) || z >= int(d))
return false; return false;
chunks[z * w + x] = chunk; chunks[z * w + x] = chunk;
chunksCount++; chunksCount++;
return true; return true;
} }
void Chunks::saveAndClear(){ void Chunks::saveAndClear(){
auto& regions = worldFiles->getRegions(); auto& regions = worldFiles->getRegions();
for (size_t i = 0; i < volume; i++){ for (size_t i = 0; i < volume; i++){
Chunk* chunk = chunks[i].get(); Chunk* chunk = chunks[i].get();
chunks[i] = nullptr; chunks[i] = nullptr;
if (chunk == nullptr || !chunk->isLighted()) if (chunk == nullptr || !chunk->isLighted())
continue; continue;
bool lightsUnsaved = !chunk->isLoadedLights() && bool lightsUnsaved = !chunk->isLoadedLights() &&
worldFiles->doesWriteLights(); worldFiles->doesWriteLights();
if (!chunk->isUnsaved() && !lightsUnsaved) if (!chunk->isUnsaved() && !lightsUnsaved)
continue; continue;
regions.put(chunk); regions.put(chunk);
} }
chunksCount = 0; chunksCount = 0;
} }