Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/spaceshipcontroll: simple world-interactivity

File size: 29.0 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
319          //todo do this more elegant
320          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
321          if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
322          {
323            terrain = (Terrain*) created;
324            CDEngine::getInstance()->setTerrain(terrain);
325          }
326          element = element->NextSiblingElement();
327          glmis->step(); //! @todo temporary
328        }
329      PRINTF(4)("Done loading WorldEntities\n");
330    }
331
332    //////////////////////////////
333    // LOADING ADDITIONAL STUFF //
334    //////////////////////////////
335
336    LoadParamXML(root, "LightManager", LightManager::getInstance(), LightManager, loadParams);
337
338    LoadParamXML(root, "ParticleEngine", ParticleEngine::getInstance(), ParticleEngine, loadParams);
339    LoadParamXML(root, "PhysicsEngine", PhysicsEngine::getInstance(), PhysicsEngine, loadParams);
340
341  // find Track
342  element = root->FirstChildElement( "Track");
343  if( element == NULL)
344    {
345      PRINTF(0)("World is missing a 'Track'\n");
346    }
347  else
348    {
349      //load track
350      PRINTF(4)("Loading Track\n");
351
352      TrackManager::getInstance()->loadParams( element);
353      TrackManager::getInstance()->finalize();
354    }
355
356  // free the XML data
357
358  delete XMLDoc;
359  /* GENERIC LOADING PROCESS FINISHED */
360
361
362  // Create a Player
363  this->localPlayer = new Player();
364  list<BaseObject*>* playableList = ClassList::getList(CL_PLAYABLE);
365  if (playableList != NULL)
366  {
367    Playable* playable = dynamic_cast<Playable*>(playableList->front());
368    if (playable != NULL)
369      this->localPlayer->setControllable(playable);
370  }
371  // bind input
372  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_UP);
373  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_DOWN);
374  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_LEFT);
375  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_RIGHT);
376  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
377  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
378  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
379  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, SDLK_PAGEUP);
380  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, SDLK_PAGEDOWN);
381
382  // bind camera
383  //this->localCamera->bind (localPlayer);
384 // this->localPlayer->addChild (this->localCamera);
385
386
387  //        TrackManager::getInstance()->setBindSlave(env);
388//  PNode* tn = TrackManager::getInstance()->getTrackNode();
389//  tn->addChild(this->localPlayer);
390
391  //localCamera->setParent(TrackNode::getInstance());
392//  tn->addChild(this->localCamera);
393//  localCamera->lookAt(tn);
394  localCamera->setClipRegion(1, 10000.0);
395//  this->localPlayer->setParentMode(PNODE_ALL);
396  TrackManager::getInstance()->condition(1, LEFTRIGHT, this->localPlayer);
397
398  if (sky != NULL)
399  {
400    this->sky->setParent(this->localCamera);
401    this->sky->setParentMode(PNODE_MOVEMENT);
402  }
403
404  // initialize debug coord system
405  objectList = glGenLists(1);
406  glNewList (objectList, GL_COMPILE);
407
408  //TrackManager::getInstance()->drawGraph(.01);
409  //TrackManager::getInstance()->debug(2);
410  glEndList();
411
412  SoundEngine::getInstance()->setListener(this->localCamera);
413
414
415
416  ////////////
417  // STATIC //
418  ////////////
419
420  Gravity* test = new Gravity();
421
422  // SYSTEM TRAILING THE PLAYER
423  // Creating a Test Particle System
424
425  //new PhysicsConnection(system, gravity);
426  //    new PhysicsConnection(this->localPlayer, gravity);
427
428//   TestEntity* testEntity = new TestEntity();
429//   testEntity->setRelCoor(Vector(570, 10, -15));
430//   testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
431//   this->spawn(testEntity);
432
433//   TestEntity* testEntity2 = new TestEntity();
434//   testEntity2->setAnim(STAND);
435//   testEntity2->setRelCoor(Vector(2400.0, 10.0, -30.0));
436//   testEntity2->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
437//   //testEntity2->setParent(this->localPlayer);
438//   this->spawn(testEntity2);
439//
440//   TestEntity* testEntity3 = new TestEntity();
441//   testEntity3->setAnim(BOOM);
442//   testEntity3->setRelCoor(Vector(2450.0, 10.0, -40.0));
443//   testEntity3->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
444//   this->spawn(testEntity3);
445//
446//   TestEntity* testEntity4 = new TestEntity();
447//   testEntity4->setAnim(FLIP);
448//   testEntity4->setRelCoor(Vector(2500.0, 10.0, -22.0));
449//   testEntity4->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
450//   this->spawn(testEntity4);
451//
452//   TestEntity* testEntity5 = new TestEntity();
453//   testEntity5->setAnim(WAVE);
454//   testEntity5->setRelCoor(Vector(2420.0, 10.0, -50.0));
455//   testEntity5->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
456//   this->spawn(testEntity5);
457//
458//   TestEntity* testEntity6 = new TestEntity();
459//   testEntity6->setAnim(WAVE);
460//   testEntity6->setRelCoor(Vector(2420.0, 10.0, -20.0));
461//   testEntity6->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
462//   this->spawn(testEntity6);
463//
464//   TestEntity* testEntity7 = new TestEntity();
465//   testEntity7->setAnim(WAVE);
466//   testEntity7->setRelCoor(Vector(2500.0, 10.0, -50.0));
467//   testEntity7->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
468//   this->spawn(testEntity7);
469
470
471
472//  PhysicsEngine::getInstance()->debug();
473
474
475
476  for(int i = 0; i < 100; i++)
477  {
478    WorldEntity* tmp = new NPCTest1();
479    char npcChar[10];
480    sprintf (npcChar, "NPC_%d", i);
481        tmp->setName(npcChar);
482    tmp->setAbsCoor(((float)rand()/RAND_MAX) * 5000, 50/*+ (float)rand()/RAND_MAX*20*/, ((float)rand()/RAND_MAX -.5) *30);
483    this->spawn(tmp);
484
485
486  }
487
488
489
490//  ClassList::debug();
491
492  this->music = NULL;//(OggPlayer*)ResourceManager::getInstance()->load("sound/00-luke_grey_-_hypermode.ogg", OGG, RP_LEVEL);
493  //music->playback();
494}
495
496
497
498/**
499 * creates a debug world: only for experimental stuff
500*/
501void World::loadDebugWorld(int worldID)
502{
503  /*monitor progress*/
504  this->glmis->step();
505  // stuff beyond this point remains to be loaded properly
506
507  // initializing the TrackManager
508  TrackManager::getInstance()->addPointV(Vector(150, -35, 5));
509  TrackManager::getInstance()->addPointV(Vector(200,-35, 5));
510  TrackManager::getInstance()->addPointV(Vector(250, -35, 5));
511  TrackManager::getInstance()->addPointV(Vector(320,-33,-.55));
512  TrackManager::getInstance()->setDuration(1);
513  TrackManager::getInstance()->setSavePoint();
514
515  TrackManager::getInstance()->addPointV(Vector(410, 0, 0));
516  TrackManager::getInstance()->addPointV(Vector(510, 20, -10));
517  TrackManager::getInstance()->addPointV(Vector(550, 20, -10));
518  TrackManager::getInstance()->addPointV(Vector(570, 20, -10));
519  TrackManager::getInstance()->setDuration(2);
520
521  TrackManager::getInstance()->forkS("testFork1,testFork2");
522  TrackManager::getInstance()->workOnS("testFork1");
523  TrackManager::getInstance()->addPointV(Vector(640, 25, -30));
524  TrackManager::getInstance()->addPointV(Vector(700, 40, -120));
525  TrackManager::getInstance()->addPointV(Vector(800, 50, -150));
526  TrackManager::getInstance()->addPointV(Vector(900, 60, -100));
527  TrackManager::getInstance()->addPointV(Vector(900, 60, -70));
528  TrackManager::getInstance()->addPointV(Vector(990, 65, -15));
529  TrackManager::getInstance()->addPointV(Vector(1050, 65, -10));
530  TrackManager::getInstance()->addPointV(Vector(1100, 65, -20));
531  TrackManager::getInstance()->setDuration(4);
532
533  TrackManager::getInstance()->workOnS("testFork2");
534  TrackManager::getInstance()->addPointV(Vector(640, 25, 20));
535  TrackManager::getInstance()->addPointV(Vector(670, 50, 120));
536  TrackManager::getInstance()->addPointV(Vector(700, 70, 80));
537  TrackManager::getInstance()->addPointV(Vector(800, 70, 65));
538  TrackManager::getInstance()->addPointV(Vector(850, 65, 65));
539  TrackManager::getInstance()->addPointV(Vector(920, 35, 40));
540  TrackManager::getInstance()->addPointV(Vector(945, 40, 40));
541  TrackManager::getInstance()->addPointV(Vector(970, 24, 40));
542  TrackManager::getInstance()->addPointV(Vector(1000, 40, -7));
543
544  TrackManager::getInstance()->setDuration(4);
545
546
547  TrackManager::getInstance()->joinS("testFork1,testFork2");
548
549  TrackManager::getInstance()->addPointV(Vector(1200, 60, -50));
550  TrackManager::getInstance()->addPointV(Vector(1300, 50, -50));
551  TrackManager::getInstance()->addPointV(Vector(1400, 40, -50));
552  TrackManager::getInstance()->addPointV(Vector(1500, 40, -60));
553  TrackManager::getInstance()->addPointV(Vector(1600, 35, -55));
554  TrackManager::getInstance()->addPointV(Vector(1700, 45, -40));
555  TrackManager::getInstance()->addPointV(Vector(1750, 60, -40));
556  TrackManager::getInstance()->addPointV(Vector(1770, 80, -40));
557  TrackManager::getInstance()->addPointV(Vector(1800, 100, -40));
558  TrackManager::getInstance()->setDuration(10);
559
560  TrackManager::getInstance()->finalize();
561
562
563  // LIGHT initialisation
564  LightManager::getInstance()->setAmbientColor(.1,.1,.1);
565//  LightManager::getInstance()->addLight();
566  LightManager::getInstance()->debug();
567
568  switch(this->debugWorldNr)
569    {
570      /*
571        this loads the hard-coded debug world. this only for simplicity and will be
572        removed by a reald world-loader, which interprets a world-file.
573        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
574        make whatever you want...
575      */
576    case DEBUG_WORLD_0:
577      {
578        LightManager::getInstance()->getLight()->setAbsCoor(-5.0, 10.0, -40.0);
579
580
581//        this->localPlayer = new Player ();
582//        this->localPlayer->setName ("player");
583//        this->spawn (this->localPlayer);
584//        this->localPlayer->setRelCoor(Vector(5,0,0));
585        /*monitor progress*/
586        this->glmis->step();
587
588
589        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
590        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
591        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
592
593        /*
594        Field* testField = new Gravity();
595        testField->setMagnitude(10);
596        new PhysicsConnection(this->localPlayer, testField);
597        */
598
599        // bind camera
600        this->localCamera = new Camera();
601        this->localCamera->setName ("camera");
602        /*monitor progress*/
603        this->glmis->step();
604
605
606        // Create SkySphere
607        this->sky = new Skysphere("pictures/sky-replace.jpg");
608        this->sky->setName("SkySphere");
609        this->spawn(this->sky);
610        this->localCamera->addChild(this->sky);
611        this->sky->setParentMode(PNODE_MOVEMENT);
612        /*monitor progress*/
613        this->glmis->step();
614
615
616        terrain = new Terrain("worlds/newGround.obj");
617        terrain->setRelCoor(Vector(0,-10,0));
618        this->spawn(terrain);
619        /*monitor progress*/
620        this->glmis->step();
621
622//        this->pilotNode = new PilotNode();
623//        this->spawn(this->pilotNode);
624//        this->pilotNode->setAbsCoor(Vector(150, -35, 5));
625//        this->pilotNode->addChild(this->localPlayer);
626//        this->pilotNode->addChild(this->localCamera);
627//        this->localCamera->lookAt(this->localPlayer);
628
629        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_UP);
630        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_DOWN);
631        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_LEFT);
632        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_RIGHT);
633        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, EV_MOUSE_MOTION);
634
635        /*
636        PNode* tn = TrackManager::getInstance()->getTrackNode();
637        tn->addChild(this->localPlayer);
638        this->localCamera->lookAt(tn);
639
640        tn->addChild(this->localCamera);
641        this->localPlayer->setParentMode(PNODE_ALL);
642        TrackManager::getInstance()->condition(2, LEFTRIGHT, this->localPlayer);
643        */
644        this->glmis->step();
645        break;
646      }
647    case DEBUG_WORLD_1:
648      {
649
650        break;
651      }
652    case DEBUG_WORLD_2:
653      {
654
655        break;
656      }
657    default:
658      break;
659    }
660}
661
662/**
663 *  initializes a new World shortly before start
664 *
665 * this is the function, that will be loaded shortly before the world is
666 * started
667*/
668ErrorMessage World::init()
669{
670  this->bPause = false;
671  this->pilotNode = NULL;
672
673  /* update the object position before game start - so there are no wrong coordinates used in the first processing */
674  NullParent::getInstance()->updateNode (0.001f);
675  NullParent::getInstance()->updateNode (0.001f);
676
677}
678
679
680/**
681 *  starts the World
682*/
683ErrorMessage World::start()
684{
685  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
686  this->bQuitOrxonox = false;
687  this->bQuitCurrentGame = false;
688  this->mainLoop();
689}
690
691/**
692 *  stops the world.
693
694   This happens, when the player decides to end the Level.
695*/
696ErrorMessage World::stop()
697{
698  PRINTF(3)("World::stop() - got stop signal\n");
699  this->bQuitCurrentGame = true;
700}
701
702/**
703 *  pauses the Game
704*/
705ErrorMessage World::pause()
706{
707  this->isPaused = true;
708}
709
710/**
711 *  ends the pause Phase
712*/
713ErrorMessage World::resume()
714{
715  this->isPaused = false;
716}
717
718/**
719 *  destroys the World
720*/
721ErrorMessage World::destroy()
722{
723
724}
725
726/**
727 *  shows the loading screen
728*/
729void World::displayLoadScreen ()
730{
731  PRINTF(3)("World::displayLoadScreen - start\n");
732
733  //GLMenuImageScreen*
734  this->glmis = new GLMenuImageScreen();
735  this->glmis->setMaximum(8);
736
737  PRINTF(3)("World::displayLoadScreen - end\n");
738}
739
740/**
741 *  removes the loadscreen, and changes over to the game
742
743   @todo take out the delay
744*/
745void World::releaseLoadScreen ()
746{
747  PRINTF(3)("World::releaseLoadScreen - start\n");
748  this->glmis->setValue(this->glmis->getMaximum());
749  PRINTF(3)("World::releaseLoadScreen - end\n");
750  delete this->glmis;
751}
752
753
754/**
755 *  gets the list of entities from the world
756 * @returns entity list
757*/
758tList<WorldEntity>* World::getEntities()
759{
760  return this->entities;
761}
762
763
764/**
765 *  this returns the current game time
766 * @returns elapsed game time
767*/
768double World::getGameTime()
769{
770  return this->gameTime;
771}
772
773
774/**
775 *  function to put your own debug stuff into it. it can display informations about
776   the current class/procedure
777*/
778void World::debug()
779{
780  PRINTF(0)("Printing out the List of alive WorldEntities:\n");
781  tIterator<WorldEntity>* iterator = this->entities->getIterator();
782  WorldEntity* entity = iterator->firstElement();
783  while( entity != NULL)
784  {
785    PRINTF(0)("%s::%s\n", entity->getClassName(), entity->getName());
786    entity = iterator->nextElement();
787  }
788  delete iterator;
789}
790
791
792/**
793  \brief main loop of the world: executing all world relevant function
794
795  in this loop we synchronize (if networked), handle input events, give the heart-beat to
796  all other member-entities of the world (tick to player, enemies etc.), checking for
797  collisions drawing everything to the screen.
798*/
799void World::mainLoop()
800{
801  this->lastFrame = SDL_GetTicks ();
802  PRINTF(3)("World::mainLoop() - Entering main loop\n");
803
804  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* @todo implement pause */
805    {
806      ++this->cycle;
807      PRINTF(4)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
808      // Network
809      this->synchronize ();
810      // Process input
811      this->handleInput ();
812      if( this->bQuitCurrentGame || this->bQuitOrxonox)
813          break;
814      // Process time
815      this->tick ();
816      // Process collision
817      this->collide ();
818      // Update the state
819      this->update ();
820      // Draw
821      this->display ();
822    }
823
824  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
825}
826
827
828/**
829 *  synchronize local data with remote data
830*/
831void World::synchronize ()
832{
833  // Get remote input
834  // Update synchronizables
835}
836
837
838/**
839 *  run all input processing
840
841   the command node is the central input event dispatcher. the node uses the even-queue from
842   sdl and has its own event-passing-queue.
843*/
844void World::handleInput ()
845{
846  // localinput
847  //CommandNode* cn = Orxonox::getInstance()->getLocalInput();
848  //cn->process();
849
850  EventHandler::getInstance()->process();
851
852  // remoteinput
853}
854
855
856/**
857 *  advance the timeline
858
859   this calculates the time used to process one frame (with all input handling, drawing, etc)
860   the time is mesured in ms and passed to all world-entities and other classes that need
861   a heart-beat.
862*/
863void World::tick ()
864{
865  Uint32 currentFrame = SDL_GetTicks();
866  if(!this->bPause)
867    {
868      this->dt = currentFrame - this->lastFrame;
869
870      if( this->dt > 10)
871        {
872          float fps = 1000/dt;
873
874          // temporary, only for showing how fast the text-engine is
875          char tmpChar[20];
876          sprintf(tmpChar, "fps: %4.0f", fps);
877        }
878      else
879        {
880          /* the frame-rate is limited to 100 frames per second, all other things are for
881             nothing.
882          */
883          PRINTF(3)("fps = 1000 - frame rate is adjusted\n");
884          SDL_Delay(10-dt);
885          this->dt = 10;
886        }
887
888      this->dtS = (float)this->dt / 1000.0 * this->speed;
889      this->gameTime += this->dtS;
890
891      tIterator<WorldEntity>* iterator = this->entities->getIterator();
892      WorldEntity* entity = iterator->firstElement();
893      while( entity != NULL)
894        {
895          entity->tick (this->dtS);
896          entity = iterator->nextElement();
897        }
898      delete iterator;
899
900      /* update tick the rest */
901      TrackManager::getInstance()->tick(this->dtS);
902      this->localCamera->tick(this->dtS);
903      // tick the engines
904      AnimationPlayer::getInstance()->tick(this->dtS);
905//      if (this->cycle > 5)
906        PhysicsEngine::getInstance()->tick(this->dtS);
907
908      ParticleEngine::getInstance()->tick(this->dtS);
909      GarbageCollector::getInstance()->tick(this->dtS);
910
911
912      /** actualy the Graphics Engine should tick the world not the other way around...
913         but since we like the things not too complicated we got it this way around
914         until there is need or time to do it the other way around.
915         @todo: GraphicsEngine ticks world: separation of processes and data...
916
917        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
918         beceause graphics have nothing(or at least not much) to do with Motion.
919      */
920      GraphicsEngine::getInstance()->tick(this->dtS);
921    }
922  this->lastFrame = currentFrame;
923}
924
925
926/**
927 *  this function gives the world a consistant state
928
929   after ticking (updating the world state) this will give a constistant
930   state to the whole system.
931*/
932void World::update()
933{
934  GarbageCollector::getInstance()->update();
935  GraphicsEngine::getInstance()->update(this->dtS);
936  NullParent::getInstance()->updateNode (this->dtS);
937
938  SoundEngine::getInstance()->update();
939  //music->update();
940}
941
942
943void World::collide()
944{
945  CDEngine::getInstance()->checkCollisions();
946}
947
948/**
949 *  render the current frame
950
951   clear all buffers and draw the world
952*/
953void World::display ()
954{
955  // clear buffer
956  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
957  // set camera
958  this->localCamera->apply ();
959  // draw world
960  this->draw();
961  // draw HUD
962  /** @todo draw HUD */
963  // flip buffers
964  GraphicsEngine::swapBuffers();
965  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
966  //SDL_Flip (screen);
967}
968
969
970/**
971 *  runs through all entities calling their draw() methods
972 */
973void World::draw ()
974{
975  /* draw entities */
976  WorldEntity* entity;
977  glLoadIdentity();
978  tIterator<WorldEntity>* iterator = this->entities->getIterator();
979  entity = iterator->firstElement();
980  while( entity != NULL )
981  {
982    if( entity->isVisible() ) entity->draw();
983    if( unlikely( this->showBV)) entity->drawBVTree(3, 226);  // to draw the bounding boxes of the objects at level 2 for debug purp
984    entity = iterator->nextElement();
985  }
986  delete iterator;
987
988  glCallList (objectList);
989
990  ParticleEngine::getInstance()->draw();
991
992  if (unlikely(this->showPNodes))
993    NullParent::getInstance()->debugDraw(0);
994
995  GraphicsEngine::getInstance()->draw();
996  //TextEngine::getInstance()->draw();
997}
998
999/**
1000 *  add and spawn a new entity to this world
1001 * @param entity to be added
1002*/
1003void World::spawn(WorldEntity* entity)
1004{
1005  this->entities->add (entity);
1006  entity->postSpawn ();
1007}
1008
1009
1010/**
1011 *  add and spawn a new entity to this world
1012 * @param entity to be added
1013 * @param absCoor At what coordinates to add this entity.
1014 * @param absDir In which direction should it look.
1015*/
1016void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1017{
1018  this->entities->add (entity);
1019
1020  entity->setAbsCoor (*absCoor);
1021  entity->setAbsDir (*absDir);
1022
1023  entity->postSpawn ();
1024}
1025
1026
1027/**
1028 *  add and spawn a new entity to this world
1029 * @param entity to be added
1030 * @param entity to be added to (PNode)
1031 * @param At what relative  coordinates to add this entity.
1032 * @param In which relative direction should it look.
1033*/
1034void World::spawn(WorldEntity* entity, PNode* parentNode,
1035                  Vector* relCoor, Quaternion* relDir)
1036{
1037  if( parentNode != NULL)
1038    {
1039      parentNode->addChild (entity);
1040
1041      entity->setRelCoor (*relCoor);
1042      entity->setRelDir (*relDir);
1043
1044      this->entities->add (entity);
1045
1046      entity->postSpawn ();
1047    }
1048}
1049
1050void World::setPath( const char* name)
1051{
1052  if (this->path)
1053    delete this->path;
1054  if (ResourceManager::isFile(name))
1055  {
1056    this->path = new char[strlen(name)+1];
1057    strcpy(this->path, name);
1058  }
1059  else
1060    {
1061      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1062      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1063    }
1064}
1065
1066const char* World::getPath( void)
1067{
1068  return path;
1069}
Note: See TracBrowser for help on using the repository browser.