Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: orxonox is now baseobject, graphicsengine handles events itself and is therefore eventlistener now

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