[6860] Implement correct effects stacking and zone limitations for item 34537.
[getmangos.git] / contrib / extractor / System.cpp
blob39bf1d5b1f63ce5052f0525430153fa3220405e2
1 #define _CRT_SECURE_NO_DEPRECATE
3 #include <stdio.h>
4 #include <deque>
5 #include <set>
7 #ifdef WIN32
8 #include "direct.h"
9 #else
10 #include <sys/stat.h>
11 #endif
13 #include "dbcfile.h"
14 #include "mpq_libmpq.h"
16 extern unsigned int iRes;
17 extern ArchiveSet gOpenArchives;
19 bool ConvertADT(char*,char*);
21 typedef struct{
22 char name[64];
23 unsigned int id;
24 }map_id;
26 typedef unsigned char uint8;
27 typedef unsigned short uint16;
28 typedef unsigned int uint32;
30 map_id * map_ids;
31 uint16 * areas;
32 char output_path[128]=".";
33 char input_path[128]=".";
35 enum Extract
37 EXTRACT_MAP = 1,
38 EXTRACT_DBC = 2
40 int extract = EXTRACT_MAP | EXTRACT_DBC;
42 static char* const langs[]={"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" };
43 #define LANG_COUNT 12
45 #define ADT_RES 64
47 void CreateDir( const std::string& Path )
49 #ifdef WIN32
50 _mkdir( Path.c_str());
51 #else
52 mkdir( Path.c_str(), 0777 );
53 #endif
56 bool FileExists( const char* FileName )
58 if( FILE* fp = fopen( FileName, "rb" ) )
60 fclose( fp );
61 return true;
64 return false;
67 void Usage(char* prg)
69 printf("Usage:\n%s -[var] [value]\n-i set input path\n-o set output path\n-r set resolution\n-e extract only MAP(1)/DBC(2) - standard: both(3)\nExample: %s -r 256 -i \"c:\\games\\game\"",
70 prg,prg);
71 exit(1);
74 void HandleArgs(int argc, char * arg[])
76 for(int c=1;c<argc;c++)
78 //i - input path
79 //o - output path
80 //r - resolution, array of (r * r) heights will be created
81 //e - extract only MAP(1)/DBC(2) - standard both(3)
82 if(arg[c][0] != '-')
83 Usage(arg[0]);
85 switch(arg[c][1])
87 case 'i':
88 if(c+1<argc)//all ok
89 strcpy(input_path,arg[(c++) +1]);
90 else
91 Usage(arg[0]);
92 break;
93 case 'o':
94 if(c+1<argc)//all ok
95 strcpy(output_path,arg[(c++) +1]);
96 else
97 Usage(arg[0]);
98 break;
99 case 'r':
100 if(c+1<argc)//all ok
101 iRes=atoi(arg[(c++) +1]);
102 else
103 Usage(arg[0]);
104 break;
105 case 'e':
106 if(c+1<argc)//all ok
108 extract=atoi(arg[(c++) +1]);
109 if(!(extract > 0 && extract < 4))
110 Usage(arg[0]);
112 else
113 Usage(arg[0]);
114 break;
119 uint32 ReadMapDBC()
121 printf("Read Map.dbc file... ");
122 DBCFile dbc("DBFilesClient\\Map.dbc");
123 dbc.open();
125 uint32 map_count=dbc.getRecordCount();
126 map_ids=new map_id[map_count];
127 for(unsigned int x=0;x<map_count;x++)
129 map_ids[x].id=dbc.getRecord(x).getUInt(0);
130 strcpy(map_ids[x].name,dbc.getRecord(x).getString(1));
132 printf("Done! (%u maps loaded)\n", map_count);
133 return map_count;
136 void ReadAreaTableDBC()
138 printf("Read AreaTable.dbc file... ");
139 DBCFile dbc("DBFilesClient\\AreaTable.dbc");
140 dbc.open();
142 unsigned int area_count=dbc.getRecordCount();
143 uint32 maxid = dbc.getMaxId();
144 areas=new uint16[maxid + 1];
145 memset(areas, 0xff, sizeof(areas));
146 for(unsigned int x=0; x<area_count;++x)
147 areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
149 printf("Done! (%u areas loaded)\n", area_count);
152 void ExtractMapsFromMpq()
154 char mpq_filename[1024];
155 char output_filename[1024];
157 printf("Extracting maps...\n");
159 uint32 map_count = ReadMapDBC();
161 ReadAreaTableDBC();
163 unsigned int total=map_count*ADT_RES*ADT_RES;
164 unsigned int done=0;
166 std::string path = output_path;
167 path += "/maps/";
168 CreateDir(path);
170 for(unsigned int x = 0; x < ADT_RES; ++x)
172 for(unsigned int y = 0; y < ADT_RES; ++y)
174 for(unsigned int z = 0; z < map_count; ++z)
176 sprintf(mpq_filename,"World\\Maps\\%s\\%s_%u_%u.adt",map_ids[z].name,map_ids[z].name,x,y);
177 sprintf(output_filename,"%s/maps/%03u%02u%02u.map",output_path,map_ids[z].id,y,x);
178 ConvertADT(mpq_filename,output_filename);
179 done++;
181 //draw progess bar
182 printf("Processing........................%d%%\r",(100*done)/total);
186 delete [] areas;
187 delete [] map_ids;
190 //bool WMO(char* filename);
192 void ExtractDBCFiles(int locale, bool basicLocale)
194 printf("Extracting dbc files...\n");
196 set<string> dbcfiles;
198 // get DBC file list
199 for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i)
201 vector<string> files;
202 (*i)->GetFileListTo(files);
203 for (vector<string>::iterator iter = files.begin(); iter != files.end(); ++iter)
204 if (iter->rfind(".dbc") == iter->length() - strlen(".dbc"))
205 dbcfiles.insert(*iter);
208 string path = output_path;
209 path += "/dbc/";
210 CreateDir(path);
211 if(!basicLocale)
213 path += langs[locale];
214 path += "/";
215 CreateDir(path);
218 // extract DBCs
219 int count = 0;
220 for (set<string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter)
222 string filename = path;
223 filename += (iter->c_str() + strlen("DBFilesClient\\"));
225 FILE *output=fopen(filename.c_str(),"wb");
226 if(!output)
228 printf("Can't create the output file '%s'\n",filename.c_str());
229 continue;
231 MPQFile m(iter->c_str());
232 if(!m.isEof())
233 fwrite(m.getPointer(),1,m.getSize(),output);
235 fclose(output);
236 ++count;
238 printf("Extracted %u DBC files\n\n", count);
241 void LoadLocaleMPQFiles(int const locale)
243 char filename[512];
245 sprintf(filename,"%s/Data/%s/locale-%s.MPQ",input_path,langs[locale],langs[locale]);
246 new MPQArchive(filename);
248 for(int i = 1; i < 5; ++i)
250 char ext[3] = "";
251 if(i > 1)
252 sprintf(ext, "-%i", i);
254 sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ",input_path,langs[locale],langs[locale],ext);
255 if(FileExists(filename))
256 new MPQArchive(filename);
260 void LoadCommonMPQFiles()
262 char filename[512];
264 sprintf(filename,"%s/Data/common.MPQ",input_path);
265 new MPQArchive(filename);
266 sprintf(filename,"%s/Data/expansion.MPQ",input_path);
267 new MPQArchive(filename);
269 for(int i = 1; i < 5; ++i)
271 char ext[3] = "";
272 if(i > 1)
273 sprintf(ext, "-%i", i);
275 sprintf(filename,"%s/Data/patch%s.MPQ",input_path,ext);
276 if(FileExists(filename))
277 new MPQArchive(filename);
281 inline void CloseMPQFiles()
283 for(ArchiveSet::iterator j = gOpenArchives.begin(); j != gOpenArchives.end();++j) (*j)->close();
284 gOpenArchives.clear();
287 int main(int argc, char * arg[])
289 printf("Map & DBC Extractor\n");
290 printf("===================\n\n");
292 HandleArgs(argc, arg);
294 int FirstLocale = -1;
296 for (int i = 0; i < LANG_COUNT; i++)
298 char tmp1[512];
299 sprintf(tmp1, "%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]);
300 if (FileExists(tmp1))
302 printf("Detected locale: %s\n", langs[i]);
304 //Open MPQs
305 LoadLocaleMPQFiles(i);
307 if((extract & EXTRACT_DBC) == 0)
309 FirstLocale=i;
310 break;
313 //Extract DBC files
314 if(FirstLocale<0)
316 ExtractDBCFiles(i, true);
317 FirstLocale = i;
319 else
320 ExtractDBCFiles(i, false);
322 //Close MPQs
323 CloseMPQFiles();
327 if(FirstLocale<0)
329 printf("No locales detected\n");
330 return 0;
333 if (extract & EXTRACT_MAP)
335 printf("Using locale: %s\n", langs[FirstLocale]);
337 // Open MPQs
338 LoadLocaleMPQFiles(FirstLocale);
339 LoadCommonMPQFiles();
341 // Extract maps
342 ExtractMapsFromMpq();
344 // Close MPQs
345 CloseMPQFiles();
348 return 0;