|
@@ -0,0 +1,266 @@
|
|
|
+#include "DimensionMap.h"
|
|
|
+
|
|
|
+#include "Constants.h"
|
|
|
+#include "World.h"
|
|
|
+
|
|
|
+DimensionMap::DimensionMap()
|
|
|
+ : ZeichnungHintergrund(),
|
|
|
+ originChunkCenter(0, 0),
|
|
|
+ scrollOffset(0, 0),
|
|
|
+ chunkCount(0),
|
|
|
+ pixelsPerBlock(16),
|
|
|
+ maxHeight(255),
|
|
|
+ waitingForChunk(0),
|
|
|
+ drag(0)
|
|
|
+{
|
|
|
+ setStyle(Style::Sichtbar | Style::Erlaubt);
|
|
|
+ chunks = new Framework::Trie<ChunkMap>();
|
|
|
+ setMausEreignis(_ret1ME);
|
|
|
+ requestNextChunk();
|
|
|
+}
|
|
|
+
|
|
|
+DimensionMap::~DimensionMap()
|
|
|
+{
|
|
|
+ chunks->release();
|
|
|
+}
|
|
|
+
|
|
|
+void DimensionMap::getAddrOf(Punkt cPos, char* addr) const
|
|
|
+{
|
|
|
+ *(int*)addr = cPos.x;
|
|
|
+ *((int*)addr + 1) = cPos.y;
|
|
|
+}
|
|
|
+
|
|
|
+void DimensionMap::getAddrOfWorld(Punkt wPos, char* addr) const
|
|
|
+{
|
|
|
+ // needed because otherwise would (-8, -8) have the same
|
|
|
+ // adress as (8, 8)
|
|
|
+ if (wPos.x < 0) wPos.x -= CHUNK_SIZE;
|
|
|
+ if (wPos.y < 0) wPos.y -= CHUNK_SIZE;
|
|
|
+
|
|
|
+ wPos /= CHUNK_SIZE;
|
|
|
+ getAddrOf(wPos, addr);
|
|
|
+}
|
|
|
+
|
|
|
+Framework::Punkt DimensionMap::getMinVisibleChunkCenter(
|
|
|
+ Framework::Punkt& screenPos) const
|
|
|
+{
|
|
|
+ screenPos = getSize() / 2 - scrollOffset;
|
|
|
+ Punkt currentChunkCenter = originChunkCenter;
|
|
|
+ while (screenPos.x + pixelsPerBlock * (CHUNK_SIZE / 2) >= 0)
|
|
|
+ {
|
|
|
+ screenPos.x -= pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ currentChunkCenter.x -= CHUNK_SIZE;
|
|
|
+ }
|
|
|
+ while (screenPos.y + pixelsPerBlock * (CHUNK_SIZE / 2) >= 0)
|
|
|
+ {
|
|
|
+ screenPos.y -= pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ currentChunkCenter.y -= CHUNK_SIZE;
|
|
|
+ }
|
|
|
+ while (screenPos.x + pixelsPerBlock * (CHUNK_SIZE / 2) < 0)
|
|
|
+ {
|
|
|
+ screenPos.x += pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ currentChunkCenter.x += CHUNK_SIZE;
|
|
|
+ }
|
|
|
+ while (screenPos.y + pixelsPerBlock * (CHUNK_SIZE / 2) < 0)
|
|
|
+ {
|
|
|
+ screenPos.y += pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ currentChunkCenter.y += CHUNK_SIZE;
|
|
|
+ }
|
|
|
+ return currentChunkCenter;
|
|
|
+}
|
|
|
+
|
|
|
+Framework::Punkt DimensionMap::getMaxVisibleChunkCenter(
|
|
|
+ Framework::Punkt& screenPos) const
|
|
|
+{
|
|
|
+ screenPos = getSize() / 2 - scrollOffset;
|
|
|
+ Punkt currentChunkCenter = originChunkCenter;
|
|
|
+ while (screenPos.x - pixelsPerBlock * (CHUNK_SIZE / 2) < getBreite())
|
|
|
+ {
|
|
|
+ screenPos.x += pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ currentChunkCenter.x += CHUNK_SIZE;
|
|
|
+ }
|
|
|
+ while (screenPos.y - pixelsPerBlock * (CHUNK_SIZE / 2) < getHeight())
|
|
|
+ {
|
|
|
+ screenPos.y += pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ currentChunkCenter.y += CHUNK_SIZE;
|
|
|
+ }
|
|
|
+ while (screenPos.x - pixelsPerBlock * (CHUNK_SIZE / 2) >= getBreite())
|
|
|
+ {
|
|
|
+ screenPos.x -= pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ currentChunkCenter.x -= CHUNK_SIZE;
|
|
|
+ }
|
|
|
+ while (screenPos.y - pixelsPerBlock * (CHUNK_SIZE / 2) >= getHeight())
|
|
|
+ {
|
|
|
+ screenPos.y -= pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ currentChunkCenter.y -= CHUNK_SIZE;
|
|
|
+ }
|
|
|
+ return currentChunkCenter;
|
|
|
+}
|
|
|
+
|
|
|
+bool DimensionMap::tick(double time)
|
|
|
+{
|
|
|
+ if (lastSize != getSize())
|
|
|
+ {
|
|
|
+ lastSize = getSize();
|
|
|
+ requestNextChunk();
|
|
|
+ }
|
|
|
+ return ZeichnungHintergrund::tick(time);
|
|
|
+}
|
|
|
+
|
|
|
+void DimensionMap::requestNextChunk()
|
|
|
+{
|
|
|
+ cs.lock();
|
|
|
+ if (waitingForChunk)
|
|
|
+ {
|
|
|
+ cs.unlock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (chunkCount == 0)
|
|
|
+ {
|
|
|
+ waitingForChunk = 1;
|
|
|
+ Vec3<float> playerPos
|
|
|
+ = World::INSTANCE->getCurrentPlayerEntity()->getPos();
|
|
|
+ char msg[9];
|
|
|
+ msg[0] = 2;
|
|
|
+ *(int*)(msg + 1) = (int)playerPos.x;
|
|
|
+ *(int*)(msg + 5) = (int)playerPos.y;
|
|
|
+ World::INSTANCE->zClient()->dimensionAPIRequest(msg, 9);
|
|
|
+ }
|
|
|
+ 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)
|
|
|
+ {
|
|
|
+ for (int y = minVisibleChunk.y; y <= maxVisibleChunk.y;
|
|
|
+ y += CHUNK_SIZE)
|
|
|
+ {
|
|
|
+ getAddrOfWorld({x, y}, addr);
|
|
|
+ if (!chunks->z(addr, 8))
|
|
|
+ {
|
|
|
+ if (minDist < 0
|
|
|
+ || (screenCenter - screenPos).getLengthSq() < minDist)
|
|
|
+ {
|
|
|
+ minDist = (screenCenter - screenPos).getLengthSq();
|
|
|
+ resultChunk = {x, y};
|
|
|
+ }
|
|
|
+ }
|
|
|
+ screenPos.y += pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ }
|
|
|
+ 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();
|
|
|
+}
|
|
|
+
|
|
|
+void DimensionMap::addChunk(ChunkMap* chunk)
|
|
|
+{
|
|
|
+ cs.lock();
|
|
|
+ if (chunkCount == 0) originChunkCenter = chunk->getChunkCenter();
|
|
|
+ char addr[8];
|
|
|
+ getAddrOfWorld(chunk->getChunkCenter(), addr);
|
|
|
+ chunks->set(addr, 8, chunk);
|
|
|
+ chunkCount++;
|
|
|
+ waitingForChunk = 0;
|
|
|
+ cs.unlock();
|
|
|
+ requestNextChunk();
|
|
|
+}
|
|
|
+
|
|
|
+void DimensionMap::render(Framework::Bild& rObj)
|
|
|
+{
|
|
|
+ ZeichnungHintergrund::render(rObj);
|
|
|
+ if (!rObj.setDrawOptions(innenPosition, innenSize)) return;
|
|
|
+ cs.lock();
|
|
|
+ Punkt minScreenPos;
|
|
|
+ Punkt minVisibleChunk = getMinVisibleChunkCenter(minScreenPos);
|
|
|
+ Punkt maxScreenPos;
|
|
|
+ Punkt maxVisibleChunk = getMaxVisibleChunkCenter(maxScreenPos);
|
|
|
+ char addr[8];
|
|
|
+ Punkt 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)
|
|
|
+ {
|
|
|
+ map->setMaxHeight((unsigned char)maxHeight);
|
|
|
+ rObj.drawBildSkall(
|
|
|
+ screenPos.x - (pixelsPerBlock * CHUNK_SIZE) / 2,
|
|
|
+ screenPos.y - (pixelsPerBlock * CHUNK_SIZE) / 2,
|
|
|
+ pixelsPerBlock * CHUNK_SIZE,
|
|
|
+ pixelsPerBlock * CHUNK_SIZE,
|
|
|
+ map->getRenderedImage());
|
|
|
+ }
|
|
|
+ screenPos.y += pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ }
|
|
|
+ screenPos.x += pixelsPerBlock * CHUNK_SIZE;
|
|
|
+ screenPos.y = minScreenPos.y;
|
|
|
+ }
|
|
|
+ cs.unlock();
|
|
|
+ rObj.releaseDrawOptions();
|
|
|
+}
|
|
|
+
|
|
|
+void DimensionMap::doMausEreignis(Framework::MausEreignis& me, bool userRet)
|
|
|
+{
|
|
|
+ if (me.id == ME_PLinks)
|
|
|
+ {
|
|
|
+ drag = 1;
|
|
|
+ lastMouse = {me.mx, me.my};
|
|
|
+ }
|
|
|
+ if (me.id == ME_RLinks || me.id == ME_Leaves) drag = 0;
|
|
|
+ if (me.id == ME_Bewegung && drag)
|
|
|
+ {
|
|
|
+ scrollOffset -= Punkt(me.mx, me.my) - lastMouse;
|
|
|
+ lastMouse = Punkt(me.mx, me.my);
|
|
|
+ rend = 1;
|
|
|
+ requestNextChunk();
|
|
|
+ }
|
|
|
+ if (me.id == ME_DScroll && pixelsPerBlock > 1)
|
|
|
+ {
|
|
|
+ scrollOffset = (scrollOffset / pixelsPerBlock) * (pixelsPerBlock - 1);
|
|
|
+ pixelsPerBlock--;
|
|
|
+ rend = 1;
|
|
|
+ requestNextChunk();
|
|
|
+ }
|
|
|
+ if (me.id == ME_UScroll)
|
|
|
+ {
|
|
|
+ scrollOffset = (scrollOffset / pixelsPerBlock) * (pixelsPerBlock + 1);
|
|
|
+ pixelsPerBlock++;
|
|
|
+ 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);
|
|
|
+}
|