Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

network: now the game-loader is prepeared for network play

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