Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: now terrain is out of the World.cc and is a world-entity

File size: 17.9 KB
RevLine 
[1853]1
2/*
3   orxonox - the future of 3D-vertical-scrollers
4
5   Copyright (C) 2004 orx
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2, or (at your option)
10   any later version.
[1855]11
12   ### File Specific:
13   main-programmer: Patrick Boenzli
[2190]14   co-programmer: Christian Meyer
[1853]15*/
16
[2190]17#include "world.h"
18#include "world_entity.h"
[3365]19#include "track_manager.h"
[2036]20#include "player.h"
[2190]21#include "command_node.h"
22#include "camera.h"
[2816]23#include "environment.h"
[3521]24#include "primitive.h"
[3365]25#include "p_node.h"
26#include "null_parent.h"
27#include "helper_parent.h"
28#include "glmenu_imagescreen.h"
[3419]29#include "skysphere.h"
[3436]30#include "light.h"
[3475]31#include "fontset.h"
[3535]32#include "track_node.h"
[3559]33#include "terrain.h"
[2036]34
[1856]35using namespace std;
[1853]36
37
[1858]38/**
[2551]39    \brief create a new World
40   
41    This creates a new empty world!
[1858]42*/
[2636]43World::World (char* name)
[1855]44{
[3526]45  this->init(name, -1);
[3529]46  NullParent* np = NullParent::getInstance();
[1855]47}
48
[3449]49/**
50   \brief creates a new World...
51   \param worldID with this ID
52*/
[2636]53World::World (int worldID)
54{
[3526]55  this->init(NULL, worldID);
[2636]56}
57
[1858]58/**
[2551]59    \brief remove the World from memory
[3365]60   
61    delete everything explicitly, that isn't contained in the parenting tree!
62    things contained in the tree are deleted automaticaly
[1858]63*/
[2190]64World::~World ()
[1872]65{
[3546]66  PRINTF(3)("World::~World() - deleting current world\n");
[3226]67  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
[3220]68  cn->unbind(this->localPlayer);
69  cn->reset();
[3459]70
[3544]71  delete this->localCamera;
[3529]72  delete this->nullParent;
[3553]73  delete this->entities;
[3502]74  //delete this->skySphere;
[3365]75
76  //delete this->trackManager;
77
78  /*
[3220]79  WorldEntity* entity = entities->enumerate(); 
80  while( entity != NULL )
81    {
82      entity->destroy();
83      entity = entities->nextElement();
84    }
85  this->entities->destroy();
[3365]86  */
[3220]87
[3365]88  /* FIX the parent list has to be cleared - not possible if we got the old list also*/
89
90
91  //delete this->entities;
92  //delete this->localCamera;
[3220]93  /* this->localPlayer hasn't to be deleted explicitly, it is
94     contained in entities*/
[1872]95}
[1858]96
[3526]97/**
98   \brief initializes a new World
99*/
100void World::init(char* name, int worldID)
101{
102  this->setClassName ("World");
[2636]103
[3526]104  this->worldName = name;
105  this->debugWorldNr = worldID;
106  this->entities = new tList<WorldEntity>();
107
108  // Enable default GL stuff
109  glEnable(GL_DEPTH_TEST);
110
111}
112
113
[3449]114/**
115   \brief loads the World by initializing all resources, and set their default values.
116*/
[3459]117ErrorMessage World::load()
[2636]118{
[3365]119  //  BezierCurve* tmpCurve = new BezierCurve();
[2636]120  if(this->debugWorldNr != -1)
121    {
[3455]122      // initializing Font
[3456]123      testFont = new FontSet();
124      testFont->buildFont("../data/pictures/font.tga");
[3455]125
126      // initializing the TrackManager
[3365]127      trackManager = TrackManager::getInstance();
128      trackManager->addPoint(Vector(0,-5,0));
129      trackManager->addPoint(Vector(10,0,5));
130      trackManager->addPoint(Vector(20,0,-5));
131      trackManager->addPoint(Vector(30,0,5));
132      trackManager->addPoint(Vector(40,0,5));
[3522]133      trackManager->setDuration(4);
134      int fork11, fork12, fork13;
135      trackManager->fork(3, &fork11, &fork12, &fork13);
[3365]136      trackManager->workOn(fork11);
[3522]137      trackManager->addPoint(Vector(70, 0, -10));
138      trackManager->addPoint(Vector(100, 0, -15));
139      trackManager->addPoint(Vector(300, 0, -15));
140      trackManager->setDuration(10);
[3365]141      trackManager->workOn(fork12);
[3522]142      trackManager->addPoint(Vector(70,  0, 0));
143      trackManager->addPoint(Vector(100, 0, 0));
144      trackManager->addPoint(Vector(120,10, 0));
145      trackManager->addPoint(Vector(150,10, 0));
146      trackManager->addPoint(Vector(180,15, 0));
147      trackManager->addPoint(Vector(200,10, 0));
[3433]148      trackManager->setDuration(7);
[3365]149      trackManager->workOn(fork13);
[3522]150      trackManager->addPoint(Vector(70,  0, 10));
151      trackManager->addPoint(Vector(100, 0, 30));
152      trackManager->addPoint(Vector(120,-10, 30));
153      trackManager->addPoint(Vector(150,-10, 30));
154      trackManager->setDuration(10);
155      trackManager->join(2, fork12, fork13);
156
157      trackManager->workOn(5);
158      trackManager->addPoint(Vector(250, 20, 10));
159      trackManager->addPoint(Vector(290, 20, 10));
160      trackManager->setDuration(5);
161      trackManager->setSavePoint();
162      trackManager->addPoint(Vector(350, 20, 10));
163      trackManager->addPoint(Vector(360, 20, 10));
164      trackManager->addPoint(Vector(370, 20, 10));
165      trackManager->setDuration(5);
166
167      trackManager->join(2, 6, fork11);
168
[3433]169      trackManager->finalize();
[3522]170
[3433]171     
[3368]172      /*monitor progress*/
173      this->glmis->step();
174
[3365]175      /*
[3433]176        tmpCurve->addNode(Vector(10,  -1,  -1));
177        tmpCurve->addNode(Vector(10,  -2,   2));
178        tmpCurve->addNode(Vector(10,   3,   3));
179        tmpCurve->addNode(Vector(10,   4,  -4), 0);
180        tmpCurve->addNode(Vector(10,  -1,  -1));
181        tmpCurve->addNode(Vector(10,  -2,   2));
182        tmpCurve->addNode(Vector(10,   3,   3));
183        tmpCurve->addNode(Vector(10,   4,  -4), 0);
184        tmpCurve->debug();
[3365]185      */
[2636]186      switch(this->debugWorldNr)
187        {
[3225]188          /*
189            this loads the hard-coded debug world. this only for simplicity and will be
190            removed by a reald world-loader, which interprets a world-file.
191            if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
192            make whatever you want...
193           */
[2636]194        case DEBUG_WORLD_0:
195          {
[3365]196            this->nullParent = NullParent::getInstance ();
197            this->nullParent->setName ("NullParent");
198
[3194]199            // !\todo old track-system has to be removed
200
[3365]201            //create helper for player
202            HelperParent* hp = new HelperParent ();
203            /* the player has to be added to this helper */
204
[2636]205            // create a player
[3365]206            WorldEntity* myPlayer = new Player ();
207            myPlayer->setName ("player");
208            this->spawn (myPlayer);
[3368]209            this->localPlayer = myPlayer;
210            /*monitor progress*/
211            this->glmis->step();           
212
[2636]213            // bind input
[3365]214            Orxonox *orx = Orxonox::getInstance ();
[3226]215            orx->getLocalInput()->bind (myPlayer);
[2636]216           
217            // bind camera
218            this->localCamera = new Camera(this);
[3365]219            this->localCamera->setName ("camera");
[3461]220            this->localCamera->bind (myPlayer);
[3507]221            /*monitor progress*/
222            this->glmis->step();           
[2816]223
[3419]224            // Create SkySphere
[3545]225            this->skySphere = new Skysphere("../data/pictures/sky-replace.jpg");
226            this->skySphere->setName("SkySphere");
[3527]227            this->localCamera->addChild(this->skySphere);
228            this->skySphere->setMode(MOVEMENT);
[3419]229
[3368]230            /*monitor progress*/
231            this->glmis->step();
232
[3521]233           
234            WorldEntity* env = new Environment();
235            env->setName ("env");
236            this->spawn(env);
237
[3539]238            /*
[3365]239            Vector* es = new Vector (50, 2, 0);
240            Quaternion* qs = new Quaternion ();
[3521]241            WorldEntity* pr = new Primitive(PSPHERE);
242            pr->setName("primitive");
243            this->spawn(pr, this->localPlayer, es, qs, ROTATION);
[3539]244            */
[3521]245
[3539]246
[3368]247            /*monitor progress*/
248            this->glmis->step();
[2816]249
[3535]250            //      trackManager->setBindSlave(env);
[3556]251            PNode* tn = trackManager->getTrackNode();
[3539]252            tn->addChild(myPlayer);
253
[3537]254            //localCamera->setParent(TrackNode::getInstance());
[3556]255            tn->addChild (this->localCamera);
[3538]256            //Vector* cameraOffset = new Vector (0, 5, -10);
257            Vector* cameraOffset = new Vector (-10, 5, 0);
[3537]258            this->localCamera->setRelCoor (cameraOffset);
[3522]259            trackManager->condition(1, NEAREST, myPlayer);
260
[2636]261            break;
262          }
263        case DEBUG_WORLD_1:
264          {
[3365]265            this->nullParent = NullParent::getInstance ();
266            this->nullParent->setName ("NullParent");
267
[2636]268            // create a player
[2644]269            WorldEntity* myPlayer = new Player();
[3365]270            myPlayer->setName ("player");
[2644]271            this->spawn(myPlayer);
[3194]272            this->localPlayer = myPlayer;           
[2636]273           
274            // bind input
275            Orxonox *orx = Orxonox::getInstance();
[3226]276            orx->getLocalInput()->bind (myPlayer);
[2636]277           
278            // bind camera
[3365]279            this->localCamera = new Camera (this);
280            this->localCamera->setName ("camera");
[3461]281            this->localCamera->bind (myPlayer); 
[3365]282            this->localPlayer->addChild (this->localCamera);
[3429]283
284            // Create SkySphere
285            skySphere = new Skysphere("../data/pictures/sky-replace.jpg");
[3502]286            this->localPlayer->addChild(this->skySphere);
[3429]287
[2636]288            break;
289          }
290        default:
291          printf("World::load() - no world with ID %i found", this->debugWorldNr );
292        }
293    }
294  else if(this->worldName != NULL)
295    {
296
297    }
[2731]298
299  // initialize debug coord system
300  objectList = glGenLists(1);
301  glNewList (objectList, GL_COMPILE);
[3559]302 
[3365]303  trackManager->drawGraph(.01);
304  trackManager->debug(2);
[2731]305  glEndList();
[3526]306
[3559]307  terrain = new Terrain();
308  this->spawn(terrain);
[3455]309  // LIGHT initialisation
310  light = Light::getInstance();
311  light->addLight(0);
312  light->setAttenuation(QUADRATIC, 1.0);
313  light->setAttenuation(CONSTANT, 2.0);
314  light->setAttenuation(QUADRATIC, 1.0);
[3458]315  light->setPosition(10.0, 10.0, 50.0);
[3455]316  light->setDiffuseColor(1,1,1);
317  //  light->addLight(1);
318  //  light->setPosition(20, 10, -20);
319  //  light->setDiffuseColor(0,0,0);
320  light->debug();
321
322
[2636]323}
324
[3459]325/**
326   \brief initializes a new World
327*/
328ErrorMessage World::init()
329{
330  this->bPause = false;
331  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
332  cn->addToWorld(this);
333  cn->enable(true);
[2636]334
[3459]335  //glMap1f (GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
336  //glEnable (GL_MAP1_VERTEX_3);
337 
338  //theNurb = gluNewNurbsRenderer ();
339  //gluNurbsProperty (theNurb, GLU_NURBS_MODE, GLU_NURBS_TESSELLATOR);
340  //gluNurbsProperty (theNurb, GLU_NURBS_VERTEX, vertexCallback );
341
342}
343
344
345/**
346   \brief starts the World
347*/
348ErrorMessage World::start()
349{
[3546]350  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
[3459]351  this->bQuitOrxonox = false;
352  this->bQuitCurrentGame = false;
353  this->mainLoop();
354}
355
356/**
357   \brief stops the world.
358
359   This happens, when the player decides to end the Level.
360*/
361ErrorMessage World::stop()
362{
[3546]363  PRINTF(3)("World::stop() - got stop signal\n");
[3459]364  this->bQuitCurrentGame = true;
365}
366
367/**
368   \brief pauses the Game
369*/
370ErrorMessage World::pause()
371{
372  this->isPaused = true;
373}
374
375/**
376   \brief ends the pause Phase
377*/
378ErrorMessage World::resume()
379{
380  this->isPaused = false;
381}
382
383/**
384   \brief destroys the World
385*/
386ErrorMessage World::destroy()
387{
388  delete trackManager;
389}
390
391/**
392   \brief shows the loading screen
393*/
394void World::displayLoadScreen ()
395{
[3546]396  PRINTF(3)("World::displayLoadScreen - start\n"); 
[3459]397 
398  //GLMenuImageScreen*
399  this->glmis = GLMenuImageScreen::getInstance();
400  this->glmis->init();
401  this->glmis->setMaximum(10);
402  this->glmis->draw();
403 
[3546]404  PRINTF(3)("World::displayLoadScreen - end\n"); 
[3459]405}
406
407/**
408   \brief removes the loadscreen, and changes over to the game
409
410   \todo take out the delay
411*/
412void World::releaseLoadScreen ()
413{
[3546]414  PRINTF(3)("World::releaseLoadScreen - start\n"); 
[3459]415  this->glmis->setValue(this->glmis->getMaximum());
416  SDL_Delay(500);
[3546]417  PRINTF(3)("World::releaseLoadScreen - end\n"); 
[3459]418}
419
420
[2636]421/**
[2551]422    \brief checks for collisions
423   
424    This method runs through all WorldEntities known to the world and checks for collisions
425    between them. In case of collisions the collide() method of the corresponding entities
426    is called.
[1858]427*/
[2190]428void World::collide ()
[1858]429{
[2816]430  /*
431  List *a, *b;
[2551]432  WorldEntity *aobj, *bobj;
[2816]433   
434  a = entities;
[2551]435 
436  while( a != NULL)
437    {
[2816]438      aobj = a->nextElement();
[2551]439      if( aobj->bCollide && aobj->collisioncluster != NULL)
[2190]440        {
[2816]441          b = a->nextElement();
[2551]442          while( b != NULL )
443            {
[2816]444              bobj = b->nextElement();
[2551]445              if( bobj->bCollide && bobj->collisioncluster != NULL )
[2190]446                {
[2551]447                  unsigned long ahitflg, bhitflg;
448                  if( check_collision ( &aobj->place, aobj->collisioncluster,
449                                        &ahitflg, &bobj->place, bobj->collisioncluster,
450                                        &bhitflg) );
451                  {
452                    aobj->collide (bobj, ahitflg, bhitflg);
453                    bobj->collide (aobj, bhitflg, ahitflg);
454                  }
[2190]455                }
[2816]456              b = b->nextElement();
[2551]457            }
[2190]458        }
[2816]459      a = a->enumerate();
[2551]460    }
[2816]461  */
[1858]462}
463
464/**
[2551]465    \brief runs through all entities calling their draw() methods
[1931]466*/
[2190]467void World::draw ()
[2077]468{
[3462]469  /* draw entities */
[2551]470  WorldEntity* entity;
[3526]471  glLoadIdentity();
472
[2822]473  entity = this->entities->enumerate();
[2816]474  while( entity != NULL ) 
[2551]475    { 
[2822]476      if( entity->bDraw ) entity->draw();
477      entity = this->entities->nextElement();
[3365]478    } 
[2551]479 
[2731]480  glCallList (objectList);
[3419]481  //! \todo skysphere is a WorldEntity and should be inside of the world-entity-list.
482  skySphere->draw();
483
[3456]484  testFont->printText(0, 0, 1, "orxonox_" PACKAGE_VERSION);
[3455]485
[1931]486}
487
[2816]488
[2190]489/**
[3225]490   \brief function to put your own debug stuff into it. it can display informations about
491   the current class/procedure
492*/
[2640]493void World::debug()
494{
[3546]495  PRINTF(2)("debug() - starting debug\n");
[3365]496  PNode* p1 = NullParent::getInstance ();
497  PNode* p2 = new PNode (new Vector(2, 2, 2), p1);
498  PNode* p3 = new PNode (new Vector(4, 4, 4), p1);
499  PNode* p4 = new PNode (new Vector(6, 6, 6), p2);
500
501  p1->debug ();
502  p2->debug ();
503  p3->debug ();
504  p4->debug ();
505
506  p1->shiftCoor (new Vector(-1, -1, -1));
507
508  printf("World::debug() - shift\n");
509  p1->debug ();
510  p2->debug ();
511  p3->debug ();
512  p4->debug ();
513 
[3551]514  p1->update ();
[3365]515
516  printf ("World::debug() - update\n");
517  p1->debug ();
518  p2->debug ();
519  p3->debug ();
520  p4->debug ();
521
522  p2->shiftCoor (new Vector(-1, -1, -1));
[3551]523  p1->update ();
[3365]524
525  p1->debug ();
526  p2->debug ();
527  p3->debug ();
528  p4->debug ();
529
530  p2->setAbsCoor (new Vector(1,2,3));
531
532
[3551]533 p1->update ();
[3365]534
535  p1->debug ();
536  p2->debug ();
537  p3->debug ();
538  p4->debug ();
539
[3544]540  delete p1;
[3365]541 
542 
543  /*
[2640]544  WorldEntity* entity;
545  printf("counting all entities\n");
[2816]546  printf("World::debug() - enumerate()\n");
547  entity = entities->enumerate(); 
548  while( entity != NULL )
[2640]549    {
550      if( entity->bDraw ) printf("got an entity\n");
[2816]551      entity = entities->nextElement();
[2640]552    }
[3365]553  */
[2640]554}
[2636]555
[2640]556
[3449]557/**
[3225]558  \brief main loop of the world: executing all world relevant function
559
560  in this loop we synchronize (if networked), handle input events, give the heart-beat to
561  all other member-entities of the world (tick to player, enemies etc.), checking for
562  collisions drawing everything to the screen.
563*/
[2636]564void World::mainLoop()
565{
[3365]566  this->lastFrame = SDL_GetTicks ();
[3546]567  PRINTF(3)("World::mainLoop() - Entering main loop\n");
[3215]568  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
[2551]569    {
[3546]570      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
[2636]571      // Network
[3365]572      this->synchronize ();
[2636]573      // Process input
[3365]574      this->handleInput ();
[3215]575      if( this->bQuitCurrentGame || this->bQuitOrxonox)
576          break;
[2636]577      // Process time
[3551]578      this->tick ();
579      // Update the state
580      this->update ();     
[2636]581      // Process collision
[3459]582      this->collide ();
[2636]583      // Draw
[3365]584      this->display ();
[3548]585
[3365]586      for( int i = 0; i < 5000000; i++) {}
587      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
[2551]588    }
[3546]589  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
[1899]590}
591
[3459]592
[2190]593/**
[2636]594   \brief synchronize local data with remote data
[1855]595*/
[2636]596void World::synchronize ()
[1855]597{
[2636]598  // Get remote input
599  // Update synchronizables
[1855]600}
[2636]601
[3459]602
[2636]603/**
604   \brief run all input processing
[3225]605
606   the command node is the central input event dispatcher. the node uses the even-queue from
607   sdl and has its own event-passing-queue.
[2636]608*/
[3225]609void World::handleInput ()
[2636]610{
611  // localinput
[3225]612  CommandNode* cn = Orxonox::getInstance()->getLocalInput();
[3216]613  cn->process();
[2636]614  // remoteinput
615}
616
[3459]617
[2636]618/**
619   \brief advance the timeline
[3225]620
621   this calculates the time used to process one frame (with all input handling, drawing, etc)
622   the time is mesured in ms and passed to all world-entities and other classes that need
623   a heart-beat.
[2636]624*/
[3551]625void World::tick ()
[2636]626{
627  Uint32 currentFrame = SDL_GetTicks();
628  if(!this->bPause)
629    {
630      Uint32 dt = currentFrame - this->lastFrame;
[2816]631     
[2636]632      if(dt > 0)
633        {
634          float fps = 1000/dt;
[3546]635          PRINTF(3)("fps = %f\n", fps);
[2636]636        }
637      else
638        {
[3225]639          /* the frame-rate is limited to 100 frames per second, all other things are for
640             nothing.
641          */
[3546]642          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
[3194]643          SDL_Delay(10);
644          dt = 10;
[2636]645        }
[3459]646      //this->timeSlice (dt);
647     
648      /* function to let all entities tick (iterate through list) */
649      WorldEntity* entity;
650      float seconds = dt / 1000.0;     
651      entity = entities->enumerate(); 
652      while( entity != NULL) 
653        { 
654          entity->tick (seconds);
655          entity = entities->nextElement();
656        }
[3502]657      //skySphere->updatePosition(localCamera->absCoordinate);
[3459]658     
659      /* update tick the rest */
[3551]660      this->localCamera->tick(dt);
[3433]661      this->trackManager->tick(dt);
[2636]662    }
663  this->lastFrame = currentFrame;
664}
665
[3216]666
[2636]667/**
[3551]668   \brief this function gives the world a consistant state
669
670   after ticking (updating the world state) this will give a constistant
671   state to the whole system.
672*/
673void World::update()
674{
675  this->nullParent->update ();
676}
677
678
679/**
[3225]680   \brief render the current frame
681   
682   clear all buffers and draw the world
[2636]683*/
684void World::display ()
685{
686  // clear buffer
687  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
688  // set camera
689  this->localCamera->apply ();
690  // draw world
691  this->draw();
692  // draw HUD
[3365]693  /* \todo draw HUD */
[2636]694  // flip buffers
695  SDL_GL_SwapBuffers();
[3365]696  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
697  //SDL_Flip (screen);
[2636]698}
699
[2644]700
[3225]701/**
702   \brief add and spawn a new entity to this world
703   \param entity to be added
704*/
[2644]705void World::spawn(WorldEntity* entity)
706{
[3365]707  this->entities->add (entity);
[3233]708  entity->postSpawn ();
[2816]709}
710
711
[3225]712/**
713   \brief add and spawn a new entity to this world
714   \param entity to be added
[3449]715   \param absCoor At what coordinates to add this entity.
716   \param absDir In which direction should it look.
[3225]717*/
[3365]718void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
[2816]719{
[3529]720  this->entities->add (entity);
721
[3365]722  entity->setAbsCoor (absCoor);
723  entity->setAbsDir (absDir);
724
[3233]725  entity->postSpawn ();
[2644]726}
[2816]727
728
[3521]729/**
730   \brief add and spawn a new entity to this world
731   \param entity to be added
732   \param entity to be added to (PNode)
733   \param At what relative  coordinates to add this entity.
734   \param In which relative direction should it look.
735*/
736void World::spawn(WorldEntity* entity, PNode* parentNode, 
737                  Vector* relCoor, Quaternion* relDir, 
738                  parentingMode mode)
739{
[3551]740  this->nullParent = NullParent::getInstance();
[3529]741  if( parentNode != NULL)
[3521]742    {
743      parentNode->addChild (entity);
744     
745      entity->setRelCoor (relCoor);
746      entity->setRelDir (relDir);
747     
748      this->entities->add (entity);
749     
750      entity->postSpawn ();
751    }
752}
753
754
755
[3449]756/**
[3225]757  \brief commands that the world must catch
758  \returns false if not used by the world
759*/
[3216]760bool World::command(Command* cmd)
761{
762  return false;
763}
[3365]764
Note: See TracBrowser for help on using the repository browser.