initial commit, lordsawar source, slightly modified
[lordsawar] / src / Tile.cpp
1 // Copyright (C) 2001, 2002, 2003 Michael Bartl
2 // Copyright (C) 2002, 2003, 2004, 2005 Ulf Lorenz
3 // Copyright (C) 2007, 2008 Ben Asselstine
4 //
5 //  This program is free software; you can redistribute it and/or modify
6 //  it under the terms of the GNU General Public License as published by
7 //  the Free Software Foundation; either version 3 of the License, or
8 //  (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU Library General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program; if not, write to the Free Software
17 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
18 //  02110-1301, USA.
19
20 #include "Tile.h"
21 #include "SmallTile.h"
22 #include <iostream>
23 #include <algorithm>
24 #include "File.h"
25 #include "tileset.h"
26
27 std::string Tile::d_tag = "tile";
28
29 using namespace std;
30
31
32 Tile::Tile()
33 {
34   d_type = Tile::GRASS;
35   d_moves = 0;
36   d_smalltile = new SmallTile();
37 }
38
39 Tile::Tile(XML_Helper* helper)
40 {
41     helper->getData(d_name, "name");
42     helper->getData(d_moves, "moves");
43     std::string type_str;
44     helper->getData(type_str, "type");
45     d_type = tileTypeFromString(type_str);
46 }
47
48 bool Tile::save(XML_Helper *helper) const
49 {
50   bool retval = true;
51
52   retval &= helper->openTag(d_tag);
53   retval &= helper->saveData("name", d_name);
54   retval &= helper->saveData("moves", d_moves);
55   std::string type_str = tileTypeToString(Tile::Type(d_type));
56   retval &= helper->saveData("type", type_str);
57   retval &= d_smalltile->save(helper);
58   for (Tile::const_iterator i = begin(); i != end(); ++i)
59     retval &= (*i)->save(helper);
60   retval &= helper->closeTag();
61
62   return retval;
63 }
64     
65 Tile::~Tile()
66 {
67   for (iterator it = begin(); it != end(); it++)
68       delete *it;
69 }
70
71 void Tile::setTypeByIndex(int idx)
72 {
73   switch (idx)
74     {
75     case 0: setType(GRASS); break;
76     case 1: setType(WATER); break;
77     case 2: setType(FOREST); break;
78     case 3: setType(HILLS); break;
79     case 4: setType(MOUNTAIN); break;
80     case 5: setType(SWAMP); break;
81     case 6: setType(VOID); break;
82     }
83 }
84
85 int Tile::getTypeIndexForType(Tile::Type type)
86 {
87   switch (type)
88     {
89     case GRASS: return 0; break;
90     case WATER: return 1; break;
91     case FOREST: return 2; break;
92     case HILLS: return 3; break;
93     case MOUNTAIN: return 4; break;
94     case SWAMP: return 5; break;
95     case VOID: return 6; break;
96     }
97   return 0;
98 }
99
100 TileStyle *Tile::getRandomTileStyle (TileStyle::Type style) const
101 {
102   std::vector<TileStyle*> tilestyles;
103   for (const_iterator it = begin(); it != end(); ++it)
104     {
105       TileStyleSet *tilestyleset = *it;
106       for (guint32 k = 0; k < tilestyleset->size(); k++)
107         {
108           TileStyle *tilestyle = (*tilestyleset)[k];
109           if (tilestyle->getType() == style)
110             tilestyles.push_back(tilestyle);
111         }
112     }
113
114   if (tilestyles.empty() == true)
115     return NULL;
116   return tilestyles[rand() % tilestyles.size()];
117 }
118
119 std::string Tile::tileTypeToString(const Tile::Type type)
120 {
121   switch (type)
122     {
123     case Tile::GRASS:
124       return "Tile::GRASS";
125     case Tile::WATER:
126       return "Tile::WATER";
127     case Tile::FOREST:
128       return "Tile::FOREST";
129     case Tile::HILLS:
130       return "Tile::HILLS";
131     case Tile::MOUNTAIN:
132       return "Tile::MOUNTAIN";
133     case Tile::SWAMP:
134       return "Tile::SWAMP";
135     case Tile::VOID:
136       return "Tile::VOID";
137     }
138   return "Tile::GRASS";
139 }
140
141 Tile::Type Tile::tileTypeFromString(const std::string str)
142 {
143   if (str.size() > 0 && isdigit(str.c_str()[0]))
144     return Tile::Type(atoi(str.c_str()));
145   if (str == "Tile::GRASS")
146     return Tile::GRASS;
147   else if (str == "Tile::WATER")
148     return Tile::WATER;
149   else if (str == "Tile::FOREST")
150     return Tile::FOREST;
151   else if (str == "Tile::HILLS")
152     return Tile::HILLS;
153   else if (str == "Tile::MOUNTAIN")
154     return Tile::MOUNTAIN;
155   else if (str == "Tile::SWAMP")
156     return Tile::SWAMP;
157   else if (str == "Tile::VOID")
158     return Tile::VOID;
159   return Tile::GRASS;
160 }
161
162       
163 bool Tile::validateGrass(std::list<TileStyle::Type> types) const
164 {
165   //grass tiles only have lone styles and other styles.
166   for (std::list<TileStyle::Type>::iterator it = types.begin(); 
167        it != types.end(); it++)
168     {
169       if ((*it) != TileStyle::LONE && (*it) != TileStyle::OTHER)
170         return false;
171     }
172   return true;
173 }
174
175 bool Tile::validateFeature(std::list<TileStyle::Type> types) const
176 {
177   //forest, water and hill tiles have a full suite of styles
178   //"other" styles are optional.
179   if (types.size() == TileStyle::OTHER)
180     return true;
181   if (types.size() == TileStyle::OTHER - 1 &&
182       find (types.begin(), types.end(), TileStyle::OTHER) == types.end())
183     return true;
184   return false;
185 }
186
187 bool Tile::consistsOnlyOfLoneAndOtherStyles() const
188 {
189   std::list<TileStyle::Type> types;
190   for (Tile::const_iterator i = begin(); i != end(); ++i)
191     (*i)->getUniqueTileStyleTypes(types);
192       return validateGrass(types);
193 }
194 bool Tile::validate() const
195 {
196   if (size() == 0)
197     return false;
198
199   for (Tile::const_iterator i = begin(); i != end(); ++i)
200     if ((*i)->validate() == false)
201       return false;
202
203   std::list<TileStyle::Type> types;
204   for (Tile::const_iterator i = begin(); i != end(); ++i)
205     (*i)->getUniqueTileStyleTypes(types);
206
207   if (types.empty())
208     return false;
209
210   switch (getType())
211     {
212     case Tile::GRASS:
213       if (validateGrass(types) == false)
214         return false;
215       break;
216     case Tile::FOREST: case Tile::WATER: case Tile::HILLS: 
217     case Tile::SWAMP: case Tile::VOID: case Tile::MOUNTAIN:
218       if (validateFeature(types) == false)
219         {
220           if (validateGrass(types) == false)
221             return false;
222           else
223             return true;
224         }
225       break;
226     }
227   return true;
228 }
229
230 void Tile::uninstantiateImages()
231 {
232   for (iterator it = begin(); it != end(); it++)
233     (*it)->uninstantiateImages();
234 }
235
236 void Tile::instantiateImages(int tilesize, Tileset *ts)
237 {
238   for (iterator it = begin(); it != end(); it++)
239     {
240       std::string file = "";
241       if ((*it)->getName().empty() == false)
242         file = ts->getFile((*it)->getName());
243       (*it)->instantiateImages(tilesize, file);
244     }
245
246 }
247 // End of file