Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5054 was 5054, checked in by patrick, 19 years ago

orxonox/trunk: only obb boxes drawn, obbtree of projectiles also generated

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