Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: renamed Array to tArray

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