1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
4 // This file is part of Scorched3D.
6 // Scorched3D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // Scorched3D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with Scorched3D; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ////////////////////////////////////////////////////////////////////////////////
21 #include <landscapedef/LandscapeDefinitions.h>
22 #include <landscapedef/LandscapeTex.h>
23 #include <landscapedef/LandscapeDefn.h>
24 #include <landscapedef/LandscapeInclude.h>
25 #include <tank/TankContainer.h>
26 #include <common/OptionsScorched.h>
27 #include <common/Defines.h>
28 #include <common/Logger.h>
34 LandscapeDefinitions::LandscapeDefinitions() :
42 LandscapeDefinitions::~LandscapeDefinitions()
46 void LandscapeDefinitions::clearLandscapeDefinitions()
48 LandscapeDefinitionsBase::clearLandscapeDefinitions();
52 include_
.clearItems();
55 LandscapeTex
*LandscapeDefinitions::getTex(const char *file
, bool load
)
57 return texs_
.getItem(this, file
, load
, true);
60 LandscapeInclude
*LandscapeDefinitions::getInclude(const char *file
, bool load
)
62 return include_
.getItem(this, file
, load
, true);
65 LandscapeDefn
*LandscapeDefinitions::getDefn(const char *file
, bool load
)
67 return defns_
.getItem(this, file
, load
, true);
70 bool LandscapeDefinitions::readLandscapeDefinitions()
72 // Clear existing landscapes
73 clearLandscapeDefinitions();
75 // Parse base landscape information
76 if (!LandscapeDefinitionsBase::readLandscapeDefinitions()) return false;
78 // Now check that the landscape tex and defn files parse correctly
79 std::list
<LandscapeDefinitionsEntry
>::iterator itor
;
80 for (itor
= entries_
.begin();
81 itor
!= entries_
.end();
84 LandscapeDefinitionsEntry
&entry
= (*itor
);
85 std::vector
<std::string
>::iterator itor2
;
87 std::vector
<std::string
> &defns
= entry
.defns
;
88 for (itor2
= defns
.begin();
92 const char *landscapeDefnFile
= (*itor2
).c_str();
93 LandscapeDefn
*landscapeDefn
= getDefn(landscapeDefnFile
, true);
94 if (!landscapeDefn
) return false;
97 std::vector
<std::string
> &texs
= entry
.texs
;
98 for (itor2
= texs
.begin();
102 const char *landscapeTexFile
= (*itor2
).c_str();
103 LandscapeTex
*landscapeTex
= getTex(landscapeTexFile
, true);
104 if (!landscapeTex
) return false;
111 const char *LandscapeDefinitions::getLeastUsedFile(std::vector
<std::string
> &files
)
113 DIALOG_ASSERT(!files
.empty());
115 const char *result
= "";
116 int usedTimes
= INT_MAX
;
118 std::vector
<std::string
>::iterator itor
;
119 for (itor
= files
.begin();
123 std::string
&file
= (*itor
);
126 std::map
<std::string
, int>::iterator findItor
=
127 usedFiles_
.find(file
);
128 if (findItor
!= usedFiles_
.end())
130 used
= (*findItor
).second
;
133 if (used
< usedTimes
)
136 result
= file
.c_str();
140 usedFiles_
[result
] = usedTimes
+ 1;
144 void LandscapeDefinitions::checkEnabled(OptionsScorched
&context
)
146 std::list
<LandscapeDefinitionsEntry
>::iterator itor
;
147 for (itor
= entries_
.begin();
148 itor
!= entries_
.end();
151 LandscapeDefinitionsEntry
&result
= *itor
;
152 if (landscapeEnabled(context
.getMainOptions(), result
.name
.c_str()))
158 context
.getChangedOptions().getLandscapesEntry().setValue("");
159 Logger::log(S3D::formatStringBuffer(
160 "Warning: No existing landscapes are enabled (Landscapes : %s)",
161 context
.getLandscapes()));
164 LandscapeDefinition
LandscapeDefinitions::getLandscapeDefn(
167 LandscapeDefinitionsEntry
*result
= 0;
169 // Build a list of the maps that are enabled
170 std::list
<LandscapeDefinitionsEntry
>::iterator itor
;
171 for (itor
= entries_
.begin();
172 itor
!= entries_
.end();
176 if (0 == strcmp(name
, result
->name
.c_str())) break;
179 // Return the chosen definition
180 std::string tex
= result
->texs
[rand() % result
->texs
.size()];
181 std::string defn
= result
->defns
[rand() % result
->defns
.size()];
182 unsigned int seed
= 33;//(unsigned int) rand();
184 LandscapeDefinition
entry(
185 tex
.c_str(), defn
.c_str(), seed
, result
->name
.c_str());
189 LandscapeDefinition
LandscapeDefinitions::getRandomLandscapeDefn(
190 OptionsScorched
&context
, TankContainer
&tankContainer
)
192 // Build a list of the maps that are enabled
193 int players
= tankContainer
.getNoOfNonSpectatorTanks();
194 std::list
<LandscapeDefinitionsEntry
*> allPassedLandscapes
;
195 std::list
<LandscapeDefinitionsEntry
*> minMaxPassedLandscapes
;
196 std::list
<LandscapeDefinitionsEntry
>::iterator itor
;
197 for (itor
= entries_
.begin();
198 itor
!= entries_
.end();
201 LandscapeDefinitionsEntry
¤t
= *itor
;
202 if (landscapeEnabled(context
.getMainOptions(), current
.name
.c_str()))
204 allPassedLandscapes
.push_back(¤t
);
206 // Check that min/max players are ok
207 std::vector
<std::string
>::iterator defnitor
;
208 for (defnitor
= current
.defns
.begin();
209 defnitor
!= current
.defns
.end();
212 LandscapeDefn
*defn
= getDefn(defnitor
->c_str());
213 if (players
>= defn
->getMinPlayers() && players
<= defn
->getMaxPlayers())
215 minMaxPassedLandscapes
.push_back(¤t
);
222 // Check we have a least one map
223 DIALOG_ASSERT(!allPassedLandscapes
.empty());
226 LandscapeDefinitionsEntry
*result
= getRandomLandscapeDefnEntry(
227 context
, minMaxPassedLandscapes
);
231 Logger::log("Warning: Cannot find any landscapes for number of players");
232 result
= getRandomLandscapeDefnEntry(context
, allPassedLandscapes
);
235 // Check we found map
238 S3D::dialogExit("Scorched3D",
239 "Failed to select a landscape definition");
242 // Return the chosen definition
243 std::string tex
= getLeastUsedFile(result
->texs
);
244 std::string defn
= getLeastUsedFile(result
->defns
);
245 unsigned int seed
= (unsigned int) rand();
246 LandscapeTex
*landscapeTex
= getTex(tex
.c_str());
247 if (landscapeTex
->seed
!= 0) seed
= landscapeTex
->seed
;
249 LandscapeDefinition
entry(
250 tex
.c_str(), defn
.c_str(), seed
, result
->name
.c_str());
255 LandscapeDefinitionsEntry
*LandscapeDefinitions::getRandomLandscapeDefnEntry(
256 OptionsScorched
&context
,
257 std::list
<LandscapeDefinitionsEntry
*> passedLandscapes
)
260 LandscapeDefinitionsEntry
*result
= 0;
261 if (context
.getCycleMaps())
263 // Just cycle through the maps
265 result
= passedLandscapes
.front();
266 std::list
<LandscapeDefinitionsEntry
*>::iterator passedItor
;
267 for (passedItor
= passedLandscapes
.begin();
268 passedItor
!= passedLandscapes
.end();
271 LandscapeDefinitionsEntry
*current
= *passedItor
;
277 if (current
== lastDefinition_
) next
= true;
279 lastDefinition_
= result
;
283 float totalWeight
= 0.0f
;
284 std::list
<LandscapeDefinitionsEntry
*>::iterator passedItor
;
285 for (passedItor
= passedLandscapes
.begin();
286 passedItor
!= passedLandscapes
.end();
289 LandscapeDefinitionsEntry
*current
= *passedItor
;
290 totalWeight
+= current
->weight
;
293 // Choose a map based on probablity
294 float pos
= RAND
* totalWeight
;
296 for (passedItor
= passedLandscapes
.begin();
297 passedItor
!= passedLandscapes
.end();
300 LandscapeDefinitionsEntry
*current
= *passedItor
;
301 soFar
+= current
->weight
;