Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/height_map/src/story_entities/world.cc @ 6267

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

heightMap: sphere with some info, draw with colors

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