Index: trunk/src/story_entities/Makefile.am
===================================================================
--- trunk/src/story_entities/Makefile.am	(revision 6626)
+++ trunk/src/story_entities/Makefile.am	(revision 6634)
@@ -12,5 +12,6 @@
 		story_entities/multi_player_world.cc \
 		story_entities/multi_player_world_data.cc \
-		story_entities/movie_loader.cc
+		story_entities/movie_loader.cc \
+		story_entities/simple_game_menu.cc
 
 StoryEntities_HEADERS_ = \
@@ -25,3 +26,4 @@
 		story_entities/multi_player_world.h \
 		story_entities/multi_player_world_data.h \
-		story_entities/movie_loader.h
+		story_entities/movie_loader.h \
+		story_entities/simple_game_menu.h
Index: trunk/src/story_entities/campaign_data.cc
===================================================================
--- trunk/src/story_entities/campaign_data.cc	(revision 6626)
+++ trunk/src/story_entities/campaign_data.cc	(revision 6634)
@@ -76,5 +76,5 @@
   LOAD_PARAM_START_CYCLE(root, element);
   {
-    StoryEntity* created = (StoryEntity*) Factory::fabricate(element);
+    StoryEntity* created = dynamic_cast<StoryEntity*>(Factory::fabricate(element));
     if( created != NULL)
       this->addStoryEntity(created);
Index: trunk/src/story_entities/game_world.cc
===================================================================
--- trunk/src/story_entities/game_world.cc	(revision 6626)
+++ trunk/src/story_entities/game_world.cc	(revision 6634)
@@ -114,4 +114,6 @@
   .describe("The Filename of this GameWorld (relative from the data-dir)");
 
+//   LoadParam(root, "soundtrack", this->dataTank, GameWorldData, setSoundTrack);
+
   PRINTF(4)("Loaded GameWorld specific stuff\n");
 }
@@ -150,5 +152,5 @@
   if( getPath() == NULL)
   {
-    PRINTF(1)("GameWorld has no path specified for loading");
+    PRINTF(1)("GameWorld has no path specified for loading\n");
     return (ErrorMessage){213,"Path not specified","GameWorld::load()"};
   }
@@ -241,4 +243,8 @@
 void GameWorld::run()
 {
+  /* start the music */
+  if(this->dataTank->music != NULL)
+    this->dataTank->music->playback();
+
   this->lastFrame = SDL_GetTicks ();
   PRINTF(3)("GameWorld::mainLoop() - Entering main loop\n");
Index: trunk/src/story_entities/game_world_data.cc
===================================================================
--- trunk/src/story_entities/game_world_data.cc	(revision 6626)
+++ trunk/src/story_entities/game_world_data.cc	(revision 6634)
@@ -72,7 +72,4 @@
   this->setClassID(CL_GAME_WORLD_DATA, "GameWorldData");
 
-  this->localPlayer = NULL;
-  this->localCamera = NULL;
-
   this->glmis = NULL;
 
@@ -283,9 +280,4 @@
   if( this->sky != NULL)
     this->localCamera->addChild(this->sky);
-
-  /* sound loading */
-  this->music = NULL;
-  //(OggPlayer*)ResourceManager::getInstance()->load("sound/00-luke_grey_-_hypermode.ogg", OGG, RP_LEVEL);
-  //music->playback();
   SoundEngine::getInstance()->setListener(this->localCamera);
 }
@@ -310,2 +302,10 @@
 }
 
+
+void GameWorldData::setSoundTrack(const char* name)
+{
+  PRINTF(3)("Setting Sound Track to %s\n", name);
+  this->music = (OggPlayer*)ResourceManager::getInstance()->load(name, OGG, RP_LEVEL);
+}
+
+
Index: trunk/src/story_entities/game_world_data.h
===================================================================
--- trunk/src/story_entities/game_world_data.h	(revision 6626)
+++ trunk/src/story_entities/game_world_data.h	(revision 6634)
@@ -40,4 +40,6 @@
     virtual ErrorMessage unloadData();
 
+    /* interface functions */
+    void setSoundTrack(const char* name);
 
   protected:
Index: trunk/src/story_entities/multi_player_world_data.cc
===================================================================
--- trunk/src/story_entities/multi_player_world_data.cc	(revision 6626)
+++ trunk/src/story_entities/multi_player_world_data.cc	(revision 6634)
@@ -263,4 +263,7 @@
 
 
+  Playable* pl = this->localPlayer->getControllable();
+  PRINTF(0)("The current regisered playable is hid: %i\n", pl->getUniqueID());
+
 
   PNode* cam = State::getCameraTarget();
