Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Explosions on Collision (—HACK—)
also made the FastFactory faster, not turning through the GarbageCollector, as it is not necessary. FastFactory also implements a Static Memeber subscriptor-Macro now
last but not least: new Functions in The ParticleEngine, and some revisited

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