Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Explosions on Collision (—HACK—)
also made the FastFactory faster, not turning through the GarbageCollector, as it is not necessary. FastFactory also implements a Static Memeber subscriptor-Macro now
last but not least: new Functions in The ParticleEngine, and some revisited

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