Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: output-issues

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