Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: The Shell now is able to be initialized by orxonox.cc, not World anymore.
The error, i was looking for laid in Element2D, where some values did not point to NULL at the beginning… this was quite stupid indeed

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