Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/story_entities/world.cc @ 5829

Last change on this file since 5829 was 5829, checked in by patrick, 18 years ago

network: much work on multiplayability, does not yet work

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