1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-07 00:58:39 +02:00

Rotation rebase2 (#912)

* Instead of [x][y][z] coordinates, map will be stored as [z][x][y].
* Nullkiller AI can get it too.
* Use boost::multi_array instead of nested vectors
* In MapHandler too
* Rotate foreach algorithms, too
* VCAI gets rotated, too
This commit is contained in:
DjWarmonger
2022-09-18 16:39:10 +02:00
committed by GitHub
parent e85f8a56bb
commit 7ba271edf1
44 changed files with 502 additions and 1015 deletions

View File

@ -52,20 +52,22 @@ struct NeighborTilesInfo
d1,
d2,
d3;
NeighborTilesInfo(const int3 & pos, const int3 & sizes, const std::vector< std::vector< std::vector<ui8> > > & visibilityMap)
NeighborTilesInfo(const int3 & pos, const int3 & sizes, std::shared_ptr<const boost::multi_array<ui8, 3>> visibilityMap)
{
auto getTile = [&](int dx, int dy)->bool
{
if ( dx + pos.x < 0 || dx + pos.x >= sizes.x
|| dy + pos.y < 0 || dy + pos.y >= sizes.y)
return false;
return settings["session"]["spectate"].Bool() ? true : visibilityMap[dx+pos.x][dy+pos.y][pos.z];
//FIXME: please do not read settings for every tile...
return settings["session"]["spectate"].Bool() ? true : (*visibilityMap)[pos.z][dx+pos.x][dy+pos.y];
};
d7 = getTile(-1, -1); //789
d8 = getTile( 0, -1); //456
d9 = getTile(+1, -1); //123
d4 = getTile(-1, 0);
d5 = visibilityMap[pos.x][pos.y][pos.z];
d5 = (*visibilityMap)[pos.z][pos.x][pos.y];
d6 = getTile(+1, 0);
d1 = getTile(-1, +1);
d2 = getTile( 0, +1);
@ -113,22 +115,9 @@ void CMapHandler::prepareFOWDefs()
FoWfullHide[frame] = graphics->fogOfWarFullHide->getImage(frame);
//initialization of type of full-hide image
hideBitmap.resize(sizes.x);
for (auto & elem : hideBitmap)
{
elem.resize(sizes.y);
}
for (auto & elem : hideBitmap)
{
for (int j = 0; j < sizes.y; ++j)
{
elem[j].resize(sizes.z);
for(int k = 0; k < sizes.z; ++k)
{
elem[j][k] = CRandomGenerator::getDefault().nextInt((int)size - 1);
}
}
}
hideBitmap.resize(boost::extents[sizes.z][sizes.x][sizes.y]);
for (int i = 0; i < hideBitmap.num_elements(); i++)
hideBitmap.data()[i] = CRandomGenerator::getDefault().nextInt(size - 1);
size = graphics->fogOfWarPartialHide->size(0);
FoWpartialHide.resize(size);
@ -211,16 +200,12 @@ void CMapHandler::initTerrainGraphics()
// Create enough room for the whole map and its frame
ttiles.resize(sizes.x, frameW, frameW);
for (int i=0-frameW;i<ttiles.size()-frameW;i++)
{
ttiles[i].resize(sizes.y, frameH, frameH);
}
for (int i=0-frameW;i<ttiles.size()-frameW;i++)
{
for (int j=0-frameH;j<(int)sizes.y+frameH;j++)
ttiles[i][j].resize(sizes.z, 0, 0);
}
//ttiles.resize(sizes.x, frameW, frameW);
//FIXME: why do we even handle array with z (surface and undeground) at the same time?
ttiles.resize(boost::extents[sizes.z][sizes.x + 2 * frameW][sizes.y + 2 * frameH]);
ttiles.reindex(std::list<int>{ 0, -frameW, -frameH }); //need to move starting coordinates so that used index is always positive
}
void CMapHandler::initBorderGraphics()
@ -321,19 +306,21 @@ void CMapHandler::initObjectRects()
obj->coveringAt(currTile.x, currTile.y) // object is visible here
)
{
ttiles[currTile.x][currTile.y][currTile.z].objects.push_back(toAdd);
ttiles[currTile.z][currTile.x][currTile.y].objects.push_back(toAdd);
}
}
}
}
for(int ix=0; ix<ttiles.size()-frameW; ++ix)
auto shape = ttiles.shape();
for(size_t z = 0; z < shape[0]; z++)
{
for(int iy=0; iy<ttiles[0].size()-frameH; ++iy)
for(size_t x = 0; x < shape[1] - frameW; x++)
{
for(int iz=0; iz<ttiles[0][0].size(); ++iz)
for(size_t y = 0; y < shape[2] - frameH; y++)
{
stable_sort(ttiles[ix][iy][iz].objects.begin(), ttiles[ix][iy][iz].objects.end(), objectBlitOrderSorter);
auto & objects = ttiles[z][x][y].objects;
stable_sort(objects.begin(), objects.end(), objectBlitOrderSorter);
}
}
}
@ -351,7 +338,7 @@ void CMapHandler::init()
//sizes of terrain
sizes.x = map->width;
sizes.y = map->height;
sizes.z = map->twoLevel ? 2 : 1;
sizes.z = map->levels();
// Total number of visible tiles. Subtract the center tile, then
// compute the number of tiles on each side, and reassemble.
@ -557,7 +544,9 @@ void CMapHandler::CMapWorldViewBlitter::drawTileOverlay(SDL_Surface * targetSurf
const CGObjectInstance * obj = object.obj;
const bool sameLevel = obj->pos.z == pos.z;
const bool isVisible = settings["session"]["spectate"].Bool() ? true : (*info->visibilityMap)[pos.x][pos.y][pos.z];
//FIXME: Don't read options in a loop :v
const bool isVisible = settings["session"]["spectate"].Bool() ? true : (*info->visibilityMap)[pos.z][pos.x][pos.y];
const bool isVisitable = obj->visitableAt(pos.x, pos.y);
if(sameLevel && isVisible && isVisitable)
@ -826,11 +815,11 @@ void CMapHandler::CMapBlitter::drawRiver(SDL_Surface * targetSurf, const Terrain
void CMapHandler::CMapBlitter::drawFow(SDL_Surface * targetSurf) const
{
const NeighborTilesInfo neighborInfo(pos, parent->sizes, *info->visibilityMap);
const NeighborTilesInfo neighborInfo(pos, parent->sizes, info->visibilityMap);
int retBitmapID = neighborInfo.getBitmapID();// >=0 -> partial hide, <0 - full hide
if (retBitmapID < 0)
retBitmapID = - parent->hideBitmap[pos.x][pos.y][pos.z] - 1; //fully hidden
retBitmapID = - parent->hideBitmap[pos.z][pos.x][pos.y] - 1; //fully hidden
std::shared_ptr<IImage> image;
@ -865,7 +854,7 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
realTileRect.x = realPos.x;
realTileRect.y = realPos.y;
const TerrainTile2 & tile = parent->ttiles[pos.x][pos.y][pos.z];
const TerrainTile2 & tile = parent->ttiles[pos.z][pos.x][pos.y];
const TerrainTile & tinfo = parent->map->getTile(pos);
const TerrainTile * tinfoUpper = pos.y > 0 ? &parent->map->getTile(int3(pos.x, pos.y - 1, pos.z)) : nullptr;
@ -896,9 +885,9 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
}
else
{
const TerrainTile2 & tile = parent->ttiles[pos.x][pos.y][pos.z];
const TerrainTile2 & tile = parent->ttiles[pos.z][pos.x][pos.y];
if(!settings["session"]["spectate"].Bool() && !(*info->visibilityMap)[pos.x][pos.y][topTile.z] && !info->showAllTerrain)
if(!settings["session"]["spectate"].Bool() && !(*info->visibilityMap)[topTile.z][pos.x][pos.y] && !info->showAllTerrain)
drawFow(targetSurf);
// overlay needs to be drawn over fow, because of artifacts-aura-like spells
@ -1105,7 +1094,7 @@ bool CMapHandler::CMapBlitter::canDrawCurrentTile() const
if(settings["session"]["spectate"].Bool())
return true;
const NeighborTilesInfo neighbors(pos, parent->sizes, *info->visibilityMap);
const NeighborTilesInfo neighbors(pos, parent->sizes, info->visibilityMap);
return !neighbors.areAllHidden();
}
@ -1136,7 +1125,7 @@ bool CMapHandler::updateObjectsFade()
++iter;
else // fade finished
{
auto &objs = ttiles[pos.x][pos.y][pos.z].objects;
auto &objs = ttiles[pos.z][pos.x][pos.y].objects;
for (auto objIter = objs.begin(); objIter != objs.end(); ++objIter)
{
if ((*objIter).fadeAnimKey == (*iter).first)
@ -1210,6 +1199,9 @@ bool CMapHandler::printObject(const CGObjectInstance * obj, bool fadein)
const int tilesW = bitmap->width()/32;
const int tilesH = bitmap->height()/32;
auto ttilesWidth = ttiles.shape()[1];
auto ttilesHeight = ttiles.shape()[2];
for(int fx=0; fx<tilesW; ++fx)
{
for(int fy=0; fy<tilesH; ++fy)
@ -1220,10 +1212,13 @@ bool CMapHandler::printObject(const CGObjectInstance * obj, bool fadein)
cr.x = fx*32;
cr.y = fy*32;
if((obj->pos.x + fx - tilesW+1)>=0 && (obj->pos.x + fx - tilesW+1)<ttiles.size()-frameW && (obj->pos.y + fy - tilesH+1)>=0 && (obj->pos.y + fy - tilesH+1)<ttiles[0].size()-frameH)
if((obj->pos.x + fx - tilesW + 1) >= 0 &&
(obj->pos.x + fx - tilesW + 1) < ttilesWidth - frameW &&
(obj->pos.y + fy - tilesH + 1) >= 0 &&
(obj->pos.y + fy - tilesH + 1) < ttilesHeight - frameH)
{
int3 pos(obj->pos.x + fx - tilesW + 1, obj->pos.y + fy - tilesH + 1, obj->pos.z);
TerrainTile2 & curt = ttiles[pos.x][pos.y][pos.z];
TerrainTile2 & curt = ttiles[pos.z][pos.x][pos.y];
TerrainTileObject toAdd(obj, cr, obj->visitableAt(pos.x, pos.y));
if (fadein && ADVOPT.objectFading)
@ -1252,59 +1247,26 @@ bool CMapHandler::printObject(const CGObjectInstance * obj, bool fadein)
bool CMapHandler::hideObject(const CGObjectInstance * obj, bool fadeout)
{
//optimized version which reveals weird bugs with missing def name
//auto pos = obj->pos;
//for (size_t i = pos.x; i > pos.x - obj->getWidth(); i--)
//{
// for (size_t j = pos.y; j > pos.y - obj->getHeight(); j--)
// {
// int3 t(i, j, pos.z);
// if (!map->isInTheMap(t))
// continue;
// auto &objs = ttiles[i][j][pos.z].objects;
// for (size_t x = 0; x < objs.size(); x++)
// {
// auto ourObj = objs[x].obj;
// if (ourObj && ourObj->id == obj->id)
// {
// if (fadeout && ADVOPT.objectFading) // object should be faded == erase is delayed until the end of fadeout
// {
// if (startObjectFade(objs[x], false, t))
// objs[x].obj = nullptr; //set original pointer to null
// else
// objs.erase(objs.begin() + x);
// }
// else
// objs.erase(objs.begin() + x);
// break;
// }
// }
// }
//}
for (size_t i = 0; i<map->width; i++)
for(size_t z = 0; z < map->levels(); z++)
{
for (size_t j = 0; j<map->height; j++)
for(size_t x = 0; x < map->width; x++)
{
for (size_t k = 0; k<(map->twoLevel ? 2 : 1); k++)
for(size_t y = 0; y < map->height; y++)
{
auto &objs = ttiles[(int)i][(int)j][(int)k].objects;
for (size_t x = 0; x < objs.size(); x++)
auto &objs = ttiles[(int)z][(int)x][(int)y].objects;
for(size_t i = 0; i < objs.size(); i++)
{
if (objs[x].obj && objs[x].obj->id == obj->id)
if (objs[i].obj && objs[i].obj->id == obj->id)
{
if (fadeout && ADVOPT.objectFading) // object should be faded == erase is delayed until the end of fadeout
{
if (startObjectFade(objs[x], false, int3((si32)i, (si32)j, (si32)k)))
objs[x].obj = nullptr;
if (startObjectFade(objs[i], false, int3((si32)x, (si32)y, (si32)z)))
objs[i].obj = nullptr;
else
objs.erase(objs.begin() + x);
objs.erase(objs.begin() + i);
}
else
objs.erase(objs.begin() + x);
objs.erase(objs.begin() + i);
break;
}
}
@ -1392,7 +1354,7 @@ CMapHandler::CMapHandler()
bool CMapHandler::hasObjectHole(const int3 & pos) const
{
const TerrainTile2 & tt = ttiles[pos.x][pos.y][pos.z];
const TerrainTile2 & tt = ttiles[pos.z][pos.x][pos.y];
for(auto & elem : tt.objects)
{
@ -1411,7 +1373,7 @@ void CMapHandler::getTerrainDescr(const int3 & pos, std::string & out, bool isRM
out = CGI->objtypeh->getObjectName(Obj::FAVORABLE_WINDS);
return;
}
const TerrainTile2 & tt = ttiles[pos.x][pos.y][pos.z];
const TerrainTile2 & tt = ttiles[pos.z][pos.x][pos.y];
bool isTile2Terrain = false;
out.clear();