Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: some weapon-specifics

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