Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/story_entities/world.cc @ 4822

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

orxonox/trunk: Singleton-Classes are now refered to as such in World and Orxonox

File size: 32.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: Christian Meyer
16*/
17
18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
19
20#include "world.h"
21
22#include "orxonox.h"
23
24#include "state.h"
25
26#include "p_node.h"
27#include "null_parent.h"
28#include "pilot_node.h"
29#include "track_node.h"
30#include "world_entity.h"
31#include "player.h"
32#include "camera.h"
33#include "environment.h"
34#include "skysphere.h"
35#include "skybox.h"
36#include "satellite.h"
37#include "test_entity.h"
38#include "terrain.h"
39#include "light.h"
40#include "text_engine.h"
41#include "load_param.h"
42
43#include "track_manager.h"
44#include "garbage_collector.h"
45#include "object_manager.h"
46#include "animation_player.h"
47#include "particle_engine.h"
48#include "graphics_engine.h"
49#include "physics_engine.h"
50#include "fields.h"
51
52#include "md2Model.h"
53
54#include "glmenu_imagescreen.h"
55#include "list.h"
56#include "game_loader.h"
57
58#include "animation3d.h"
59
60#include "substring.h"
61
62#include "factory.h"
63
64#include "projectile.h"
65#include "event_handler.h"
66
67#include "sound_engine.h"
68
69#include "class_list.h"
70
71#include "crosshair.h"
72Crosshair* crosshair=NULL;
73
74
75using namespace std;
76
77WorldInterface* WorldInterface::singletonRef = 0;
78
79
80/**
81   \brief private constructor because of singleton
82*/
83WorldInterface::WorldInterface()
84{
85  this->worldIsInitialized = false;
86  this->worldReference = NULL;
87}
88
89/**
90   \brief public deconstructor
91*/
92WorldInterface::~WorldInterface()
93{
94  this->singletonRef = NULL;
95  this->worldIsInitialized = false;
96  this->worldReference = NULL;
97}
98
99/**
100   \brief gets the singleton instance
101   \returns singleton instance
102*/
103WorldInterface* WorldInterface::getInstance()
104{
105  if( singletonRef == NULL)
106    singletonRef = new WorldInterface();
107  return singletonRef;
108}
109
110
111/**
112   \brief initializes the interface
113   \param reference to the world
114
115   if the worldinterface is not initilizes, there wont be any
116   useable interface
117*/
118void WorldInterface::init(World* world)
119{
120  this->worldReference = world;
121  if( world != NULL)
122    {
123      this->worldIsInitialized = true;
124      PRINTF(3)("WorldInterface up and running\n");
125    }
126}
127
128
129/**
130   \brief gets the entity list from the world
131   \return entity list
132*/
133tList<WorldEntity>* WorldInterface::getEntityList()
134{
135  if( this->worldIsInitialized)
136    return this->worldReference->getEntities();
137  PRINT(1)("Someone tried to use the WorldInterface before it has been initizlized! this can result in SEGFAULTs!\n");
138  return NULL;
139}
140
141CREATE_FACTORY(World);
142
143World::World(const TiXmlElement* root)
144{
145  this->constuctorInit("", -1);
146  this->path = NULL;
147
148  this->loadParams(root);
149}
150
151/**
152    \brief create a new World
153
154    This creates a new empty world!
155*/
156World::World (char* name)
157{
158  this->path = NULL;
159  this->constuctorInit(name, -1);
160  //NullParent* np = NullParent::getInstance();
161}
162
163/**
164   \brief creates a new World...
165   \param worldID with this ID
166*/
167World::World (int worldID)
168{
169  this->path = NULL;
170  this->constuctorInit(NULL, worldID);
171}
172
173/**
174    \brief remove the World from memory
175
176    delete everything explicitly, that isn't contained in the parenting tree!
177    things contained in the tree are deleted automaticaly
178*/
179World::~World ()
180{
181  PRINTF(3)("World::~World() - deleting current world\n");
182
183  ParticleEngine::getInstance()->debug();
184
185  EventHandler::getInstance()->unsubscribe(this->localPlayer);
186
187  delete WorldInterface::getInstance();
188  delete this->nullParent;
189  delete this->entities;
190  delete LightManager::getInstance();
191  delete TrackManager::getInstance();
192  delete ParticleEngine::getInstance();
193
194  TextEngine::getInstance()->flush();
195  SoundEngine::getInstance()->flushAllBuffers();
196
197  delete AnimationPlayer::getInstance(); // this should be at the end of the unloading sequence.
198  delete PhysicsEngine::getInstance();
199  //delete garbagecollecor
200  //delete animator
201
202  LoadClassDescription::printAll();
203
204  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
205}
206
207/**
208   \brief initializes the world.
209
210   set all stuff here that is world generic and does not use to much memory
211   because the real init() function StoryEntity::init() will be called
212   shortly before start of the game.
213   since all worlds are initiated/referenced before they will be started.
214   NO LEVEL LOADING HERE - NEVER!
215*/
216void World::constuctorInit(char* name, int worldID)
217{
218  this->setClassID(CL_WORLD, "World");
219
220  //this->worldName = name;
221  //this->worldName = new char[strlen(name)+1];
222  //strcpy(this->worldName, name);
223  this->debugWorldNr = worldID;
224  this->entities = new tList<WorldEntity>();
225  this->cycle = 0;
226
227}
228
229void World::loadParams(const TiXmlElement* root)
230{
231  const char *string;
232  char *name;
233  int id;
234
235  PRINTF(4)("Creating a World\n");
236
237  LoadParam<World>(root, "identifier", this, &World::setStoryID)
238    .describe("Sets the StoryID of this world");
239  LoadParam<World>(root, "nextid", this, &World::setNextStoryID)
240    .describe("Sets the ID of the next world");
241  LoadParam<World>(root, "path", this, &World::setPath)
242    .describe("The Filename of this World (relative from the data-dir)");
243
244  if (!crosshair)
245    crosshair = new Crosshair();
246
247  /*
248  // identifier
249  string = grabParameter( root, "identifier");
250  if( string == NULL || sscanf(string, "%d", &id) != 1)
251  {
252  PRINTF0("World is missing a proper 'identifier'\n");
253  this->setStoryID( -1);
254  }
255  else setStoryID( id);
256
257  // next id
258  string = grabParameter( root, "nextid");
259  if( string == NULL || sscanf(string, "%d", &id) != 1)
260  {
261  PRINTF0("World is missing a proper 'nextid'\n");
262  this->setStoryID( -1);
263  }
264  else setNextStoryID( id);
265
266
267  // path
268  string = grabParameter( root, "path");
269  if( string == NULL)
270  {
271  PRINTF0("World is missing a proper 'path'\n");
272  this->setPath( NULL);
273  }
274  else
275  {
276  name = new char[strlen(string + 2)];
277  strcpy( name, string);
278  this->setPath( name);
279  }
280  */
281}
282
283
284/**
285   \brief this is executed before load
286
287   since the load function sometimes needs data, that has been init before
288   the load and after the proceeding storyentity has finished
289*/
290ErrorMessage World::preLoad()
291{
292  /* init the world interface */
293  WorldInterface* wi = WorldInterface::getInstance();
294  wi->init(this);
295
296  LightManager::getInstance();
297  this->nullParent = NullParent::getInstance ();
298  this->nullParent->setName ("NullParent");
299
300  AnimationPlayer::getInstance(); // initializes the animationPlayer
301  PhysicsEngine::getInstance();
302
303  this->localCamera = new Camera();
304  this->localCamera->setName ("Camera");
305
306  State::getInstance()->setCamera(this->localCamera, this->localCamera->getTarget());
307
308  GraphicsEngine::getInstance()->displayFPS(true);
309}
310
311
312/**
313   \brief loads the World by initializing all resources, and set their default values.
314*/
315ErrorMessage World::load()
316{
317  PRINTF(3)("> Loading world: '%s'\n", getPath());
318  TiXmlElement* element;
319  GameLoader* loader = GameLoader::getInstance();
320
321  if( getPath() == NULL)
322    {
323      PRINTF(1)("World has no path specified for loading");
324      this->loadDebugWorld(this->getStoryID());
325      return (ErrorMessage){213,"Path not specified","World::load()"};
326    }
327
328  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
329  // load the campaign document
330  if( !XMLDoc->LoadFile())
331  {
332    // report an error
333    PRINTF(1)("loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
334    delete XMLDoc;
335    return (ErrorMessage){213,"XML File parsing error","World::load()"};
336  }
337
338  // check basic validity
339  TiXmlElement* root = XMLDoc->RootElement();
340  assert( root != NULL);
341
342  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
343    {
344      // report an error
345      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
346      delete XMLDoc;
347      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
348    }
349
350  // load the parameters
351  // name
352  char* temp;
353  const char* string = grabParameter( root, "name");
354  if( string == NULL)
355    {
356      PRINTF(2)("World is missing a proper 'name'\n");
357      string = "Unknown";
358      temp = new char[strlen(string + 2)];
359      strcpy( temp, string);
360      this->worldName = temp;
361    }
362  else
363    {
364      temp = new char[strlen(string + 2)];
365      strcpy( temp, string);
366      this->worldName = temp;
367    }
368  ////////////////
369  // LOADSCREEN //
370  ////////////////
371  element = root->FirstChildElement("LoadScreen");
372  if (element == NULL)
373    {
374      PRINTF(2)("no LoadScreen specified, loading default\n");
375
376      glmis->setBackgroundImage("pictures/load_screen.jpg");
377      this->glmis->setMaximum(8);
378      this->glmis->draw();
379    }
380  else
381    {
382      this->glmis->loadParams(element);
383      this->glmis->draw();
384    }
385  this->glmis->draw();
386
387  ////////////////////////
388  // find WorldEntities //
389  ////////////////////////
390
391  element = root->FirstChildElement("WorldEntities");
392
393  if( element == NULL)
394    {
395      PRINTF(1)("World is missing 'WorldEntities'\n");
396    }
397  else
398    {
399      element = element->FirstChildElement();
400      // load Players/Objects/Whatever
401      PRINTF(4)("Loading WorldEntities\n");
402      while( element != NULL)
403        {
404          WorldEntity* created = dynamic_cast<WorldEntity*>( loader->fabricate( element));
405          if( created != NULL) this->spawn( created);
406          // if we load a 'Player' we use it as localPlayer
407          //todo do this more elegant
408          if( element->Value() != NULL && !strcmp( element->Value(), "Player")) localPlayer = (Player*) created;
409          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
410          if( element->Value() != NULL && !strcmp( element->Value(), "Terrain")) terrain = (Terrain*) created;
411          element = element->NextSiblingElement();
412          glmis->step(); //! \todo temporary
413        }
414      PRINTF(4)("Done loading WorldEntities\n");
415    }
416
417    //////////////////////////////
418    // LOADING ADDITIONAL STUFF //
419    //////////////////////////////
420
421    LoadParam<LightManager>(root, "LightManager", LightManager::getInstance(), &LightManager::loadParams);
422
423    LoadParam<ParticleEngine>(root, "ParticleEngine", ParticleEngine::getInstance(), &ParticleEngine::loadParams);
424    LoadParam<PhysicsEngine>(root, "PhysicsEngine", PhysicsEngine::getInstance(), &PhysicsEngine::loadParams);
425
426  // find Track
427  element = root->FirstChildElement( "Track");
428  if( element == NULL)
429    {
430      PRINTF(0)("World is missing a 'Track'\n");
431    }
432  else
433    {
434      //load track
435      PRINTF(4)("Loading Track\n");
436
437      TrackManager::getInstance()->loadParams( element);
438      TrackManager::getInstance()->finalize();
439    }
440
441  // free the XML data
442
443  delete XMLDoc;
444  /* GENERIC LOADING PROCESS FINISHED */
445
446  // bind input
447  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_UP);
448  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_DOWN);
449  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_LEFT);
450  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_RIGHT);
451  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
452  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
453  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
454
455  // bind camera
456  //this->localCamera->bind (localPlayer);
457  this->localPlayer->addChild (this->localCamera);
458
459
460//   lightMan->setAmbientColor(.1,.1,.1);
461//   lightMan->addLight();
462//   //      lightMan->setAttenuation(1.0, .01, 0.0);
463//   //      lightMan->setDiffuseColor(1,1,1);
464//   //  lightMan->addLight(1);
465//   //  lightMan->setPosition(20, 10, -20);
466//   //  lightMan->setDiffuseColor(0,0,0);
467//   //lightMan->debug();
468//   lightMan->setPosition(-5.0, 50.0, -40.0);
469//   lightMan->addLight();
470//   lightMan->setPosition(100, 80, 60);
471
472  //        TrackManager::getInstance()->setBindSlave(env);
473  PNode* tn = TrackManager::getInstance()->getTrackNode();
474  tn->addChild(this->localPlayer);
475
476  //localCamera->setParent(TrackNode::getInstance());
477  tn->addChild(this->localCamera);
478  localCamera->lookAt(tn);
479  localCamera->setParentMode(PNODE_MOVEMENT);
480  localCamera->setClipRegion(1, 10000.0);
481  this->localPlayer->setParentMode(PNODE_ALL);
482  Vector* cameraOffset = new Vector (0, 5, -10);
483  TrackManager::getInstance()->condition(1, LEFTRIGHT, this->localPlayer);
484
485  this->sky->setParent(this->localCamera);
486
487  // initialize debug coord system
488  objectList = glGenLists(1);
489  glNewList (objectList, GL_COMPILE);
490
491  //TrackManager::getInstance()->drawGraph(.01);
492  //TrackManager::getInstance()->debug(2);
493  glEndList();
494
495  SoundEngine::getInstance()->setListener(this->localCamera);
496
497
498
499
500  ////////////
501  // STATIC //
502  ////////////
503
504  Gravity* test = new Gravity();
505
506  // SYSTEM TRAILING THE PLAYER
507  // Creating a Test Particle System
508
509  //new PhysicsConnection(system, gravity);
510  //    new PhysicsConnection(this->localPlayer, gravity);
511
512//   TestEntity* testEntity = new TestEntity();
513//   testEntity->setRelCoor(Vector(570, 10, -15));
514//   testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
515//   this->spawn(testEntity);
516
517  TestEntity* testEntity2 = new TestEntity();
518  testEntity2->setAnim(RUN);
519  testEntity2->setRelCoor(Vector(2400, 25, 260));
520  testEntity2->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
521  this->spawn(testEntity2);
522
523  TestEntity* testEntity3 = new TestEntity();
524  testEntity3->setAnim(RUN);
525  testEntity3->setRelCoor(Vector(2400, 25, 280));
526  testEntity3->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
527  this->spawn(testEntity3);
528
529  TestEntity* testEntity4 = new TestEntity();
530  testEntity4->setAnim(RUN);
531  testEntity4->setRelCoor(Vector(2430, 25, 250));
532  testEntity4->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
533  this->spawn(testEntity4);
534
535
536  PhysicsEngine::getInstance()->debug();
537
538
539  ClassList::debug();
540}
541
542
543
544/**
545   \brief loads the debug world: only for experimental stuff
546*/
547void World::loadDebugWorld(int worldID)
548{
549  /*monitor progress*/
550  this->glmis->step();
551  // stuff beyond this point remains to be loaded properly
552
553  // initializing the TrackManager
554  TrackManager::getInstance()->addPointV(Vector(150, -35, 5));
555  TrackManager::getInstance()->addPointV(Vector(200,-35, 5));
556  TrackManager::getInstance()->addPointV(Vector(250, -35, 5));
557  TrackManager::getInstance()->addPointV(Vector(320,-33,-.55));
558  TrackManager::getInstance()->setDuration(1);
559  TrackManager::getInstance()->setSavePoint();
560
561  TrackManager::getInstance()->addPointV(Vector(410, 0, 0));
562  TrackManager::getInstance()->addPointV(Vector(510, 20, -10));
563  TrackManager::getInstance()->addPointV(Vector(550, 20, -10));
564  TrackManager::getInstance()->addPointV(Vector(570, 20, -10));
565  TrackManager::getInstance()->setDuration(2);
566
567  TrackManager::getInstance()->forkS("testFork1,testFork2");
568  TrackManager::getInstance()->workOnS("testFork1");
569  TrackManager::getInstance()->addPointV(Vector(640, 25, -30));
570  TrackManager::getInstance()->addPointV(Vector(700, 40, -120));
571  TrackManager::getInstance()->addPointV(Vector(800, 50, -150));
572  TrackManager::getInstance()->addPointV(Vector(900, 60, -100));
573  TrackManager::getInstance()->addPointV(Vector(900, 60, -70));
574  TrackManager::getInstance()->addPointV(Vector(990, 65, -15));
575  TrackManager::getInstance()->addPointV(Vector(1050, 65, -10));
576  TrackManager::getInstance()->addPointV(Vector(1100, 65, -20));
577  TrackManager::getInstance()->setDuration(4);
578
579  TrackManager::getInstance()->workOnS("testFork2");
580  TrackManager::getInstance()->addPointV(Vector(640, 25, 20));
581  TrackManager::getInstance()->addPointV(Vector(670, 50, 120));
582  TrackManager::getInstance()->addPointV(Vector(700, 70, 80));
583  TrackManager::getInstance()->addPointV(Vector(800, 70, 65));
584  TrackManager::getInstance()->addPointV(Vector(850, 65, 65));
585  TrackManager::getInstance()->addPointV(Vector(920, 35, 40));
586  TrackManager::getInstance()->addPointV(Vector(945, 40, 40));
587  TrackManager::getInstance()->addPointV(Vector(970, 24, 40));
588  TrackManager::getInstance()->addPointV(Vector(1000, 40, -7));
589
590  TrackManager::getInstance()->setDuration(4);
591
592
593  TrackManager::getInstance()->joinS("testFork1,testFork2");
594
595  TrackManager::getInstance()->addPointV(Vector(1200, 60, -50));
596  TrackManager::getInstance()->addPointV(Vector(1300, 50, -50));
597  TrackManager::getInstance()->addPointV(Vector(1400, 40, -50));
598  TrackManager::getInstance()->addPointV(Vector(1500, 40, -60));
599  TrackManager::getInstance()->addPointV(Vector(1600, 35, -55));
600  TrackManager::getInstance()->addPointV(Vector(1700, 45, -40));
601  TrackManager::getInstance()->addPointV(Vector(1750, 60, -40));
602  TrackManager::getInstance()->addPointV(Vector(1770, 80, -40));
603  TrackManager::getInstance()->addPointV(Vector(1800, 100, -40));
604  TrackManager::getInstance()->setDuration(10);
605
606  TrackManager::getInstance()->finalize();
607
608
609  // LIGHT initialisation
610  LightManager::getInstance()->setAmbientColor(.1,.1,.1);
611//  LightManager::getInstance()->addLight();
612  LightManager::getInstance()->debug();
613
614  switch(this->debugWorldNr)
615    {
616      /*
617        this loads the hard-coded debug world. this only for simplicity and will be
618        removed by a reald world-loader, which interprets a world-file.
619        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
620        make whatever you want...
621      */
622    case DEBUG_WORLD_0:
623      {
624        LightManager::getInstance()->getLight()->setAbsCoor(-5.0, 10.0, -40.0);
625
626
627        this->localPlayer = new Player ();
628        this->localPlayer->setName ("player");
629        this->spawn (this->localPlayer);
630        this->localPlayer->setRelCoor(Vector(5,0,0));
631        /*monitor progress*/
632        this->glmis->step();
633
634
635        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
636        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
637        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
638
639        /*
640        Field* testField = new Gravity();
641        testField->setMagnitude(10);
642        new PhysicsConnection(this->localPlayer, testField);
643        */
644
645        // bind camera
646        this->localCamera = new Camera();
647        this->localCamera->setName ("camera");
648        /*monitor progress*/
649        this->glmis->step();
650
651
652        // Create SkySphere
653        this->sky = new Skysphere("pictures/sky-replace.jpg");
654        this->sky->setName("SkySphere");
655        this->spawn(this->sky);
656        this->localCamera->addChild(this->sky);
657        this->sky->setParentMode(PNODE_MOVEMENT);
658        /*monitor progress*/
659        this->glmis->step();
660
661
662        terrain = new Terrain("worlds/newGround.obj");
663        terrain->setRelCoor(Vector(0,-10,0));
664        this->spawn(terrain);
665        /*monitor progress*/
666        this->glmis->step();
667
668        this->pilotNode = new PilotNode();
669        this->spawn(this->pilotNode);
670        this->pilotNode->setAbsCoor(Vector(150, -35, 5));
671        this->pilotNode->addChild(this->localPlayer);
672        this->pilotNode->addChild(this->localCamera);
673        this->localCamera->lookAt(this->localPlayer);
674
675        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_UP);
676        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_DOWN);
677        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_LEFT);
678        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_RIGHT);
679        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, EV_MOUSE_MOTION);
680
681        // bind input
682        Orxonox *orx = Orxonox::getInstance ();
683        //orx->getLocalInput()->bind (this->pilotNode);
684
685        /*
686        PNode* tn = TrackManager::getInstance()->getTrackNode();
687        tn->addChild(this->localPlayer);
688        this->localCamera->lookAt(tn);
689
690        tn->addChild(this->localCamera);
691        this->localPlayer->setParentMode(PNODE_ALL);
692        TrackManager::getInstance()->condition(2, LEFTRIGHT, this->localPlayer);
693        */
694        this->glmis->step();
695        break;
696      }
697    case DEBUG_WORLD_1:
698      {
699
700        break;
701      }
702    case DEBUG_WORLD_2:
703      {
704
705        break;
706      }
707    default:
708      break;
709    }
710}
711
712
713
714/**
715   \brief initializes a new World shortly before start
716
717   this is the function, that will be loaded shortly before the world is
718   started
719*/
720ErrorMessage World::init()
721{
722  this->bPause = false;
723  this->pilotNode = NULL;
724}
725
726
727/**
728   \brief starts the World
729*/
730ErrorMessage World::start()
731{
732  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
733  this->bQuitOrxonox = false;
734  this->bQuitCurrentGame = false;
735  this->mainLoop();
736}
737
738/**
739   \brief stops the world.
740
741   This happens, when the player decides to end the Level.
742*/
743ErrorMessage World::stop()
744{
745  PRINTF(3)("World::stop() - got stop signal\n");
746  this->bQuitCurrentGame = true;
747}
748
749/**
750   \brief pauses the Game
751*/
752ErrorMessage World::pause()
753{
754  this->isPaused = true;
755}
756
757/**
758   \brief ends the pause Phase
759*/
760ErrorMessage World::resume()
761{
762  this->isPaused = false;
763}
764
765/**
766   \brief destroys the World
767*/
768ErrorMessage World::destroy()
769{
770
771}
772
773/**
774   \brief shows the loading screen
775*/
776void World::displayLoadScreen ()
777{
778  PRINTF(3)("World::displayLoadScreen - start\n");
779
780  //GLMenuImageScreen*
781  this->glmis = new GLMenuImageScreen();
782  this->glmis->setMaximum(8);
783
784  PRINTF(3)("World::displayLoadScreen - end\n");
785}
786
787/**
788   \brief removes the loadscreen, and changes over to the game
789
790   \todo take out the delay
791*/
792void World::releaseLoadScreen ()
793{
794  PRINTF(3)("World::releaseLoadScreen - start\n");
795  this->glmis->setValue(this->glmis->getMaximum());
796  PRINTF(3)("World::releaseLoadScreen - end\n");
797  delete this->glmis;
798}
799
800
801/**
802   \brief gets the list of entities from the world
803   \returns entity list
804*/
805tList<WorldEntity>* World::getEntities()
806{
807  return this->entities;
808}
809
810
811/**
812   \brief this returns the current game time
813   \returns elapsed game time
814*/
815double World::getGameTime()
816{
817  return this->gameTime;
818}
819
820
821/**
822    \brief checks for collisions
823
824    This method runs through all WorldEntities known to the world and checks for collisions
825    between them. In case of collisions the collide() method of the corresponding entities
826    is called.
827*/
828void World::collide ()
829{
830  /*
831  List *a, *b;
832  WorldEntity *aobj, *bobj;
833
834  a = entities;
835
836  while( a != NULL)
837    {
838      aobj = a->nextElement();
839      if( aobj->bCollide && aobj->collisioncluster != NULL)
840        {
841          b = a->nextElement();
842          while( b != NULL )
843            {
844              bobj = b->nextElement();
845              if( bobj->bCollide && bobj->collisioncluster != NULL )
846                {
847                  unsigned long ahitflg, bhitflg;
848                  if( check_collision ( &aobj->place, aobj->collisioncluster,
849                                        &ahitflg, &bobj->place, bobj->collisioncluster,
850                                        &bhitflg) );
851                  {
852                    aobj->collide (bobj, ahitflg, bhitflg);
853                    bobj->collide (aobj, bhitflg, ahitflg);
854                  }
855                }
856              b = b->nextElement();
857            }
858        }
859      a = a->enumerate();
860    }
861  */
862}
863
864/**
865    \brief runs through all entities calling their draw() methods
866*/
867void World::draw ()
868{
869  /* draw entities */
870  WorldEntity* entity;
871  glLoadIdentity();
872  //entity = this->entities->enumerate();
873  tIterator<WorldEntity>* iterator = this->entities->getIterator();
874  entity = iterator->nextElement();
875  while( entity != NULL )
876    {
877      if( entity->bDraw ) entity->draw();
878      //entity = this->entities->nextElement();
879      entity = iterator->nextElement();
880    }
881  delete iterator;
882
883  glCallList (objectList);
884
885  ParticleEngine::getInstance()->draw(); //!< \todo should be dts like in the Trunk;
886
887  crosshair->draw();
888  TextEngine::getInstance()->draw();
889  LightManager::getInstance()->draw(); // must be at the end of the drawing procedure, otherwise Light cannot be handled as PNodes //
890}
891
892
893/**
894   \brief function to put your own debug stuff into it. it can display informations about
895   the current class/procedure
896*/
897void World::debug()
898{
899  PRINTF(2)("debug() - starting debug\n");
900  PNode* p1 = NullParent::getInstance ();
901  PNode* p2 = new PNode (Vector(2, 2, 2), p1);
902  PNode* p3 = new PNode (Vector(4, 4, 4), p1);
903  PNode* p4 = new PNode (Vector(6, 6, 6), p2);
904
905  p1->debug ();
906  p2->debug ();
907  p3->debug ();
908  p4->debug ();
909
910  p1->shiftCoor (Vector(-1, -1, -1));
911
912  printf("World::debug() - shift\n");
913  p1->debug ();
914  p2->debug ();
915  p3->debug ();
916  p4->debug ();
917
918  p1->update (0);
919
920  printf ("World::debug() - update\n");
921  p1->debug ();
922  p2->debug ();
923  p3->debug ();
924  p4->debug ();
925
926  p2->shiftCoor (Vector(-1, -1, -1));
927  p1->update (0);
928
929  p1->debug ();
930  p2->debug ();
931  p3->debug ();
932  p4->debug ();
933
934  p2->setAbsCoor (Vector(1,2,3));
935
936
937 p1->update (0);
938
939  p1->debug ();
940  p2->debug ();
941  p3->debug ();
942  p4->debug ();
943
944  delete p1;
945
946
947  /*
948  WorldEntity* entity;
949  printf("counting all entities\n");
950  printf("World::debug() - enumerate()\n");
951  entity = entities->enumerate();
952  while( entity != NULL )
953    {
954      if( entity->bDraw ) printf("got an entity\n");
955      entity = entities->nextElement();
956    }
957  */
958}
959
960
961/**
962  \brief main loop of the world: executing all world relevant function
963
964  in this loop we synchronize (if networked), handle input events, give the heart-beat to
965  all other member-entities of the world (tick to player, enemies etc.), checking for
966  collisions drawing everything to the screen.
967*/
968void World::mainLoop()
969{
970  this->lastFrame = SDL_GetTicks ();
971  PRINTF(3)("World::mainLoop() - Entering main loop\n");
972  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
973    {
974      ++this->cycle;
975      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
976      // Network
977      this->synchronize ();
978      // Process input
979      this->handleInput ();
980      if( this->bQuitCurrentGame || this->bQuitOrxonox)
981          break;
982      // Process time
983      this->tick ();
984      // Update the state
985      this->update ();
986      // Process collision
987      this->collide ();
988      // Draw
989      this->display ();
990
991      //      for( int i = 0; i < 5000000; i++) {}
992      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
993    }
994  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
995}
996
997
998/**
999   \brief synchronize local data with remote data
1000*/
1001void World::synchronize ()
1002{
1003  // Get remote input
1004  // Update synchronizables
1005}
1006
1007
1008/**
1009   \brief run all input processing
1010
1011   the command node is the central input event dispatcher. the node uses the even-queue from
1012   sdl and has its own event-passing-queue.
1013*/
1014void World::handleInput ()
1015{
1016  // localinput
1017  //CommandNode* cn = Orxonox::getInstance()->getLocalInput();
1018  //cn->process();
1019
1020  EventHandler::getInstance()->process();
1021
1022  // remoteinput
1023}
1024
1025
1026/**
1027   \brief advance the timeline
1028
1029   this calculates the time used to process one frame (with all input handling, drawing, etc)
1030   the time is mesured in ms and passed to all world-entities and other classes that need
1031   a heart-beat.
1032*/
1033void World::tick ()
1034{
1035  Uint32 currentFrame = SDL_GetTicks();
1036  if(!this->bPause)
1037    {
1038      this->dt = currentFrame - this->lastFrame;
1039
1040      if( this->dt > 10)
1041        {
1042          float fps = 1000/dt;
1043
1044          // temporary, only for showing how fast the text-engine is
1045          char tmpChar[20];
1046          sprintf(tmpChar, "fps: %4.0f", fps);
1047        }
1048      else
1049        {
1050          /* the frame-rate is limited to 100 frames per second, all other things are for
1051             nothing.
1052          */
1053          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
1054          SDL_Delay(10-dt);
1055          this->dt = 10;
1056        }
1057
1058      this->dtS = (float)this->dt / 1000.0;
1059      this->gameTime += this->dtS;
1060      //entity = entities->enumerate();
1061      tIterator<WorldEntity>* iterator = this->entities->getIterator();
1062      WorldEntity* entity = iterator->nextElement();
1063      while( entity != NULL)
1064        {
1065          entity->tick (this->dtS);
1066          entity = iterator->nextElement();
1067        }
1068      delete iterator;
1069
1070      /* update tick the rest */
1071      TrackManager::getInstance()->tick(this->dt);
1072      this->localCamera->tick(this->dt);
1073      // tick the engines
1074      AnimationPlayer::getInstance()->tick(this->dtS);
1075      if (this->cycle > 5)
1076        PhysicsEngine::getInstance()->tick(this->dtS);
1077
1078      ParticleEngine::getInstance()->tick(this->dtS);
1079      GarbageCollector::getInstance()->tick(this->dtS);
1080
1081      /** actualy the Graphics Engine should tick the world not the other way around...
1082         but since we like the things not too complicated we got it this way around
1083         until there is need or time to do it the other way around.
1084         \todo: GraphicsEngine ticks world: separation of processes and data...
1085
1086        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
1087         beceause graphics have nothing(or at least not much) to do with Motion.
1088      */
1089      GraphicsEngine::getInstance()->tick(this->dtS);
1090    }
1091  this->lastFrame = currentFrame;
1092}
1093
1094
1095/**
1096   \brief this function gives the world a consistant state
1097
1098   after ticking (updating the world state) this will give a constistant
1099   state to the whole system.
1100*/
1101void World::update()
1102{
1103  GarbageCollector::getInstance()->update();
1104  this->nullParent->update (this->dtS);
1105
1106  SoundEngine::getInstance()->update();
1107}
1108
1109
1110/**
1111   \brief render the current frame
1112
1113   clear all buffers and draw the world
1114*/
1115void World::display ()
1116{
1117  // clear buffer
1118  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1119  // set camera
1120  this->localCamera->apply ();
1121  // draw world
1122  this->draw();
1123  // draw HUD
1124  /* \todo draw HUD */
1125  // flip buffers
1126  GraphicsEngine::swapBuffers();
1127  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
1128  //SDL_Flip (screen);
1129}
1130
1131
1132/**
1133   \brief add and spawn a new entity to this world
1134   \param entity to be added
1135*/
1136void World::spawn(WorldEntity* entity)
1137{
1138  this->entities->add (entity);
1139  entity->postSpawn ();
1140}
1141
1142
1143/**
1144   \brief add and spawn a new entity to this world
1145   \param entity to be added
1146   \param absCoor At what coordinates to add this entity.
1147   \param absDir In which direction should it look.
1148*/
1149void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1150{
1151  this->entities->add (entity);
1152
1153  entity->setAbsCoor (*absCoor);
1154  entity->setAbsDir (*absDir);
1155
1156  entity->postSpawn ();
1157}
1158
1159
1160/**
1161   \brief add and spawn a new entity to this world
1162   \param entity to be added
1163   \param entity to be added to (PNode)
1164   \param At what relative  coordinates to add this entity.
1165   \param In which relative direction should it look.
1166*/
1167void World::spawn(WorldEntity* entity, PNode* parentNode,
1168                  Vector* relCoor, Quaternion* relDir)
1169{
1170  this->nullParent = NullParent::getInstance();
1171  if( parentNode != NULL)
1172    {
1173      parentNode->addChild (entity);
1174
1175      entity->setRelCoor (*relCoor);
1176      entity->setRelDir (*relDir);
1177
1178      this->entities->add (entity);
1179
1180      entity->postSpawn ();
1181    }
1182}
1183
1184
1185
1186/**
1187  \brief commands that the world must catch
1188  \returns false if not used by the world
1189*/
1190bool World::command(Command* cmd)
1191{
1192  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1193  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1194  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1195  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1196  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1197  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1198  return false;
1199}
1200
1201void World::setPath( const char* name)
1202{
1203  if (this->path)
1204    delete this->path;
1205  if (ResourceManager::isFile(name))
1206  {
1207    this->path = new char[strlen(name)+1];
1208    strcpy(this->path, name);
1209  }
1210  else
1211    {
1212      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1213      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1214    }
1215}
1216
1217const char* World::getPath( void)
1218{
1219  return path;
1220}
Note: See TracBrowser for help on using the repository browser.