Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4746 was 4739, checked in by bensch, 19 years ago

orxonox/trunk: factory is now registered in Factory, not in Gameloader

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