Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/spaceshipcontrol/src/story_entities/world.cc @ 5851

Last change on this file since 5851 was 5851, checked in by bensch, 18 years ago

orxonox/trunk: cut player out of the Player class

File size: 28.8 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Patrick Boenzli
13   co-programmer: Christian Meyer
14   co-programmer: Benjamin Grauer
15*/
16
17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
18
19#include "world.h"
20
21#include "shell_command.h"
22
23#include "state.h"
24
25#include "p_node.h"
26#include "null_parent.h"
27#include "pilot_node.h"
28#include "track_node.h"
29#include "world_entity.h"
30#include "player.h"
31#include "camera.h"
32#include "environment.h"
33#include "skysphere.h"
34#include "skybox.h"
35#include "satellite.h"
36#include "test_entity.h"
37#include "terrain.h"
38#include "light.h"
39#include "load_param.h"
40#include "shell.h"
41
42#include "track_manager.h"
43#include "garbage_collector.h"
44#include "fast_factory.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 "weapons/projectile.h"
64#include "event_handler.h"
65
66#include "sound_engine.h"
67#include "ogg_player.h"
68
69#include "class_list.h"
70
71#include "cd_engine.h"
72#include "npcs/npc_test1.h"
73#include "shader.h"
74
75SHELL_COMMAND(speed, World, setSpeed);
76SHELL_COMMAND(togglePNodeVisibility, World, togglePNodeVisibility);
77SHELL_COMMAND(toggleBVVisibility, World, toggleBVVisibility);
78
79using namespace std;
80
81//! This creates a Factory to fabricate a World
82CREATE_FACTORY(World, CL_WORLD);
83
84World::World(const TiXmlElement* root)
85{
86  this->constuctorInit("", -1);
87  this->path = NULL;
88
89  this->loadParams(root);
90}
91
92/**
93  *  create a new World
94
95    This creates a new empty world!
96*/
97World::World (const char* name)
98{
99  this->path = NULL;
100  this->constuctorInit(name, -1);
101}
102
103/**
104 *  creates a new World...
105 * @param worldID with this ID
106*/
107World::World (int worldID)
108{
109  this->path = NULL;
110  this->constuctorInit(NULL, worldID);
111}
112
113/**
114 *  remove the World from memory
115
116    delete everything explicitly, that isn't contained in the parenting tree!
117    things contained in the tree are deleted automaticaly
118 */
119World::~World ()
120{
121  delete this->shell;
122  PRINTF(3)("World::~World() - deleting current world\n");
123
124  // here everything that is alocated by the World is deleted
125  delete this->entities;
126  State::setWorldEntityList(NULL);
127
128
129  // delete all the initialized Engines.
130  FastFactory::flushAll(true);
131  delete LightManager::getInstance();
132  delete TrackManager::getInstance();
133  delete ParticleEngine::getInstance();
134  delete AnimationPlayer::getInstance();
135  delete PhysicsEngine::getInstance();
136
137  // external engines initialized by the orxonox-class get deleted
138  SoundEngine::getInstance()->flushAllBuffers();
139  SoundEngine::getInstance()->flushAllSources();
140
141
142  // erease everything that is left.
143  delete NullParent::getInstance();
144  Shader::suspendShader();
145
146  // unload the resources !!
147  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
148
149  delete[] this->path;
150}
151
152/**
153 * initializes the world.
154 * @param name the name of the world
155 * @param worldID the ID of this world
156 *
157 * set all stuff here that is world generic and does not use to much memory
158 * because the real init() function StoryEntity::init() will be called
159 * shortly before start of the game.
160 * since all worlds are initiated/referenced before they will be started.
161 * NO LEVEL LOADING HERE - NEVER!
162*/
163void World::constuctorInit(const char* name, int worldID)
164{
165  this->setClassID(CL_WORLD, "World");
166
167  this->setName(name);
168  this->debugWorldNr = worldID;
169  this->gameTime = 0.0f;
170  this->setSpeed(1.0);
171  this->music = NULL;
172  this->shell = NULL;
173  this->entities = NULL;
174
175  this->showPNodes = false;
176  this->showBV = false;
177}
178
179/**
180 * loads the parameters of a World from an XML-element
181 * @param root the XML-element to load from
182 */
183void World::loadParams(const TiXmlElement* root)
184{
185  PRINTF(4)("Creating a World\n");
186
187  LoadParam(root, "identifier", this, World, setStoryID)
188    .describe("Sets the StoryID of this world");
189
190  LoadParam(root, "nextid", this, World, setNextStoryID)
191    .describe("Sets the ID of the next world");
192
193  LoadParam(root, "path", this, World, setPath)
194    .describe("The Filename of this World (relative from the data-dir)");
195}
196
197/**
198 * this is executed just before load
199 *
200 * since the load function sometimes needs data, that has been initialized
201 * before the load and after the proceeding storyentity has finished
202*/
203ErrorMessage World::preLoad()
204{
205  State::setWorldEntityList(this->entities = new tList<WorldEntity>());
206  this->cycle = 0;
207
208  /* init the world interface */
209  this->shell = new Shell();
210
211  LightManager::getInstance();
212  NullParent::getInstance ();
213
214  AnimationPlayer::getInstance(); // initializes the animationPlayer
215  PhysicsEngine::getInstance();
216
217  this->localCamera = new Camera();
218  this->localCamera->setName ("World-Camera");
219
220  State::setCamera(this->localCamera, this->localCamera->getTarget());
221
222  GraphicsEngine::getInstance()->displayFPS(true);
223
224  CDEngine::getInstance()->setEntityList( this->entities);
225}
226
227
228/**
229 *  loads the World by initializing all resources, and set their default values.
230*/
231ErrorMessage World::load()
232{
233  PRINTF(3)("> Loading world: '%s'\n", getPath());
234  TiXmlElement* element;
235  GameLoader* loader = GameLoader::getInstance();
236
237  if( getPath() == NULL)
238    {
239      PRINTF(1)("World has no path specified for loading");
240      this->loadDebugWorld(this->getStoryID());
241      return (ErrorMessage){213,"Path not specified","World::load()"};
242    }
243
244  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
245  // load the campaign document
246  if( !XMLDoc->LoadFile())
247  {
248    // report an error
249    PRINTF(1)("loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
250    delete XMLDoc;
251    return (ErrorMessage){213,"XML File parsing error","World::load()"};
252  }
253
254  // check basic validity
255  TiXmlElement* root = XMLDoc->RootElement();
256  assert( root != NULL);
257
258  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
259    {
260      // report an error
261      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
262      delete XMLDoc;
263      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
264    }
265
266  // load the parameters
267  // name
268  const char* string = grabParameter( root, "name");
269  if( string == NULL)
270    {
271      PRINTF(2)("World is missing a proper 'name'\n");
272      this->setName("Unknown");
273    }
274  else
275    {
276      this->setName(string);
277    }
278
279  ////////////////
280  // LOADSCREEN //
281  ////////////////
282  element = root->FirstChildElement("LoadScreen");
283  if (element == NULL)
284    {
285      PRINTF(2)("no LoadScreen specified, loading default\n");
286
287      glmis->setBackgroundImage("pictures/load_screen.jpg");
288      this->glmis->setMaximum(8);
289      this->glmis->draw();
290    }
291  else
292    {
293      this->glmis->loadParams(element);
294      this->glmis->draw();
295    }
296  this->glmis->draw();
297
298  ////////////////////////
299  // find WorldEntities //
300  ////////////////////////
301
302  element = root->FirstChildElement("WorldEntities");
303
304  if( element == NULL)
305    {
306      PRINTF(1)("World is missing 'WorldEntities'\n");
307    }
308  else
309    {
310      element = element->FirstChildElement();
311      // load Players/Objects/Whatever
312      PRINTF(4)("Loading WorldEntities\n");
313      while( element != NULL)
314        {
315          WorldEntity* created = dynamic_cast<WorldEntity*>( loader->fabricate( element));
316          if( created != NULL) this->spawn( created);
317          // if we load a 'Player' we use it as localPlayer
318          //todo do this more elegant
319          if( element->Value() != NULL && !strcmp( element->Value(), "Player"))
320          {
321            localPlayer = (Player*) created;
322          }
323          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
324          if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
325          {
326            terrain = (Terrain*) created;
327            CDEngine::getInstance()->setTerrain(terrain);
328          }
329          element = element->NextSiblingElement();
330          glmis->step(); //! @todo temporary
331        }
332      PRINTF(4)("Done loading WorldEntities\n");
333    }
334
335    //////////////////////////////
336    // LOADING ADDITIONAL STUFF //
337    //////////////////////////////
338
339    LoadParamXML(root, "LightManager", LightManager::getInstance(), LightManager, loadParams);
340
341    LoadParamXML(root, "ParticleEngine", ParticleEngine::getInstance(), ParticleEngine, loadParams);
342    LoadParamXML(root, "PhysicsEngine", PhysicsEngine::getInstance(), PhysicsEngine, loadParams);
343
344  // find Track
345  element = root->FirstChildElement( "Track");
346  if( element == NULL)
347    {
348      PRINTF(0)("World is missing a 'Track'\n");
349    }
350  else
351    {
352      //load track
353      PRINTF(4)("Loading Track\n");
354
355      TrackManager::getInstance()->loadParams( element);
356      TrackManager::getInstance()->finalize();
357    }
358
359  // free the XML data
360
361  delete XMLDoc;
362  /* GENERIC LOADING PROCESS FINISHED */
363
364  // bind input
365  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_UP);
366  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_DOWN);
367  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_LEFT);
368  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_RIGHT);
369  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
370  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
371  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
372  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, SDLK_PAGEUP);
373  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, SDLK_PAGEDOWN);
374
375  // bind camera
376  //this->localCamera->bind (localPlayer);
377 // this->localPlayer->addChild (this->localCamera);
378
379
380  //        TrackManager::getInstance()->setBindSlave(env);
381//  PNode* tn = TrackManager::getInstance()->getTrackNode();
382//  tn->addChild(this->localPlayer);
383
384  //localCamera->setParent(TrackNode::getInstance());
385//  tn->addChild(this->localCamera);
386//  localCamera->lookAt(tn);
387  localCamera->setClipRegion(1, 10000.0);
388//  this->localPlayer->setParentMode(PNODE_ALL);
389  TrackManager::getInstance()->condition(1, LEFTRIGHT, this->localPlayer);
390
391  if (sky != NULL)
392  {
393    this->sky->setParent(this->localCamera);
394    this->sky->setParentMode(PNODE_MOVEMENT);
395  }
396
397  // initialize debug coord system
398  objectList = glGenLists(1);
399  glNewList (objectList, GL_COMPILE);
400
401  //TrackManager::getInstance()->drawGraph(.01);
402  //TrackManager::getInstance()->debug(2);
403  glEndList();
404
405  SoundEngine::getInstance()->setListener(this->localCamera);
406
407
408
409  ////////////
410  // STATIC //
411  ////////////
412
413  Gravity* test = new Gravity();
414
415  // SYSTEM TRAILING THE PLAYER
416  // Creating a Test Particle System
417
418  //new PhysicsConnection(system, gravity);
419  //    new PhysicsConnection(this->localPlayer, gravity);
420
421//   TestEntity* testEntity = new TestEntity();
422//   testEntity->setRelCoor(Vector(570, 10, -15));
423//   testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
424//   this->spawn(testEntity);
425
426//   TestEntity* testEntity2 = new TestEntity();
427//   testEntity2->setAnim(STAND);
428//   testEntity2->setRelCoor(Vector(2400.0, 10.0, -30.0));
429//   testEntity2->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
430//   //testEntity2->setParent(this->localPlayer);
431//   this->spawn(testEntity2);
432//
433//   TestEntity* testEntity3 = new TestEntity();
434//   testEntity3->setAnim(BOOM);
435//   testEntity3->setRelCoor(Vector(2450.0, 10.0, -40.0));
436//   testEntity3->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
437//   this->spawn(testEntity3);
438//
439//   TestEntity* testEntity4 = new TestEntity();
440//   testEntity4->setAnim(FLIP);
441//   testEntity4->setRelCoor(Vector(2500.0, 10.0, -22.0));
442//   testEntity4->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
443//   this->spawn(testEntity4);
444//
445//   TestEntity* testEntity5 = new TestEntity();
446//   testEntity5->setAnim(WAVE);
447//   testEntity5->setRelCoor(Vector(2420.0, 10.0, -50.0));
448//   testEntity5->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
449//   this->spawn(testEntity5);
450//
451//   TestEntity* testEntity6 = new TestEntity();
452//   testEntity6->setAnim(WAVE);
453//   testEntity6->setRelCoor(Vector(2420.0, 10.0, -20.0));
454//   testEntity6->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
455//   this->spawn(testEntity6);
456//
457//   TestEntity* testEntity7 = new TestEntity();
458//   testEntity7->setAnim(WAVE);
459//   testEntity7->setRelCoor(Vector(2500.0, 10.0, -50.0));
460//   testEntity7->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
461//   this->spawn(testEntity7);
462
463
464
465//  PhysicsEngine::getInstance()->debug();
466
467
468
469  for(int i = 0; i < 100; i++)
470  {
471    WorldEntity* tmp = new NPCTest1();
472    char npcChar[10];
473    sprintf (npcChar, "NPC_%d", i);
474        tmp->setName(npcChar);
475    tmp->setAbsCoor(((float)rand()/RAND_MAX) * 5000, 50/*+ (float)rand()/RAND_MAX*20*/, ((float)rand()/RAND_MAX -.5) *30);
476    this->spawn(tmp);
477
478
479  }
480
481
482
483//  ClassList::debug();
484
485  this->music = NULL;//(OggPlayer*)ResourceManager::getInstance()->load("sound/00-luke_grey_-_hypermode.ogg", OGG, RP_LEVEL);
486  //music->playback();
487}
488
489
490
491/**
492 * creates a debug world: only for experimental stuff
493*/
494void World::loadDebugWorld(int worldID)
495{
496  /*monitor progress*/
497  this->glmis->step();
498  // stuff beyond this point remains to be loaded properly
499
500  // initializing the TrackManager
501  TrackManager::getInstance()->addPointV(Vector(150, -35, 5));
502  TrackManager::getInstance()->addPointV(Vector(200,-35, 5));
503  TrackManager::getInstance()->addPointV(Vector(250, -35, 5));
504  TrackManager::getInstance()->addPointV(Vector(320,-33,-.55));
505  TrackManager::getInstance()->setDuration(1);
506  TrackManager::getInstance()->setSavePoint();
507
508  TrackManager::getInstance()->addPointV(Vector(410, 0, 0));
509  TrackManager::getInstance()->addPointV(Vector(510, 20, -10));
510  TrackManager::getInstance()->addPointV(Vector(550, 20, -10));
511  TrackManager::getInstance()->addPointV(Vector(570, 20, -10));
512  TrackManager::getInstance()->setDuration(2);
513
514  TrackManager::getInstance()->forkS("testFork1,testFork2");
515  TrackManager::getInstance()->workOnS("testFork1");
516  TrackManager::getInstance()->addPointV(Vector(640, 25, -30));
517  TrackManager::getInstance()->addPointV(Vector(700, 40, -120));
518  TrackManager::getInstance()->addPointV(Vector(800, 50, -150));
519  TrackManager::getInstance()->addPointV(Vector(900, 60, -100));
520  TrackManager::getInstance()->addPointV(Vector(900, 60, -70));
521  TrackManager::getInstance()->addPointV(Vector(990, 65, -15));
522  TrackManager::getInstance()->addPointV(Vector(1050, 65, -10));
523  TrackManager::getInstance()->addPointV(Vector(1100, 65, -20));
524  TrackManager::getInstance()->setDuration(4);
525
526  TrackManager::getInstance()->workOnS("testFork2");
527  TrackManager::getInstance()->addPointV(Vector(640, 25, 20));
528  TrackManager::getInstance()->addPointV(Vector(670, 50, 120));
529  TrackManager::getInstance()->addPointV(Vector(700, 70, 80));
530  TrackManager::getInstance()->addPointV(Vector(800, 70, 65));
531  TrackManager::getInstance()->addPointV(Vector(850, 65, 65));
532  TrackManager::getInstance()->addPointV(Vector(920, 35, 40));
533  TrackManager::getInstance()->addPointV(Vector(945, 40, 40));
534  TrackManager::getInstance()->addPointV(Vector(970, 24, 40));
535  TrackManager::getInstance()->addPointV(Vector(1000, 40, -7));
536
537  TrackManager::getInstance()->setDuration(4);
538
539
540  TrackManager::getInstance()->joinS("testFork1,testFork2");
541
542  TrackManager::getInstance()->addPointV(Vector(1200, 60, -50));
543  TrackManager::getInstance()->addPointV(Vector(1300, 50, -50));
544  TrackManager::getInstance()->addPointV(Vector(1400, 40, -50));
545  TrackManager::getInstance()->addPointV(Vector(1500, 40, -60));
546  TrackManager::getInstance()->addPointV(Vector(1600, 35, -55));
547  TrackManager::getInstance()->addPointV(Vector(1700, 45, -40));
548  TrackManager::getInstance()->addPointV(Vector(1750, 60, -40));
549  TrackManager::getInstance()->addPointV(Vector(1770, 80, -40));
550  TrackManager::getInstance()->addPointV(Vector(1800, 100, -40));
551  TrackManager::getInstance()->setDuration(10);
552
553  TrackManager::getInstance()->finalize();
554
555
556  // LIGHT initialisation
557  LightManager::getInstance()->setAmbientColor(.1,.1,.1);
558//  LightManager::getInstance()->addLight();
559  LightManager::getInstance()->debug();
560
561  switch(this->debugWorldNr)
562    {
563      /*
564        this loads the hard-coded debug world. this only for simplicity and will be
565        removed by a reald world-loader, which interprets a world-file.
566        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
567        make whatever you want...
568      */
569    case DEBUG_WORLD_0:
570      {
571        LightManager::getInstance()->getLight()->setAbsCoor(-5.0, 10.0, -40.0);
572
573
574//        this->localPlayer = new Player ();
575//        this->localPlayer->setName ("player");
576//        this->spawn (this->localPlayer);
577//        this->localPlayer->setRelCoor(Vector(5,0,0));
578        /*monitor progress*/
579        this->glmis->step();
580
581
582        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
583        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
584        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
585
586        /*
587        Field* testField = new Gravity();
588        testField->setMagnitude(10);
589        new PhysicsConnection(this->localPlayer, testField);
590        */
591
592        // bind camera
593        this->localCamera = new Camera();
594        this->localCamera->setName ("camera");
595        /*monitor progress*/
596        this->glmis->step();
597
598
599        // Create SkySphere
600        this->sky = new Skysphere("pictures/sky-replace.jpg");
601        this->sky->setName("SkySphere");
602        this->spawn(this->sky);
603        this->localCamera->addChild(this->sky);
604        this->sky->setParentMode(PNODE_MOVEMENT);
605        /*monitor progress*/
606        this->glmis->step();
607
608
609        terrain = new Terrain("worlds/newGround.obj");
610        terrain->setRelCoor(Vector(0,-10,0));
611        this->spawn(terrain);
612        /*monitor progress*/
613        this->glmis->step();
614
615//        this->pilotNode = new PilotNode();
616//        this->spawn(this->pilotNode);
617//        this->pilotNode->setAbsCoor(Vector(150, -35, 5));
618//        this->pilotNode->addChild(this->localPlayer);
619//        this->pilotNode->addChild(this->localCamera);
620//        this->localCamera->lookAt(this->localPlayer);
621
622        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_UP);
623        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_DOWN);
624        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_LEFT);
625        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_RIGHT);
626        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, EV_MOUSE_MOTION);
627
628        /*
629        PNode* tn = TrackManager::getInstance()->getTrackNode();
630        tn->addChild(this->localPlayer);
631        this->localCamera->lookAt(tn);
632
633        tn->addChild(this->localCamera);
634        this->localPlayer->setParentMode(PNODE_ALL);
635        TrackManager::getInstance()->condition(2, LEFTRIGHT, this->localPlayer);
636        */
637        this->glmis->step();
638        break;
639      }
640    case DEBUG_WORLD_1:
641      {
642
643        break;
644      }
645    case DEBUG_WORLD_2:
646      {
647
648        break;
649      }
650    default:
651      break;
652    }
653}
654
655/**
656 *  initializes a new World shortly before start
657 *
658 * this is the function, that will be loaded shortly before the world is
659 * started
660*/
661ErrorMessage World::init()
662{
663  this->bPause = false;
664  this->pilotNode = NULL;
665
666  /* update the object position before game start - so there are no wrong coordinates used in the first processing */
667  NullParent::getInstance()->updateNode (0.001f);
668  NullParent::getInstance()->updateNode (0.001f);
669
670}
671
672
673/**
674 *  starts the World
675*/
676ErrorMessage World::start()
677{
678  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
679  this->bQuitOrxonox = false;
680  this->bQuitCurrentGame = false;
681  this->mainLoop();
682}
683
684/**
685 *  stops the world.
686
687   This happens, when the player decides to end the Level.
688*/
689ErrorMessage World::stop()
690{
691  PRINTF(3)("World::stop() - got stop signal\n");
692  this->bQuitCurrentGame = true;
693}
694
695/**
696 *  pauses the Game
697*/
698ErrorMessage World::pause()
699{
700  this->isPaused = true;
701}
702
703/**
704 *  ends the pause Phase
705*/
706ErrorMessage World::resume()
707{
708  this->isPaused = false;
709}
710
711/**
712 *  destroys the World
713*/
714ErrorMessage World::destroy()
715{
716
717}
718
719/**
720 *  shows the loading screen
721*/
722void World::displayLoadScreen ()
723{
724  PRINTF(3)("World::displayLoadScreen - start\n");
725
726  //GLMenuImageScreen*
727  this->glmis = new GLMenuImageScreen();
728  this->glmis->setMaximum(8);
729
730  PRINTF(3)("World::displayLoadScreen - end\n");
731}
732
733/**
734 *  removes the loadscreen, and changes over to the game
735
736   @todo take out the delay
737*/
738void World::releaseLoadScreen ()
739{
740  PRINTF(3)("World::releaseLoadScreen - start\n");
741  this->glmis->setValue(this->glmis->getMaximum());
742  PRINTF(3)("World::releaseLoadScreen - end\n");
743  delete this->glmis;
744}
745
746
747/**
748 *  gets the list of entities from the world
749 * @returns entity list
750*/
751tList<WorldEntity>* World::getEntities()
752{
753  return this->entities;
754}
755
756
757/**
758 *  this returns the current game time
759 * @returns elapsed game time
760*/
761double World::getGameTime()
762{
763  return this->gameTime;
764}
765
766
767/**
768 *  function to put your own debug stuff into it. it can display informations about
769   the current class/procedure
770*/
771void World::debug()
772{
773  PRINTF(0)("Printing out the List of alive WorldEntities:\n");
774  tIterator<WorldEntity>* iterator = this->entities->getIterator();
775  WorldEntity* entity = iterator->firstElement();
776  while( entity != NULL)
777  {
778    PRINTF(0)("%s::%s\n", entity->getClassName(), entity->getName());
779    entity = iterator->nextElement();
780  }
781  delete iterator;
782}
783
784
785/**
786  \brief main loop of the world: executing all world relevant function
787
788  in this loop we synchronize (if networked), handle input events, give the heart-beat to
789  all other member-entities of the world (tick to player, enemies etc.), checking for
790  collisions drawing everything to the screen.
791*/
792void World::mainLoop()
793{
794  this->lastFrame = SDL_GetTicks ();
795  PRINTF(3)("World::mainLoop() - Entering main loop\n");
796
797  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* @todo implement pause */
798    {
799      ++this->cycle;
800      PRINTF(4)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
801      // Network
802      this->synchronize ();
803      // Process input
804      this->handleInput ();
805      if( this->bQuitCurrentGame || this->bQuitOrxonox)
806          break;
807      // Process time
808      this->tick ();
809      // Process collision
810      this->collide ();
811      // Update the state
812      this->update ();
813      // Draw
814      this->display ();
815    }
816
817  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
818}
819
820
821/**
822 *  synchronize local data with remote data
823*/
824void World::synchronize ()
825{
826  // Get remote input
827  // Update synchronizables
828}
829
830
831/**
832 *  run all input processing
833
834   the command node is the central input event dispatcher. the node uses the even-queue from
835   sdl and has its own event-passing-queue.
836*/
837void World::handleInput ()
838{
839  // localinput
840  //CommandNode* cn = Orxonox::getInstance()->getLocalInput();
841  //cn->process();
842
843  EventHandler::getInstance()->process();
844
845  // remoteinput
846}
847
848
849/**
850 *  advance the timeline
851
852   this calculates the time used to process one frame (with all input handling, drawing, etc)
853   the time is mesured in ms and passed to all world-entities and other classes that need
854   a heart-beat.
855*/
856void World::tick ()
857{
858  Uint32 currentFrame = SDL_GetTicks();
859  if(!this->bPause)
860    {
861      this->dt = currentFrame - this->lastFrame;
862
863      if( this->dt > 10)
864        {
865          float fps = 1000/dt;
866
867          // temporary, only for showing how fast the text-engine is
868          char tmpChar[20];
869          sprintf(tmpChar, "fps: %4.0f", fps);
870        }
871      else
872        {
873          /* the frame-rate is limited to 100 frames per second, all other things are for
874             nothing.
875          */
876          PRINTF(3)("fps = 1000 - frame rate is adjusted\n");
877          SDL_Delay(10-dt);
878          this->dt = 10;
879        }
880
881      this->dtS = (float)this->dt / 1000.0 * this->speed;
882      this->gameTime += this->dtS;
883
884      tIterator<WorldEntity>* iterator = this->entities->getIterator();
885      WorldEntity* entity = iterator->firstElement();
886      while( entity != NULL)
887        {
888          entity->tick (this->dtS);
889          entity = iterator->nextElement();
890        }
891      delete iterator;
892
893      /* update tick the rest */
894      TrackManager::getInstance()->tick(this->dtS);
895      this->localCamera->tick(this->dtS);
896      // tick the engines
897      AnimationPlayer::getInstance()->tick(this->dtS);
898//      if (this->cycle > 5)
899        PhysicsEngine::getInstance()->tick(this->dtS);
900
901      ParticleEngine::getInstance()->tick(this->dtS);
902      GarbageCollector::getInstance()->tick(this->dtS);
903
904
905      /** actualy the Graphics Engine should tick the world not the other way around...
906         but since we like the things not too complicated we got it this way around
907         until there is need or time to do it the other way around.
908         @todo: GraphicsEngine ticks world: separation of processes and data...
909
910        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
911         beceause graphics have nothing(or at least not much) to do with Motion.
912      */
913      GraphicsEngine::getInstance()->tick(this->dtS);
914    }
915  this->lastFrame = currentFrame;
916}
917
918
919/**
920 *  this function gives the world a consistant state
921
922   after ticking (updating the world state) this will give a constistant
923   state to the whole system.
924*/
925void World::update()
926{
927  GarbageCollector::getInstance()->update();
928  GraphicsEngine::getInstance()->update(this->dtS);
929  NullParent::getInstance()->updateNode (this->dtS);
930
931  SoundEngine::getInstance()->update();
932  //music->update();
933}
934
935
936void World::collide()
937{
938  CDEngine::getInstance()->checkCollisions();
939}
940
941/**
942 *  render the current frame
943
944   clear all buffers and draw the world
945*/
946void World::display ()
947{
948  // clear buffer
949  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
950  // set camera
951  this->localCamera->apply ();
952  // draw world
953  this->draw();
954  // draw HUD
955  /** @todo draw HUD */
956  // flip buffers
957  GraphicsEngine::swapBuffers();
958  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
959  //SDL_Flip (screen);
960}
961
962
963/**
964 *  runs through all entities calling their draw() methods
965 */
966void World::draw ()
967{
968  /* draw entities */
969  WorldEntity* entity;
970  glLoadIdentity();
971  tIterator<WorldEntity>* iterator = this->entities->getIterator();
972  entity = iterator->firstElement();
973  while( entity != NULL )
974  {
975    if( entity->isVisible() ) entity->draw();
976    if( unlikely( this->showBV)) entity->drawBVTree(3, 226);  // to draw the bounding boxes of the objects at level 2 for debug purp
977    entity = iterator->nextElement();
978  }
979  delete iterator;
980
981  glCallList (objectList);
982
983  ParticleEngine::getInstance()->draw();
984
985  if (unlikely(this->showPNodes))
986    NullParent::getInstance()->debugDraw(0);
987
988  GraphicsEngine::getInstance()->draw();
989  //TextEngine::getInstance()->draw();
990}
991
992/**
993 *  add and spawn a new entity to this world
994 * @param entity to be added
995*/
996void World::spawn(WorldEntity* entity)
997{
998  this->entities->add (entity);
999  entity->postSpawn ();
1000}
1001
1002
1003/**
1004 *  add and spawn a new entity to this world
1005 * @param entity to be added
1006 * @param absCoor At what coordinates to add this entity.
1007 * @param absDir In which direction should it look.
1008*/
1009void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1010{
1011  this->entities->add (entity);
1012
1013  entity->setAbsCoor (*absCoor);
1014  entity->setAbsDir (*absDir);
1015
1016  entity->postSpawn ();
1017}
1018
1019
1020/**
1021 *  add and spawn a new entity to this world
1022 * @param entity to be added
1023 * @param entity to be added to (PNode)
1024 * @param At what relative  coordinates to add this entity.
1025 * @param In which relative direction should it look.
1026*/
1027void World::spawn(WorldEntity* entity, PNode* parentNode,
1028                  Vector* relCoor, Quaternion* relDir)
1029{
1030  if( parentNode != NULL)
1031    {
1032      parentNode->addChild (entity);
1033
1034      entity->setRelCoor (*relCoor);
1035      entity->setRelDir (*relDir);
1036
1037      this->entities->add (entity);
1038
1039      entity->postSpawn ();
1040    }
1041}
1042
1043void World::setPath( const char* name)
1044{
1045  if (this->path)
1046    delete this->path;
1047  if (ResourceManager::isFile(name))
1048  {
1049    this->path = new char[strlen(name)+1];
1050    strcpy(this->path, name);
1051  }
1052  else
1053    {
1054      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1055      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1056    }
1057}
1058
1059const char* World::getPath( void)
1060{
1061  return path;
1062}
Note: See TracBrowser for help on using the repository browser.