Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/shipSelection/src/orxonox/ShipManager.cc @ 9157

Last change on this file since 9157 was 9157, checked in by huttemat, 12 years ago

ShipSelecting working, still hackish and featureless though

File size: 7.0 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 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Damian 'Mozork' Frick
26 *
27 */
28
29/**
30    @file LevelManager.cc
31    @brief Implementation of the LevelManager singleton.
32*/
33
34#include "LevelManager.h"
35
36#include <map>
37
38#include "util/ScopedSingletonManager.h"
39#include "core/ClassTreeMask.h"
40#include "core/CommandLineParser.h"
41#include "core/ConfigValueIncludes.h"
42#include "core/CoreIncludes.h"
43#include "core/Loader.h"
44#include "core/Resource.h"
45#include "core/XMLFile.h"
46#include "Level.h"
47#include "PlayerManager.h"
48
49namespace orxonox
50{
51    SetCommandLineArgument(level, "").shortcut("l").information("Default level file (overrides LevelManager::defaultLevelName_ configValue)");
52
53    ManageScopedSingleton(LevelManager, ScopeID::Root, false);
54
55    /**
56    @brief
57        Constructor.
58    */
59    ShipManager::ShipManager()
60    {
61        RegisterRootObject(LevelManager);
62        this->compileAvailableLevelList();
63        this->nextIndex_ = 0;
64        this->nextLevel_ = this->availableLevels_.begin();
65    }
66
67    ShipManager::~ShipManager()
68    {
69        // Delete all the Ship objects because the LevelManager created them
70        std::set<SpaceShip*, LevelInfoCompare>::iterator it = availableLevels_.begin();
71        for (; it != availableLevels_.end(); ++it)
72            delete *it;
73    }
74
75   
76    /**
77    @brief
78        Get the number of available Ships.
79    @return
80        Returns the number of available Ships.
81    */
82    unsigned int LevelManager::getNumberOfLevels(){ return this->availableLevels_.size(); }
83
84    /**
85    @brief
86        Get the SpaceShip at the given index in the list of available Ships.
87        The SpaceShips are sorted in alphabetical order accoridng to the name of the Ship.
88        This method is most efficiently called with consecutive indices (or at least ascending indices).
89    @param index
90        The index of the item that should be returned.
91    @return
92        Returns a pointer to the SpaceShip at the given index.
93    */
94    SpaceShip* ShipManager::getAvailableShipListItem(unsigned int index)
95    {
96        if(index >= this->availableShips_.size())
97            return NULL;
98
99        // If this index directly follows the last we can optimize a lot.
100        if(index == this->nextIndex_)
101        {
102            this->nextIndex_++;
103            std::set<SpaceShip*, SpaceShipCompare>::iterator it = this->nextShip_;
104            this->nextLevel_++;
105            return *it;
106        }
107        else
108        {
109            // If this index is bigger than the last, we can optimize a little.
110            if(index < this->nextIndex_)
111            {
112                this->nextIndex_ = 0;
113                this->nextShip_ = this->availableShips_.begin();
114            }
115
116            while(this->nextIndex_ != index)
117            {
118                this->nextIndex_++;
119                this->nextShip_++;
120            }
121            this->nextIndex_++;
122            std::set<SpaceShip*, SpaceShipCompare>::iterator it = this->nextLevel_;
123            this->nextLevel_++;
124            return *it;
125        }
126    }
127
128    /**
129    @brief
130        Compile the list of available Levels.
131        Iterates over all *.oxw files, loads the LevelInfo objects in them and from that it creates the LevelInfoItems which are inserted in a list.
132    */
133    void ShipManager::compileAvailableShipList()
134    {
135                /*
136                // We only want to load as little as possible
137                ClassTreeMask mask;
138                    mask.exclude(Class(BaseObject));
139                    mask.include(Class(SpaceShip));
140                SpaceShip* info = NULL;
141                XMLFile file = XMLFile(ship);
142                Loader::load(&file, mask, false, true);
143                for(ObjectList<SpaceShip>::iterator item = ObjectList<SpaceShip>::begin(); item != ObjectList<SpaceShip>::end(); ++item)
144                        if(item->getXMLFilename() == *it)
145                            info = item->copy();
146                Loader::unload(&file);
147                */
148   
149        // Get all files matching the level criteria
150        Ogre::StringVectorPtr levels = Resource::findResourceNames("*.oxw");
151
152        // We only want to load as little as possible
153        ClassTreeMask mask;
154        mask.exclude(Class(BaseObject));
155        mask.include(Class(LevelInfo));
156
157        // Iterate over all the found *.oxw files
158        orxout(internal_info) << "Loading LevelInfos..." << endl;
159        std::set<std::string> names;
160        for (Ogre::StringVector::const_iterator it = levels->begin(); it != levels->end(); ++it)
161        {
162            // TODO: Replace with tag?
163            if (it->find("old/") != 0 )
164            {
165                LevelInfoItem* info = NULL;
166
167                // Load the LevelInfo object from the level file.
168                XMLFile file = XMLFile(*it);
169                Loader::load(&file, mask, false, true);
170
171                // Find the LevelInfo object we've just loaded (if there was one)
172                for(ObjectList<LevelInfo>::iterator item = ObjectList<LevelInfo>::begin(); item != ObjectList<LevelInfo>::end(); ++item)
173                    if(item->getXMLFilename() == *it)
174                        info = item->copy();
175
176                // We don't need the loaded stuff anymore
177                Loader::unload(&file);
178
179                if(info == NULL)
180                {
181                    // Create a default LevelInfoItem object that merely contains the name
182                    std::string filenameWOExtension = it->substr(0, it->find(".oxw"));
183                    info = new LevelInfoItem(filenameWOExtension, *it);
184                }
185
186                // Warn about levels with the same name.
187                if(!names.insert(info->getName()).second)
188                    orxout(internal_warning) << "Multiple levels (" << info->getXMLFilename() << ") with name '" << info->getName() << "' found!" << endl;
189
190                // Warn about multiple items so that it gets fixed quickly
191                if(availableLevels_.find(info) != availableLevels_.end())
192                {
193                    orxout(internal_warning) << "Multiple levels (" << info->getXMLFilename() << ") with same name '" << info->getName() << "' and filename found! Exluding..." << endl;
194                    // Delete LevelInfoItem to avoid a dangling pointer
195                    delete info;
196                }
197                else
198                    this->availableLevels_.insert(info);
199            }
200        }
201    }
202}
Note: See TracBrowser for help on using the repository browser.