Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/release2012/src/orxonox/LevelInfo.cc @ 11075

Last change on this file since 11075 was 9373, checked in by jo, 12 years ago

On the way to adjust multiplayermenue. Levels tagged with singleplayer should NOT be displayed in the multiplayermenue.

  • Property svn:eol-style set to native
File size: 9.3 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program 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.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Damian 'Mozork' Frick
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "LevelInfo.h"
30
31#include <sstream>
32#include <vector>
33
34#include "util/SubString.h"
35#include "core/CoreIncludes.h"
36#include "core/XMLPort.h"
37
38#include "LevelManager.h"
39
40namespace orxonox
41{
42
43    // LevelInfoItem
44
45    //! The list of allowed tags.
46    /*static*/ std::set<std::string> LevelInfoItem::possibleTags_s = std::set<std::string>();
47
48    /**
49    @brief
50        Default constructor.
51    */
52    LevelInfoItem::LevelInfoItem()
53    {
54
55    }
56
57    /**
58    @brief
59        Constructor. Initializes the object.
60    @param name
61        The name of the Level.
62    @param filename
63        The XML-filename of the Level.
64    */
65    LevelInfoItem::LevelInfoItem(const std::string& name, const std::string filename)
66    {
67        this->setName(name);
68        this->setXMLFilename(filename);
69    }
70
71    /**
72    @brief
73        Destructor.
74    */
75    LevelInfoItem::~LevelInfoItem()
76    {
77
78    }
79
80    /**
81    @brief
82        Initialize the set of allowed tags.
83    */
84    /*static*/ void LevelInfoItem::initializeTags(void)
85    {
86        if(!LevelInfoItem::initialized_s)
87        {
88            LevelInfoItem::possibleTags_s.insert("test");
89            LevelInfoItem::possibleTags_s.insert("showcase");
90            LevelInfoItem::possibleTags_s.insert("tutorial");
91            LevelInfoItem::possibleTags_s.insert("presentation");
92            LevelInfoItem::possibleTags_s.insert("mission");
93            LevelInfoItem::possibleTags_s.insert("gametype");
94            LevelInfoItem::possibleTags_s.insert("minigame");
95            LevelInfoItem::possibleTags_s.insert("shipselection");
96            LevelInfoItem::possibleTags_s.insert("singleplayer");
97        }
98    }
99
100    /**
101    @brief
102        Set the tags the Level is tagged with.
103    @param tags
104        A comma-seperated string of all the tags to be set.
105    */
106    void LevelInfoItem::setTags(const std::string& tags)
107    {
108        SubString substr = SubString(tags, ",", " "); // Split the string into tags.
109        const std::vector<std::string>& strings = substr.getAllStrings();
110        for (std::vector<std::string>::const_iterator it = strings.begin(); it != strings.end(); it++)
111            this->addTag(*it, false);
112
113        this->tagsUpdated();
114    }
115    /**
116    @brief
117        Set the starting ship models of the level
118    @param tags
119        A comma-seperated string of all the allowed ship models for the shipselection.
120    */
121    void LevelInfoItem::setStartingShips(const std::string& ships)
122    {
123        SubString substr = SubString(ships, ",", " "); // Split the string into tags.
124        const std::vector<std::string>& strings = substr.getAllStrings();
125        for(std::vector<std::string>::const_iterator it = strings.begin(); it != strings.end(); it++)
126            this->addStartingShip(*it, false);
127
128        this->startingshipsUpdated();
129    }
130
131    /**
132    @brief
133        Add a tag to the set of tags the Level is tagged with.
134    @param tag
135        The tag to be added.
136    @param update
137        Whether the comma-seperated string of all tags should be updated. Default is true.
138    @return
139        Returns true if the tag was successfully added, if the tag was already present it returns false.
140    */
141    bool LevelInfoItem::addTag(const std::string& tag, bool update)
142    {
143        if(!this->validateTag(tag))
144        {
145            orxout(internal_warning) << "Bad LevelInfo tag '" << tag << "' in " << this->getXMLFilename() << ". Ignoring..." << endl;
146            return false;
147        }
148        bool success = this->tags_.insert(*LevelInfoItem::possibleTags_s.find(tag)).second;
149        if(update && success)
150            this->tagsUpdated();
151        return success;
152    }
153
154    /**
155    @brief
156        Add a ship model to allowed models for the shipselection
157    @param ship
158        The ship model to be added.
159    @param update
160        Whether the comma-seperated string of all ship models should be updated. Default is true.
161    @return
162        Returns true if the ship was successfully added, if the ship was already present it returns false.
163    */
164    bool LevelInfoItem::addStartingShip(const std::string& ship, bool update)
165    {
166        bool success = this->startingShips_.insert(ship).second;
167        if(update && success)
168            this->startingshipsUpdated();
169
170        return success;
171    }
172
173
174    /**
175    @brief
176        Updates the comma-seperated string of all tags, if the set of tags has changed.
177    */
178    void LevelInfoItem::tagsUpdated(void)
179    {
180        std::stringstream stream;
181        std::set<std::string>::iterator temp;
182        for(std::set<std::string>::iterator it = this->tags_.begin(); it != this->tags_.end(); )
183        {
184            temp = it;
185            if(++it == this->tags_.end()) // If this is the last tag we don't add a comma.
186                stream << *temp;
187            else
188                stream << *temp << ", ";
189        }
190
191        this->tagsString_ = std::string(stream.str());
192    }
193
194    /**
195    @brief
196        Updates the comma-seperated string of all ships, if the set of tags has changed.
197    */
198    void LevelInfoItem::startingshipsUpdated(void)
199    {
200        std::stringstream stream;
201        std::set<std::string>::iterator temp;
202        for(std::set<std::string>::iterator it = this->startingShips_.begin(); it != this->startingShips_.end(); )
203        {
204            temp = it;
205            if(++it == this->startingShips_.end()) // If this is the last ship we don't add a comma.
206                stream << *temp;
207            else
208                stream << *temp << ", ";
209        }
210
211        this->startingShipsString_ = std::string(stream.str());
212    }
213
214    void LevelInfoItem::changeStartingShip(const std::string& model)
215    {
216        static std::string shipSelectionTag = "shipselection";
217        //HACK: Read Level XML File, find "shipselection", replace with ship model
218        std::string levelPath = "../levels/";
219        levelPath.append(this->getXMLFilename());
220        std::string tempPath = "../levels/";
221        tempPath.append("_temp.oxw");
222        orxout(user_status) << levelPath << endl;
223        orxout(user_status) << tempPath << endl;
224        std::ifstream myLevel (levelPath.c_str());
225        std::ofstream tempLevel (tempPath.c_str());
226        while(!myLevel.eof())
227        {
228            std::string buff;
229            std::getline(myLevel, buff);
230            std::string pawndesignString = "pawndesign=";
231            size_t found = buff.find(pawndesignString.append(shipSelectionTag));
232            if (found!= std::string::npos)
233                buff = buff.substr(0, found + 11) + model + buff.substr(found+11+shipSelectionTag.length(), std::string::npos);
234            tempLevel.write(buff.c_str(), buff.length());
235            tempLevel << std::endl;
236        }
237        myLevel.close();
238        tempLevel.close();
239        orxout(user_status) << "done" << endl;
240    }
241
242
243    // LevelInfo
244
245    CreateFactory(LevelInfo);
246
247    /**
248    @brief
249
250    @param creator
251        The creator of this object.
252    */
253    LevelInfo::LevelInfo(BaseObject* creator) : BaseObject(creator)
254    {
255        RegisterObject(LevelInfo);
256
257        this->xmlfilename_ = this->getFilename();
258    }
259
260    /**
261    @brief
262        Destructor.
263    */
264    LevelInfo::~LevelInfo()
265    {
266
267    }
268
269    /**
270    @brief
271        Creates a LevelInfo object through XML.
272    */
273    void LevelInfo::XMLPort(Element& xmlelement, XMLPort::Mode mode)
274    {
275        SUPER(LevelInfo, XMLPort, xmlelement, mode);
276
277        XMLPortParam(LevelInfo, "description", setDescription, getDescription, xmlelement, mode);
278        XMLPortParam(LevelInfo, "screenshot", setScreenshot, getScreenshot, xmlelement, mode);
279        XMLPortParam(LevelInfo, "tags", setTags, getTags, xmlelement, mode);
280        XMLPortParam(LevelInfo, "startingships", setStartingShips, getStartingShips, xmlelement, mode);
281    }
282
283    /**
284    @brief
285        Copies the contents of this LevelInfo object to a new LevelInfoItem object.
286        This is needed, because a LeveInfo object is only created within the scope of the XML-file it is loaded with and is destroyed once that is unloaded.
287    @return
288        Returns a new LevelInfoItem with the same contents as the LevelInfo object.
289    */
290    LevelInfoItem* LevelInfo::copy(void)
291    {
292        LevelInfoItem* info = new LevelInfoItem(this->BaseObject::getName(), this->getXMLFilename());
293        info->setDescription(this->getDescription());
294        info->setScreenshot(this->getScreenshot());
295        info->setTags(this->getTags());
296        info->setStartingShips(this->getStartingShips());
297        return info;
298    }
299
300}
301
Note: See TracBrowser for help on using the repository browser.