Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: reverted the steps taken in Revision 5095
The error seems to come from somewhere else…

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