Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: cleaner outtakes of the ShellBuffer

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