Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: overdone a minor 'BUG' in the NullParent-lib.
this is not a fix but a temporary solution, until PNode is again as the Element2D, where the deleting process is clear already

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