Index: trunk/src/story_entities/simple_game_menu.cc
===================================================================
--- trunk/src/story_entities/simple_game_menu.cc	(revision 6634)
+++ trunk/src/story_entities/simple_game_menu.cc	(revision 6634)
@@ -0,0 +1,367 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "simple_game_menu.h"
+
+#include "state.h"
+#include "class_list.h"
+
+#include "load_param.h"
+#include "fast_factory.h"
+#include "factory.h"
+
+#include "p_node.h"
+#include "world_entity.h"
+#include "image_entity.h"
+#include "terrain.h"
+#include "camera.h"
+
+#include "event_handler.h"
+#include "graphics_engine.h"
+
+#include "cd_engine.h"
+
+
+using namespace std;
+
+
+//! This creates a Factory to fabricate a SimpleGameMenu
+CREATE_FACTORY(SimpleGameMenu, CL_SIMPLE_GAME_MENU);
+
+
+
+SimpleGameMenu::SimpleGameMenu(const TiXmlElement* root)
+  : GameWorld(root)
+{
+  this->setClassID(CL_SIMPLE_GAME_MENU, "SimpleGameMenu");
+  this->setName("SimpleGameMenu uninitialized");
+
+  this->dataTank = new SimpleGameMenuData();
+
+  this->cameraVector = Vector(50.0, 0.0, 0.0);
+
+  this->loadParams(root);
+}
+
+
+/**
+ *  remove the SimpleGameMenu from memory
+ *
+ *  delete everything explicitly, that isn't contained in the parenting tree!
+ *  things contained in the tree are deleted automaticaly
+ */
+SimpleGameMenu::~SimpleGameMenu ()
+{
+  PRINTF(3)("SimpleGameMenu::~SimpleGameMenu() - deleting current world\n");
+
+  if( this->dataTank)
+    delete this->dataTank;
+}
+
+
+/**
+ * loads the parameters of a SimpleGameMenu from an XML-element
+ * @param root the XML-element to load from
+ */
+void SimpleGameMenu::loadParams(const TiXmlElement* root)
+{
+  /* skip the GameWorld, since it does not define any useful loadParams for this class */
+  static_cast<GameWorld*>(this)->loadParams(root);
+
+  PRINTF(4)("Loaded SimpleGameMenu specific stuff\n");
+}
+
+
+/**
+ * this is executed just before load
+ *
+ * since the load function sometimes needs data, that has been initialized
+ * before the load and after the proceeding storyentity has finished
+ */
+ErrorMessage SimpleGameMenu::init()
+{
+  /* call underlying init funciton */
+  GameWorld::init();
+
+  EventHandler::getInstance()->subscribe(this, ES_MENU, SDLK_UP);
+  EventHandler::getInstance()->subscribe(this, ES_MENU, SDLK_DOWN);
+  EventHandler::getInstance()->subscribe(this, ES_MENU, SDLK_RETURN);
+  EventHandler::getInstance()->subscribe(this, ES_MENU, SDLK_SPACE);
+
+  this->dataTank->localCamera->setRelCoor(this->cameraVector);
+
+  GraphicsEngine::getInstance()->displayFPS(false);
+}
+
+
+/**
+ * load the data
+ */
+ErrorMessage SimpleGameMenu::loadData()
+{
+  GameWorld::loadData();
+
+  /* get the menu list */
+  const std::list<BaseObject*>* imageEntityList = ClassList::getList(CL_IMAGE_ENTITY);
+  std::list<BaseObject*>::const_iterator entity;
+  for (entity = imageEntityList->begin(); entity != imageEntityList->end(); entity++)
+  {
+
+    if( !strcmp("Selector_Menu", (*entity)->getName()))
+    {
+      this->menuSelector = dynamic_cast<ImageEntity*>(*entity);
+      PRINTF(0)("Found the selector: %s\n", (*entity)->getName());
+    }
+    else if( !strcmp( "StartGame_Menu", (*entity)->getName()))
+    {
+      PRINTF(0)("Found a StartItem: %s\n", (*entity)->getName());
+      this->menuStartGame = dynamic_cast<ImageEntity*>(*entity);
+      this->menuList.push_back(dynamic_cast<ImageEntity*>(*entity));
+    }
+    else if( !strcmp( "Multiplayer_Menu", (*entity)->getName()))
+    {
+      PRINTF(0)("Found a MultiplayerItem: %s\n", (*entity)->getName());
+      this->menuStartMultiplayerGame = dynamic_cast<ImageEntity*>(*entity);
+      this->menuList.push_back(dynamic_cast<ImageEntity*>(*entity));
+    }
+    else if( !strcmp( "Quit_Menu", (*entity)->getName()))
+    {
+      PRINTF(0)("Found a QuitItem: %s\n", (*entity)->getName());
+      this->menuQuitGame = dynamic_cast<ImageEntity*>(*entity);
+      this->menuList.push_back(dynamic_cast<ImageEntity*>(*entity));
+    }
+  }
+  this->menuSelectedIndex = 0;
+  this->menuSelected = this->menuList[this->menuSelectedIndex];
+  this->menuSelector->setAbsCoor(this->menuSelected->getAbsCoor());
+}
+
+
+
+/**
+ * start the menu
+ */
+bool SimpleGameMenu::start()
+{
+  EventHandler::getInstance()->pushState(ES_MENU);
+
+  /* now call the underlying*/
+  GameWorld::start();
+}
+
+
+
+/**
+ * stop the menu
+ */
+bool SimpleGameMenu::stop()
+{
+  EventHandler::getInstance()->popState();
+
+  /* now call the underlying*/
+  GameWorld::stop();
+}
+
+
+/**
+ *  override the standard tick for more functionality
+ */
+void SimpleGameMenu::tick()
+{
+  GameWorld::tick();
+
+  this->animateScene(this->dt);
+}
+
+
+/**
+ *  no collision detection in the menu
+ */
+void SimpleGameMenu::collide()
+{
+//   this->dataTank->localCamera->
+}
+
+
+/**
+ *  animate the scene
+ */
+void SimpleGameMenu::animateScene(float dt)
+{
+  Quaternion q(/*0.00005*/ 0.0001* dt, Vector(0.0, 1.0, 0.0));
+  this->cameraVector = q.apply(this->cameraVector);
+  this->dataTank->localCamera->setRelCoor(this->cameraVector);
+  this->dataTank->localCamera->getTarget()->setRelCoorSoft(0,0,0);
+}
+
+
+/**
+ * event dispatcher funciton
+ * @param event the incoming event
+ */
+void SimpleGameMenu::process(const Event &event)
+{
+  if( event.type == SDLK_RETURN)
+  {
+    if( this->menuSelected == this->menuQuitGame)
+    {
+      this->setNextStoryID(WORLD_ID_GAMEEND);
+      this->stop();
+    }
+    if( this->menuSelected == this->menuStartGame)
+    {
+      this->stop();
+    }
+  }
+  else if( event.type == SDLK_DOWN && event.bPressed == true)
+  {
+//     ImageEntity*
+    if(this->menuSelectedIndex < (this->menuList.size() - 1))
+    {
+      this->menuSelected = this->menuList[++this->menuSelectedIndex];
+      this->menuSelector->setAbsCoor(this->menuSelected->getAbsCoor());
+    }
+  }
+  else if( event.type == SDLK_UP && event.bPressed == true)
+  {
+    if(this->menuSelectedIndex > 0)
+    {
+      this->menuSelected = this->menuList[--this->menuSelectedIndex];
+      this->menuSelector->setAbsCoor(this->menuSelected->getAbsCoor());
+    }
+  }
+}
+
+
+
+
+
+
+/**********************************************************************************************
+    SimpleGameMenuData
+ **********************************************************************************************/
+
+
+/**
+ * SimpleGameMenuData constructor
+ */
+SimpleGameMenuData::SimpleGameMenuData()
+{}
+
+/**
+ * SimpleGameMenuData decontructor
+ */
+SimpleGameMenuData::~SimpleGameMenuData()
+{}
+
+
+/**
+ *  initialize the GameWorldDataData
+ */
+ErrorMessage SimpleGameMenuData::init()
+{
+  /* call underlying function */
+  GameWorldData::init();
+}
+
+
+/**
+ *  loads the GUI data
+ * @param root reference to the xml root element
+ */
+ErrorMessage SimpleGameMenuData::loadGUI(TiXmlElement* root)
+{
+  /* call underlying function */
+  GameWorldData::loadGUI(root);
+}
+
+
+/**
+ *  unloads the GUI data
+ */
+ErrorMessage SimpleGameMenuData::unloadGUI()
+{
+  /* call underlying function */
+  GameWorldData::unloadGUI();
+}
+
+
+/**
+ *  overloads the GameWorld::loadWorldEntities(...) class since the menu WorldEntity loading is different (less loading stuff)
+ * @param root reference to the xml root parameter
+ */
+ErrorMessage SimpleGameMenuData::loadWorldEntities(TiXmlElement* root)
+{
+  TiXmlElement* element = root->FirstChildElement("WorldEntities");
+
+  if( element != NULL)
+  {
+    element = element->FirstChildElement();
+    PRINTF(4)("Loading WorldEntities\n");
+    while( element != NULL)
+    {
+      BaseObject* created = Factory::fabricate(element);
+      if( created != NULL )
+        printf("Created a %s: %s\n", created->getClassName(), created->getName());
+
+      if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox"))
+        this->sky = dynamic_cast<WorldEntity*>(created);
+      if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
+        this->terrain = dynamic_cast<Terrain*>(created);
+      element = element->NextSiblingElement();
+    }
+    PRINTF(4)("Done loading WorldEntities\n");
+  }
+
+  /* init the pnode tree */
+  PNode::getNullParent()->init();
+}
+
+
+/**
+ *  unloads the world entities from the xml file
+ */
+ErrorMessage SimpleGameMenuData::unloadWorldEntities()
+{
+  /* call underlying function */
+  GameWorldData::unloadWorldEntities();
+}
+
+
+/**
+ *  loads the scene data
+ * @param root reference to the xml root element
+ */
+ErrorMessage SimpleGameMenuData::loadScene(TiXmlElement* root)
+{
+  /* call underlying function */
+  GameWorldData::loadScene(root);
+}
+
+
+/**
+ *  unloads the scene data
+ */
+ErrorMessage SimpleGameMenuData::unloadScene()
+{
+  /* call underlying function */
+  GameWorldData::unloadScene();
+}
+
+
+
Index: trunk/src/story_entities/simple_game_menu.h
===================================================================
--- trunk/src/story_entities/simple_game_menu.h	(revision 6634)
+++ trunk/src/story_entities/simple_game_menu.h	(revision 6634)
@@ -0,0 +1,90 @@
+/*!
+ * @file simple_game_menu.h
+ *  a StoryEntity that contains a simple game menu
+ */
+
+#ifndef _SIMPLE_GAME_MENU_H
+#define _SIMPLE_GAME_MENU_H
+
+
+#include "game_world.h"
+#include "event_listener.h"
+#include "game_world_data.h"
+#include <vector>
+#include "vector.h"
+
+
+class SimpleGameMenuData;
+class TiXmlElement;
+class ImageEntity;
+
+//! a simple game menu based on a story entity
+/**
+ * This is a simple menu, that is based on the StoryEntity. Therefore this menu is absolutly
+ * loadable and is exchangeable very easely :D
+ */
+class SimpleGameMenu : virtual public GameWorld, virtual public EventListener
+{
+
+  public:
+    SimpleGameMenu(const TiXmlElement* root = NULL);
+    virtual ~SimpleGameMenu();
+
+    void loadParams(const TiXmlElement* root);
+
+    virtual ErrorMessage init();
+    virtual ErrorMessage loadData();
+
+    virtual bool start();
+    virtual bool stop();
+
+    virtual void process(const Event &event);
+
+
+  protected:
+    virtual void tick();
+    virtual void collide();
+
+
+  private:
+    void animateScene(float dt);
+
+
+  private:
+    std::vector<ImageEntity*>         menuList;                        //!< the list of the menu items
+    ImageEntity*                      menuSelected;                    //!< ref to the selected menu entity
+    ImageEntity*                      menuSelector;                    //!< ref to the selector image
+    ImageEntity*                      menuStartGame;
+    ImageEntity*                      menuStartMultiplayerGame;
+    ImageEntity*                      menuQuitGame;
+    int                               menuSelectedIndex;
+
+    Vector                            cameraVector;
+};
+
+
+
+//! the simple game menu data
+class SimpleGameMenuData : public GameWorldData
+{
+
+  public:
+    SimpleGameMenuData();
+    virtual ~SimpleGameMenuData();
+
+    virtual ErrorMessage init();
+
+
+  protected:
+    virtual ErrorMessage loadGUI(TiXmlElement* root);
+    virtual ErrorMessage loadWorldEntities(TiXmlElement* root);
+    virtual ErrorMessage loadScene(TiXmlElement* root);
+
+    virtual ErrorMessage unloadGUI();
+    virtual ErrorMessage unloadWorldEntities();
+    virtual ErrorMessage unloadScene();
+
+};
+
+
+#endif /* _GAME_WORLD_H */
Index: trunk/src/story_entities/story_entity.h
===================================================================
--- trunk/src/story_entities/story_entity.h	(revision 6626)
+++ trunk/src/story_entities/story_entity.h	(revision 6634)
@@ -24,5 +24,5 @@
 
 //! A class that represents something to play in orxonox. it is a container for worlds, movies, mission briefings, etc...
-class StoryEntity : public BaseObject {
+class StoryEntity : virtual public BaseObject {
 
  public:
