Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: implemented default font.

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