|
@@ -3,14 +3,14 @@
|
|
|
#include "Constants.h"
|
|
|
#include "World.h"
|
|
|
|
|
|
-DimensionMap::DimensionMap()
|
|
|
+DimensionMap::DimensionMap(MapOptions* zOptions)
|
|
|
: ZeichnungHintergrund(),
|
|
|
+ zOptions(zOptions),
|
|
|
originChunkCenter(0, 0),
|
|
|
scrollOffset(0, 0),
|
|
|
chunkCount(0),
|
|
|
pixelsPerBlock(16),
|
|
|
- maxHeight(255),
|
|
|
- waitingForChunk(0),
|
|
|
+ requestCount(0),
|
|
|
drag(0)
|
|
|
{
|
|
|
setStyle(Style::Sichtbar | Style::Erlaubt);
|
|
@@ -97,6 +97,28 @@ Framework::Punkt DimensionMap::getMaxVisibleChunkCenter(
|
|
|
return currentChunkCenter;
|
|
|
}
|
|
|
|
|
|
+void DimensionMap::removeUnused() const
|
|
|
+{
|
|
|
+ Punkt tmp;
|
|
|
+ Framework::Punkt min = getMinVisibleChunkCenter(tmp);
|
|
|
+ Framework::Punkt max = getMaxVisibleChunkCenter(tmp);
|
|
|
+ char addr[8];
|
|
|
+ for (auto i = chunkList.begin(); i;)
|
|
|
+ {
|
|
|
+ if (i->getChunkCenter().x < min.x || i->getChunkCenter().y < min.y
|
|
|
+ || i->getChunkCenter().x > max.x || i->getChunkCenter().y > max.y)
|
|
|
+ {
|
|
|
+ getAddrOfWorld(i->getChunkCenter(), addr);
|
|
|
+ chunks->remove(addr, 8);
|
|
|
+ i.remove();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
bool DimensionMap::tick(double time)
|
|
|
{
|
|
|
if (lastSize != getSize())
|
|
@@ -110,14 +132,14 @@ bool DimensionMap::tick(double time)
|
|
|
void DimensionMap::requestNextChunk()
|
|
|
{
|
|
|
cs.lock();
|
|
|
- if (waitingForChunk)
|
|
|
+ if (requestCount >= 20)
|
|
|
{
|
|
|
cs.unlock();
|
|
|
return;
|
|
|
}
|
|
|
if (chunkCount == 0)
|
|
|
{
|
|
|
- waitingForChunk = 1;
|
|
|
+ requestCount++;
|
|
|
Vec3<float> playerPos
|
|
|
= World::INSTANCE->getCurrentPlayerEntity()->getPos();
|
|
|
char msg[9];
|
|
@@ -128,43 +150,54 @@ void DimensionMap::requestNextChunk()
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- Punkt minScreenPos;
|
|
|
- Punkt minVisibleChunk = getMinVisibleChunkCenter(minScreenPos);
|
|
|
- Punkt maxScreenPos;
|
|
|
- Punkt maxVisibleChunk = getMaxVisibleChunkCenter(maxScreenPos);
|
|
|
- Punkt screenPos = minScreenPos;
|
|
|
- Punkt screenCenter = getSize() / 2;
|
|
|
- double minDist = -1;
|
|
|
- Punkt resultChunk(0, 0);
|
|
|
- char addr[8];
|
|
|
- for (int x = minVisibleChunk.x; x <= maxVisibleChunk.x; x += CHUNK_SIZE)
|
|
|
+ while (requestCount < 20)
|
|
|
{
|
|
|
- for (int y = minVisibleChunk.y; y <= maxVisibleChunk.y;
|
|
|
- y += CHUNK_SIZE)
|
|
|
+ Punkt minScreenPos;
|
|
|
+ Punkt minVisibleChunk = getMinVisibleChunkCenter(minScreenPos);
|
|
|
+ Punkt maxScreenPos;
|
|
|
+ Punkt maxVisibleChunk = getMaxVisibleChunkCenter(maxScreenPos);
|
|
|
+ Punkt screenPos = minScreenPos;
|
|
|
+ Punkt screenCenter = getSize() / 2;
|
|
|
+ double minDist = -1;
|
|
|
+ Punkt resultChunk(0, 0);
|
|
|
+ char addr[8];
|
|
|
+ for (int x = minVisibleChunk.x; x <= maxVisibleChunk.x;
|
|
|
+ x += CHUNK_SIZE)
|
|
|
{
|
|
|
- getAddrOfWorld({x, y}, addr);
|
|
|
- if (!chunks->z(addr, 8))
|
|
|
+ for (int y = minVisibleChunk.y; y <= maxVisibleChunk.y;
|
|
|
+ y += CHUNK_SIZE)
|
|
|
{
|
|
|
- if (minDist < 0
|
|
|
- || (screenCenter - screenPos).getLengthSq() < minDist)
|
|
|
+ getAddrOfWorld({x, y}, addr);
|
|
|
+ if (!chunks->z(addr, 8))
|
|
|
{
|
|
|
- minDist = (screenCenter - screenPos).getLengthSq();
|
|
|
- resultChunk = {x, y};
|
|
|
+ if (minDist < 0
|
|
|
+ || (screenCenter - screenPos).getLengthSq()
|
|
|
+ < minDist)
|
|
|
+ {
|
|
|
+ minDist = (screenCenter - screenPos).getLengthSq();
|
|
|
+ resultChunk = {x, y};
|
|
|
+ }
|
|
|
}
|
|
|
+ screenPos.y += pixelsPerBlock * CHUNK_SIZE;
|
|
|
}
|
|
|
- screenPos.y += pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ screenPos.x += pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ screenPos.y = minScreenPos.y;
|
|
|
+ }
|
|
|
+ if (minDist >= 0)
|
|
|
+ {
|
|
|
+ requestCount++;
|
|
|
+ char msg[9];
|
|
|
+ msg[0] = 2;
|
|
|
+ *(int*)(msg + 1) = (int)resultChunk.x;
|
|
|
+ *(int*)(msg + 5) = (int)resultChunk.y;
|
|
|
+ World::INSTANCE->zClient()->dimensionAPIRequest(msg, 9);
|
|
|
+ getAddrOfWorld({resultChunk.x, resultChunk.y}, addr);
|
|
|
+ chunks->set(addr, 8, new ChunkMap(resultChunk));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ break;
|
|
|
}
|
|
|
- screenPos.x += pixelsPerBlock * CHUNK_SIZE;
|
|
|
- screenPos.y = minScreenPos.y;
|
|
|
- }
|
|
|
- if (minDist >= 0)
|
|
|
- {
|
|
|
- waitingForChunk = 1;
|
|
|
- char msg[9];
|
|
|
- msg[0] = 2;
|
|
|
- *(int*)(msg + 1) = (int)resultChunk.x;
|
|
|
- *(int*)(msg + 5) = (int)resultChunk.y;
|
|
|
- World::INSTANCE->zClient()->dimensionAPIRequest(msg, 9);
|
|
|
}
|
|
|
}
|
|
|
cs.unlock();
|
|
@@ -177,8 +210,10 @@ void DimensionMap::addChunk(ChunkMap* chunk)
|
|
|
char addr[8];
|
|
|
getAddrOfWorld(chunk->getChunkCenter(), addr);
|
|
|
chunks->set(addr, 8, chunk);
|
|
|
+ chunkList.add(chunk);
|
|
|
chunkCount++;
|
|
|
- waitingForChunk = 0;
|
|
|
+ requestCount--;
|
|
|
+ removeUnused();
|
|
|
cs.unlock();
|
|
|
requestNextChunk();
|
|
|
}
|
|
@@ -188,11 +223,21 @@ void DimensionMap::render(Framework::Bild& rObj)
|
|
|
ZeichnungHintergrund::render(rObj);
|
|
|
if (!rObj.setDrawOptions(innenPosition, innenSize)) return;
|
|
|
cs.lock();
|
|
|
+ if (zOptions->isFollowPlayer())
|
|
|
+ {
|
|
|
+ Vec3<float> playerPos
|
|
|
+ = World::INSTANCE->getCurrentPlayerEntity()->getPos();
|
|
|
+ scrollOffset
|
|
|
+ = (Punkt((int)playerPos.x, (int)playerPos.y) - originChunkCenter)
|
|
|
+ * pixelsPerBlock;
|
|
|
+ requestNextChunk();
|
|
|
+ }
|
|
|
Punkt minScreenPos;
|
|
|
Punkt minVisibleChunk = getMinVisibleChunkCenter(minScreenPos);
|
|
|
Punkt maxScreenPos;
|
|
|
Punkt maxVisibleChunk = getMaxVisibleChunkCenter(maxScreenPos);
|
|
|
char addr[8];
|
|
|
+ // render chunks
|
|
|
Punkt screenPos = minScreenPos;
|
|
|
for (int x = minVisibleChunk.x; x <= maxVisibleChunk.x; x += CHUNK_SIZE)
|
|
|
{
|
|
@@ -202,7 +247,18 @@ void DimensionMap::render(Framework::Bild& rObj)
|
|
|
ChunkMap* map = chunks->z(addr, 8);
|
|
|
if (map)
|
|
|
{
|
|
|
- map->setMaxHeight((unsigned char)maxHeight);
|
|
|
+ if (zOptions->isUnderground())
|
|
|
+ {
|
|
|
+ map->setMaxHeight(
|
|
|
+ (int)(World::INSTANCE->getCurrentPlayerEntity()
|
|
|
+ ->getPos()
|
|
|
+ .z
|
|
|
+ / 2));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ map->setMaxHeight(255);
|
|
|
+ }
|
|
|
Punkt topLeft(screenPos.x - (pixelsPerBlock * CHUNK_SIZE) / 2,
|
|
|
screenPos.y - (pixelsPerBlock * CHUNK_SIZE) / 2);
|
|
|
rObj.drawBildSkall(topLeft.x,
|
|
@@ -210,42 +266,162 @@ void DimensionMap::render(Framework::Bild& rObj)
|
|
|
pixelsPerBlock * CHUNK_SIZE,
|
|
|
pixelsPerBlock * CHUNK_SIZE,
|
|
|
map->getRenderedImage());
|
|
|
+ }
|
|
|
+ screenPos.y += pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ }
|
|
|
+ screenPos.x += pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ screenPos.y = minScreenPos.y;
|
|
|
+ }
|
|
|
+ // render shadow and borders
|
|
|
+ screenPos = minScreenPos;
|
|
|
+ for (int x = minVisibleChunk.x; x <= maxVisibleChunk.x; x += CHUNK_SIZE)
|
|
|
+ {
|
|
|
+ for (int y = minVisibleChunk.y; y <= maxVisibleChunk.y; y += CHUNK_SIZE)
|
|
|
+ {
|
|
|
+ getAddrOfWorld({x, y}, addr);
|
|
|
+ ChunkMap* map = chunks->z(addr, 8);
|
|
|
+ if (map)
|
|
|
+ {
|
|
|
+ Punkt topLeft(screenPos.x - (pixelsPerBlock * CHUNK_SIZE) / 2,
|
|
|
+ screenPos.y - (pixelsPerBlock * CHUNK_SIZE) / 2);
|
|
|
+ getAddrOfWorld({x, y - CHUNK_SIZE}, addr);
|
|
|
+ ChunkMap* tmp = chunks->z(addr, 8);
|
|
|
+ unsigned char* heightMapTop = tmp ? tmp->getHeightMap() : 0;
|
|
|
+ getAddrOfWorld({x + CHUNK_SIZE, y}, addr);
|
|
|
+ tmp = chunks->z(addr, 8);
|
|
|
+ unsigned char* heightMapRight = tmp ? tmp->getHeightMap() : 0;
|
|
|
+ getAddrOfWorld({x, y + CHUNK_SIZE}, addr);
|
|
|
+ tmp = chunks->z(addr, 8);
|
|
|
+ unsigned char* heightMapBottom = tmp ? tmp->getHeightMap() : 0;
|
|
|
+ getAddrOfWorld({x - CHUNK_SIZE, y}, addr);
|
|
|
+ tmp = chunks->z(addr, 8);
|
|
|
+ unsigned char* heightMapLeft = tmp ? tmp->getHeightMap() : 0;
|
|
|
unsigned char* heightMap = map->getHeightMap();
|
|
|
- for (int xx = 0; xx < CHUNK_SIZE - 1; xx++)
|
|
|
+ for (int xx = 0; xx < CHUNK_SIZE; xx++)
|
|
|
{
|
|
|
- for (int yy = 0; yy < CHUNK_SIZE - 1; yy++)
|
|
|
+ for (int yy = 0; yy < CHUNK_SIZE; yy++)
|
|
|
{
|
|
|
- if (heightMap[yy * CHUNK_SIZE + xx]
|
|
|
- > heightMap[yy * CHUNK_SIZE + xx + 1]
|
|
|
- )
|
|
|
+ bool shadowR = 0;
|
|
|
+ bool shadowB = 0;
|
|
|
+ if (xx < CHUNK_SIZE - 1)
|
|
|
{
|
|
|
- rObj.drawLinieVAlpha((xx * pixelsPerBlock)
|
|
|
- + topLeft.x
|
|
|
- + pixelsPerBlock,
|
|
|
- (yy * pixelsPerBlock) + topLeft.y,
|
|
|
- pixelsPerBlock,
|
|
|
- 0xFF000000);
|
|
|
+ if (heightMap[yy * CHUNK_SIZE + xx]
|
|
|
+ > heightMap[yy * CHUNK_SIZE + xx + 1])
|
|
|
+ {
|
|
|
+ rObj.drawLinieVAlpha((xx * pixelsPerBlock)
|
|
|
+ + topLeft.x
|
|
|
+ + pixelsPerBlock,
|
|
|
+ (yy * pixelsPerBlock) + topLeft.y,
|
|
|
+ pixelsPerBlock,
|
|
|
+ 0x40000000);
|
|
|
+ shadowR = 1;
|
|
|
+ }
|
|
|
}
|
|
|
- if (heightMap[yy * CHUNK_SIZE + xx]
|
|
|
- > heightMap[(yy + 1) * CHUNK_SIZE + xx])
|
|
|
+ else if (heightMapRight)
|
|
|
{
|
|
|
- rObj.drawLinieHAlpha(
|
|
|
- (xx * pixelsPerBlock) + topLeft.x,
|
|
|
- (yy * pixelsPerBlock) + topLeft.y
|
|
|
- + pixelsPerBlock,
|
|
|
- pixelsPerBlock,
|
|
|
- 0x40000000);
|
|
|
+ if (heightMap[yy * CHUNK_SIZE + xx]
|
|
|
+ > heightMapRight[yy * CHUNK_SIZE])
|
|
|
+ {
|
|
|
+ rObj.drawLinieVAlpha((xx * pixelsPerBlock)
|
|
|
+ + topLeft.x
|
|
|
+ + pixelsPerBlock,
|
|
|
+ (yy * pixelsPerBlock) + topLeft.y,
|
|
|
+ pixelsPerBlock,
|
|
|
+ 0x40000000);
|
|
|
+ shadowR = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (yy < CHUNK_SIZE - 1)
|
|
|
+ {
|
|
|
+ if (heightMap[yy * CHUNK_SIZE + xx]
|
|
|
+ > heightMap[(yy + 1) * CHUNK_SIZE + xx])
|
|
|
+ {
|
|
|
+ rObj.drawLinieHAlpha(
|
|
|
+ (xx * pixelsPerBlock) + topLeft.x,
|
|
|
+ (yy * pixelsPerBlock) + topLeft.y
|
|
|
+ + pixelsPerBlock,
|
|
|
+ pixelsPerBlock,
|
|
|
+ 0x30000000);
|
|
|
+ shadowB = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (heightMapBottom)
|
|
|
+ {
|
|
|
+ if (heightMap[yy * CHUNK_SIZE + xx]
|
|
|
+ > heightMapBottom[xx])
|
|
|
+ {
|
|
|
+ rObj.drawLinieHAlpha(
|
|
|
+ (xx * pixelsPerBlock) + topLeft.x,
|
|
|
+ (yy * pixelsPerBlock) + topLeft.y
|
|
|
+ + pixelsPerBlock,
|
|
|
+ pixelsPerBlock,
|
|
|
+ 0x30000000);
|
|
|
+ shadowB = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (xx > 0)
|
|
|
+ {
|
|
|
+ if (heightMap[yy * CHUNK_SIZE + xx]
|
|
|
+ > heightMap[yy * CHUNK_SIZE + xx - 1])
|
|
|
+ {
|
|
|
+ rObj.drawLinieVAlpha(
|
|
|
+ (xx * pixelsPerBlock) + topLeft.x,
|
|
|
+ (yy * pixelsPerBlock) + topLeft.y,
|
|
|
+ pixelsPerBlock - shadowB,
|
|
|
+ 0x20FFFFFF);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (heightMapLeft)
|
|
|
+ {
|
|
|
+ if (heightMap[yy * CHUNK_SIZE + xx]
|
|
|
+ > heightMapLeft[yy * CHUNK_SIZE + CHUNK_SIZE
|
|
|
+ - 1])
|
|
|
+ {
|
|
|
+ rObj.drawLinieVAlpha(
|
|
|
+ (xx * pixelsPerBlock) + topLeft.x,
|
|
|
+ (yy * pixelsPerBlock) + topLeft.y,
|
|
|
+ pixelsPerBlock - shadowB,
|
|
|
+ 0x20FFFFFF);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (yy > 0)
|
|
|
+ {
|
|
|
+ if (heightMap[yy * CHUNK_SIZE + xx]
|
|
|
+ > heightMap[(yy - 1) * CHUNK_SIZE + xx])
|
|
|
+ {
|
|
|
+ rObj.drawLinieHAlpha(
|
|
|
+ (xx * pixelsPerBlock) + topLeft.x,
|
|
|
+ (yy * pixelsPerBlock) + topLeft.y,
|
|
|
+ pixelsPerBlock - shadowR,
|
|
|
+ 0x10FFFFFF);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (heightMapTop)
|
|
|
+ {
|
|
|
+ if (heightMap[yy * CHUNK_SIZE + xx]
|
|
|
+ > heightMapTop[(CHUNK_SIZE - 1) * CHUNK_SIZE
|
|
|
+ + xx])
|
|
|
+ {
|
|
|
+ rObj.drawLinieHAlpha(
|
|
|
+ (xx * pixelsPerBlock) + topLeft.x,
|
|
|
+ (yy * pixelsPerBlock) + topLeft.y,
|
|
|
+ pixelsPerBlock - shadowR,
|
|
|
+ 0x10FFFFFF);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- rObj.drawLinieHAlpha(topLeft.x,
|
|
|
- topLeft.y,
|
|
|
- pixelsPerBlock * CHUNK_SIZE,
|
|
|
- 0x50FFFFFF);
|
|
|
- rObj.drawLinieVAlpha(topLeft.x,
|
|
|
- topLeft.y,
|
|
|
- pixelsPerBlock * CHUNK_SIZE,
|
|
|
- 0x50FFFFFF);
|
|
|
+ if (zOptions->isShowChunkBorders())
|
|
|
+ {
|
|
|
+ rObj.drawLinieHAlpha(topLeft.x,
|
|
|
+ topLeft.y,
|
|
|
+ pixelsPerBlock * CHUNK_SIZE,
|
|
|
+ 0x50FFFFFF);
|
|
|
+ rObj.drawLinieVAlpha(topLeft.x,
|
|
|
+ topLeft.y,
|
|
|
+ pixelsPerBlock * CHUNK_SIZE,
|
|
|
+ 0x50FFFFFF);
|
|
|
+ }
|
|
|
}
|
|
|
screenPos.y += pixelsPerBlock * CHUNK_SIZE;
|
|
|
}
|
|
@@ -285,19 +461,5 @@ void DimensionMap::doMausEreignis(Framework::MausEreignis& me, bool userRet)
|
|
|
rend = 1;
|
|
|
requestNextChunk();
|
|
|
}
|
|
|
- if (me.id == ME_RRechts)
|
|
|
- {
|
|
|
- if (maxHeight != 255)
|
|
|
- {
|
|
|
- maxHeight = 255;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- maxHeight
|
|
|
- = (int)(World::INSTANCE->getCurrentPlayerEntity()->getPos().z
|
|
|
- / 2);
|
|
|
- }
|
|
|
- rend = 1;
|
|
|
- }
|
|
|
ZeichnungHintergrund::doMausEreignis(me, userRet);
|
|
|
}
|