Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/masterserver2/src/orxonox/gamestates/GSLevel.cc @ 8016

Last change on this file since 8016 was 7879, checked in by landauf, 14 years ago

moved compositor unloading to avoid crashes in rare cases
disabled compositor unloading for Ogre 1.7.0+ which fixes some issues with shaders

I'm unsure if this belongs into GSLevel anyway, since it's resource related and removeAll() requires quite some attention to be called in the right place.

  • Property svn:eol-style set to native
File size: 6.8 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 *      Reto Grieder
24 *   Co-authors:
25 *      Fabian 'x3n' Landau
26 *      Benjamin Knecht
27 *
28 */
29
30#include "GSLevel.h"
31
32#include <OgreCompositorManager.h>
33
34#include "util/Clock.h"
35#include "core/input/InputManager.h"
36#include "core/input/InputState.h"
37#include "core/input/KeyBinderManager.h"
38#include "core/Core.h"
39#include "core/Game.h"
40#include "core/GameMode.h"
41#include "core/GUIManager.h"
42#include "core/Loader.h"
43#include "core/XMLFile.h"
44#include "core/command/ConsoleCommand.h"
45
46#include "LevelManager.h"
47#include "PlayerManager.h"
48
49namespace orxonox
50{
51    DeclareGameState(GSLevel, "level", false, false);
52
53    static const std::string __CC_startMainMenu_name = "startMainMenu";
54    static const std::string __CC_changeGame_name = "changeGame";
55
56    SetConsoleCommand(__CC_startMainMenu_name, &GSLevel::startMainMenu).deactivate();
57    SetConsoleCommand(__CC_changeGame_name, &GSLevel::changeGame).defaultValues(BLANKSTRING).deactivate();
58
59    GSLevel::GSLevel(const GameStateInfo& info)
60        : GameState(info)
61        , gameInputState_(0)
62        , guiMouseOnlyInputState_(0)
63        , guiKeysOnlyInputState_(0)
64        , startFile_(0)
65        , bShowIngameGUI_(false)
66    {
67    }
68
69    GSLevel::~GSLevel()
70    {
71    }
72
73    void GSLevel::activate()
74    {
75        if (GameMode::showsGraphics())
76        {
77            gameInputState_ = InputManager::getInstance().createInputState("game");
78            gameInputState_->setMouseExclusive(TriBool::True);
79            gameInputState_->setHandler(KeyBinderManager::getInstance().getDefaultAsHandler());
80            KeyBinderManager::getInstance().setToDefault();
81
82            guiMouseOnlyInputState_ = InputManager::getInstance().createInputState("guiMouseOnly");
83            guiMouseOnlyInputState_->setMouseExclusive(TriBool::True);
84            guiMouseOnlyInputState_->setMouseHandler(&GUIManager::getInstance());
85
86            guiKeysOnlyInputState_ = InputManager::getInstance().createInputState("guiKeysOnly");
87            guiKeysOnlyInputState_->setKeyHandler(&GUIManager::getInstance());
88        }
89
90        if (GameMode::isMaster())
91        {
92            this->loadLevel();
93        }
94
95        if (GameMode::showsGraphics())
96        {
97            // level is loaded: we can start capturing the input
98            InputManager::getInstance().enterState("game");
99
100            // connect the HumanPlayer to the game
101            PlayerManager::getInstance().clientConnected(0);
102
103            ModifyConsoleCommand(__CC_startMainMenu_name).activate();
104        }
105
106        if (GameMode::isStandalone())
107            ModifyConsoleCommand(__CC_changeGame_name).activate();
108    }
109
110    void GSLevel::deactivate()
111    {
112        if (GameMode::showsGraphics())
113            InputManager::getInstance().leaveState("game");
114
115        // disconnect all HumanPlayers
116        PlayerManager::getInstance().disconnectAllClients();
117
118        if (GameMode::isMaster())
119            this->unloadLevel();
120
121        if (GameMode::showsGraphics())
122        {
123#if OGRE_VERSION < 0x010700
124            // unload all compositors (this is only necessary because we don't yet destroy all resources!)
125            Ogre::CompositorManager::getSingleton().removeAll();
126#endif
127
128            gameInputState_->setHandler(0);
129            guiMouseOnlyInputState_->setHandler(0);
130            guiKeysOnlyInputState_->setHandler(0);
131            InputManager::getInstance().destroyState("game");
132            InputManager::getInstance().destroyState("guiKeysOnly");
133            InputManager::getInstance().destroyState("guiMouseOnly");
134
135            ModifyConsoleCommand(__CC_startMainMenu_name  ).deactivate();
136        }
137
138        if (GameMode::isStandalone())
139            ModifyConsoleCommand(__CC_changeGame_name).deactivate();
140    }
141
142    void GSLevel::update(const Clock& time)
143    {
144        // Note: Temporarily moved to GSRoot.
145        //// Call the scene objects
146        //for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
147        //    it->tick(time.getDeltaTime() * this->timeFactor_);
148    }
149
150    void GSLevel::loadLevel()
151    {
152        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it != ObjectList<BaseObject>::end(); ++it)
153            this->staticObjects_.insert(*it);
154
155        // call the loader
156        COUT(0) << "Loading level..." << std::endl;
157        startFile_ = new XMLFile(LevelManager::getInstance().getDefaultLevel());
158        Loader::open(startFile_);
159
160        Core::getInstance().updateLastLevelTimestamp();
161    }
162
163    void GSLevel::unloadLevel()
164    {
165        Loader::unload(startFile_);
166        delete startFile_;
167
168        COUT(3) << "Unloaded level. Remaining objects:" << std::endl;
169        unsigned int i = 0;
170        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it != ObjectList<BaseObject>::end(); ++it)
171        {
172            std::set<BaseObject*>::const_iterator find = this->staticObjects_.find(*it);
173            if (find == this->staticObjects_.end())
174            {
175                COUT(3) << ++i << ": " << it->getIdentifier()->getName() << " (" << *it << "), references: " << it->getReferenceCount() << std::endl;
176            }
177        }
178        COUT(3) << i << " objects remaining.";
179        if (i == 0)
180            COUT(3) << " Well done!" << std::endl;
181        else
182            COUT(3) << " Try harder!" << std::endl;
183    }
184
185    /**
186    @brief
187        Starts the MainMenu.
188    */
189    /*static*/ void GSLevel::startMainMenu(void)
190    {
191        // HACK
192        Game::getInstance().popState();
193        Game::getInstance().popState();
194    }
195
196    /**
197    @brief
198        Terminates the current game and starts a new game.
199    @param level
200        The filename of the level to be started.
201    */
202    /*static*/ void GSLevel::changeGame(const std::string& level)
203    {
204        if(level != BLANKSTRING)
205            LevelManager::getInstance().setDefaultLevel(level);
206
207        // HACK
208        Game::getInstance().popState();
209        Game::getInstance().popState();
210        Game::getInstance().requestStates("standalone, level");
211    }
212}
Note: See TracBrowser for help on using the repository browser.