Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: vulcan spy some Splinters

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