Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

network: added the class ids

File size: 9.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#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}
115
116
117/**
118 *  reads a campaign definition file into a campaign class
119 * @param fileName to be loaded
120 * @returns the loaded campaign
121 *
122 * this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
123 */
124ErrorMessage GameLoader::loadNetworkCampaign(const char* fileName, int nodeState)
125{
126  ErrorMessage errorCode;
127  char* campaignName = ResourceManager::getFullName(fileName);
128  if (campaignName)
129  {
130    this->currentCampaign = this->fileToNetworkCampaign(campaignName, nodeState);
131    delete[] campaignName;
132  }
133}
134
135
136/**
137 *  loads a debug campaign for test purposes only.
138 * @param campaignID the identifier of the campaign.
139 * @returns error message if not able to do so.
140 */
141ErrorMessage GameLoader::loadDebugCampaign(Uint32 campaignID)
142{
143  switch(campaignID)
144    {
145      /*
146         Debug Level 0: Debug level used to test the base frame work.
147         As you can see, all storyentity data is allocated before game
148         start. the storyentity will load themselfs shortly before start
149         through the StoryEntity::init() funtion.
150      */
151    case DEBUG_CAMPAIGN_0:
152      {
153        Campaign* debugCampaign = new Campaign();
154
155        World* world0 = new World(DEBUG_WORLD_0);
156        world0->setNextStoryID(WORLD_ID_1);
157        debugCampaign->addEntity(world0, WORLD_ID_0);
158
159        World* world1 = new World(DEBUG_WORLD_1);
160        world1->setNextStoryID(WORLD_ID_2);
161        debugCampaign->addEntity(world1, WORLD_ID_1);
162
163        World* world2 = new World(DEBUG_WORLD_2);
164        world2->setNextStoryID(WORLD_ID_GAMEEND);
165        debugCampaign->addEntity(world2, WORLD_ID_2);
166
167        this->currentCampaign = debugCampaign;
168        break;
169      }
170    }
171}
172
173
174/**
175 *  starts the current entity
176 * @returns error code if this action has caused a error
177 */
178ErrorMessage GameLoader::start()
179{
180  if(this->currentCampaign != NULL)
181    this->currentCampaign->start();
182}
183
184
185/**
186 *  stops the current entity
187 * @returns error code if this action has caused a error
188 *
189 *  ATTENTION: this function shouldn't call other functions, or if so, they must return
190 *  after finishing. If you ignore or forget to do so, the current entity is not able to
191 *  terminate and it will run in the background or the ressources can't be freed or even
192 *  worse: are freed and the program will end in a segmentation fault!
193 *  hehehe, have ya seen it... :)
194 */
195void GameLoader::stop()
196{
197  if(this->currentCampaign != NULL)
198    this->currentCampaign->stop();
199}
200
201
202/**
203 *  pause the current entity
204 * @returns error code if this action has caused a error
205 *
206 * this pauses the current entity or passes this call forth to the running entity.
207 */
208ErrorMessage GameLoader::pause()
209{
210  this->isPaused = true;
211  if(this->currentCampaign != NULL)
212    this->currentCampaign->pause();
213}
214
215
216/**
217 *  resumes a pause
218 * @returns error code if this action has caused a error
219 *
220 *  this resumess the current entity or passes this call forth to the running entity.
221 */
222ErrorMessage GameLoader::resume()
223{
224  this->isPaused = false;
225  if(this->currentCampaign != NULL)
226    this->currentCampaign->resume();
227}
228
229
230/**
231 *  release the mem ATTENTION: not implemented
232 */
233ErrorMessage GameLoader::destroy()
234{
235
236}
237
238
239/**
240 *  reads a campaign definition file into a campaign class
241 * @param fileName to be loaded
242 * @returns the loaded campaign
243 *
244 * this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
245 */
246Campaign* GameLoader::fileToCampaign(const char* fileName)
247{
248  /* do not entirely load the campaign. just the current world
249     before start of each world, it has to be initialized so it
250     can load everything it needs into memory then.
251  */
252
253  if( fileName == NULL)
254    {
255      PRINTF(2)("No filename specified for loading");
256      return NULL;
257    }
258
259  TiXmlDocument* XMLDoc = new TiXmlDocument( fileName);
260  // load the campaign document
261  if( !XMLDoc->LoadFile())
262    {
263      // report an error
264      PRINTF(1)("Could not load XML File %s: %s @ %d:%d\n", fileName, XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
265      delete XMLDoc;
266      return NULL;
267    }
268
269  // check basic validity
270  TiXmlElement* root = XMLDoc->RootElement();
271  assert( root != NULL);
272
273  if( strcmp( root->Value(), "Campaign"))
274    {
275      // report an error
276      PRINTF(2)("Specified XML File is not an orxonox campaign file (Campaign element missing)\n");
277      delete XMLDoc;
278      return NULL;
279    }
280
281  // construct campaign
282  Campaign* c = new Campaign( root);
283
284  // free the XML data
285  delete XMLDoc;
286
287  return c;
288}
289
290
291/**
292 *  reads a campaign definition file into a campaign class
293 * @param fileName to be loaded
294 * @returns the loaded campaign
295 *
296 *  this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
297 */
298Campaign* GameLoader::fileToNetworkCampaign(const char* fileName, int nodeState)
299{
300  /* do not entirely load the campaign. just the current world
301  before start of each world, it has to be initialized so it
302  can load everything it needs into memory then.
303  */
304
305  if( fileName == NULL)
306  {
307    PRINTF(2)("No filename specified for loading");
308    return NULL;
309  }
310
311  TiXmlDocument* XMLDoc = new TiXmlDocument( fileName);
312  // load the campaign document
313  if( !XMLDoc->LoadFile())
314  {
315      // report an error
316    PRINTF(1)("Could not load XML File %s: %s @ %d:%d\n", fileName, XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
317    delete XMLDoc;
318    return NULL;
319  }
320
321  // check basic validity
322  TiXmlElement* root = XMLDoc->RootElement();
323  assert( root != NULL);
324
325  if( strcmp( root->Value(), "Campaign"))
326  {
327      // report an error
328    PRINTF(2)("Specified XML File is not an orxonox campaign file (Campaign element missing)\n");
329    delete XMLDoc;
330    return NULL;
331  }
332
333  // construct campaign
334  Campaign* c = new Campaign( root);
335
336  // free the XML data
337  delete XMLDoc;
338
339  return c;
340}
341
342
343/**
344 *  handle keyboard commands
345 * @param event the event to handle
346 */
347void GameLoader::process(const Event& event)
348{
349  if( event.type == KeyMapper::PEV_NEXT_WORLD)
350  {
351    if( likely(event.bPressed))
352    {
353      this->nextLevel();
354    }
355  }
356  else if( event.type == KeyMapper::PEV_PREVIOUS_WORLD)
357  {
358    if( likely(event.bPressed))
359    {
360      this->previousLevel();
361    }
362  }
363  else if( event.type == KeyMapper::PEV_PAUSE)
364  {
365    if( likely(event.bPressed))
366    {
367      if(this->isPaused)
368        this->resume();
369      else
370        this->pause();
371    }
372  }
373  else if( event.type == KeyMapper::PEV_QUIT)
374  {
375    if( event.bPressed) this->stop();
376  }
377  else if (event.type == EV_MAIN_QUIT)
378    this->stop();
379}
380
381
382/**
383 *  \brief this changes to the next level
384 */
385void GameLoader::nextLevel()
386{
387  if(this->currentCampaign != NULL)
388    this->currentCampaign->nextLevel();
389}
390
391
392/**
393 *  change to the previous level - not implemented
394 *
395 * this propably useless
396 */
397void GameLoader::previousLevel()
398{
399  if(this->currentCampaign != NULL)
400    this->currentCampaign->previousLevel();
401}
Note: See TracBrowser for help on using the repository browser.