Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/objectmanager/src/story_entities/world.cc @ 6121

Last change on this file since 6121 was 6121, checked in by bensch, 18 years ago

orxonox/trunk: packing the first entities into their lists

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