2022-08-30 00:44:02 +02:00
|
|
|
#include "StdInc.h"
|
|
|
|
#include "maphandler.h"
|
|
|
|
#include "../lib/mapping/CMap.h"
|
|
|
|
|
2022-08-30 02:15:54 +02:00
|
|
|
const int tileSize = 32;
|
2022-08-30 00:44:02 +02:00
|
|
|
|
2022-08-30 02:15:54 +02:00
|
|
|
MapHandler::MapHandler(const CMap * Map):
|
|
|
|
map(Map), surface(Map->width * tileSize, Map->height * tileSize), painter(&surface)
|
|
|
|
{
|
|
|
|
init();
|
2022-08-30 00:44:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapHandler::init()
|
|
|
|
{
|
|
|
|
//sizes of terrain
|
|
|
|
sizes.x = map->width;
|
|
|
|
sizes.y = map->height;
|
|
|
|
sizes.z = map->twoLevel ? 2 : 1;
|
|
|
|
|
|
|
|
initTerrainGraphics();
|
|
|
|
logGlobal->info("\tPreparing terrain, roads, rivers, borders");
|
|
|
|
initObjectRects();
|
|
|
|
logGlobal->info("\tMaking object rects");
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapHandler::initTerrainGraphics()
|
|
|
|
{
|
|
|
|
static const std::map<std::string, std::string> ROAD_FILES =
|
|
|
|
{
|
|
|
|
{ROAD_NAMES[1], "dirtrd"},
|
|
|
|
{ROAD_NAMES[2], "gravrd"},
|
|
|
|
{ROAD_NAMES[3], "cobbrd"}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const std::map<std::string, std::string> RIVER_FILES =
|
|
|
|
{
|
|
|
|
{RIVER_NAMES[1], "clrrvr"},
|
|
|
|
{RIVER_NAMES[2], "icyrvr"},
|
|
|
|
{RIVER_NAMES[3], "mudrvr"},
|
|
|
|
{RIVER_NAMES[4], "lavrvr"}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
auto loadFlipped = [](TFlippedAnimations & animation, TFlippedCache & cache, const std::map<std::string, std::string> & files)
|
|
|
|
{
|
|
|
|
//no rotation and basic setup
|
|
|
|
for(auto & type : files)
|
|
|
|
{
|
|
|
|
animation[type.first][0] = make_unique<Animation>(type.second);
|
|
|
|
animation[type.first][0]->preload();
|
|
|
|
const size_t views = animation[type.first][0]->size(0);
|
|
|
|
cache[type.first].resize(views);
|
|
|
|
|
|
|
|
for(int j = 0; j < views; j++)
|
|
|
|
cache[type.first][j][0] = animation[type.first][0]->getImage(j);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(int rotation = 1; rotation < 4; rotation++)
|
|
|
|
{
|
|
|
|
for(auto & type : files)
|
|
|
|
{
|
|
|
|
animation[type.first][rotation] = make_unique<Animation>(type.second);
|
|
|
|
animation[type.first][rotation]->preload();
|
|
|
|
const size_t views = animation[type.first][rotation]->size(0);
|
|
|
|
|
|
|
|
for(int j = 0; j < views; j++)
|
|
|
|
{
|
|
|
|
auto image = animation[type.first][rotation]->getImage(j);
|
|
|
|
|
|
|
|
//if(rotation == 2 || rotation == 3)
|
|
|
|
//image->horizontalFlip();
|
|
|
|
//if(rotation == 1 || rotation == 3)
|
|
|
|
//image->verticalFlip();
|
|
|
|
|
|
|
|
cache[type.first][j][rotation] = image;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
std::map<std::string, std::string> terrainFiles;
|
|
|
|
for(auto & terrain : Terrain::Manager::terrains())
|
|
|
|
{
|
|
|
|
terrainFiles[terrain] = Terrain::Manager::getInfo(terrain).tilesFilename;
|
|
|
|
}
|
|
|
|
|
|
|
|
loadFlipped(terrainAnimations, terrainImages, terrainFiles);
|
|
|
|
loadFlipped(roadAnimations, roadImages, ROAD_FILES);
|
|
|
|
loadFlipped(riverAnimations, riverImages, RIVER_FILES);
|
|
|
|
}
|
|
|
|
|
2022-08-30 02:15:54 +02:00
|
|
|
void MapHandler::drawTerrainTile(int x, int y, const TerrainTile & tinfo)
|
2022-08-30 00:44:02 +02:00
|
|
|
{
|
|
|
|
//Rect destRect(realTileRect);
|
|
|
|
|
|
|
|
ui8 rotation = tinfo.extTileFlags % 4;
|
|
|
|
|
|
|
|
if(terrainImages.at(tinfo.terType).size() <= tinfo.terView)
|
2022-08-30 02:15:54 +02:00
|
|
|
return;
|
2022-08-30 00:44:02 +02:00
|
|
|
|
2022-08-30 02:15:54 +02:00
|
|
|
painter.drawImage(x * tileSize, y * tileSize, *terrainImages.at(tinfo.terType)[tinfo.terView][rotation]);
|
2022-08-30 00:44:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapHandler::initObjectRects()
|
|
|
|
{
|
|
|
|
//initializing objects / rects
|
|
|
|
/*for(auto & elem : map->objects)
|
|
|
|
{
|
|
|
|
const CGObjectInstance *obj = elem;
|
|
|
|
if( !obj
|
|
|
|
|| (obj->ID==Obj::HERO && static_cast<const CGHeroInstance*>(obj)->inTownGarrison) //garrisoned hero
|
|
|
|
|| (obj->ID==Obj::BOAT && static_cast<const CGBoat*>(obj)->hero)) //boat with hero (hero graphics is used)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<Animation> animation = graphics->getAnimation(obj);
|
|
|
|
|
|
|
|
//no animation at all
|
|
|
|
if(!animation)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
//empty animation
|
|
|
|
if(animation->size(0) == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
auto image = animation->getImage(0,0);
|
|
|
|
|
|
|
|
for(int fx=0; fx < obj->getWidth(); ++fx)
|
|
|
|
{
|
|
|
|
for(int fy=0; fy < obj->getHeight(); ++fy)
|
|
|
|
{
|
|
|
|
int3 currTile(obj->pos.x - fx, obj->pos.y - fy, obj->pos.z);
|
|
|
|
SDL_Rect cr;
|
|
|
|
cr.w = 32;
|
|
|
|
cr.h = 32;
|
|
|
|
cr.x = image->width() - fx * 32 - 32;
|
|
|
|
cr.y = image->height() - fy * 32 - 32;
|
|
|
|
TerrainTileObject toAdd(obj, cr, obj->visitableAt(currTile.x, currTile.y));
|
|
|
|
|
|
|
|
|
|
|
|
if( map->isInTheMap(currTile) && // within map
|
|
|
|
cr.x + cr.w > 0 && // image has data on this tile
|
|
|
|
cr.y + cr.h > 0 &&
|
|
|
|
obj->coveringAt(currTile.x, currTile.y) // object is visible here
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ttiles[currTile.x][currTile.y][currTile.z].objects.push_back(toAdd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(int ix=0; ix<ttiles.size()-frameW; ++ix)
|
|
|
|
{
|
|
|
|
for(int iy=0; iy<ttiles[0].size()-frameH; ++iy)
|
|
|
|
{
|
|
|
|
for(int iz=0; iz<ttiles[0][0].size(); ++iz)
|
|
|
|
{
|
|
|
|
stable_sort(ttiles[ix][iy][iz].objects.begin(), ttiles[ix][iy][iz].objects.end(), objectBlitOrderSorter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
}
|