Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/story_entities/network_world.cc @ 6098

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

network: the client now loads only a reduced world

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