Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: classList now counts the count of classes

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