Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/weaponSystem/src/story_entities/world.cc @ 4882

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

orxonox/branches/weaponSystem: cleanup WorldEntity and Player (or at least started cleaning up)

File size: 31.0 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 *  private constructor because of singleton
79*/
80WorldInterface::WorldInterface()
81{
82  this->worldIsInitialized = false;
83  this->worldReference = NULL;
84}
85
86/**
87 *  public deconstructor
88*/
89WorldInterface::~WorldInterface()
90{
91  this->singletonRef = NULL;
92  this->worldIsInitialized = false;
93  this->worldReference = NULL;
94}
95
96/**
97 *  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 *  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 *  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  *  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 *  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 *  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  delete WorldInterface::getInstance();
183  delete this->entities;
184  State::setWorldEntityList(NULL);
185
186
187  delete LightManager::getInstance();
188  delete TrackManager::getInstance();
189  delete ParticleEngine::getInstance();
190
191  TextEngine::getInstance()->flush();
192  SoundEngine::getInstance()->flushAllBuffers();
193  SoundEngine::getInstance()->flushAllSources();
194
195  delete AnimationPlayer::getInstance(); // this should be at the end of the unloading sequence.
196  delete PhysicsEngine::getInstance();
197  //delete garbagecollecor
198  //delete animator
199
200  delete NullParent::getInstance();
201  EventHandler::getInstance()->debug();
202
203  LoadClassDescription::printAll();
204
205  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
206}
207
208/**
209 *  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 *  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 *  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 *  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 *  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 *  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 *  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 *  pauses the Game
717*/
718ErrorMessage World::pause()
719{
720  this->isPaused = true;
721}
722
723/**
724 *  ends the pause Phase
725*/
726ErrorMessage World::resume()
727{
728  this->isPaused = false;
729}
730
731/**
732 *  destroys the World
733*/
734ErrorMessage World::destroy()
735{
736
737}
738
739/**
740 *  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 *  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 *  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 *  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  *  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  *  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->isVisible() ) 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  GraphicsEngine::getInstance()->draw();
854  //TextEngine::getInstance()->draw();
855}
856
857
858/**
859 *  function to put your own debug stuff into it. it can display informations about
860   the current class/procedure
861*/
862void World::debug()
863{
864  PRINTF(2)("debug() - starting debug\n");
865  PNode* p1 = NullParent::getInstance ();
866  PNode* p2 = new PNode (Vector(2, 2, 2), p1);
867  PNode* p3 = new PNode (Vector(4, 4, 4), p1);
868  PNode* p4 = new PNode (Vector(6, 6, 6), p2);
869
870  p1->debug ();
871  p2->debug ();
872  p3->debug ();
873  p4->debug ();
874
875  p1->shiftCoor (Vector(-1, -1, -1));
876
877  printf("World::debug() - shift\n");
878  p1->debug ();
879  p2->debug ();
880  p3->debug ();
881  p4->debug ();
882
883  p1->update (0);
884
885  printf ("World::debug() - update\n");
886  p1->debug ();
887  p2->debug ();
888  p3->debug ();
889  p4->debug ();
890
891  p2->shiftCoor (Vector(-1, -1, -1));
892  p1->update (0);
893
894  p1->debug ();
895  p2->debug ();
896  p3->debug ();
897  p4->debug ();
898
899  p2->setAbsCoor (Vector(1,2,3));
900
901
902 p1->update (0);
903
904  p1->debug ();
905  p2->debug ();
906  p3->debug ();
907  p4->debug ();
908
909  delete p1;
910
911
912  /*
913  WorldEntity* entity;
914  printf("counting all entities\n");
915  printf("World::debug() - enumerate()\n");
916  entity = entities->enumerate();
917  while( entity != NULL )
918    {
919      if( entity->bDraw ) printf("got an entity\n");
920      entity = entities->nextElement();
921    }
922  */
923}
924
925
926/**
927  \brief main loop of the world: executing all world relevant function
928
929  in this loop we synchronize (if networked), handle input events, give the heart-beat to
930  all other member-entities of the world (tick to player, enemies etc.), checking for
931  collisions drawing everything to the screen.
932*/
933void World::mainLoop()
934{
935  this->lastFrame = SDL_GetTicks ();
936  PRINTF(3)("World::mainLoop() - Entering main loop\n");
937  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* @todo implement pause */
938    {
939      ++this->cycle;
940      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
941      // Network
942      this->synchronize ();
943      // Process input
944      this->handleInput ();
945      if( this->bQuitCurrentGame || this->bQuitOrxonox)
946          break;
947      // Process time
948      this->tick ();
949      // Update the state
950      this->update ();
951      // Process collision
952      this->collide ();
953      // Draw
954      this->display ();
955
956      //      for( int i = 0; i < 5000000; i++) {}
957      /* @todo this is to slow down the program for openGl Software emulator computers, reimplement*/
958    }
959  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
960}
961
962
963/**
964 *  synchronize local data with remote data
965*/
966void World::synchronize ()
967{
968  // Get remote input
969  // Update synchronizables
970}
971
972
973/**
974 *  run all input processing
975
976   the command node is the central input event dispatcher. the node uses the even-queue from
977   sdl and has its own event-passing-queue.
978*/
979void World::handleInput ()
980{
981  // localinput
982  //CommandNode* cn = Orxonox::getInstance()->getLocalInput();
983  //cn->process();
984
985  EventHandler::getInstance()->process();
986
987  // remoteinput
988}
989
990
991/**
992 *  advance the timeline
993
994   this calculates the time used to process one frame (with all input handling, drawing, etc)
995   the time is mesured in ms and passed to all world-entities and other classes that need
996   a heart-beat.
997*/
998void World::tick ()
999{
1000  Uint32 currentFrame = SDL_GetTicks();
1001  if(!this->bPause)
1002    {
1003      this->dt = currentFrame - this->lastFrame;
1004
1005      if( this->dt > 10)
1006        {
1007          float fps = 1000/dt;
1008
1009          // temporary, only for showing how fast the text-engine is
1010          char tmpChar[20];
1011          sprintf(tmpChar, "fps: %4.0f", fps);
1012        }
1013      else
1014        {
1015          /* the frame-rate is limited to 100 frames per second, all other things are for
1016             nothing.
1017          */
1018          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
1019          SDL_Delay(10-dt);
1020          this->dt = 10;
1021        }
1022
1023      this->dtS = (float)this->dt / 1000.0;
1024      this->gameTime += this->dtS;
1025
1026      tIterator<WorldEntity>* iterator = this->entities->getIterator();
1027      WorldEntity* entity = iterator->nextElement();
1028      while( entity != NULL)
1029        {
1030          entity->tick (this->dtS);
1031          entity = iterator->nextElement();
1032        }
1033      delete iterator;
1034
1035      /* update tick the rest */
1036      TrackManager::getInstance()->tick(this->dtS);
1037      this->localCamera->tick(this->dtS);
1038      // tick the engines
1039      AnimationPlayer::getInstance()->tick(this->dtS);
1040      if (this->cycle > 5)
1041        PhysicsEngine::getInstance()->tick(this->dtS);
1042
1043      ParticleEngine::getInstance()->tick(this->dtS);
1044      GarbageCollector::getInstance()->tick(this->dtS);
1045
1046
1047      /** actualy the Graphics Engine should tick the world not the other way around...
1048         but since we like the things not too complicated we got it this way around
1049         until there is need or time to do it the other way around.
1050         @todo: GraphicsEngine ticks world: separation of processes and data...
1051
1052        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
1053         beceause graphics have nothing(or at least not much) to do with Motion.
1054      */
1055      GraphicsEngine::getInstance()->tick(this->dtS);
1056    }
1057  this->lastFrame = currentFrame;
1058}
1059
1060
1061/**
1062 *  this function gives the world a consistant state
1063
1064   after ticking (updating the world state) this will give a constistant
1065   state to the whole system.
1066*/
1067void World::update()
1068{
1069  GarbageCollector::getInstance()->update();
1070  this->nullParent->update (this->dtS);
1071
1072  SoundEngine::getInstance()->update();
1073}
1074
1075
1076/**
1077 *  render the current frame
1078
1079   clear all buffers and draw the world
1080*/
1081void World::display ()
1082{
1083  // clear buffer
1084  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1085  // set camera
1086  this->localCamera->apply ();
1087  // draw world
1088  this->draw();
1089  // draw HUD
1090  /** @todo draw HUD */
1091  // flip buffers
1092  GraphicsEngine::swapBuffers();
1093  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
1094  //SDL_Flip (screen);
1095}
1096
1097
1098/**
1099 *  add and spawn a new entity to this world
1100 * @param entity to be added
1101*/
1102void World::spawn(WorldEntity* entity)
1103{
1104  this->entities->add (entity);
1105  entity->postSpawn ();
1106}
1107
1108
1109/**
1110 *  add and spawn a new entity to this world
1111 * @param entity to be added
1112 * @param absCoor At what coordinates to add this entity.
1113 * @param absDir In which direction should it look.
1114*/
1115void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1116{
1117  this->entities->add (entity);
1118
1119  entity->setAbsCoor (*absCoor);
1120  entity->setAbsDir (*absDir);
1121
1122  entity->postSpawn ();
1123}
1124
1125
1126/**
1127 *  add and spawn a new entity to this world
1128 * @param entity to be added
1129 * @param entity to be added to (PNode)
1130 * @param At what relative  coordinates to add this entity.
1131 * @param In which relative direction should it look.
1132*/
1133void World::spawn(WorldEntity* entity, PNode* parentNode,
1134                  Vector* relCoor, Quaternion* relDir)
1135{
1136  this->nullParent = NullParent::getInstance();
1137  if( parentNode != NULL)
1138    {
1139      parentNode->addChild (entity);
1140
1141      entity->setRelCoor (*relCoor);
1142      entity->setRelDir (*relDir);
1143
1144      this->entities->add (entity);
1145
1146      entity->postSpawn ();
1147    }
1148}
1149
1150
1151
1152/**
1153  \brief commands that the world must catch
1154  @returns false if not used by the world
1155*/
1156bool World::command(Command* cmd)
1157{
1158  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1159  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1160  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1161  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1162  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1163  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1164  return false;
1165}
1166
1167void World::setPath( const char* name)
1168{
1169  if (this->path)
1170    delete this->path;
1171  if (ResourceManager::isFile(name))
1172  {
1173    this->path = new char[strlen(name)+1];
1174    strcpy(this->path, name);
1175  }
1176  else
1177    {
1178      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1179      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1180    }
1181}
1182
1183const char* World::getPath( void)
1184{
1185  return path;
1186}
Note: See TracBrowser for help on using the repository browser.