Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: multiple new Reparenting modes in PNode.
Testing the stuff in GuidedMissile
Projectile has a PNode as reference not as pointer
some minor weapon changes

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