#include
#include
#include
#include
#include
#include
struct EnvelopedQuad
{
int m_GroupID;
int m_LayerID;
int m_TilePosX;
int m_TilePosY;
};
bool OpenMap(const char pMapName[64], CDataFileReader &InputMap)
{
IStorage *pStorage = CreateLocalStorage();
if(!InputMap.Open(pStorage, pMapName, IStorage::TYPE_ABSOLUTE))
{
dbg_msg("map_find_env", "ERROR: unable to open map '%s'", pMapName);
return false;
}
return true;
}
bool GetLayerGroupIDs(CDataFileReader &InputMap, const int LayerNumber, int &GroupID, int &LayerRelativeID)
{
int Start, Num;
InputMap.GetType(MAPITEMTYPE_GROUP, &Start, &Num);
for(int i = 0; i < Num; i++)
{
CMapItemGroup *pItem = (CMapItemGroup *)InputMap.GetItem(Start + i);
if(LayerNumber >= pItem->m_StartLayer && LayerNumber <= pItem->m_StartLayer + pItem->m_NumLayers)
{
GroupID = i;
LayerRelativeID = LayerNumber - pItem->m_StartLayer - 1;
return true;
}
}
return false;
}
int FxToTilePos(const int FxPos)
{
return std::floor(fx2f(FxPos) / 32);
}
bool GetEnvelopedQuads(const CQuad *pQuads, const int NumQuads, const int EnvID, const int GroupID, const int LayerID, int &QuadsCounter, EnvelopedQuad pEnvQuads[1024])
{
bool bFound = false;
for(int i = 0; i < NumQuads; i++)
{
if(pQuads[i].m_PosEnv != EnvID && pQuads[i].m_ColorEnv != EnvID)
continue;
pEnvQuads[QuadsCounter].m_GroupID = GroupID;
pEnvQuads[QuadsCounter].m_LayerID = LayerID;
pEnvQuads[QuadsCounter].m_TilePosX = FxToTilePos(pQuads[i].m_aPoints[4].x);
pEnvQuads[QuadsCounter].m_TilePosY = FxToTilePos(pQuads[i].m_aPoints[4].y);
QuadsCounter++;
bFound = true;
}
return bFound;
}
void PrintEnvelopedQuads(const EnvelopedQuad pEnvQuads[1024], const int EnvID, const int QuadsCounter)
{
if(!QuadsCounter)
{
dbg_msg("map_find_env", "No quads found with env number #%d", EnvID + 1);
return;
}
dbg_msg("map_find_env", "Found %d quads with env number #%d:", QuadsCounter, EnvID + 1);
for(int i = 0; i < QuadsCounter; i++)
dbg_msg("map_find_env", "%*d. Group: #%d - Layer: #%d - Pos: %d,%d", (int)(std::log10(absolute(QuadsCounter))) + 1, i + 1, pEnvQuads[i].m_GroupID, pEnvQuads[i].m_LayerID, pEnvQuads[i].m_TilePosX, pEnvQuads[i].m_TilePosY);
}
bool FindEnv(const char aFilename[64], const int EnvID)
{
CDataFileReader InputMap;
if(!OpenMap(aFilename, InputMap))
return false;
int LayersStart, LayersCount, QuadsCounter = 0;
InputMap.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersCount);
EnvelopedQuad pEnvQuads[1024];
for(int i = 0; i < LayersCount; i++)
{
CMapItemLayer *pItem;
pItem = (CMapItemLayer *)InputMap.GetItem(LayersStart + i);
if(pItem->m_Type != LAYERTYPE_QUADS)
continue;
CMapItemLayerQuads *pQuadLayer = (CMapItemLayerQuads *)pItem;
CQuad *pQuads = (CQuad *)InputMap.GetDataSwapped(pQuadLayer->m_Data);
int GroupID = 0, LayerRelativeID = 0;
if(!GetLayerGroupIDs(InputMap, i + 1, GroupID, LayerRelativeID))
return false;
GetEnvelopedQuads(pQuads, pQuadLayer->m_NumQuads, EnvID, GroupID, LayerRelativeID, QuadsCounter, pEnvQuads);
}
PrintEnvelopedQuads(pEnvQuads, EnvID, QuadsCounter);
return true;
}
int main(int argc, const char **argv)
{
CCmdlineFix CmdlineFix(&argc, &argv);
log_set_global_logger_default();
if(argc < 3)
{
dbg_msg("map_find_env", "Invalid arguments");
dbg_msg("map_find_env", "Usage: %s ", argv[0]);
dbg_msg("map_find_env", "Note: returned quads positions are relative to their layers");
return -1;
}
char aFilename[64];
str_copy(aFilename, argv[1]);
int EnvID = str_toint(argv[2]) - 1;
dbg_msg("map_find_env", "input_map='%s'; env_number='#%d';", aFilename, EnvID + 1);
return FindEnv(aFilename, EnvID);
}