Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: more fixes due to valgrind

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