Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: code should now also run on OS-X

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