Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/util/loading/game_loader.cc @ 4411

Last change on this file since 4411 was 4411, checked in by patrick, 19 years ago

orxonox/trunk: now system events work again: quit, pause, next-level

File size: 7.8 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer: ...
16*/
17
18#include "game_loader.h"
19#include "campaign.h"
20#include "world.h"
21#include "player.h"
22#include "orxonox.h"
23#include "camera.h"
24#include "command_node.h"
25#include "vector.h"
26#include "resource_manager.h"
27#include "factory.h"
28#include "event.h"
29#include "event_handler.h"
30
31#include <string.h>
32
33
34using namespace std;
35
36
37GameLoader* GameLoader::singletonRef = 0;
38
39
40GameLoader::GameLoader () 
41{
42  first = NULL;
43}
44
45
46GameLoader::~GameLoader () {}
47
48
49/**
50   \brief this class is a singleton class
51   \returns an instance of itself
52
53   if you are unsure about singleton classes, check the theory out on the internet :)
54*/
55GameLoader* GameLoader::getInstance()
56{
57  if(singletonRef == NULL)
58    singletonRef = new GameLoader();
59  return singletonRef;
60}
61
62
63ErrorMessage GameLoader::init()
64{
65  if(this->currentCampaign != NULL)
66    this->currentCampaign->init();
67
68  this->eventHandler = EventHandler::getInstance();
69  this->eventHandler->subscribe(this, ES_ALL, KeyMapper::PEV_PAUSE);
70  this->eventHandler->subscribe(this, ES_ALL, KeyMapper::PEV_QUIT);
71  this->eventHandler->subscribe(this, ES_ALL, KeyMapper::PEV_NEXT_WORLD);
72  this->eventHandler->subscribe(this, ES_ALL, KeyMapper::PEV_PREVIOUS_WORLD);
73}
74
75
76/**
77   \brief reads a campaign definition file into a campaign class
78   \param filename to be loaded
79   \returns the loaded campaign
80
81   this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
82*/
83ErrorMessage GameLoader::loadCampaign(const char* name)
84{
85  ErrorMessage errorCode;
86  char* campaignName = ResourceManager::getFullName(name);
87  if (campaignName)
88    {
89      this->currentCampaign = this->fileToCampaign(campaignName);
90      delete campaignName;
91    }
92  World* world0 = new World(DEBUG_WORLD_0);
93  world0->setNextStoryID(WORLD_ID_GAMEEND);
94  this->currentCampaign->addEntity(world0, WORLD_ID_2);
95}
96
97/**
98   \brief loads a debug campaign for test purposes only.
99   \param the identifier of the campaign.
100   \returns error message if not able to do so.
101*/
102ErrorMessage GameLoader::loadDebugCampaign(Uint32 campaignID)
103{
104  switch(campaignID)
105    {
106      /*
107         Debug Level 0: Debug level used to test the base frame work.
108         As you can see, all storyentity data is allocated before game
109         start. the storyentity will load themselfs shortly before start
110         through the StoryEntity::init() funtion.
111      */
112    case DEBUG_CAMPAIGN_0:
113      {
114        Campaign* debugCampaign = new Campaign();
115
116        World* world0 = new World(DEBUG_WORLD_0);
117        world0->setNextStoryID(WORLD_ID_1);
118        debugCampaign->addEntity(world0, WORLD_ID_0);
119
120        World* world1 = new World(DEBUG_WORLD_1);
121        world1->setNextStoryID(WORLD_ID_2);
122        debugCampaign->addEntity(world1, WORLD_ID_1);
123
124        World* world2 = new World(DEBUG_WORLD_2);
125        world2->setNextStoryID(WORLD_ID_GAMEEND);
126        debugCampaign->addEntity(world2, WORLD_ID_2);
127
128        this->currentCampaign = debugCampaign;
129        break;
130      }
131    }
132}
133
134ErrorMessage GameLoader::start()
135{
136  if(this->currentCampaign != NULL)
137    this->currentCampaign->start();
138}
139
140
141ErrorMessage GameLoader::stop()
142{
143  if(this->currentCampaign != NULL)
144    this->currentCampaign->stop();
145  this->currentCampaign = NULL;
146}
147
148
149ErrorMessage GameLoader::pause()
150{
151  this->isPaused = true;
152  if(this->currentCampaign != NULL)
153    this->currentCampaign->pause();
154}
155
156
157ErrorMessage GameLoader::resume()
158{
159  this->isPaused = false;
160  if(this->currentCampaign != NULL)
161    this->currentCampaign->resume();
162}
163
164/**
165   \brief release the mem
166 */
167ErrorMessage GameLoader::destroy()
168{}
169
170
171/**
172   \brief reads a campaign definition file into a campaign class
173   \param filename to be loaded
174   \returns the loaded campaign
175
176   this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
177*/
178Campaign* GameLoader::fileToCampaign(const char *name)
179{
180  /* do not entirely load the campaign. just the current world
181     before start of each world, it has to be initialized so it
182     can load everything it needs into memory then.
183  */
184 
185  if( name == NULL)
186    {
187      PRINTF(2)("No filename specified for loading");
188      return NULL;
189    }
190 
191  TiXmlDocument* XMLDoc = new TiXmlDocument( name);
192  // load the campaign document
193  if( !XMLDoc->LoadFile())
194    {
195      // report an error
196      PRINTF(1)("Could not load XML File %s: %s @ %d:%d\n", name, XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
197      delete XMLDoc;
198      return NULL;
199    }
200       
201  // check basic validity
202  TiXmlElement* root = XMLDoc->RootElement();
203  assert( root != NULL);
204       
205  if( strcmp( root->Value(), "Campaign"))
206    {
207      // report an error
208      PRINTF(2)("Specified XML File is not an orxonox campaign file (Campaign element missing)\n");
209      delete XMLDoc;
210      return NULL;
211    }
212       
213  // construct campaign
214  Campaign* c = new Campaign( root);
215       
216  // free the XML data
217  delete XMLDoc;
218       
219  return c;
220}
221
222
223/**
224   \brief handle keyboard commands
225   \param cmd: the command to handle
226   \returns true if the command was handled by the system
227*/
228bool GameLoader::worldCommand (Command* cmd)
229{
230  if( !strcmp( cmd->cmd, CONFIG_NAME_NEXT_WORLD))
231    {
232      if( !cmd->bUp) 
233        {
234          this->nextLevel();
235        }
236      return true;
237    }
238  else if( !strcmp( cmd->cmd, CONFIG_NAME_PREV_WORLD))
239    {
240      if( !cmd->bUp)
241        {
242          this->previousLevel();
243        }
244      return true;
245    }
246  else if( !strcmp( cmd->cmd, CONFIG_NAME_PAUSE))
247    {
248      if( !cmd->bUp)
249        {
250          if(this->isPaused)
251            this->resume();
252          else
253            this->pause();
254        }
255      return true;
256    }
257  else if( !strcmp( cmd->cmd, CONFIG_NAME_QUIT))
258    {
259      if( !cmd->bUp) this->stop();
260      return true;
261    }
262  return false;
263}
264
265
266
267
268void GameLoader::process(const Event& event)
269{
270  if( event.type == KeyMapper::PEV_NEXT_WORLD)
271    {
272      if( likely(event.bPressed)) 
273        {
274          this->nextLevel();
275        }
276    }
277  else if( event.type == KeyMapper::PEV_PREVIOUS_WORLD)
278    {
279      if( likely(event.bPressed))
280        {
281          this->previousLevel();
282        }
283    }
284  else if( event.type == KeyMapper::PEV_PAUSE)
285    {
286      if( likely(event.bPressed))
287        {
288          if(this->isPaused)
289            this->resume();
290          else
291            this->pause();
292        }
293    }
294  else if( event.type == KeyMapper::PEV_QUIT)
295    {
296      if( event.bPressed) this->stop();
297    }
298}
299
300/*
301  \brief this changes to the next level
302*/
303void GameLoader::nextLevel()
304{
305  if(this->currentCampaign != NULL)
306    this->currentCampaign->nextLevel();
307}
308
309
310/*
311  \brief change to the previous level - not implemented
312
313  this propably useless
314*/
315void GameLoader::previousLevel()
316{
317  if(this->currentCampaign != NULL)
318    this->currentCampaign->previousLevel();
319}
320
321/**
322   \brief add a Factory to the Factory Q
323   \param factory a Factory to be registered
324*/
325void GameLoader::registerFactory( Factory* factory)
326{
327        assert( factory != NULL);
328       
329        PRINTF(4)("Registered factory for '%s'\n", factory->getFactoryName());
330       
331        if( first == NULL) first = factory;
332        else first->registerFactory( factory);
333}
334
335/**
336   \brief load a StoryEntity
337   \param element a XMLElement containing all the needed info
338*/
339BaseObject* GameLoader::fabricate( TiXmlElement* element)
340{
341  assert( element != NULL);
342       
343  if( first == NULL)
344    {
345      PRINTF(1)("GameLoader does not know any factories, fabricate() failed\n");
346      return NULL;
347    }
348       
349  if( element->Value() != NULL)
350    {
351      PRINTF(4)("Attempting fabrication of a '%s'\n", element->Value());
352      BaseObject* b = first->fabricate( element);
353      if( b == NULL) 
354        PRINTF(2)("Failed to fabricate a '%s'\n", element->Value());
355      else 
356        PRINTF(4)("Successfully fabricated a '%s'\n", element->Value());
357      return b;
358    }
359       
360  PRINTF(2)("Fabricate failed, TiXmlElement did not contain a value\n");
361       
362  return NULL;
363}
Note: See TracBrowser for help on using the repository browser.