Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6028 was 6001, checked in by bknecht, 19 years ago

changes on camera so it is now dynamic

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
72#include "playable.h"
73
74SHELL_COMMAND(speed, World, setSpeed);
75SHELL_COMMAND(togglePNodeVisibility, World, togglePNodeVisibility);
76SHELL_COMMAND(toggleBVVisibility, World, toggleBVVisibility);
77
78using namespace std;
79
80//! This creates a Factory to fabricate a World
81CREATE_FACTORY(World, CL_WORLD);
82
83World::World(const TiXmlElement* root)
84{
85  this->constuctorInit("", -1);
86  this->path = NULL;
87
88  this->loadParams(root);
89}
90
91/**
92  *  create a new World
93
94    This creates a new empty world!
95*/
96World::World (const char* name)
97{
98  this->path = NULL;
99  this->constuctorInit(name, -1);
100}
101
102/**
103 *  creates a new World...
104 * @param worldID with this ID
105*/
106World::World (int worldID)
107{
108  this->path = NULL;
109  this->constuctorInit(NULL, worldID);
110}
111
112/**
113 *  remove the World from memory
114
115    delete everything explicitly, that isn't contained in the parenting tree!
116    things contained in the tree are deleted automaticaly
117 */
118World::~World ()
119{
120  delete this->shell;
121  PRINTF(3)("World::~World() - deleting current world\n");
122
123
124  // here everything that is alocated by the World is deleted
125  delete this->entities;
126  State::setWorldEntityList(NULL);
127
128  delete this->localPlayer;
129
130  // delete all the initialized Engines.
131  FastFactory::flushAll(true);
132  delete LightManager::getInstance();
133  delete ParticleEngine::getInstance();
134  delete AnimationPlayer::getInstance();
135  delete PhysicsEngine::getInstance();
136
137  // external engines initialized by the orxonox-class get deleted
138  SoundEngine::getInstance()->flushAllBuffers();
139  SoundEngine::getInstance()->flushAllSources();
140
141
142  // erease everything that is left.
143  delete NullParent::getInstance();
144
145  Shader::suspendShader();
146
147  // unload the resources !!
148  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
149
150  delete[] this->path;
151}
152
153/**
154 * initializes the world.
155 * @param name the name of the world
156 * @param worldID the ID of this world
157 *
158 * set all stuff here that is world generic and does not use to much memory
159 * because the real init() function StoryEntity::init() will be called
160 * shortly before start of the game.
161 * since all worlds are initiated/referenced before they will be started.
162 * NO LEVEL LOADING HERE - NEVER!
163*/
164void World::constuctorInit(const char* name, int worldID)
165{
166  this->setClassID(CL_WORLD, "World");
167
168  this->setName(name);
169  this->debugWorldNr = worldID;
170  this->gameTime = 0.0f;
171  this->setSpeed(1.0);
172  this->music = NULL;
173  this->shell = NULL;
174  this->entities = NULL;
175  this->localPlayer = NULL;
176  this->localCamera = NULL;
177
178  this->showPNodes = false;
179  this->showBV = false;
180}
181
182/**
183 * loads the parameters of a World from an XML-element
184 * @param root the XML-element to load from
185 */
186void World::loadParams(const TiXmlElement* root)
187{
188  PRINTF(4)("Creating a World\n");
189
190  LoadParam(root, "identifier", this, World, setStoryID)
191    .describe("Sets the StoryID of this world");
192
193  LoadParam(root, "nextid", this, World, setNextStoryID)
194    .describe("Sets the ID of the next world");
195
196  LoadParam(root, "path", this, World, setPath)
197    .describe("The Filename of this World (relative from the data-dir)");
198}
199
200/**
201 * this is executed just before load
202 *
203 * since the load function sometimes needs data, that has been initialized
204 * before the load and after the proceeding storyentity has finished
205*/
206ErrorMessage World::preLoad()
207{
208  State::setWorldEntityList(this->entities = new tList<WorldEntity>());
209  this->cycle = 0;
210
211  /* init the world interface */
212  this->shell = new Shell();
213
214  LightManager::getInstance();
215  NullParent::getInstance ();
216
217  AnimationPlayer::getInstance(); // initializes the animationPlayer
218  ParticleEngine::getInstance();
219  PhysicsEngine::getInstance();
220
221  this->localCamera = new Camera();
222  this->localCamera->setName ("World-Camera");
223
224  State::setCamera(this->localCamera, this->localCamera->getTarget());
225
226  GraphicsEngine::getInstance()->displayFPS(true);
227
228  CDEngine::getInstance()->setEntityList( this->entities);
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 = (loader->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  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  NullParent::getInstance()->updateNode (0.001f);
502  NullParent::getInstance()->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 *  gets the list of entities from the world
583 * @returns entity list
584*/
585tList<WorldEntity>* World::getEntities()
586{
587  return this->entities;
588}
589
590
591/**
592 *  this returns the current game time
593 * @returns elapsed game time
594*/
595double World::getGameTime()
596{
597  return this->gameTime;
598}
599
600
601/**
602 *  function to put your own debug stuff into it. it can display informations about
603   the current class/procedure
604*/
605void World::debug()
606{
607  PRINTF(0)("Printing out the List of alive WorldEntities:\n");
608  tIterator<WorldEntity>* iterator = this->entities->getIterator();
609  WorldEntity* entity = iterator->firstElement();
610  while( entity != NULL)
611  {
612    PRINTF(0)("%s::%s\n", entity->getClassName(), entity->getName());
613    entity = iterator->nextElement();
614  }
615  delete iterator;
616}
617
618
619/**
620  \brief main loop of the world: executing all world relevant function
621
622  in this loop we synchronize (if networked), handle input events, give the heart-beat to
623  all other member-entities of the world (tick to player, enemies etc.), checking for
624  collisions drawing everything to the screen.
625*/
626void World::mainLoop()
627{
628  this->lastFrame = SDL_GetTicks ();
629  PRINTF(3)("World::mainLoop() - Entering main loop\n");
630
631  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* @todo implement pause */
632    {
633      ++this->cycle;
634      PRINTF(4)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
635      // Network
636      this->synchronize ();
637      // Process input
638      this->handleInput ();
639      if( this->bQuitCurrentGame || this->bQuitOrxonox)
640          break;
641      // Process time
642      this->tick ();
643      // Process collision
644      this->collide ();
645      // Update the state
646      this->update ();
647      // Draw
648      this->display ();
649    }
650
651  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
652}
653
654
655/**
656 *  synchronize local data with remote data
657*/
658void World::synchronize ()
659{
660  // Get remote input
661  // Update synchronizables
662}
663
664
665/**
666 *  run all input processing
667
668   the command node is the central input event dispatcher. the node uses the even-queue from
669   sdl and has its own event-passing-queue.
670*/
671void World::handleInput ()
672{
673  EventHandler::getInstance()->process();
674
675  // remoteinput
676}
677
678
679/**
680 *  advance the timeline
681
682   this calculates the time used to process one frame (with all input handling, drawing, etc)
683   the time is mesured in ms and passed to all world-entities and other classes that need
684   a heart-beat.
685*/
686void World::tick ()
687{
688  Uint32 currentFrame = SDL_GetTicks();
689  if(!this->bPause)
690    {
691      this->dt = currentFrame - this->lastFrame;
692
693      if( this->dt > 10)
694        {
695          float fps = 1000/dt;
696
697          // temporary, only for showing how fast the text-engine is
698          char tmpChar[20];
699          sprintf(tmpChar, "fps: %4.0f", fps);
700        }
701      else
702        {
703          /* the frame-rate is limited to 100 frames per second, all other things are for
704             nothing.
705          */
706          PRINTF(3)("fps = 1000 - frame rate is adjusted\n");
707          SDL_Delay(10-dt);
708          this->dt = 10;
709        }
710
711      this->dtS = (float)this->dt / 1000.0 * this->speed;
712      this->gameTime += this->dtS;
713
714      tIterator<WorldEntity>* iterator = this->entities->getIterator();
715      WorldEntity* entity = iterator->firstElement();
716      while( entity != NULL)
717        {
718          entity->tick (this->dtS);
719          entity = iterator->nextElement();
720        }
721      delete iterator;
722
723      /* update tick the rest */
724      this->localCamera->tick(this->dtS);
725      // tick the engines
726      AnimationPlayer::getInstance()->tick(this->dtS);
727//      if (this->cycle > 5)
728        PhysicsEngine::getInstance()->tick(this->dtS);
729
730      ParticleEngine::getInstance()->tick(this->dtS);
731      GarbageCollector::getInstance()->tick(this->dtS);
732
733
734      /** actualy the Graphics Engine should tick the world not the other way around...
735         but since we like the things not too complicated we got it this way around
736         until there is need or time to do it the other way around.
737         @todo: GraphicsEngine ticks world: separation of processes and data...
738
739        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
740         beceause graphics have nothing(or at least not much) to do with Motion.
741      */
742      GraphicsEngine::getInstance()->tick(this->dtS);
743    }
744  this->lastFrame = currentFrame;
745}
746
747
748/**
749 *  this function gives the world a consistant state
750
751   after ticking (updating the world state) this will give a constistant
752   state to the whole system.
753*/
754void World::update()
755{
756  GarbageCollector::getInstance()->update();
757  GraphicsEngine::getInstance()->update(this->dtS);
758  NullParent::getInstance()->updateNode (this->dtS);
759
760  SoundEngine::getInstance()->update();
761  //music->update();
762}
763
764
765void World::collide()
766{
767  CDEngine::getInstance()->checkCollisions();
768}
769
770/**
771 *  render the current frame
772
773   clear all buffers and draw the world
774*/
775void World::display ()
776{
777  // clear buffer
778  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
779  // set camera
780  this->localCamera->apply ();
781  // draw world
782  this->draw();
783  // draw HUD
784  /** @todo draw HUD */
785  // flip buffers
786  GraphicsEngine::swapBuffers();
787  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
788  //SDL_Flip (screen);
789}
790
791
792/**
793 *  runs through all entities calling their draw() methods
794 */
795void World::draw ()
796{
797  /* draw entities */
798  WorldEntity* entity;
799  glLoadIdentity();
800  tIterator<WorldEntity>* iterator = this->entities->getIterator();
801  entity = iterator->firstElement();
802  while( entity != NULL )
803  {
804    if( entity->isVisible() ) entity->draw();
805    if( unlikely( this->showBV)) entity->drawBVTree(3, 226);  // to draw the bounding boxes of the objects at level 2 for debug purp
806    entity = iterator->nextElement();
807  }
808  delete iterator;
809
810  glCallList (objectList);
811
812  ParticleEngine::getInstance()->draw();
813
814  if (unlikely(this->showPNodes))
815    NullParent::getInstance()->debugDraw(0);
816
817  GraphicsEngine::getInstance()->draw();
818  //TextEngine::getInstance()->draw();
819}
820
821/**
822 *  add and spawn a new entity to this world
823 * @param entity to be added
824*/
825void World::spawn(WorldEntity* entity)
826{
827  this->entities->add (entity);
828  entity->postSpawn ();
829}
830
831
832/**
833 *  add and spawn a new entity to this world
834 * @param entity to be added
835 * @param absCoor At what coordinates to add this entity.
836 * @param absDir In which direction should it look.
837*/
838void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
839{
840  this->entities->add (entity);
841
842  entity->setAbsCoor (*absCoor);
843  entity->setAbsDir (*absDir);
844
845  entity->postSpawn ();
846}
847
848
849/**
850 *  add and spawn a new entity to this world
851 * @param entity to be added
852 * @param entity to be added to (PNode)
853 * @param At what relative  coordinates to add this entity.
854 * @param In which relative direction should it look.
855*/
856void World::spawn(WorldEntity* entity, PNode* parentNode,
857                  Vector* relCoor, Quaternion* relDir)
858{
859  if( parentNode != NULL)
860    {
861      parentNode->addChild (entity);
862
863      entity->setRelCoor (*relCoor);
864      entity->setRelDir (*relDir);
865
866      this->entities->add (entity);
867
868      entity->postSpawn ();
869    }
870}
871
872void World::setPath( const char* name)
873{
874  if (this->path)
875    delete this->path;
876  if (ResourceManager::isFile(name))
877  {
878    this->path = new char[strlen(name)+1];
879    strcpy(this->path, name);
880  }
881  else
882    {
883      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
884      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
885    }
886}
887
888const char* World::getPath( void)
889{
890  return path;
891}
Note: See TracBrowser for help on using the repository browser.