Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: implemented default font.

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