Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: more loading procedures, fixed small bugs in loadparam

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