Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2012/src/orxonox/ShipManager.cc @ 9216

Last change on this file since 9216 was 9208, checked in by smerkli, 13 years ago

merged branch shipSelection

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