Introduced FileSystem and Out classes
[openstranded.git] / src / kingdom.cc
bloba09ec470fff060155685a2528b61833d4b1a2058
1 /*
2 * See kingdom.hh for a brief description of kingdoms.
4 * Copyright (C) 2008 Hermann Walth
6 * This file is part of OpenStranded
8 * OpenStranded is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * OpenStranded is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with OpenStranded. If not, see <http://www.gnu.org/licenses/>.
22 #include "output.hh"
23 #include "kingdom.hh"
24 #include "object.hh"
25 #include "unit.hh"
26 #include "item.hh"
27 #include "defparse/defparse.hh"
29 #include <iostream>
31 #ifdef unix
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <dirent.h>
35 #include <fcntl.h>
36 #include <string.h>
37 #else
38 #include <windows.h>
39 #endif
42 std::map <ID, Kingdom*> Kingdom::kingdomList;
45 Kingdom::Kingdom(const char *name):
46 name(std::string(name))
48 highestEntityID = 0;
52 Kingdom::~Kingdom ()
54 std::map <ID, Type*>::iterator type;
55 for (type = typeList.begin (); type != typeList.end (); type++)
56 destroyType (type->second);
58 std::map <ID, Entity*>::iterator entity;
59 for (entity = entityList.begin (); entity != entityList.end (); entity++)
60 destroyEntity (entity->second);
64 Entity*
65 Kingdom::getEntity (ID index)
67 if (entityExists (index))
68 return entityList[index];
69 else
70 return NULL;
74 Type*
75 Kingdom::getType (ID index)
77 if (typeExists (index))
78 return typeList[index];
79 else
80 return NULL;
84 bool
85 Kingdom::entityExists (ID entity)
87 if (entityList.find (entity) != entityList.end ())
88 return true;
89 else
90 return false;
94 bool
95 Kingdom::typeExists (ID type)
97 if (typeList.find (type) != typeList.end ())
98 return true;
99 else
100 return false;
104 Entity*
105 Kingdom::appendEntity (ID type)
107 return entityList[++highestEntityID] = createEntity (type);
111 Entity*
112 Kingdom::insertEntity (ID type, ID entity)
114 if (!entityExists (entity))
115 entityList[entity] = createEntity (type);
117 if (entity > highestEntityID)
118 highestEntityID = entity;
120 return entityList[entity];
124 Type*
125 Kingdom::insertType (const char* name, ID type)
127 if (!typeExists (type))
128 typeList[type] = createType (name);
129 return typeList[type];
133 Type*
134 Kingdom::insertType (ID type)
136 return this->insertType ("", type);
140 Entity*
141 Kingdom::createEntity (ID type)
143 return new Entity (type);
147 void
148 Kingdom::destroyEntity (Entity *entity)
150 delete entity;
154 Type*
155 Kingdom::createType (const char* name)
157 return new Type (name);
161 void
162 Kingdom::destroyType (Type *type)
164 delete type;
168 * Functions for the kingdomList
169 * TODO: In terms of beauty and modularity,
170 * these functions should be outsourced into another file
172 void
173 Kingdom::initKingdomList (std::string mod)
175 kingdomList[S2_OBJECT] = new ObjectKingdom;
176 kingdomList[S2_UNIT] = new UnitKingdom;
177 kingdomList[S2_ITEM] = new ItemKingdom;
179 // Load entity types
180 parseEntityTypes(mod, "object");
184 void
185 Kingdom::uninitKingdomList ()
187 std::map <ID, Kingdom*>::iterator iter;
188 for (iter = kingdomList.begin (); iter != kingdomList.end (); iter++)
189 delete (iter->second);
192 void
193 Kingdom::parseEntityTypes(std::string mod, std::string name)
195 std::string sysdir = std::string("mods/") + mod + "/sys/";
196 // Search for entity files within sys/
197 #ifdef __unix__
198 DIR *dir = opendir(sysdir.c_str());
199 if (!dir)
201 std::cerr << "Could not read sys/.\n";
202 std::cerr << sysdir << "\n";
203 return;
206 while (1)
208 struct dirent *dirent = readdir(dir);
209 if (!dirent) break;
210 if (strcmp(dirent->d_name, "..") && strcmp(dirent->d_name, "."))
212 std::string filename = sysdir + dirent->d_name;
213 int file = open(filename.c_str(), O_RDONLY);
214 if (!file)
216 Out::msg.printf("Could not open file \"%s\".\n", filename.c_str());
217 continue;
219 struct stat stat;
220 fstat(file, &stat);
221 close(file);
223 if (stat.st_mode & S_IFREG)
225 if (!strncmp(dirent->d_name, name.c_str(), strlen(name.c_str()))
226 && !strcmp(dirent->d_name + strlen(dirent->d_name) - 4, ".inf"))
228 Out::msg.printf("Parsing %s\n", filename.c_str());
229 def::object::parse(filename.c_str());
234 closedir(dir);
235 #else
236 std::string pattern = sysdir + name + "s_*.inf";
237 WIN32_FIND_DATA finddata;
238 HANDLE findhandle = FindFirstFile(pattern.c_str(), &finddata);
239 if (findhandle != INVALID_HANDLE_VALUE)
241 def::object::parse(finddata.cFileName);
242 while (FindNextFile(findhandle, &finddata))
244 def::object::parse(finddata.cFileName);
246 FindClose(findhandle);
248 #endif