Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/height_map/src/story_entities/world.cc @ 5941

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