Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: remake of the Projectile and TestBullet

File size: 31.1 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer: Christian Meyer
16*/
17
18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
19
20#include "world.h"
21
22#include "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//  delete NullParent::getInstance();
186
187
188  delete LightManager::getInstance();
189  delete TrackManager::getInstance();
190  delete ParticleEngine::getInstance();
191
192  TextEngine::getInstance()->flush();
193  SoundEngine::getInstance()->flushAllBuffers();
194  SoundEngine::getInstance()->flushAllSources();
195
196  delete AnimationPlayer::getInstance(); // this should be at the end of the unloading sequence.
197  delete PhysicsEngine::getInstance();
198  //delete garbagecollecor
199  //delete animator
200
201  delete NullParent::getInstance();
202  EventHandler::getInstance()->debug();
203
204  LoadClassDescription::printAll();
205
206  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
207}
208
209/**
210 *  initializes the world.
211
212   set all stuff here that is world generic and does not use to much memory
213   because the real init() function StoryEntity::init() will be called
214   shortly before start of the game.
215   since all worlds are initiated/referenced before they will be started.
216   NO LEVEL LOADING HERE - NEVER!
217*/
218void World::constuctorInit(char* name, int worldID)
219{
220  this->setClassID(CL_WORLD, "World");
221
222  //this->worldName = name;
223  //this->worldName = new char[strlen(name)+1];
224  //strcpy(this->worldName, name);
225  this->debugWorldNr = worldID;
226}
227
228void World::loadParams(const TiXmlElement* root)
229{
230  const char *string;
231  char *name;
232  int id;
233
234  PRINTF(4)("Creating a World\n");
235
236  LoadParam<World>(root, "identifier", this, &World::setStoryID)
237    .describe("Sets the StoryID of this world");
238
239  LoadParam<World>(root, "nextid", this, &World::setNextStoryID)
240    .describe("Sets the ID of the next world");
241
242  LoadParam<World>(root, "path", this, &World::setPath)
243    .describe("The Filename of this World (relative from the data-dir)");
244}
245
246
247/**
248 *  this is executed before load
249
250   since the load function sometimes needs data, that has been init before
251   the load and after the proceeding storyentity has finished
252*/
253ErrorMessage World::preLoad()
254{
255  State::setWorldEntityList(this->entities = new tList<WorldEntity>());
256  this->cycle = 0;
257
258
259  /* init the world interface */
260  WorldInterface* wi = WorldInterface::getInstance();
261  wi->init(this);
262
263  LightManager::getInstance();
264  this->nullParent = NullParent::getInstance ();
265  this->nullParent->setName ("NullParent");
266
267  AnimationPlayer::getInstance(); // initializes the animationPlayer
268  PhysicsEngine::getInstance();
269
270  this->localCamera = new Camera();
271  this->localCamera->setName ("Camera");
272
273  State::setCamera(this->localCamera, this->localCamera->getTarget());
274
275  GraphicsEngine::getInstance()->displayFPS(true);
276}
277
278
279/**
280 *  loads the World by initializing all resources, and set their default values.
281*/
282ErrorMessage World::load()
283{
284  PRINTF(3)("> Loading world: '%s'\n", getPath());
285  TiXmlElement* element;
286  GameLoader* loader = GameLoader::getInstance();
287
288  if( getPath() == NULL)
289    {
290      PRINTF(1)("World has no path specified for loading");
291      this->loadDebugWorld(this->getStoryID());
292      return (ErrorMessage){213,"Path not specified","World::load()"};
293    }
294
295  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
296  // load the campaign document
297  if( !XMLDoc->LoadFile())
298  {
299    // report an error
300    PRINTF(1)("loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
301    delete XMLDoc;
302    return (ErrorMessage){213,"XML File parsing error","World::load()"};
303  }
304
305  // check basic validity
306  TiXmlElement* root = XMLDoc->RootElement();
307  assert( root != NULL);
308
309  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
310    {
311      // report an error
312      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
313      delete XMLDoc;
314      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
315    }
316
317  // load the parameters
318  // name
319  char* temp;
320  const char* string = grabParameter( root, "name");
321  if( string == NULL)
322    {
323      PRINTF(2)("World is missing a proper 'name'\n");
324      string = "Unknown";
325      temp = new char[strlen(string + 2)];
326      strcpy( temp, string);
327      this->worldName = temp;
328    }
329  else
330    {
331      temp = new char[strlen(string + 2)];
332      strcpy( temp, string);
333      this->worldName = temp;
334    }
335  ////////////////
336  // LOADSCREEN //
337  ////////////////
338  element = root->FirstChildElement("LoadScreen");
339  if (element == NULL)
340    {
341      PRINTF(2)("no LoadScreen specified, loading default\n");
342
343      glmis->setBackgroundImage("pictures/load_screen.jpg");
344      this->glmis->setMaximum(8);
345      this->glmis->draw();
346    }
347  else
348    {
349      this->glmis->loadParams(element);
350      this->glmis->draw();
351    }
352  this->glmis->draw();
353
354  ////////////////////////
355  // find WorldEntities //
356  ////////////////////////
357
358  element = root->FirstChildElement("WorldEntities");
359
360  if( element == NULL)
361    {
362      PRINTF(1)("World is missing 'WorldEntities'\n");
363    }
364  else
365    {
366      element = element->FirstChildElement();
367      // load Players/Objects/Whatever
368      PRINTF(4)("Loading WorldEntities\n");
369      while( element != NULL)
370        {
371          WorldEntity* created = dynamic_cast<WorldEntity*>( loader->fabricate( element));
372          if( created != NULL) this->spawn( created);
373          // if we load a 'Player' we use it as localPlayer
374          //todo do this more elegant
375          if( element->Value() != NULL && !strcmp( element->Value(), "Player")) localPlayer = (Player*) created;
376          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
377          if( element->Value() != NULL && !strcmp( element->Value(), "Terrain")) terrain = (Terrain*) created;
378          element = element->NextSiblingElement();
379          glmis->step(); //! @todo temporary
380        }
381      PRINTF(4)("Done loading WorldEntities\n");
382    }
383
384    //////////////////////////////
385    // LOADING ADDITIONAL STUFF //
386    //////////////////////////////
387
388    LoadParam<LightManager>(root, "LightManager", LightManager::getInstance(), &LightManager::loadParams);
389
390    LoadParam<ParticleEngine>(root, "ParticleEngine", ParticleEngine::getInstance(), &ParticleEngine::loadParams);
391    LoadParam<PhysicsEngine>(root, "PhysicsEngine", PhysicsEngine::getInstance(), &PhysicsEngine::loadParams);
392
393  // find Track
394  element = root->FirstChildElement( "Track");
395  if( element == NULL)
396    {
397      PRINTF(0)("World is missing a 'Track'\n");
398    }
399  else
400    {
401      //load track
402      PRINTF(4)("Loading Track\n");
403
404      TrackManager::getInstance()->loadParams( element);
405      TrackManager::getInstance()->finalize();
406    }
407
408  // free the XML data
409
410  delete XMLDoc;
411  /* GENERIC LOADING PROCESS FINISHED */
412
413  // bind input
414  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_UP);
415  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_DOWN);
416  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_LEFT);
417  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_RIGHT);
418  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
419  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
420  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
421
422  // bind camera
423  //this->localCamera->bind (localPlayer);
424  this->localPlayer->addChild (this->localCamera);
425
426
427//   lightMan->setAmbientColor(.1,.1,.1);
428//   lightMan->addLight();
429//   //      lightMan->setAttenuation(1.0, .01, 0.0);
430//   //      lightMan->setDiffuseColor(1,1,1);
431//   //  lightMan->addLight(1);
432//   //  lightMan->setPosition(20, 10, -20);
433//   //  lightMan->setDiffuseColor(0,0,0);
434//   //lightMan->debug();
435//   lightMan->setPosition(-5.0, 50.0, -40.0);
436//   lightMan->addLight();
437//   lightMan->setPosition(100, 80, 60);
438
439  //        TrackManager::getInstance()->setBindSlave(env);
440  PNode* tn = TrackManager::getInstance()->getTrackNode();
441  tn->addChild(this->localPlayer);
442
443  //localCamera->setParent(TrackNode::getInstance());
444  tn->addChild(this->localCamera);
445  localCamera->lookAt(tn);
446  localCamera->setParentMode(PNODE_MOVEMENT);
447  localCamera->setClipRegion(1, 10000.0);
448  this->localPlayer->setParentMode(PNODE_ALL);
449  Vector* cameraOffset = new Vector (0, 5, -10);
450  TrackManager::getInstance()->condition(1, LEFTRIGHT, this->localPlayer);
451
452  this->sky->setParent(this->localCamera);
453
454  // initialize debug coord system
455  objectList = glGenLists(1);
456  glNewList (objectList, GL_COMPILE);
457
458  //TrackManager::getInstance()->drawGraph(.01);
459  //TrackManager::getInstance()->debug(2);
460  glEndList();
461
462  SoundEngine::getInstance()->setListener(this->localCamera);
463
464
465
466
467  ////////////
468  // STATIC //
469  ////////////
470
471  Gravity* test = new Gravity();
472
473  // SYSTEM TRAILING THE PLAYER
474  // Creating a Test Particle System
475
476  //new PhysicsConnection(system, gravity);
477  //    new PhysicsConnection(this->localPlayer, gravity);
478
479//   TestEntity* testEntity = new TestEntity();
480//   testEntity->setRelCoor(Vector(570, 10, -15));
481//   testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
482//   this->spawn(testEntity);
483
484  TestEntity* testEntity2 = new TestEntity();
485  testEntity2->setAnim(RUN);
486  testEntity2->setRelCoor(Vector(2400, 25, 260));
487  testEntity2->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
488  this->spawn(testEntity2);
489
490  TestEntity* testEntity3 = new TestEntity();
491  testEntity3->setAnim(RUN);
492  testEntity3->setRelCoor(Vector(2400, 25, 280));
493  testEntity3->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
494  this->spawn(testEntity3);
495
496  TestEntity* testEntity4 = new TestEntity();
497  testEntity4->setAnim(RUN);
498  testEntity4->setRelCoor(Vector(2430, 25, 250));
499  testEntity4->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
500  this->spawn(testEntity4);
501
502
503  PhysicsEngine::getInstance()->debug();
504
505
506  ClassList::debug();
507}
508
509
510
511/**
512 *  loads the debug world: only for experimental stuff
513*/
514void World::loadDebugWorld(int worldID)
515{
516  /*monitor progress*/
517  this->glmis->step();
518  // stuff beyond this point remains to be loaded properly
519
520  // initializing the TrackManager
521  TrackManager::getInstance()->addPointV(Vector(150, -35, 5));
522  TrackManager::getInstance()->addPointV(Vector(200,-35, 5));
523  TrackManager::getInstance()->addPointV(Vector(250, -35, 5));
524  TrackManager::getInstance()->addPointV(Vector(320,-33,-.55));
525  TrackManager::getInstance()->setDuration(1);
526  TrackManager::getInstance()->setSavePoint();
527
528  TrackManager::getInstance()->addPointV(Vector(410, 0, 0));
529  TrackManager::getInstance()->addPointV(Vector(510, 20, -10));
530  TrackManager::getInstance()->addPointV(Vector(550, 20, -10));
531  TrackManager::getInstance()->addPointV(Vector(570, 20, -10));
532  TrackManager::getInstance()->setDuration(2);
533
534  TrackManager::getInstance()->forkS("testFork1,testFork2");
535  TrackManager::getInstance()->workOnS("testFork1");
536  TrackManager::getInstance()->addPointV(Vector(640, 25, -30));
537  TrackManager::getInstance()->addPointV(Vector(700, 40, -120));
538  TrackManager::getInstance()->addPointV(Vector(800, 50, -150));
539  TrackManager::getInstance()->addPointV(Vector(900, 60, -100));
540  TrackManager::getInstance()->addPointV(Vector(900, 60, -70));
541  TrackManager::getInstance()->addPointV(Vector(990, 65, -15));
542  TrackManager::getInstance()->addPointV(Vector(1050, 65, -10));
543  TrackManager::getInstance()->addPointV(Vector(1100, 65, -20));
544  TrackManager::getInstance()->setDuration(4);
545
546  TrackManager::getInstance()->workOnS("testFork2");
547  TrackManager::getInstance()->addPointV(Vector(640, 25, 20));
548  TrackManager::getInstance()->addPointV(Vector(670, 50, 120));
549  TrackManager::getInstance()->addPointV(Vector(700, 70, 80));
550  TrackManager::getInstance()->addPointV(Vector(800, 70, 65));
551  TrackManager::getInstance()->addPointV(Vector(850, 65, 65));
552  TrackManager::getInstance()->addPointV(Vector(920, 35, 40));
553  TrackManager::getInstance()->addPointV(Vector(945, 40, 40));
554  TrackManager::getInstance()->addPointV(Vector(970, 24, 40));
555  TrackManager::getInstance()->addPointV(Vector(1000, 40, -7));
556
557  TrackManager::getInstance()->setDuration(4);
558
559
560  TrackManager::getInstance()->joinS("testFork1,testFork2");
561
562  TrackManager::getInstance()->addPointV(Vector(1200, 60, -50));
563  TrackManager::getInstance()->addPointV(Vector(1300, 50, -50));
564  TrackManager::getInstance()->addPointV(Vector(1400, 40, -50));
565  TrackManager::getInstance()->addPointV(Vector(1500, 40, -60));
566  TrackManager::getInstance()->addPointV(Vector(1600, 35, -55));
567  TrackManager::getInstance()->addPointV(Vector(1700, 45, -40));
568  TrackManager::getInstance()->addPointV(Vector(1750, 60, -40));
569  TrackManager::getInstance()->addPointV(Vector(1770, 80, -40));
570  TrackManager::getInstance()->addPointV(Vector(1800, 100, -40));
571  TrackManager::getInstance()->setDuration(10);
572
573  TrackManager::getInstance()->finalize();
574
575
576  // LIGHT initialisation
577  LightManager::getInstance()->setAmbientColor(.1,.1,.1);
578//  LightManager::getInstance()->addLight();
579  LightManager::getInstance()->debug();
580
581  switch(this->debugWorldNr)
582    {
583      /*
584        this loads the hard-coded debug world. this only for simplicity and will be
585        removed by a reald world-loader, which interprets a world-file.
586        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
587        make whatever you want...
588      */
589    case DEBUG_WORLD_0:
590      {
591        LightManager::getInstance()->getLight()->setAbsCoor(-5.0, 10.0, -40.0);
592
593
594        this->localPlayer = new Player ();
595        this->localPlayer->setName ("player");
596        this->spawn (this->localPlayer);
597        this->localPlayer->setRelCoor(Vector(5,0,0));
598        /*monitor progress*/
599        this->glmis->step();
600
601
602        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
603        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
604        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
605
606        /*
607        Field* testField = new Gravity();
608        testField->setMagnitude(10);
609        new PhysicsConnection(this->localPlayer, testField);
610        */
611
612        // bind camera
613        this->localCamera = new Camera();
614        this->localCamera->setName ("camera");
615        /*monitor progress*/
616        this->glmis->step();
617
618
619        // Create SkySphere
620        this->sky = new Skysphere("pictures/sky-replace.jpg");
621        this->sky->setName("SkySphere");
622        this->spawn(this->sky);
623        this->localCamera->addChild(this->sky);
624        this->sky->setParentMode(PNODE_MOVEMENT);
625        /*monitor progress*/
626        this->glmis->step();
627
628
629        terrain = new Terrain("worlds/newGround.obj");
630        terrain->setRelCoor(Vector(0,-10,0));
631        this->spawn(terrain);
632        /*monitor progress*/
633        this->glmis->step();
634
635        this->pilotNode = new PilotNode();
636        this->spawn(this->pilotNode);
637        this->pilotNode->setAbsCoor(Vector(150, -35, 5));
638        this->pilotNode->addChild(this->localPlayer);
639        this->pilotNode->addChild(this->localCamera);
640        this->localCamera->lookAt(this->localPlayer);
641
642        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_UP);
643        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_DOWN);
644        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_LEFT);
645        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_RIGHT);
646        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, EV_MOUSE_MOTION);
647
648        // bind input
649        Orxonox *orx = Orxonox::getInstance ();
650        //orx->getLocalInput()->bind (this->pilotNode);
651
652        /*
653        PNode* tn = TrackManager::getInstance()->getTrackNode();
654        tn->addChild(this->localPlayer);
655        this->localCamera->lookAt(tn);
656
657        tn->addChild(this->localCamera);
658        this->localPlayer->setParentMode(PNODE_ALL);
659        TrackManager::getInstance()->condition(2, LEFTRIGHT, this->localPlayer);
660        */
661        this->glmis->step();
662        break;
663      }
664    case DEBUG_WORLD_1:
665      {
666
667        break;
668      }
669    case DEBUG_WORLD_2:
670      {
671
672        break;
673      }
674    default:
675      break;
676    }
677}
678
679
680
681/**
682 *  initializes a new World shortly before start
683
684   this is the function, that will be loaded shortly before the world is
685   started
686*/
687ErrorMessage World::init()
688{
689  this->bPause = false;
690  this->pilotNode = NULL;
691}
692
693
694/**
695 *  starts the World
696*/
697ErrorMessage World::start()
698{
699  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
700  this->bQuitOrxonox = false;
701  this->bQuitCurrentGame = false;
702  this->mainLoop();
703}
704
705/**
706 *  stops the world.
707
708   This happens, when the player decides to end the Level.
709*/
710ErrorMessage World::stop()
711{
712  PRINTF(3)("World::stop() - got stop signal\n");
713  this->bQuitCurrentGame = true;
714}
715
716/**
717 *  pauses the Game
718*/
719ErrorMessage World::pause()
720{
721  this->isPaused = true;
722}
723
724/**
725 *  ends the pause Phase
726*/
727ErrorMessage World::resume()
728{
729  this->isPaused = false;
730}
731
732/**
733 *  destroys the World
734*/
735ErrorMessage World::destroy()
736{
737
738}
739
740/**
741 *  shows the loading screen
742*/
743void World::displayLoadScreen ()
744{
745  PRINTF(3)("World::displayLoadScreen - start\n");
746
747  //GLMenuImageScreen*
748  this->glmis = new GLMenuImageScreen();
749  this->glmis->setMaximum(8);
750
751  PRINTF(3)("World::displayLoadScreen - end\n");
752}
753
754/**
755 *  removes the loadscreen, and changes over to the game
756
757   @todo take out the delay
758*/
759void World::releaseLoadScreen ()
760{
761  PRINTF(3)("World::releaseLoadScreen - start\n");
762  this->glmis->setValue(this->glmis->getMaximum());
763  PRINTF(3)("World::releaseLoadScreen - end\n");
764  delete this->glmis;
765}
766
767
768/**
769 *  gets the list of entities from the world
770 * @returns entity list
771*/
772tList<WorldEntity>* World::getEntities()
773{
774  return this->entities;
775}
776
777
778/**
779 *  this returns the current game time
780 * @returns elapsed game time
781*/
782double World::getGameTime()
783{
784  return this->gameTime;
785}
786
787
788/**
789  *  checks for collisions
790
791    This method runs through all WorldEntities known to the world and checks for collisions
792    between them. In case of collisions the collide() method of the corresponding entities
793    is called.
794*/
795void World::collide ()
796{
797  /*
798  List *a, *b;
799  WorldEntity *aobj, *bobj;
800
801  a = entities;
802
803  while( a != NULL)
804    {
805      aobj = a->nextElement();
806      if( aobj->bCollide && aobj->collisioncluster != NULL)
807        {
808          b = a->nextElement();
809          while( b != NULL )
810            {
811              bobj = b->nextElement();
812              if( bobj->bCollide && bobj->collisioncluster != NULL )
813                {
814                  unsigned long ahitflg, bhitflg;
815                  if( check_collision ( &aobj->place, aobj->collisioncluster,
816                                        &ahitflg, &bobj->place, bobj->collisioncluster,
817                                        &bhitflg) );
818                  {
819                    aobj->collide (bobj, ahitflg, bhitflg);
820                    bobj->collide (aobj, bhitflg, ahitflg);
821                  }
822                }
823              b = b->nextElement();
824            }
825        }
826      a = a->enumerate();
827    }
828  */
829}
830
831/**
832  *  runs through all entities calling their draw() methods
833*/
834void World::draw ()
835{
836  /* draw entities */
837  WorldEntity* entity;
838  glLoadIdentity();
839  //entity = this->entities->enumerate();
840  tIterator<WorldEntity>* iterator = this->entities->getIterator();
841  entity = iterator->nextElement();
842  while( entity != NULL )
843    {
844      if( entity->isVisible() ) entity->draw();
845      //entity = this->entities->nextElement();
846      entity = iterator->nextElement();
847    }
848  delete iterator;
849
850  glCallList (objectList);
851
852  ParticleEngine::getInstance()->draw();
853
854  GraphicsEngine::getInstance()->draw();
855  //TextEngine::getInstance()->draw();
856}
857
858
859/**
860 *  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 *  synchronize local data with remote data
966*/
967void World::synchronize ()
968{
969  // Get remote input
970  // Update synchronizables
971}
972
973
974/**
975 *  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 *  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 *  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 *  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 *  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 *  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 *  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.