Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: flotilia

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