Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/spaceship-controll: world transformation

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