Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/SuperOrxoBros_HS18/src/orxonox/LevelInfo.cc @ 12207

Last change on this file since 12207 was 12177, checked in by siramesh, 6 years ago

Super Orxo Bros Final (Sidharth Ramesh, Nisa Balta, Jeff Ren)

File size: 10.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("Orxobros");
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>& tokens = substr.getAllStrings();
110        for (const std::string& token : tokens)
111            this->addTag(token, false);
112
113        this->tagsUpdated();
114    }
115    /**
116    @brief
117        Set the starting ship models of the level
118    @param ships
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>& tokens = substr.getAllStrings();
125        for(const std::string& token : tokens)
126            this->addStartingShip(token, 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    void LevelInfoItem::changeStartingLevel(const std::string& model)
243    {
244        static std::string shipSelectionTag = "orxobros";
245        //HACK: Read Level XML File, find "shipselection", replace with ship model
246        std::string levelPath = "../levels/";
247        levelPath.append(this->getXMLFilename());
248        std::string tempPath = "../levels/";
249        //tempPath.append("_temp.oxw");
250        orxout(user_status) << levelPath << endl;
251        orxout(user_status) << tempPath << endl;
252        std::ifstream myLevel (levelPath.c_str());
253        std::ofstream tempLevel (tempPath.c_str());
254        /*while(!myLevel.eof())
255        {
256            std::string buff;
257            std::getline(myLevel, buff);
258            std::string pawndesignString = "pawndesign=";
259            size_t found = buff.find(pawndesignString.append(shipSelectionTag));
260            if (found!= std::string::npos)
261                buff = buff.substr(0, found + 11) + model + buff.substr(found+11+shipSelectionTag.length(), std::string::npos);
262            tempLevel.write(buff.c_str(), buff.length());
263            tempLevel << std::endl;
264        }
265        myLevel.close();
266        tempLevel.close();
267        */
268        orxout(user_status) << "done" << endl;
269    }
270
271
272    // LevelInfo
273
274    RegisterClass(LevelInfo);
275
276    LevelInfo::LevelInfo(Context* context) : BaseObject(context)
277    {
278        RegisterObject(LevelInfo);
279
280        this->xmlfilename_ = this->getFilename();
281    }
282
283    /**
284    @brief
285        Destructor.
286    */
287    LevelInfo::~LevelInfo()
288    {
289
290    }
291
292    /**
293    @brief
294        Creates a LevelInfo object through XML.
295    */
296    void LevelInfo::XMLPort(Element& xmlelement, XMLPort::Mode mode)
297    {
298        SUPER(LevelInfo, XMLPort, xmlelement, mode);
299
300        XMLPortParam(LevelInfo, "description", setDescription, getDescription, xmlelement, mode);
301        XMLPortParam(LevelInfo, "screenshot", setScreenshot, getScreenshot, xmlelement, mode);
302        XMLPortParam(LevelInfo, "tags", setTags, getTags, xmlelement, mode);
303        XMLPortParam(LevelInfo, "startingships", setStartingShips, getStartingShips, xmlelement, mode);
304    }
305
306    /**
307    @brief
308        Copies the contents of this LevelInfo object to a new LevelInfoItem object.
309        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.
310    @return
311        Returns a new LevelInfoItem with the same contents as the LevelInfo object.
312    */
313    LevelInfoItem* LevelInfo::copy(void)
314    {
315        LevelInfoItem* info = new LevelInfoItem(this->BaseObject::getName(), this->getXMLFilename());
316        info->setDescription(this->getDescription());
317        info->setScreenshot(this->getScreenshot());
318        info->setTags(this->getTags());
319        info->setStartingShips(this->getStartingShips());
320        return info;
321    }
322
323}
324
Note: See TracBrowser for help on using the repository browser.