Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: crosshair in WeaponManager (instead of World) and implemented easy Cyling for LoadParam

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