1 | #include <base/logger.h> |
2 | #include <base/system.h> |
3 | #include <engine/shared/datafile.h> |
4 | #include <engine/storage.h> |
5 | #include <game/mapitems.h> |
6 | |
7 | struct EnvelopedQuad |
8 | { |
9 | int m_GroupId; |
10 | int m_LayerId; |
11 | int m_TilePosX; |
12 | int m_TilePosY; |
13 | }; |
14 | |
15 | bool OpenMap(const char pMapName[64], CDataFileReader &InputMap) |
16 | { |
17 | IStorage *pStorage = CreateLocalStorage(); |
18 | |
19 | if(!InputMap.Open(pStorage, pFilename: pMapName, StorageType: IStorage::TYPE_ABSOLUTE)) |
20 | { |
21 | dbg_msg(sys: "map_find_env" , fmt: "ERROR: unable to open map '%s'" , pMapName); |
22 | return false; |
23 | } |
24 | return true; |
25 | } |
26 | |
27 | bool GetLayerGroupIds(CDataFileReader &InputMap, const int LayerNumber, int &GroupId, int &LayerRelativeId) |
28 | { |
29 | int Start, Num; |
30 | InputMap.GetType(Type: MAPITEMTYPE_GROUP, pStart: &Start, pNum: &Num); |
31 | |
32 | for(int i = 0; i < Num; i++) |
33 | { |
34 | CMapItemGroup *pItem = (CMapItemGroup *)InputMap.GetItem(Index: Start + i); |
35 | if(LayerNumber >= pItem->m_StartLayer && LayerNumber <= pItem->m_StartLayer + pItem->m_NumLayers) |
36 | { |
37 | GroupId = i; |
38 | LayerRelativeId = LayerNumber - pItem->m_StartLayer - 1; |
39 | return true; |
40 | } |
41 | } |
42 | |
43 | return false; |
44 | } |
45 | |
46 | int FxToTilePos(const int FxPos) |
47 | { |
48 | return std::floor(x: fx2f(v: FxPos) / 32); |
49 | } |
50 | |
51 | bool GetEnvelopedQuads(const CQuad *pQuads, const int NumQuads, const int EnvId, const int GroupId, const int LayerId, int &QuadsCounter, EnvelopedQuad pEnvQuads[1024]) |
52 | { |
53 | bool Found = false; |
54 | for(int i = 0; i < NumQuads; i++) |
55 | { |
56 | if(pQuads[i].m_PosEnv != EnvId && pQuads[i].m_ColorEnv != EnvId) |
57 | continue; |
58 | |
59 | pEnvQuads[QuadsCounter].m_GroupId = GroupId; |
60 | pEnvQuads[QuadsCounter].m_LayerId = LayerId; |
61 | pEnvQuads[QuadsCounter].m_TilePosX = FxToTilePos(FxPos: pQuads[i].m_aPoints[4].x); |
62 | pEnvQuads[QuadsCounter].m_TilePosY = FxToTilePos(FxPos: pQuads[i].m_aPoints[4].y); |
63 | |
64 | QuadsCounter++; |
65 | Found = true; |
66 | } |
67 | |
68 | return Found; |
69 | } |
70 | |
71 | void PrintEnvelopedQuads(const EnvelopedQuad pEnvQuads[1024], const int EnvId, const int QuadsCounter) |
72 | { |
73 | if(!QuadsCounter) |
74 | { |
75 | dbg_msg(sys: "map_find_env" , fmt: "No quads found with env number #%d" , EnvId + 1); |
76 | return; |
77 | } |
78 | |
79 | dbg_msg(sys: "map_find_env" , fmt: "Found %d quads with env number #%d:" , QuadsCounter, EnvId + 1); |
80 | for(int i = 0; i < QuadsCounter; i++) |
81 | dbg_msg(sys: "map_find_env" , fmt: "%*d. Group: #%d - Layer: #%d - Pos: %d,%d" , (int)(std::log10(x: absolute(a: QuadsCounter))) + 1, i + 1, pEnvQuads[i].m_GroupId, pEnvQuads[i].m_LayerId, pEnvQuads[i].m_TilePosX, pEnvQuads[i].m_TilePosY); |
82 | } |
83 | |
84 | bool FindEnv(const char aFilename[64], const int EnvId) |
85 | { |
86 | CDataFileReader InputMap; |
87 | if(!OpenMap(pMapName: aFilename, InputMap)) |
88 | return false; |
89 | |
90 | int , LayersCount, QuadsCounter = 0; |
91 | InputMap.GetType(Type: MAPITEMTYPE_LAYER, pStart: &LayersStart, pNum: &LayersCount); |
92 | EnvelopedQuad pEnvQuads[1024]; |
93 | |
94 | for(int i = 0; i < LayersCount; i++) |
95 | { |
96 | CMapItemLayer *pItem; |
97 | pItem = (CMapItemLayer *)InputMap.GetItem(Index: LayersStart + i); |
98 | |
99 | if(pItem->m_Type != LAYERTYPE_QUADS) |
100 | continue; |
101 | |
102 | CMapItemLayerQuads *pQuadLayer = (CMapItemLayerQuads *)pItem; |
103 | CQuad *pQuads = (CQuad *)InputMap.GetDataSwapped(Index: pQuadLayer->m_Data); |
104 | |
105 | int GroupId = 0, LayerRelativeId = 0; |
106 | if(!GetLayerGroupIds(InputMap, LayerNumber: i + 1, GroupId, LayerRelativeId)) |
107 | return false; |
108 | |
109 | GetEnvelopedQuads(pQuads, NumQuads: pQuadLayer->m_NumQuads, EnvId, GroupId, LayerId: LayerRelativeId, QuadsCounter, pEnvQuads); |
110 | } |
111 | |
112 | PrintEnvelopedQuads(pEnvQuads, EnvId, QuadsCounter); |
113 | |
114 | return true; |
115 | } |
116 | |
117 | int main(int argc, const char **argv) |
118 | { |
119 | CCmdlineFix CmdlineFix(&argc, &argv); |
120 | log_set_global_logger_default(); |
121 | |
122 | if(argc < 3) |
123 | { |
124 | dbg_msg(sys: "map_find_env" , fmt: "Invalid arguments" ); |
125 | dbg_msg(sys: "map_find_env" , fmt: "Usage: %s <input_map> <env_number>" , argv[0]); |
126 | dbg_msg(sys: "map_find_env" , fmt: "Note: returned quads positions are relative to their layers" ); |
127 | |
128 | return -1; |
129 | } |
130 | |
131 | char aFilename[64]; |
132 | str_copy(dst&: aFilename, src: argv[1]); |
133 | int EnvId = str_toint(str: argv[2]) - 1; |
134 | dbg_msg(sys: "map_find_env" , fmt: "input_map='%s'; env_number='#%d';" , aFilename, EnvId + 1); |
135 | |
136 | return FindEnv(aFilename, EnvId); |
137 | } |
138 | |