Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/util/loading/game_loader.cc @ 6063

Last change on this file since 6063 was 6063, checked in by patrick, 18 years ago

network: added extended game_loader interface

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