Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Shaders now work :)

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