Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: removed the WorldInterface, as its job is already been taken by state.h
also removed some totally obsolete but very cool functions of NPC

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