Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/spaceshipcontrol/src/story_entities/world.cc @ 5895

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

controll: playable interface work

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