Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4711 was 4598, checked in by bensch, 19 years ago

orxonox/trunk: campaign now gets loaded via LoadParam

File size: 8.5 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 "vector.h"
25#include "resource_manager.h"
26#include "factory.h"
27#include "event.h"
28#include "event_handler.h"
29
30#include <string.h>
31
32
33using namespace std;
34
35
36GameLoader* GameLoader::singletonRef = 0;
37
38/**
39   \brief simple constructor
40*/
41GameLoader::GameLoader ()
42{
43  this->setClassID(CL_GAME_LOADER, "GameLoader");
44  this->setName("GameLoader");
45  first = NULL;
46}
47
48
49/**
50   \brief simple deconstructor
51*/
52GameLoader::~GameLoader () {}
53
54
55/**
56   \brief this class is a singleton class
57   \returns an instance of itself
58
59   if you are unsure about singleton classes, check the theory out on the internet :)
60*/
61GameLoader* GameLoader::getInstance()
62{
63  if(singletonRef == NULL)
64    singletonRef = new GameLoader();
65  return singletonRef;
66}
67
68/**
69   \brief initializes the GameLoader
70*/
71ErrorMessage GameLoader::init()
72{
73  if(this->currentCampaign != NULL)
74    this->currentCampaign->init();
75
76  this->eventHandler = EventHandler::getInstance();
77  this->eventHandler->subscribe(this, ES_ALL, KeyMapper::PEV_PAUSE);
78  this->eventHandler->subscribe(this, ES_ALL, KeyMapper::PEV_QUIT);
79  this->eventHandler->subscribe(this, ES_ALL, KeyMapper::PEV_NEXT_WORLD);
80  this->eventHandler->subscribe(this, ES_ALL, KeyMapper::PEV_PREVIOUS_WORLD);
81}
82
83
84/**
85   \brief reads a campaign definition file into a campaign class
86   \param fileName to be loaded
87   \returns the loaded campaign
88
89   this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
90*/
91ErrorMessage GameLoader::loadCampaign(const char* fileName)
92{
93  ErrorMessage errorCode;
94  char* campaignName = ResourceManager::getFullName(fileName);
95  if (campaignName)
96    {
97      this->currentCampaign = this->fileToCampaign(campaignName);
98      delete campaignName;
99    }
100  World* world0 = new World(DEBUG_WORLD_0);
101  world0->setNextStoryID(WORLD_ID_GAMEEND);
102  this->currentCampaign->addEntity(world0, WORLD_ID_2);
103}
104
105/**
106   \brief loads a debug campaign for test purposes only.
107   \param campaignID the identifier of the campaign.
108   \returns error message if not able to do so.
109*/
110ErrorMessage GameLoader::loadDebugCampaign(Uint32 campaignID)
111{
112  switch(campaignID)
113    {
114      /*
115         Debug Level 0: Debug level used to test the base frame work.
116         As you can see, all storyentity data is allocated before game
117         start. the storyentity will load themselfs shortly before start
118         through the StoryEntity::init() funtion.
119      */
120    case DEBUG_CAMPAIGN_0:
121      {
122        Campaign* debugCampaign = new Campaign();
123
124        World* world0 = new World(DEBUG_WORLD_0);
125        world0->setNextStoryID(WORLD_ID_1);
126        debugCampaign->addEntity(world0, WORLD_ID_0);
127
128        World* world1 = new World(DEBUG_WORLD_1);
129        world1->setNextStoryID(WORLD_ID_2);
130        debugCampaign->addEntity(world1, WORLD_ID_1);
131
132        World* world2 = new World(DEBUG_WORLD_2);
133        world2->setNextStoryID(WORLD_ID_GAMEEND);
134        debugCampaign->addEntity(world2, WORLD_ID_2);
135
136        this->currentCampaign = debugCampaign;
137        break;
138      }
139    }
140}
141
142
143/**
144    \brief starts the current entity
145    \returns error code if this action has caused a error
146*/
147ErrorMessage GameLoader::start()
148{
149  if(this->currentCampaign != NULL)
150    this->currentCampaign->start();
151}
152
153
154/**
155    \brief stops the current entity
156    \returns error code if this action has caused a error
157
158    ATTENTION: this function shouldn't call other functions, or if so, they must return
159    after finishing. If you ignore or forget to do so, the current entity is not able to
160    terminate and it will run in the background or the ressources can't be freed or even
161    worse: are freed and the program will end in a segmentation fault!
162    hehehe, have ya seen it... :)
163*/
164ErrorMessage GameLoader::stop()
165{
166  if(this->currentCampaign != NULL)
167    this->currentCampaign->stop();
168  this->currentCampaign = NULL;
169}
170
171
172/**
173    \brief pause the current entity
174    \returns error code if this action has caused a error
175
176    this pauses the current entity or passes this call forth to the running entity.
177*/
178ErrorMessage GameLoader::pause()
179{
180  this->isPaused = true;
181  if(this->currentCampaign != NULL)
182    this->currentCampaign->pause();
183}
184
185
186/**
187    \brief resumes a pause
188    \returns error code if this action has caused a error
189
190    this resumess the current entity or passes this call forth to the running entity.
191*/
192ErrorMessage GameLoader::resume()
193{
194  this->isPaused = false;
195  if(this->currentCampaign != NULL)
196    this->currentCampaign->resume();
197}
198
199
200/**
201   \brief release the mem ATTENTION: not implemented
202 */
203ErrorMessage GameLoader::destroy()
204{
205
206}
207
208
209/**
210   \brief reads a campaign definition file into a campaign class
211   \param fileName to be loaded
212   \returns the loaded campaign
213
214   this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
215*/
216Campaign* GameLoader::fileToCampaign(const char* fileName)
217{
218  /* do not entirely load the campaign. just the current world
219     before start of each world, it has to be initialized so it
220     can load everything it needs into memory then.
221  */
222
223  if( fileName == NULL)
224    {
225      PRINTF(2)("No filename specified for loading");
226      return NULL;
227    }
228
229  TiXmlDocument* XMLDoc = new TiXmlDocument( fileName);
230  // load the campaign document
231  if( !XMLDoc->LoadFile())
232    {
233      // report an error
234      PRINTF(1)("Could not load XML File %s: %s @ %d:%d\n", fileName, XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
235      delete XMLDoc;
236      return NULL;
237    }
238
239  // check basic validity
240  TiXmlElement* root = XMLDoc->RootElement();
241  assert( root != NULL);
242
243  if( strcmp( root->Value(), "Campaign"))
244    {
245      // report an error
246      PRINTF(2)("Specified XML File is not an orxonox campaign file (Campaign element missing)\n");
247      delete XMLDoc;
248      return NULL;
249    }
250
251  // construct campaign
252  Campaign* c = new Campaign( root);
253
254  // free the XML data
255  delete XMLDoc;
256
257  return c;
258}
259
260
261/**
262   \brief handle keyboard commands
263   \param event the event to handle
264*/
265void GameLoader::process(const Event& event)
266{
267  if( event.type == KeyMapper::PEV_NEXT_WORLD)
268    {
269      if( likely(event.bPressed))
270        {
271          this->nextLevel();
272        }
273    }
274  else if( event.type == KeyMapper::PEV_PREVIOUS_WORLD)
275    {
276      if( likely(event.bPressed))
277        {
278          this->previousLevel();
279        }
280    }
281  else if( event.type == KeyMapper::PEV_PAUSE)
282    {
283      if( likely(event.bPressed))
284        {
285          if(this->isPaused)
286            this->resume();
287          else
288            this->pause();
289        }
290    }
291  else if( event.type == KeyMapper::PEV_QUIT)
292    {
293      if( event.bPressed) this->stop();
294    }
295}
296
297
298/**
299  \brief this changes to the next level
300*/
301void GameLoader::nextLevel()
302{
303  if(this->currentCampaign != NULL)
304    this->currentCampaign->nextLevel();
305}
306
307
308/**
309  \brief change to the previous level - not implemented
310
311  this propably useless
312*/
313void GameLoader::previousLevel()
314{
315  if(this->currentCampaign != NULL)
316    this->currentCampaign->previousLevel();
317}
318
319
320/**
321   \brief add a Factory to the Factory Q
322   \param factory a Factory to be registered
323*/
324void GameLoader::registerFactory( Factory* factory)
325{
326        assert( factory != NULL);
327
328        PRINTF(4)("Registered factory for '%s'\n", factory->getFactoryName());
329
330        if( first == NULL) first = factory;
331        else first->registerFactory( factory);
332}
333
334
335/**
336   \brief load a StoryEntity
337   \param element a XMLElement containing all the needed info
338*/
339BaseObject* GameLoader::fabricate(const 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.