Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: cleaner outtakes of the ShellBuffer

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