Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merge the ObjectManager to the trunk
merged with command:
svn merge -r6082:HEAD objectmanager/ ../trunk/

conflicts resolution was easy this time :)
but specially merged the world to network_world

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