Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: new Layering system works, now i have to do the check on reparenting, so no lower layers are children of high-layer-parents

File size: 29.3 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 "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 "npc.h"
73#include "npc2.h"
74#include "shader.h"
75
76SHELL_COMMAND(speed, World, setSpeed);
77SHELL_COMMAND(togglePNodeVisibility, World, togglePNodeVisibility);
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}
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  delete LightManager::getInstance();
131  delete TrackManager::getInstance();
132  delete ParticleEngine::getInstance();
133  delete AnimationPlayer::getInstance();
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  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}
177
178/**
179 * loads the parameters of a World from an XML-element
180 * @param root the XML-element to load from
181 */
182void World::loadParams(const TiXmlElement* root)
183{
184  PRINTF(4)("Creating a World\n");
185
186  LoadParam<World>(root, "identifier", this, &World::setStoryID)
187    .describe("Sets the StoryID of this world");
188
189  LoadParam<World>(root, "nextid", this, &World::setNextStoryID)
190    .describe("Sets the ID of the next world");
191
192  LoadParam<World>(root, "path", this, &World::setPath)
193    .describe("The Filename of this World (relative from the data-dir)");
194}
195
196/**
197 * this is executed just before load
198 *
199 * since the load function sometimes needs data, that has been initialized
200 * before the load and after the proceeding storyentity has finished
201*/
202ErrorMessage World::preLoad()
203{
204  State::setWorldEntityList(this->entities = new tList<WorldEntity>());
205  this->cycle = 0;
206
207  /* init the world interface */
208  this->shell = new Shell();
209
210  LightManager::getInstance();
211  NullParent::getInstance ();
212
213  AnimationPlayer::getInstance(); // initializes the animationPlayer
214  PhysicsEngine::getInstance();
215
216  this->localCamera = new Camera();
217  this->localCamera->setName ("World-Camera");
218
219  State::setCamera(this->localCamera, this->localCamera->getTarget());
220
221  GraphicsEngine::getInstance()->displayFPS(true);
222
223  CDEngine::getInstance()->setEntityList( this->entities);
224}
225
226
227/**
228 *  loads the World by initializing all resources, and set their default values.
229*/
230ErrorMessage World::load()
231{
232  PRINTF(3)("> Loading world: '%s'\n", getPath());
233  TiXmlElement* element;
234  GameLoader* loader = GameLoader::getInstance();
235
236  if( getPath() == NULL)
237    {
238      PRINTF(1)("World has no path specified for loading");
239      this->loadDebugWorld(this->getStoryID());
240      return (ErrorMessage){213,"Path not specified","World::load()"};
241    }
242
243  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
244  // load the campaign document
245  if( !XMLDoc->LoadFile())
246  {
247    // report an error
248    PRINTF(1)("loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
249    delete XMLDoc;
250    return (ErrorMessage){213,"XML File parsing error","World::load()"};
251  }
252
253  // check basic validity
254  TiXmlElement* root = XMLDoc->RootElement();
255  assert( root != NULL);
256
257  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
258    {
259      // report an error
260      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
261      delete XMLDoc;
262      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
263    }
264
265  // load the parameters
266  // name
267  const char* string = grabParameter( root, "name");
268  if( string == NULL)
269    {
270      PRINTF(2)("World is missing a proper 'name'\n");
271      this->setName("Unknown");
272    }
273  else
274    {
275      this->setName(string);
276    }
277
278  ////////////////
279  // LOADSCREEN //
280  ////////////////
281  element = root->FirstChildElement("LoadScreen");
282  if (element == NULL)
283    {
284      PRINTF(2)("no LoadScreen specified, loading default\n");
285
286      glmis->setBackgroundImage("pictures/load_screen.jpg");
287      this->glmis->setMaximum(8);
288      this->glmis->draw();
289    }
290  else
291    {
292      this->glmis->loadParams(element);
293      this->glmis->draw();
294    }
295  this->glmis->draw();
296
297  ////////////////////////
298  // find WorldEntities //
299  ////////////////////////
300
301  element = root->FirstChildElement("WorldEntities");
302
303  if( element == NULL)
304    {
305      PRINTF(1)("World is missing 'WorldEntities'\n");
306    }
307  else
308    {
309      element = element->FirstChildElement();
310      // load Players/Objects/Whatever
311      PRINTF(4)("Loading WorldEntities\n");
312      while( element != NULL)
313        {
314          WorldEntity* created = dynamic_cast<WorldEntity*>( loader->fabricate( element));
315          if( created != NULL) this->spawn( created);
316          // if we load a 'Player' we use it as localPlayer
317          //todo do this more elegant
318          if( element->Value() != NULL && !strcmp( element->Value(), "Player"))
319          {
320            localPlayer = (Player*) created;
321            CDEngine::getInstance()->setPlayer(localPlayer);
322          }
323          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
324          if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
325          {
326            terrain = (Terrain*) created;
327            CDEngine::getInstance()->setTerrain(terrain);
328          }
329          element = element->NextSiblingElement();
330          glmis->step(); //! @todo temporary
331        }
332      PRINTF(4)("Done loading WorldEntities\n");
333    }
334
335    //////////////////////////////
336    // LOADING ADDITIONAL STUFF //
337    //////////////////////////////
338
339    LoadParam<LightManager>(root, "LightManager", LightManager::getInstance(), &LightManager::loadParams);
340
341    LoadParam<ParticleEngine>(root, "ParticleEngine", ParticleEngine::getInstance(), &ParticleEngine::loadParams);
342    LoadParam<PhysicsEngine>(root, "PhysicsEngine", PhysicsEngine::getInstance(), &PhysicsEngine::loadParams);
343
344  // find Track
345  element = root->FirstChildElement( "Track");
346  if( element == NULL)
347    {
348      PRINTF(0)("World is missing a 'Track'\n");
349    }
350  else
351    {
352      //load track
353      PRINTF(4)("Loading Track\n");
354
355      TrackManager::getInstance()->loadParams( element);
356      TrackManager::getInstance()->finalize();
357    }
358
359  // free the XML data
360
361  delete XMLDoc;
362  /* GENERIC LOADING PROCESS FINISHED */
363
364  // bind input
365  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_UP);
366  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_DOWN);
367  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_LEFT);
368  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_RIGHT);
369  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
370  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
371  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
372
373  // bind camera
374  //this->localCamera->bind (localPlayer);
375 // this->localPlayer->addChild (this->localCamera);
376
377
378  //        TrackManager::getInstance()->setBindSlave(env);
379  PNode* tn = TrackManager::getInstance()->getTrackNode();
380  tn->addChild(this->localPlayer);
381
382  //localCamera->setParent(TrackNode::getInstance());
383  tn->addChild(this->localCamera);
384  localCamera->lookAt(tn);
385  localCamera->setClipRegion(1, 10000.0);
386  this->localPlayer->setParentMode(PNODE_ALL);
387  TrackManager::getInstance()->condition(1, LEFTRIGHT, this->localPlayer);
388
389  if (sky != NULL)
390  {
391    this->sky->setParent(this->localCamera);
392    this->sky->setParentMode(PNODE_MOVEMENT);
393  }
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 NPC();
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) *30);
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  if (unlikely(this->showPNodes))
984    NullParent::getInstance()->debugDraw(0);
985
986  GraphicsEngine::getInstance()->draw();
987  //TextEngine::getInstance()->draw();
988}
989
990/**
991 *  add and spawn a new entity to this world
992 * @param entity to be added
993*/
994void World::spawn(WorldEntity* entity)
995{
996  this->entities->add (entity);
997  entity->postSpawn ();
998}
999
1000
1001/**
1002 *  add and spawn a new entity to this world
1003 * @param entity to be added
1004 * @param absCoor At what coordinates to add this entity.
1005 * @param absDir In which direction should it look.
1006*/
1007void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1008{
1009  this->entities->add (entity);
1010
1011  entity->setAbsCoor (*absCoor);
1012  entity->setAbsDir (*absDir);
1013
1014  entity->postSpawn ();
1015}
1016
1017
1018/**
1019 *  add and spawn a new entity to this world
1020 * @param entity to be added
1021 * @param entity to be added to (PNode)
1022 * @param At what relative  coordinates to add this entity.
1023 * @param In which relative direction should it look.
1024*/
1025void World::spawn(WorldEntity* entity, PNode* parentNode,
1026                  Vector* relCoor, Quaternion* relDir)
1027{
1028  if( parentNode != NULL)
1029    {
1030      parentNode->addChild (entity);
1031
1032      entity->setRelCoor (*relCoor);
1033      entity->setRelDir (*relDir);
1034
1035      this->entities->add (entity);
1036
1037      entity->postSpawn ();
1038    }
1039}
1040
1041
1042
1043/**
1044  \brief commands that the world must catch
1045  @returns false if not used by the world
1046*/
1047bool World::command(Command* cmd)
1048{
1049  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1050  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1051  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1052  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1053  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1054  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1055  return false;
1056}
1057
1058void World::setPath( const char* name)
1059{
1060  if (this->path)
1061    delete this->path;
1062  if (ResourceManager::isFile(name))
1063  {
1064    this->path = new char[strlen(name)+1];
1065    strcpy(this->path, name);
1066  }
1067  else
1068    {
1069      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1070      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1071    }
1072}
1073
1074const char* World::getPath( void)
1075{
1076  return path;
1077}
Note: See TracBrowser for help on using the repository browser.