Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/src/orxonox/LevelInfo.cc @ 11003

Last change on this file since 11003 was 10916, checked in by landauf, 10 years ago

use actual types instead of 'auto'. only exception is for complicated template types, e.g. when iterating over a map

  • Property svn:eol-style set to native
File size: 9.1 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        }
97    }
98
99    /**
100    @brief
101        Set the tags the Level is tagged with.
102    @param tags
103        A comma-seperated string of all the tags to be set.
104    */
105    void LevelInfoItem::setTags(const std::string& tags)
106    {
107        SubString substr = SubString(tags, ",", " "); // Split the string into tags.
108        const std::vector<std::string>& tokens = substr.getAllStrings();
109        for (const std::string& token : tokens)
110            this->addTag(token, false);
111
112        this->tagsUpdated();
113    }
114    /**
115    @brief
116        Set the starting ship models of the level
117    @param tags
118        A comma-seperated string of all the allowed ship models for the shipselection.
119    */
120    void LevelInfoItem::setStartingShips(const std::string& ships)
121    {
122        SubString substr = SubString(ships, ",", " "); // Split the string into tags.
123        const std::vector<std::string>& tokens = substr.getAllStrings();
124        for(const std::string& token : tokens)
125            this->addStartingShip(token, false);
126
127        this->startingshipsUpdated();
128    }
129
130    /**
131    @brief
132        Add a tag to the set of tags the Level is tagged with.
133    @param tag
134        The tag to be added.
135    @param update
136        Whether the comma-seperated string of all tags should be updated. Default is true.
137    @return
138        Returns true if the tag was successfully added, if the tag was already present it returns false.
139    */
140    bool LevelInfoItem::addTag(const std::string& tag, bool update)
141    {
142        if(!this->validateTag(tag))
143        {
144            orxout(internal_warning) << "Bad LevelInfo tag '" << tag << "' in " << this->getXMLFilename() << ". Ignoring..." << endl;
145            return false;
146        }
147        bool success = this->tags_.insert(*LevelInfoItem::possibleTags_s.find(tag)).second;
148        if(update && success)
149            this->tagsUpdated();
150        return success;
151    }
152
153    /**
154    @brief
155        Add a ship model to allowed models for the shipselection
156    @param ship
157        The ship model to be added.
158    @param update
159        Whether the comma-seperated string of all ship models should be updated. Default is true.
160    @return
161        Returns true if the ship was successfully added, if the ship was already present it returns false.
162    */
163    bool LevelInfoItem::addStartingShip(const std::string& ship, bool update)
164    {
165        bool success = this->startingShips_.insert(ship).second;
166        if(update && success)
167            this->startingshipsUpdated();
168
169        return success;
170    }
171
172
173    /**
174    @brief
175        Updates the comma-seperated string of all tags, if the set of tags has changed.
176    */
177    void LevelInfoItem::tagsUpdated(void)
178    {
179        std::stringstream stream;
180        std::set<std::string>::iterator temp;
181        for(std::set<std::string>::iterator it = this->tags_.begin(); it != this->tags_.end(); )
182        {
183            temp = it;
184            if(++it == this->tags_.end()) // If this is the last tag we don't add a comma.
185                stream << *temp;
186            else
187                stream << *temp << ", ";
188        }
189
190        this->tagsString_ = std::string(stream.str());
191    }
192
193    /**
194    @brief
195        Updates the comma-seperated string of all ships, if the set of tags has changed.
196    */
197    void LevelInfoItem::startingshipsUpdated(void)
198    {
199        std::stringstream stream;
200        std::set<std::string>::iterator temp;
201        for(std::set<std::string>::iterator it = this->startingShips_.begin(); it != this->startingShips_.end(); )
202        {
203            temp = it;
204            if(++it == this->startingShips_.end()) // If this is the last ship we don't add a comma.
205                stream << *temp;
206            else
207                stream << *temp << ", ";
208        }
209
210        this->startingShipsString_ = std::string(stream.str());
211    }
212
213    void LevelInfoItem::changeStartingShip(const std::string& model)
214    {
215        static std::string shipSelectionTag = "shipselection";
216        //HACK: Read Level XML File, find "shipselection", replace with ship model
217        std::string levelPath = "../levels/";
218        levelPath.append(this->getXMLFilename());
219        std::string tempPath = "../levels/";
220        tempPath.append("_temp.oxw");
221        orxout(user_status) << levelPath << endl;
222        orxout(user_status) << tempPath << endl;
223        std::ifstream myLevel (levelPath.c_str());
224        std::ofstream tempLevel (tempPath.c_str());
225        while(!myLevel.eof())
226        {
227            std::string buff;
228            std::getline(myLevel, buff);
229            std::string pawndesignString = "pawndesign=";
230            size_t found = buff.find(pawndesignString.append(shipSelectionTag));
231            if (found!= std::string::npos)
232                buff = buff.substr(0, found + 11) + model + buff.substr(found+11+shipSelectionTag.length(), std::string::npos);
233            tempLevel.write(buff.c_str(), buff.length());
234            tempLevel << std::endl;
235        }
236        myLevel.close();
237        tempLevel.close();
238        orxout(user_status) << "done" << endl;
239    }
240
241
242    // LevelInfo
243
244    RegisterClass(LevelInfo);
245
246    /**
247    @brief
248
249    @param creator
250        The creator of this object.
251    */
252    LevelInfo::LevelInfo(Context* context) : BaseObject(context)
253    {
254        RegisterObject(LevelInfo);
255
256        this->xmlfilename_ = this->getFilename();
257    }
258
259    /**
260    @brief
261        Destructor.
262    */
263    LevelInfo::~LevelInfo()
264    {
265
266    }
267
268    /**
269    @brief
270        Creates a LevelInfo object through XML.
271    */
272    void LevelInfo::XMLPort(Element& xmlelement, XMLPort::Mode mode)
273    {
274        SUPER(LevelInfo, XMLPort, xmlelement, mode);
275
276        XMLPortParam(LevelInfo, "description", setDescription, getDescription, xmlelement, mode);
277        XMLPortParam(LevelInfo, "screenshot", setScreenshot, getScreenshot, xmlelement, mode);
278        XMLPortParam(LevelInfo, "tags", setTags, getTags, xmlelement, mode);
279        XMLPortParam(LevelInfo, "startingships", setStartingShips, getStartingShips, xmlelement, mode);
280    }
281
282    /**
283    @brief
284        Copies the contents of this LevelInfo object to a new LevelInfoItem object.
285        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.
286    @return
287        Returns a new LevelInfoItem with the same contents as the LevelInfo object.
288    */
289    LevelInfoItem* LevelInfo::copy(void)
290    {
291        LevelInfoItem* info = new LevelInfoItem(this->BaseObject::getName(), this->getXMLFilename());
292        info->setDescription(this->getDescription());
293        info->setScreenshot(this->getScreenshot());
294        info->setTags(this->getTags());
295        info->setStartingShips(this->getStartingShips());
296        return info;
297    }
298
299}
300
Note: See TracBrowser for help on using the repository browser.