Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5829 was 5829, checked in by patrick, 18 years ago

network: much work on multiplayability, does not yet work

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