Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/story_entities/world.cc @ 5824

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

orxonox/trunk: merged branches world_entities to trunk again
merged with command
svn merge -r5795:HEAD branches/world_entities/ trunk/
no conflicts (what a wonder)

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