123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- #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);
- }
|