Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged branches world_entities to trunk again
merged with command
svn merge -r5795:HEAD branches/world_entities/ trunk/
no conflicts (what a wonder)

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