Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4846 was 4838, checked in by bensch, 20 years ago

orxonox/trunk: Element2D added → will be moved to lib/graphics afterwards
ProtoClass update
EventListeners do not have to be unsubscribed externally, but still one listener won't unsubscribe

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