Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: removed the old command node files and cleaned up the last references to them

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