Index: trunk/src/world_entities/WorldEntities.am
===================================================================
--- trunk/src/world_entities/WorldEntities.am	(revision 9002)
+++ trunk/src/world_entities/WorldEntities.am	(revision 9003)
@@ -5,4 +5,6 @@
                 world_entities/npcs/ground_turret.cc \
                 world_entities/npcs/generic_npc.cc \
+                world_entities/npcs/door.cc \
+                world_entities/npcs/repair_station.cc \
                 \
                 world_entities/environment.cc \
@@ -16,5 +18,4 @@
                 world_entities/character_attributes.cc \
                 world_entities/test_entity.cc \
-                world_entities/door.cc \
                 world_entities/planet.cc \
                 world_entities/bsp_entity.cc \
@@ -67,4 +68,7 @@
                 npcs/npc_test1.h \
                 npcs/ground_turret.h \
+                npcs/door.cc \
+                npcs/repair_station.cc \
+                \
                 environment.h \
                 skysphere.h \
@@ -77,5 +81,4 @@
                 character_attributes.h \
                 test_entity.h \
-                door.h \
                 planet.h \
                 bsp_entity.h \
Index: trunk/src/world_entities/bsp_entity.cc
===================================================================
--- trunk/src/world_entities/bsp_entity.cc	(revision 9002)
+++ trunk/src/world_entities/bsp_entity.cc	(revision 9003)
@@ -1,12 +1,12 @@
 /*
    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: Claudio Botta
@@ -15,4 +15,5 @@
 
 #include "bsp_entity.h"
+#include "util/loading/resource_manager.h"
 #include "util/loading/resource_manager.h"
 
@@ -38,7 +39,8 @@
 BspEntity::~BspEntity ()
 {
-  if( this->bspManager)
+  if( this->bspManager != NULL)
     delete this->bspManager;
 }
+
 
 
@@ -49,9 +51,6 @@
 void BspEntity::init()
 {
-  this->setClassID(CL_BSP_ENTITY, "BspEntity");
 
-  this->bspManager = new BspManager(this);
-  this->toList(OM_ENVIRON);
-
+  this->bspManager = NULL;
   /**
    * @todo: Write CL_BSP_ENTITY INTO THE src/defs/class_id.h (your own definition)
@@ -64,5 +63,20 @@
   PRINTF(0)("+++++++++++ LOADING NAME %s\n", name.c_str());
 
-  this->bspManager->load(name.c_str(), 0.1f);
+  // Check wether file exists....
+  if ( File(ResourceManager::getFullName(name)).exists()  ) {
+
+    this->setClassID(CL_BSP_ENTITY, "BspEntity");
+    this->bspManager = new BspManager(this);
+
+    if(this->bspManager->load(name.c_str(), 0.1f) == -1 ) {
+      this->bspManager = NULL;
+
+    } else {
+      this->toList(OM_ENVIRON); // Success!!!
+    }
+  } else {
+    this->bspManager = NULL;
+    this->toList(OM_DEAD);
+  }
 }
 
@@ -76,12 +90,12 @@
 {
   // all the clases this Entity is directly derived from must be called in this way, to load all settings.
- // WorldEntity::loadParam(root);
+  // WorldEntity::loadParam(root);
 
   LoadParam(root, "Name", this, BspEntity, setName)
-      .describe("Sets the of the BSP file.");
+  .describe("Sets the of the BSP file.");
 
-/*  LoadParam(root, "Scale", this, BSpEntity, setScale)
-      .describe("Sets the scale factore of the bsp level.");
-*/
+  /*  LoadParam(root, "Scale", this, BSpEntity, setScale)
+        .describe("Sets the scale factore of the bsp level.");
+  */
 
   /**
@@ -115,5 +129,3 @@
  */
 void BspEntity::collidesWith (WorldEntity* entity, const Vector& location)
-{
-
-}
+{}
Index: trunk/src/world_entities/creatures/fps_player.cc
===================================================================
--- trunk/src/world_entities/creatures/fps_player.cc	(revision 9002)
+++ trunk/src/world_entities/creatures/fps_player.cc	(revision 9003)
@@ -83,4 +83,5 @@
   this->bBackward = false;
   this->bJump = false;
+  this->bPosBut = false;
 
   this->xMouse = 0.0f;
@@ -90,4 +91,5 @@
   this->setHealth(80);
 
+  this->fallVelocity = 0.0f;
 
   this->cameraNode.setParent(this);
@@ -121,8 +123,8 @@
 
   this->getWeaponManager().setSlotCount(2);
-  this->getWeaponManager().setSlotPosition(0, Vector(0.0, 5.0, 0.0));
-  this->getWeaponManager().setSlotDirection(1, Quaternion(M_PI_4*.5, Vector(0,1,0)));
+  this->getWeaponManager().setSlotPosition(0, Vector(1.5, -0.7, 1.1));
+//   this->getWeaponManager().setSlotDirection(0, Quaternion(M_PI_2, Vector(0,1,0)));
   this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
-  this->getWeaponManager().setSlotPosition(1, Vector(-0.5, .2, 1.9));
+  this->getWeaponManager().setSlotPosition(1, Vector(5.0, 0.0, 0.0));
   this->getWeaponManager().setSlotDirection(1, Quaternion(M_PI_4*.5, Vector(1,0,0)));
 
@@ -205,4 +207,11 @@
 void FPSPlayer::tick (float time)
 {
+  
+  if( this->bPosBut)
+  {
+    this->bPosBut = false;
+    printf("prisoner:walkTo( %f, height, %f)\n",this->getAbsCoorX(),this->getAbsCoorZ());
+  }
+  
   Playable::tick( time );
 
@@ -251,7 +260,24 @@
   }
 
+
   velocity *= 100;
 
+
+  // physical falling of the player
+  if( !this->isOnGround())
+  {
+    this->fallVelocity += 300.0f * time;
+    velocity -= Vector(0.0, 1.0, 0.0) * this->fallVelocity;
+  }
+  else
+  {
+    this->fallVelocity = 0.0f;
+  }
+
+
   this->shiftCoor( velocity*time );
+
+
+
 
 
@@ -321,8 +347,8 @@
   }
   else if( event.type == KeyMapper::PEV_JUMP)
-    this->getAbsCoor().debug();
-}
-
-
-
-
+    this->bPosBut = event.bPressed;
+}
+
+
+
+
Index: trunk/src/world_entities/creatures/fps_player.h
===================================================================
--- trunk/src/world_entities/creatures/fps_player.h	(revision 9002)
+++ trunk/src/world_entities/creatures/fps_player.h	(revision 9003)
@@ -42,4 +42,5 @@
     bool                  bBackward;
     bool                  bJump;              //!< jumping
+    bool                  bPosBut;             //!< position button
 
     float                 xMouse;             //!< mouse moved in x-Direction
@@ -51,4 +52,6 @@
 
     PNode                 cameraNode;
+
+    float                 fallVelocity;        //!< velocity for falling down
 };
 
Index: trunk/src/world_entities/door.cc
===================================================================
--- trunk/src/world_entities/door.cc	(revision 9002)
+++ 	(revision )
@@ -1,189 +1,0 @@
-
-
-/*
-   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
-   co-programmer:
-*/
-#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
-
-
-#include "util/loading/factory.h"
-#include "util/loading/load_param.h"
-
-#include "interactive_model.h"
-
-
-#include "door.h"
-#include "class_list.h"
-
-
-using namespace std;
-
-
-CREATE_FACTORY(Door, CL_DOOR);
-
-
-
-//! list of all different animations a std md2model supports
-sAnim Door::animationList[2] =
-{
- // begin, end, fps, interruptable
-  {   0,  15,  9,  0 },   //!< OPEN
-  {   15, 30,  9,  0 }    //!< CLOSE
-};
-
-
-
-Door::Door ()
-{
-  this->init();
-}
-
-
-Door::Door(const TiXmlElement* root)
-{
-
-  this->setClassID(CL_DOOR, "Door");
-  this->scale = 1.0f;
-
-  if( root != NULL)
-    this->loadParams(root);
-
-  this->toList(OM_COMMON);
-  this->bLocked = false;
-
-  this->loadMD2Texture("maps/doors.jpg");
-  this->loadModel("models/creatures/doors.md2", this->scale);
-  this->setAnimation(DOOR_CLOSE, MD2_ANIM_ONCE);
-}
-
-
-Door::~Door ()
-{}
-
-
-
-/**
- * loads the Settings of a MD2Creature from an XML-element.
- * @param root the XML-element to load the MD2Creature's properties from
- */
-void Door::loadParams(const TiXmlElement* root)
-{
-  WorldEntity::loadParams(root);
-
-  LoadParam(root, "action-radius", this, Door, setActionRadius)
-      .describe("sets the action radius of the door")
-      .defaultValues(3.0);
-  LoadParam(root, "scale", this, Door, setScale)
-      .describe("sets the scale of the door")
-      .defaultValues(1.0);
-}
-
-
-/**
- * sets the animatin of this entity
- */
-void  Door::setAnimation(int animNum, int playbackMode)
-{
-  if( likely(this->getModel(0) != NULL))
-    ((InteractiveModel*)this->getModel(0))->setAnimation(animationList[animNum].firstFrame,
-                                                         animationList[animNum].lastFrame,
-                                                         animationList[animNum].fps,
-                                                         animationList[animNum].bStoppable,
-                                                         playbackMode);
-}
-
-
-/**
- * ticks the door
- * @param time: time since last tick
- */
-void Door::tick (float time)
-{
-  if( likely(this->getModel(0) != NULL))
-    ((InteractiveModel*)this->getModel(0))->tick(time);
-
-  if( this->checkOpen() && !this->bOpen)
-    this->open();
-  else if( bOpen)
-    this->close();
-
-}
-
-
-/**
- * open the door
- */
-void Door::open()
-{
-  if( this->bLocked)
-    return;
-
-  this->setAnimation(DOOR_OPEN, MD2_ANIM_ONCE);
-  this->bOpen = true;
-}
-
-
-/**
- * close the door
- */
-void Door::close()
-{
-  this->setAnimation(DOOR_CLOSE, MD2_ANIM_ONCE);
-  this->bOpen = false;
-}
-
-
-
-/**
- * checks if the door is open
- */
-bool Door::checkOpen()
-{
-
-  std::list<BaseObject*>::const_iterator it;
-  const std::list<BaseObject*>* list = ClassList::getList(CL_PLAYABLE);
-  WorldEntity* entity;
-  float distance;
-
-  if( list == NULL)
-    return false;
-
-  // for all players
-  for( it = list->begin(); it != list->end(); it++)
-  {
-    entity = dynamic_cast<WorldEntity*>(*it);
-
-    distance = fabs((this->getAbsCoor() - entity->getAbsCoor()).len());
-    if( distance < this->actionRadius)
-      return true;
-  }
-
-
-  list = ClassList::getList(CL_GENERIC_NPC);
-  if( list == NULL)
-    return false;
-  for( it = list->begin(); it != list->end(); it++)
-  {
-    entity = dynamic_cast<WorldEntity*>(*it);
-
-    distance = fabs((this->getAbsCoor() - entity->getAbsCoor()).len());
-    if( distance < this->actionRadius)
-      return true;
-  }
-
-  return false;
-}
-
-
-
Index: trunk/src/world_entities/door.h
===================================================================
--- trunk/src/world_entities/door.h	(revision 9002)
+++ 	(revision )
@@ -1,60 +1,0 @@
-#ifndef _DOOR_H
-#define _DOOR_H
-
-#include "world_entity.h"
-
-#include "md2/md2Model.h"
-
-class TiXmlElement;
-
-
-//! animation names enumeration
-typedef enum DoorAnimType
-{
-  DOOR_OPEN = 0,
-  DOOR_CLOSE,
-
-  DOOR_MAX_ANIMATIONS
-};
-
-
-class Door : public WorldEntity
-{
-  public:
-    Door ();
-    Door(const TiXmlElement* root);
-    virtual ~Door ();
-
-    virtual void loadParams(const TiXmlElement* root);
-
-    void setActionRadius(float radius) { this->actionRadius = radius; }
-    void setScale(float scale) { this->scale = scale; }
-
-    void open();
-    void close();
-
-    void lock() { this->bLocked = true; }
-    void unlock() { this->bLocked = false; }
-    bool isLocked() const { return this->bLocked; }
-
-
-    virtual void tick (float time);
-
-
-  private:
-    bool checkOpen();
-    void setAnimation(int animNum, int playbackMode = 0);
-
-
-  private:
-    bool           bOpen;             //!< true if the door is open
-    bool           bLocked;           //!< true if this door is locked
-    float          actionRadius;      //!< action radius
-    float          scale;             //!< the scale of the model
-
-    static sAnim   animationList[2];  //!< list of the animations
-
-
-};
-
-#endif /* _DOOR_H */
Index: trunk/src/world_entities/elements/glgui_radar.cc
===================================================================
--- trunk/src/world_entities/elements/glgui_radar.cc	(revision 9002)
+++ trunk/src/world_entities/elements/glgui_radar.cc	(revision 9003)
@@ -135,5 +135,5 @@
       glRotatef((this->_centerNode->getAbsDir().getHeading() - M_PI_2)* 180.0 /M_PI , 0, 0, 1);
 
-      glPointSize(2.0f);
+      glPointSize(4.0f);
       for (unsigned int i = 0; i < this->_dotLists.size(); ++i)
       {
Index: trunk/src/world_entities/npcs/door.cc
===================================================================
--- trunk/src/world_entities/npcs/door.cc	(revision 9003)
+++ trunk/src/world_entities/npcs/door.cc	(revision 9003)
@@ -0,0 +1,200 @@
+
+
+/*
+   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
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+#include "interactive_model.h"
+
+
+#include "door.h"
+#include "class_list.h"
+
+
+using namespace std;
+
+
+CREATE_FACTORY(Door, CL_DOOR);
+
+
+
+//! list of all different animations a std md2model supports
+sAnim Door::animationList[2] =
+{
+ // begin, end, fps, interruptable
+  {   0,  15,  30,  0 },   //!< OPEN
+  {   15, 29,  30,  0 }    //!< CLOSE
+};
+
+
+
+Door::Door ()
+{
+  this->init();
+}
+
+
+Door::Door(const TiXmlElement* root)
+{
+
+  this->setClassID(CL_DOOR, "Door");
+  this->scale = 1.0f;
+
+  if( root != NULL)
+    this->loadParams(root);
+
+  this->toList(OM_COMMON);
+  this->bLocked = false;
+
+  this->loadMD2Texture("maps/doors.jpg");
+  this->loadModel("models/creatures/doors.md2", this->scale);
+
+  this->setAnimation(DOOR_CLOSE, MD2_ANIM_ONCE);
+}
+
+
+Door::~Door ()
+{}
+
+
+
+/**
+ * loads the Settings of a MD2Creature from an XML-element.
+ * @param root the XML-element to load the MD2Creature's properties from
+ */
+void Door::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "action-radius", this, Door, setActionRadius)
+      .describe("sets the action radius of the door")
+      .defaultValues(3.0);
+  LoadParam(root, "scale", this, Door, setScale)
+      .describe("sets the scale of the door")
+      .defaultValues(1.0);
+}
+
+
+/**
+ * sets the animatin of this entity
+ */
+void  Door::setAnimation(int animNum, int playbackMode)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->setAnimation(animationList[animNum].firstFrame,
+                                                         animationList[animNum].lastFrame,
+                                                         animationList[animNum].fps,
+                                                         animationList[animNum].bStoppable,
+                                                         playbackMode);
+}
+
+
+/**
+ * ticks the door
+ * @param time: time since last tick
+ */
+void Door::tick (float time)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->tick(time);
+
+  if( !this->bOpen)
+  {
+    if( this->checkOpen())
+    {
+      this->open();
+    }
+  }
+  else
+  {
+    if( !this->checkOpen())
+    {
+      this->close();
+    }
+  }
+
+}
+
+
+/**
+ * open the door
+ */
+void Door::open()
+{
+  if( this->bLocked)
+    return;
+
+  this->setAnimation(DOOR_OPEN, MD2_ANIM_ONCE);
+  this->bOpen = true;
+}
+
+
+/**
+ * close the door
+ */
+void Door::close()
+{
+  this->setAnimation(DOOR_CLOSE, MD2_ANIM_ONCE);
+  this->bOpen = false;
+}
+
+
+
+/**
+ * checks if the door is open
+ */
+bool Door::checkOpen()
+{
+
+  std::list<BaseObject*>::const_iterator it;
+  const std::list<BaseObject*>* list = ClassList::getList(CL_PLAYABLE);
+  WorldEntity* entity;
+  float distance;
+
+  if( list == NULL)
+    return false;
+
+  // for all players
+  for( it = list->begin(); it != list->end(); it++)
+  {
+    entity = dynamic_cast<WorldEntity*>(*it);
+
+    distance = fabs((this->getAbsCoor() - entity->getAbsCoor()).len());
+    if( distance < this->actionRadius)
+      return true;
+  }
+
+
+  list = ClassList::getList(CL_GENERIC_NPC);
+  if( list == NULL)
+    return false;
+  for( it = list->begin(); it != list->end(); it++)
+  {
+    entity = dynamic_cast<WorldEntity*>(*it);
+
+    distance = fabs((this->getAbsCoor() - entity->getAbsCoor()).len());
+    if( distance < this->actionRadius)
+      return true;
+  }
+
+  return false;
+}
+
+
+
Index: trunk/src/world_entities/npcs/door.h
===================================================================
--- trunk/src/world_entities/npcs/door.h	(revision 9003)
+++ trunk/src/world_entities/npcs/door.h	(revision 9003)
@@ -0,0 +1,60 @@
+#ifndef _DOOR_H
+#define _DOOR_H
+
+#include "world_entity.h"
+
+#include "md2/md2Model.h"
+
+class TiXmlElement;
+
+
+//! animation names enumeration
+typedef enum DoorAnimType
+{
+  DOOR_OPEN = 0,
+  DOOR_CLOSE,
+
+  DOOR_MAX_ANIMATIONS
+};
+
+
+class Door : public WorldEntity
+{
+  public:
+    Door ();
+    Door(const TiXmlElement* root);
+    virtual ~Door ();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    void setActionRadius(float radius) { this->actionRadius = radius; }
+    void setScale(float scale) { this->scale = scale; }
+
+    void open();
+    void close();
+
+    void lock() { this->bLocked = true; }
+    void unlock() { this->bLocked = false; }
+    bool isLocked() const { return this->bLocked; }
+
+
+    virtual void tick (float time);
+
+
+  private:
+    bool checkOpen();
+    void setAnimation(int animNum, int playbackMode = 0);
+
+
+  private:
+    bool           bOpen;             //!< true if the door is open
+    bool           bLocked;           //!< true if this door is locked
+    float          actionRadius;      //!< action radius
+    float          scale;             //!< the scale of the model
+
+    static sAnim   animationList[2];  //!< list of the animations
+
+
+};
+
+#endif /* _DOOR_H */
Index: trunk/src/world_entities/npcs/generic_npc.cc
===================================================================
--- trunk/src/world_entities/npcs/generic_npc.cc	(revision 9002)
+++ trunk/src/world_entities/npcs/generic_npc.cc	(revision 9003)
@@ -17,4 +17,6 @@
 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
 
+#include "generic_npc.h"
+
 
 #include "util/loading/factory.h"
@@ -28,11 +30,4 @@
 #include "loading/resource_manager.h"
 
-#include "generic_npc.h"
-
-#include "animation/animation3d.h"
-
-using namespace std;
-
-
 
 CREATE_FACTORY(GenericNPC, CL_GENERIC_NPC);
@@ -40,12 +35,13 @@
 #include "script_class.h"
 CREATE_SCRIPTABLE_CLASS(GenericNPC, CL_GENERIC_NPC,
-                       // Move
-                        addMethod("walkTo", ExecutorLua3ret<GenericNPC,float,float,float,float>(&GenericNPC::walkTo))
-                        ->addMethod("setTime", ExecutorLua1<GenericNPC,float>(&GenericNPC::setTime))
-                        ->addMethod("turnTo", ExecutorLua4ret<GenericNPC,bool,float,float,float,float>(&GenericNPC::turnTo))
-                       // Display
+                        // Move
+                        addMethod("walkTo", ExecutorLua3<GenericNPC,float,float,float>(&GenericNPC::walkTo))
+                        ->addMethod("runTo", ExecutorLua3<GenericNPC,float,float,float>(&GenericNPC::runTo))
+                        ->addMethod("turnTo", ExecutorLua1<GenericNPC,float>(&GenericNPC::turnTo))
+                        ->addMethod("finalGoalReached", ExecutorLua0ret<GenericNPC,bool>(&GenericNPC::finalGoalReached))
+                        // Display
                         ->addMethod("hide", ExecutorLua0<WorldEntity>(&WorldEntity::hide))
                         ->addMethod("unhide", ExecutorLua0<WorldEntity>(&WorldEntity::unhide))
-                       // Coordinates
+                        // Coordinates
                         ->addMethod("getAbsCoorX", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorX))
                         ->addMethod("getAbsCoorY", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorY))
@@ -53,5 +49,5 @@
                         ->addMethod("setAbsCoor", ExecutorLua3<PNode,float,float,float>(&PNode::setAbsCoor))
                         ->addMethod("setAbsDir", ExecutorLua4<PNode,float,float,float,float>(&PNode::setAbsDir))
-                            
+
                        );
 
@@ -62,5 +58,5 @@
  */
 GenericNPC::GenericNPC(const TiXmlElement* root)
-  : NPC(root)
+    : NPC(root)
 {
   this->init();
@@ -71,18 +67,9 @@
 
 
-GenericNPC::GenericNPC()
-  : NPC(NULL)
-{
-
-}
-
 /**
  * deconstructor
  */
 GenericNPC::~GenericNPC ()
-{
-  if( this->currentAnim != NULL)
-    delete this->currentAnim;
-}
+{}
 
 
@@ -100,6 +87,7 @@
 
   time = 30.0f;
+
   // collision reaction registration
-//   this->subscribeReaction(CREngine::CR_PHYSICS_GROUND_WALK, CL_BSP_ENTITY);
+  this->subscribeReaction(CREngine::CR_PHYSICS_GROUND_WALK, CL_BSP_ENTITY);
 }
 
@@ -128,4 +116,41 @@
 
 
+
+/**
+ * @returns the current animation number
+ */
+int GenericNPC::getAnimation()
+{
+  if( likely(this->getModel(0) != NULL))
+    return ((InteractiveModel*)this->getModel(0))->getAnimation();
+  else
+    return -1;
+}
+
+
+
+/**
+ * @returns true if animation is finished
+ */
+bool GenericNPC::isAnimationFinished()
+{
+  if( likely(this->getModel(0) != NULL))
+    return ((InteractiveModel*)this->getModel(0))->isAnimationFinished();
+  else
+    return false;
+}
+
+
+/**
+ * sets the animation speed of this entity
+ */
+void GenericNPC::setAnimationSpeed(float speed)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->setAnimationSpeed(speed);
+}
+
+
+
 /**
  * sets the animation of this npc
@@ -146,243 +171,6 @@
  */
 void GenericNPC::playSound(std::string filename)
-{
-
-}
-
-
-/**
- * walt to
- * @param coordinate: coordinate to go to
- */
-float GenericNPC::walkTo(float x, float y, float z, float qu, float qx, float qy, float qz)
-{
-  Vector destCoor = Vector(x, y, z);
-  Quaternion destDir = Quaternion(Vector(qx, qy, qz), qu);
-
-  // check if this is the current goal
-  if( this->destCoor != destCoor || this->destDir != destDir)
-  {
-    this->destCoor = destCoor;
-    this->destDir = destDir;
-
-    //float time = 100.0f;
-
-    if( this->currentAnim != NULL)
-      delete this->currentAnim;
-
-    this->currentAnim = new Animation3D(this);
-    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), 0.0f, ANIM_LINEAR, ANIM_LINEAR);
-    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), time, ANIM_LINEAR, ANIM_LINEAR);
-    this->currentAnim->addKeyFrame(this->destCoor, this->destDir, time, ANIM_LINEAR, ANIM_LINEAR);
-
-    this->currentAnim->setInfinity(ANIM_INF_CONSTANT);
-    this->currentAnim->play();
-
-    this->setAnimation(RUN, MD2_ANIM_LOOP);
-  }
-
-  // calculate the distance
-  Vector distance = this->getAbsCoor() - this->destCoor;
-  return distance.len();
-}
-
-
-/**
- * walk to a specific place with direction
- *
- * @param x: x coordinate to go to
- * @param y: y coordinate to go to
- * @param z: z coordinate to go to
- *
- * without turning itself
- */
-float GenericNPC::walkTo(float x, float y, float z)
-{
-  Quaternion q = this->getAbsDir();
-
-  //printf("%s moving to %f, %f, %f \n",this->getName(),x,y,z);
-
-  return this->walkTo(x, y, z, q.w, q.v.x, q.v.y, q.v.z);
-}
-
-/**
- * walk to a specific place with direction
- *
- * @param x: x coordinate to go to
- * @param y: y coordinate to go to
- * @param qu: angle to rotate
- * @param qx: x coordinate of rotation vector
- * @param qy: y coordinate of rotation vector
- * @param qz: z coordinate of rotation vector
- *
- */
-float GenericNPC::walkTo(float x, float y, float qu, float qx, float qy, float qz)
-{
-  return this->walkTo(x, y, 0.0f, qu, qx, qy, qz);
-}
-
-
-/**
- * walk to a specific place with direction
- *
- * @param coor: vector place
- * @param dir: direction
- *
- */
-float GenericNPC::walkTo(const Vector& coor, const Quaternion& dir)
-{
-  return this->walkTo(coor.x, coor.y, coor.z, dir.w, dir.v.x, dir.v.y, dir.v.z);
-}
-
-
-
-/**
- * run to a specific place with direction
- *
- * @param x: x coordinate to go to
- * @param y: y coordinate to go to
- * @param z: z coordinate to go to
- * @param qu: angle to rotate
- * @param qx: x coordinate of rotation vector
- * @param qy: y coordinate of rotation vector
- * @param qz: z coordinate of rotation vector
- *
- */
-float GenericNPC::runTo(float x, float y, float z, float qu, float qx, float qy, float qz)
-{
-  Vector destCoor = Vector(x, y, z);
-  Quaternion destDir = Quaternion(Vector(qx, qy, qz), qu);
-
-  // check if this is the current goal
-  if( this->destCoor != destCoor || this->destDir != destDir)
-  {
-    this->destCoor = destCoor;
-    this->destDir = destDir;
-
-    float time = 5.0f;
-
-    if( this->currentAnim != NULL)
-      delete this->currentAnim;
-
-    this->currentAnim = new Animation3D(this);
-    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), time, ANIM_LINEAR, ANIM_LINEAR);
-    this->currentAnim->addKeyFrame(this->destCoor, this->destDir, time, ANIM_LINEAR, ANIM_LINEAR);
-
-
-    this->currentAnim->setInfinity(ANIM_INF_CONSTANT);
-    this->currentAnim->play();
-
-    this->setAnimation(RUN, MD2_ANIM_LOOP);
-  }
-
-  // calculate the distance
-  Vector distance = this->getAbsCoor() - this->destCoor;
-  return distance.len();
-}
-
-
-/**
- * run to a specific place with direction
- *
- * @param x: x coordinate to go to
- * @param y: y coordinate to go to
- * @param qu: angle to rotate
- * @param qx: x coordinate of rotation vector
- * @param qy: y coordinate of rotation vector
- * @param qz: z coordinate of rotation vector
- *
- */
-float GenericNPC::runTo(float x, float y, float qu, float qx, float qy, float qz)
-{
-  this->runTo(x, y, 0.0f, qu, qx, qy, qz);
-}
-
-
-/**
- * run to a specific place with direction
- *
- * @param coor: vector place
- * @param dir: direction
- *
- */
-float GenericNPC::runTo(const Vector& coordinate, const Quaternion& dir)
-{
-  this->runTo(coordinate.x, coordinate.y, coordinate.z, dir.w, dir.v.x, dir.v.y, dir.v.z);
-}
-
-
-/**
- * crouch to a specific place with direction
- *
- * @param x: x coordinate to go to
- * @param y: y coordinate to go to
- * @param z: z coordinate to go to
- * @param qu: angle to rotate
- * @param qx: x coordinate of rotation vector
- * @param qy: y coordinate of rotation vector
- * @param qz: z coordinate of rotation vector
- *
- */
-float GenericNPC::crouchTo(float x, float y, float z, float qu, float qx, float qy, float qz)
-{
-  Vector destCoor = Vector(x, y, z);
-  Quaternion destDir = Quaternion(Vector(qx, qy, qz), qu);
-
-  // check if this is the current goal
-  if( this->destCoor != destCoor || this->destDir != destDir)
-  {
-    this->destCoor = destCoor;
-    this->destDir = destDir;
-
-
-    if( this->currentAnim != NULL)
-      delete this->currentAnim;
-
-    this->currentAnim = new Animation3D(this);
-    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), time, ANIM_LINEAR, ANIM_LINEAR);
-    this->currentAnim->addKeyFrame(this->destCoor, this->destDir, time, ANIM_LINEAR, ANIM_LINEAR);
-
-
-    this->currentAnim->setInfinity(ANIM_INF_CONSTANT);
-    this->currentAnim->play();
-
-    this->setAnimation(CROUCH_WALK, MD2_ANIM_LOOP);
-  }
-
-  // calculate the distance
-  Vector distance = this->getAbsCoor() - this->destCoor;
-  return distance.len();
-}
-
-
-/**
- * couch to a specific place with direction
- *
- * @param x: x coordinate to go to
- * @param y: y coordinate to go to
- * @param qu: angle to rotate
- * @param qx: x coordinate of rotation vector
- * @param qy: y coordinate of rotation vector
- * @param qz: z coordinate of rotation vector
- *
- */
-float GenericNPC::crouchTo(float x, float y, float qu, float qx, float qy, float qz)
-{
-  this->crouchTo(x, y, 0.0f, qu, qx, qy, qz);
-}
-
-
-
-/**
- * crouch to a specific place with direction
- *
- * @param coor: vector place
- * @param dir: direction
- *
- */
-float GenericNPC::crouchTo(const Vector& coordinate, const Quaternion& dir)
-{
-  this->crouchTo(coordinate.x, coordinate.y, coordinate.z, dir.w, dir.v.x, dir.v.y, dir.v.z);
-}
+{}
+
 
 
@@ -391,14 +179,229 @@
  */
 void GenericNPC::stop()
-{
-  if( this->currentAnim != NULL)
-  {
-    this->currentAnim->stop();
-    delete this->currentAnim;
-    this->currentAnim = NULL;
-
+{}
+
+
+
+void GenericNPC::initNPC()
+{
+  if (!this->behaviourList.empty())
+  {
+    GenericNPC::Anim currentAnimation = this->behaviourList.front();
+
+    switch(this->behaviourList.front().type)
+    {
+      case Walk:
+      {
+        if( this->getAnimation() != RUN)
+          this->setAnimation(RUN, MD2_ANIM_LOOP);
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor());
+        dir.y = 0.0f;
+        dir.getNormalized();
+        this->setAbsDir(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)));
+
+        this->setAnimationSpeed(0.5f);
+      }
+        break;
+      case Run:
+      {
+        if( this->getAnimation() != RUN)
+          this->setAnimation(RUN, MD2_ANIM_LOOP);
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
+        this->setAbsDir(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)));
+
+        this->setAnimationSpeed(1.0f);
+      }
+        break;
+      case Crouch:
+      {
+        if( this->getAnimation() != CROUCH_WALK)
+          this->setAnimation(CROUCH_WALK, MD2_ANIM_LOOP);
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
+        this->setAbsDir(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)));
+
+        this->setAnimationSpeed(1.0f);
+      }
+        break;
+      case LookAt:
+        if( this->getAnimation() != STAND)
+          this->setAnimation(STAND, MD2_ANIM_LOOP);
+        break;
+      case Shoot:
+        if( this->getAnimation() != STAND)
+          this->setAnimation(STAND, MD2_ANIM_LOOP);
+        break;
+
+      default:
+        if( this->getAnimation() != STAND)
+          this->setAnimation(STAND, MD2_ANIM_LOOP);
+        break;
+
+    }
+  }
+}
+
+
+void GenericNPC::nextStep()
+{
+  if (!this->behaviourList.empty())
+    this->behaviourList.pop_front();
+  else
+    return;
+
+
+  if (!this->behaviourList.empty())
+  {
+    GenericNPC::Anim currentAnimation = this->behaviourList.front();
+
+    switch( currentAnimation.type)
+    {
+      case Walk:
+      {
+        if( this->getAnimation() != RUN)
+          this->setAnimation(RUN, MD2_ANIM_LOOP);
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor());
+        dir.y = 0.0f;
+        dir.getNormalized();
+        this->setAbsDirSoft(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)), 4.0);
+
+        this->setAnimationSpeed(0.5f);
+      }
+        break;
+      case Run:
+      {
+        if( this->getAnimation() != RUN)
+          this->setAnimation(RUN, MD2_ANIM_LOOP);
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
+        this->setAbsDirSoft(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)), 4.0);
+
+        this->setAnimationSpeed(1.0f);
+      }
+        break;
+      case Crouch:
+      {
+        if( this->getAnimation() != CROUCH_WALK)
+          this->setAnimation(CROUCH_WALK, MD2_ANIM_LOOP);
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
+        this->setAbsDirSoft(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)), 4.0);
+
+        this->setAnimationSpeed(1.0f);
+      }
+        break;
+      case LookAt:
+      {
+        if( this->getAnimation() != STAND)
+          this->setAnimation(STAND, MD2_ANIM_LOOP);
+      }
+        break;
+      case Shoot:
+        if( this->getAnimation() != STAND)
+        this->setAnimation(STAND, MD2_ANIM_LOOP);
+        break;
+
+      default:
+        if( this->getAnimation() != STAND)
+        this->setAnimation(STAND, MD2_ANIM_LOOP);
+        break;
+
+    }
+  }
+  else
+  {
     this->setAnimation(STAND, MD2_ANIM_LOOP);
   }
 }
+
+
+
+
+void GenericNPC::walkTo(const Vector& coordinate)
+{
+
+  GenericNPC::Anim anim;
+  anim.v = coordinate;
+  anim.type = Walk;
+  anim.speed = 30.0f;
+
+  if( this->behaviourList.empty())
+  {
+    this->behaviourList.push_back(anim);
+    this->initNPC();
+  }
+  else
+    this->behaviourList.push_back(anim);
+}
+
+void GenericNPC::walkTo(float x, float y, float z)
+{
+  //printf("Walking to %f, %f, %f \n",x,y,z);
+  this->walkTo(Vector(x,y,z));
+
+}
+
+/* running functions */
+void GenericNPC::runTo(const Vector& coordinate)
+{
+  GenericNPC::Anim anim;
+  anim.v = coordinate;
+  anim.type = Run;
+  anim.speed = 60.0f;
+
+  if( this->behaviourList.empty())
+  {
+    this->behaviourList.push_back(anim);
+    this->initNPC();
+  }
+  else
+    this->behaviourList.push_back(anim);
+}
+
+void GenericNPC::runTo(float x, float y, float z)
+{
+  this->runTo(Vector(x,y,z));
+}
+
+/* couching functinos */
+void GenericNPC::crouchTo(const Vector& coordinate)
+{
+  GenericNPC::Anim anim;
+  anim.v = coordinate;
+  anim.type = Crouch;
+
+  if( this->behaviourList.empty())
+  {
+    this->behaviourList.push_back(anim);
+    this->initNPC();
+  }
+  else
+    this->behaviourList.push_back(anim);
+}
+void GenericNPC::crouchTo(float x, float y, float z)
+{
+  this->crouchTo(Vector(x,y,z));
+}
+
+
+
+void GenericNPC::turnTo(float degreeInY)
+{
+  GenericNPC::Anim anim;
+  anim.q = Quaternion(Vector(0,1,0), degreeInY);
+  anim.type = TurnTo;
+
+  if( this->behaviourList.empty())
+  {
+    this->behaviourList.push_back(anim);
+    this->initNPC();
+  }
+  else
+    this->behaviourList.push_back(anim);
+}
+
 
 
@@ -407,48 +410,19 @@
  * @param worldEntity: the worldentity to look at
  */
-float GenericNPC::lookAt(WorldEntity* worldEntity)
-{}
-
-
-/**
- * turns to a given direction
- */
-bool GenericNPC::turnTo(float qu, float qx, float qy, float qz)
-{
-  Quaternion destDir = Quaternion(Vector(qx, qy, qz).getNormalized(), qu);
-
-  printf("Turning: %f, %f, %f, %f \n",qu,qx,qy,qz);
-  // check if this is the current goal
-  if( this->destDir != destDir)
-  {
-//     if( this->currentAnim != NULL)
-//       this->currentAnim->stop();
-//
-    PRINTF(0)("SET ANIMATION\n");
-    this->destDir = destDir;
-//
-
-
-    if( this->currentAnim != NULL)
-      delete this->currentAnim;
-
-    this->setAbsDir(destDir);
-/*
-    this->currentAnim = new Animation3D(this);
-    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), 0.0f, ANIM_LINEAR, ANIM_LINEAR);
-    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), time, ANIM_LINEAR, ANIM_LINEAR);
-    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->destDir, time, ANIM_LINEAR, ANIM_LINEAR);
-
-
-    this->currentAnim->setInfinity(ANIM_INF_CONSTANT);
-    this->currentAnim->play();*/
-
-    this->setAnimation(STAND, MD2_ANIM_LOOP);
-  }
-
-  // calculate the distance
-  Vector distance = this->getAbsCoor() - this->destCoor;
-  return distance.len();
-}
+void GenericNPC::lookAt(WorldEntity* worldEntity)
+{
+  GenericNPC::Anim anim;
+  anim.entity = worldEntity;
+  anim.type = LookAt;
+
+  if( this->behaviourList.empty())
+  {
+    this->behaviourList.push_back(anim);
+    this->initNPC();
+  }
+  else
+    this->behaviourList.push_back(anim);
+}
+
 
 
@@ -459,5 +433,5 @@
  * @param dialogNr: sound nr to be played (from the xml load tags)
  */
-float GenericNPC::talkTo(WorldEntity* worldEntity, int dialogNr)
+void GenericNPC::talkTo(WorldEntity* worldEntity, int dialogNr)
 {}
 
@@ -483,8 +457,83 @@
  * @param time: time in seconds expirded since the last tick
  */
-void GenericNPC::tick (float time)
+void GenericNPC::tick (float dt)
 {
   if( likely(this->getModel(0) != NULL))
-    ((InteractiveModel*)this->getModel(0))->tick(time);
+    ((InteractiveModel*)this->getModel(0))->tick(dt);
+
+
+  if (!this->behaviourList.empty())
+  {
+    GenericNPC::Anim currentAnimation = this->behaviourList.front();
+
+    switch( currentAnimation.type)
+    {
+      case Walk:
+        {
+          Vector dest = currentAnimation.v - this->getAbsCoor();
+          if (dest.len() < .5)
+            this->nextStep();
+          else
+          {
+            dest.y = 0.0f;
+            this->shiftCoor(dest.getNormalized() * currentAnimation.speed * dt);
+
+          }
+        }
+        break;
+
+      case Run:
+      {
+        Vector dest = currentAnimation.v - this->getAbsCoor();
+        if (dest.len() < .5)
+          this->nextStep();
+        else
+        {
+          this->shiftCoor(dest.getNormalized() * currentAnimation.speed * dt);
+        }
+      }
+      break;
+
+      case Crouch:
+      {
+        Vector dest = currentAnimation.v - this->getAbsCoor();
+        if (dest.len() < .5)
+          this->nextStep();
+        else
+        {
+          this->shiftCoor(dest.getNormalized() * currentAnimation.speed * dt);
+        }
+      }
+      break;
+
+      case TurnTo:
+        //Quaternion direction = this->
+        break;
+
+      case LookAt:
+        break;
+
+      case Shoot:
+        break;
+
+      default:
+        break;
+
+    }
+  }
+
+  // physical falling of the player
+  if( !this->isOnGround())
+  {
+    this->fallVelocity += 300.0f * dt;
+    velocity -= Vector(0.0, 1.0, 0.0) * this->fallVelocity;
+   // PRINTF(0)("%s is not on ground\n", this->getName());
+  }
+  else
+  {
+    this->fallVelocity = 0.0f;
+  }
+
+  this->shiftCoor(Vector(0, -this->fallVelocity * dt,0));
 
 }
@@ -495,4 +544,6 @@
 {
   int randi = (int)(5.0f * (float)rand()/(float)RAND_MAX);
+
+  this->setAnimationSpeed(1.0f);
 
   if( randi == 1)
Index: trunk/src/world_entities/npcs/generic_npc.h
===================================================================
--- trunk/src/world_entities/npcs/generic_npc.h	(revision 9002)
+++ trunk/src/world_entities/npcs/generic_npc.h	(revision 9003)
@@ -10,11 +10,6 @@
 #include "npc.h"
 
-#include <string>
 
 #include "sound_source.h"
-
-#include "vector.h"
-#include "quaternion.h"
-
 
 namespace OrxSound{ class SoundSource; }
@@ -27,44 +22,43 @@
 class GenericNPC : public NPC
 {
+
+
  public:
-  GenericNPC();
-  GenericNPC(const TiXmlElement* root);
+  GenericNPC(const TiXmlElement* root = NULL);
   virtual ~GenericNPC ();
 
-  void init();
   virtual void loadParams(const TiXmlElement* root);
 
-  void setAnimation(int animationIndex, int animPlaybackMode);
   /** sets the sound volume to @param vol: volume of the sound */
   inline void setVolume(float vol) { this->soundVolume = vol; }
 
 
-  /* npc controlling functions */
 
+  bool finalGoalReached() { return this->behaviourList.empty(); };
+
+  /* npc controlling functions to be Queued */
   /* walking functions */
-  float walkTo(const Vector& coordinate, const Quaternion& dir);
-  float walkTo(float x, float y, float z);
-  float walkTo(float x, float y, float z, float qu, float qx, float qy, float qz);
-  float walkTo(float x, float y, float qu, float qx, float qy, float qz);
+  void walkTo(const Vector& coordinate);
+  void walkTo(float x, float y, float z);
 
   /* running functions */
-  float runTo(const Vector& coordinate, const Quaternion& dir);
-  float runTo(float x, float y, float z, float qu, float qx, float qy, float qz);
-  float runTo(float x, float y, float qu, float qx, float qy, float qz);
+  void runTo(const Vector& coordinate);
+  void runTo(float x, float y, float z);
 
   /* couching functinos */
-  float crouchTo(const Vector& coordinate, const Quaternion& dir);
-  float crouchTo(float x, float y, float z, float qu, float qx, float qy, float qz);
-  float crouchTo(float x, float y, float qu, float qx, float qy, float qz);
+  void crouchTo(const Vector& coordinate);
+  void crouchTo(float x, float y, float z);
 
   /* stopping the movement */
   void stop();
+  void nextStep();
 
   /* some oriantation functions */
-  float lookAt(WorldEntity* worldEntity);
-  bool turnTo(float qu, float qx, float qy, float qz);
+  void lookAt(WorldEntity* worldEntity);
+  void turnTo(float qu, float qx, float qy, float qz);
+  void turnTo(float degreeInY);
 
   /* talking funcitons*/
-  float talkTo(WorldEntity* worldEntity, int dialogNr);
+  void talkTo(WorldEntity* worldEntity, int dialogNr);
 
   /* shooting functions */
@@ -77,6 +71,4 @@
   void playSound(int i);
 
-  void setTime(float newTime){ this->time = newTime; };
-  
   virtual void tick (float time);
 
@@ -84,10 +76,52 @@
   void destroy();
 
+  private:
+    void init();
+
+    void setAnimation(int animationIndex, int animPlaybackMode);
+    int getAnimation();
+    bool isAnimationFinished();
+    void setAnimationSpeed(float speed);
+
+    void initNPC();
+
 
  private:
+
+   typedef enum {
+    Walk,
+    Run,
+    Crouch,
+    Jump,
+    TurnTo,
+    LookAt,
+    TalkTo,
+
+    Shoot,
+
+
+   } AnimType;
+
+   typedef struct Anim
+   {
+     Vector        v;
+     Quaternion    q;
+
+
+     WorldEntity*  entity;
+     float         speed;
+
+
+     AnimType      type;
+   };
+   typedef std::list<GenericNPC::Anim>     genNPCAnimList;
+
+
+
    OrxSound::SoundSource                   soundSource;
    OrxSound::SoundBuffer*                  soundBuffer;
    float                                   soundVolume;
 
+   std::list<GenericNPC::Anim>             behaviourList;
    Vector                                  destCoor;
    Quaternion                              destDir;
@@ -95,4 +129,5 @@
    Animation3D*                            currentAnim;
    float                                   time;          //!< Duration of the action
+   float                                   fallVelocity;
 };
 
Index: trunk/src/world_entities/npcs/npc.cc
===================================================================
--- trunk/src/world_entities/npcs/npc.cc	(revision 9002)
+++ trunk/src/world_entities/npcs/npc.cc	(revision 9003)
@@ -29,4 +29,5 @@
 
   this->toList(OM_GROUP_00);
+
 }
 
Index: trunk/src/world_entities/npcs/repair_station.cc
===================================================================
--- trunk/src/world_entities/npcs/repair_station.cc	(revision 9003)
+++ trunk/src/world_entities/npcs/repair_station.cc	(revision 9003)
@@ -0,0 +1,197 @@
+
+
+/*
+   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
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+#include "interactive_model.h"
+
+
+#include "repair_station.h"
+#include "class_list.h"
+
+
+using namespace std;
+
+
+CREATE_FACTORY(RepairStation, CL_DOOR);
+
+
+
+//! list of all different animations a std md2model supports
+// sAnim RepairStation::animationList[2] =
+// {
+//  // begin, end, fps, interruptable
+//   {   0,  10,  30,  0 },   //!< OPEN
+//   {   10, 20,  30,  0 }    //!< CLOSE
+// };
+
+
+sAnim RepairStation::animationList[8] =
+{
+ // begin, end, fps, interruptable
+  {   0,  12,  20,  0 },   //!< CYCLE01
+  {   12, 24,  30,  0 },   //!< CYCLE02
+  {   24, 40,  10,  0 },   //!< CYCLE03
+  {   40, 55,  30,  0 },   //!< CYCLE04
+  {   55, 68,  20,  0 },   //!< CYCLE05
+  {   68, 81,  30,  0 },   //!< CYCLE06
+  {   81, 89,  40,  0 },   //!< CYCLE07
+  {   89, 99,  30,  0 }    //!< CYCLE08
+};
+
+
+
+RepairStation::RepairStation ()
+{
+  this->init();
+}
+
+
+RepairStation::RepairStation(const TiXmlElement* root)
+{
+
+  this->setClassID(CL_DOOR, "RepairStation");
+  this->scale = 1.0f;
+
+  if( root != NULL)
+    this->loadParams(root);
+
+  this->toList(OM_COMMON);
+
+  this->bActivated = true;
+  this->animationStep = 1;
+  this->animationCurrent = REPAIR_CYCLE01;
+
+  this->loadMD2Texture("maps/repairstation.jpg");
+  this->loadModel("models/creatures/repairstation.md2", this->scale);
+
+  this->setAnimation(REPAIR_CYCLE01, MD2_ANIM_ONCE);
+}
+
+
+RepairStation::~RepairStation ()
+{}
+
+
+
+/**
+ * loads the Settings of a MD2Creature from an XML-element.
+ * @param root the XML-element to load the MD2Creature's properties from
+ */
+void RepairStation::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "scale", this, RepairStation, setScale)
+      .describe("sets the scale of the repair station")
+      .defaultValues(1.0);
+}
+
+
+/**
+ * sets the animatin of this entity
+ */
+void  RepairStation::setAnimation(int animNum, int playbackMode)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->setAnimation(animationList[animNum].firstFrame,
+                                                         animationList[animNum].lastFrame,
+                                                         animationList[animNum].fps,
+                                                         animationList[animNum].bStoppable,
+                                                         playbackMode);
+}
+
+
+/**
+ * @returns the current animation number
+ */
+int RepairStation::getAnimation()
+{
+  if( likely(this->getModel(0) != NULL))
+    return ((InteractiveModel*)this->getModel(0))->getAnimation();
+  else
+    return -1;
+}
+
+
+
+/**
+ * @returns true if animation is finished
+ */
+bool RepairStation::isAnimationFinished()
+{
+  if( likely(this->getModel(0) != NULL))
+    return ((InteractiveModel*)this->getModel(0))->isAnimationFinished();
+  else
+    return false;
+}
+
+
+/**
+ * this activates the repair station and makes it working
+ */
+void RepairStation::activate()
+{
+  this->animationStep = 1;
+  this->bActivated = true;
+}
+
+
+/**
+ * this deactivates the repair station
+ */
+void RepairStation::deactivate()
+{
+  this->animationStep = 0;
+  this->bActivated = false;
+}
+
+
+/**
+ * this toggles the rotation direction
+ */
+void RepairStation::toggleRotation()
+{
+  this->animationStep *= -1;
+}
+
+
+/**
+ * ticks the door
+ * @param time: time since last tick
+ */
+void RepairStation::tick (float time)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->tick(time);
+
+  if( !this->bActivated)
+    return;
+
+  if( this->isAnimationFinished())
+  {
+    this->animationCurrent = (this->animationCurrent + this->animationStep) % REPAIR_MAX_ANIMATIONS;
+    this->setAnimation( this->animationCurrent, MD2_ANIM_ONCE);
+  }
+}
+
+
+
+
Index: trunk/src/world_entities/npcs/repair_station.h
===================================================================
--- trunk/src/world_entities/npcs/repair_station.h	(revision 9003)
+++ trunk/src/world_entities/npcs/repair_station.h	(revision 9003)
@@ -0,0 +1,63 @@
+#ifndef _REPAIR_STATION_H
+#define _REPAIR_STATION_H
+
+#include "world_entity.h"
+
+#include "md2/md2Model.h"
+
+class TiXmlElement;
+
+
+//! animation names enumeration
+typedef enum RepairStationAnimType
+{
+  REPAIR_CYCLE01 = 0,
+  REPAIR_CYCLE02,
+  REPAIR_CYCLE03,
+  REPAIR_CYCLE04,
+  REPAIR_CYCLE05,
+  REPAIR_CYCLE06,
+  REPAIR_CYCLE07,
+  REPAIR_CYCLE08,
+
+  REPAIR_MAX_ANIMATIONS
+};
+
+
+class RepairStation : public WorldEntity
+{
+  public:
+    RepairStation ();
+    RepairStation(const TiXmlElement* root);
+    virtual ~RepairStation ();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    void setScale(float scale) { this->scale = scale; }
+
+    void activate();
+    void deactivate();
+    void toggleRotation();
+
+    virtual void tick (float time);
+
+
+  private:
+    void setAnimation(int animNum, int playbackMode = 0);
+    int getAnimation();
+    bool isAnimationFinished();
+
+
+  private:
+    float          scale;             //!< the scale of the model
+
+    static sAnim   animationList[8];  //!< list of the animations
+
+    int            animationCurrent;  //!< number of the current animation
+    int            animationStep;     //!< the incrementation step of the animation
+
+    bool           bActivated;        //!< true if activated
+
+};
+
+#endif /* _REPAIR_STATION_H */
Index: trunk/src/world_entities/script_trigger.cc
===================================================================
--- trunk/src/world_entities/script_trigger.cc	(revision 9002)
+++ trunk/src/world_entities/script_trigger.cc	(revision 9003)
@@ -14,5 +14,4 @@
 */
 
-
 #include "script_trigger.h"
 #include "class_list.h"
@@ -23,8 +22,18 @@
 
 CREATE_SCRIPTABLE_CLASS(ScriptTrigger, CL_SCRIPT_TRIGGER,
-                            addMethod("setAbsCoor", ExecutorLua3<PNode,float,float,float>(&PNode::setAbsCoor))
-                            ->addMethod("getAbsCoorX", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorX))
-                            ->addMethod("getAbsCoorY", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorY))
-                            ->addMethod("getAbsCoorZ", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorZ))
+                          //Position
+                     addMethod("setAbsCoor", ExecutorLua3<PNode,float,float,float>(&PNode::setAbsCoor))
+                     ->addMethod("getAbsCoorX", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorX))
+                     ->addMethod("getAbsCoorY", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorY))
+                     ->addMethod("getAbsCoorZ", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorZ))
+                     //Set values
+                    // ->addMethod("setTarget", ExecutorLua1<ScriptTrigger, std::string >(&ScriptTrigger::setTarget))
+                    // ->addMethod("setTriggerParent", ExecutorLua1<ScriptTrigger, std::string >(&ScriptTrigger::setTriggerParent))
+                     ->addMethod("setTriggerLasts", ExecutorLua1<ScriptTrigger, bool >(&ScriptTrigger::setTriggerLasts))
+                     ->addMethod("setInvert", ExecutorLua1<ScriptTrigger, bool >(&ScriptTrigger::setInvert))
+                     ->addMethod("setRadius", ExecutorLua1<ScriptTrigger, float >(&ScriptTrigger::setRadius))
+                     //->addMethod("setScript", ExecutorLua1<ScriptTrigger, std::string >(&ScriptTrigger::setScript))
+                     //->addMethod("setFunction", ExecutorLua1<ScriptTrigger, std::string >(&ScriptTrigger::setFunction))
+                     ->addMethod("setDebugDraw", ExecutorLua1<ScriptTrigger, bool >(&ScriptTrigger::setInvert))
                        );
 
@@ -92,7 +101,4 @@
     LoadParam(root, "radius", this, ScriptTrigger, setRadius)
         .describe("the fileName of the script, that should be triggered by this script trigger")
-        .defaultValues(0);
-    LoadParam(root, "delay", this, ScriptTrigger, setDelay)
-        .describe("the delay after which the funtion sould be triggered")
         .defaultValues(0);
     LoadParam(root, "worldentity", this, ScriptTrigger, setTarget)
Index: trunk/src/world_entities/script_trigger.h
===================================================================
--- trunk/src/world_entities/script_trigger.h	(revision 9002)
+++ trunk/src/world_entities/script_trigger.h	(revision 9003)
@@ -38,5 +38,4 @@
     void setInvert(const bool inv) { this->invert = invert; }
     void setRadius(const float radius) { if(radius>0) this->radius = radius; }
-    void setDelay(const float time){if(delay>0) this->delay = delay; }
     void setScript(const std::string& file);
     void setFunction(const std::string& function){ this->functionName = function;}
Index: trunk/src/world_entities/test_entity.cc
===================================================================
--- trunk/src/world_entities/test_entity.cc	(revision 9002)
+++ trunk/src/world_entities/test_entity.cc	(revision 9003)
@@ -37,4 +37,13 @@
 
 CREATE_FACTORY(TestEntity, CL_TEST_ENTITY);
+
+#include "script_class.h"
+CREATE_SCRIPTABLE_CLASS(TestEntity, CL_TEST_ENTITY,
+                            addMethod("setAbsCoor", ExecutorLua3<PNode,float,float,float>(&PNode::setAbsCoor))
+                            ->addMethod("getAbsCoorX", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorX))
+                            ->addMethod("getAbsCoorY", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorY))
+                            ->addMethod("getAbsCoorZ", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorZ))
+                            
+                       );
 
 
Index: trunk/src/world_entities/weapons/fps_sniper_rifle.cc
===================================================================
--- trunk/src/world_entities/weapons/fps_sniper_rifle.cc	(revision 9002)
+++ trunk/src/world_entities/weapons/fps_sniper_rifle.cc	(revision 9003)
@@ -67,4 +67,6 @@
 {
   // model will be deleted from WorldEntity-destructor
+  if( this->material != NULL)
+    delete this->material;
 }
 
@@ -74,5 +76,9 @@
   this->setClassID(CL_FPS_SNIPER_RIFLE, "FPSSniperRifle");
 
-  this->loadModel("models/guns/fps_sniper_rifle.obj", 0.1);
+  this->loadModel("models/guns/fps_sniper_rifle.obj", 0.2);
+  this->material = new Material();
+  this->material->setIllum(3);
+  this->material->setAmbient(1.0, 1.0, 1.0);
+  this->material->setDiffuseMap("maps/rifle01tex.jpg");
 
   this->setStateDuration(WS_SHOOTING, .1);
@@ -149,2 +155,31 @@
 
 
+
+
+/**
+ *  this will draw the weapon
+ */
+void FPSSniperRifle::draw () const
+{
+  /* draw gun body */
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  if( this->leftRight == W_RIGHT)
+    glScalef(1.0, 1.0, -1.0);
+
+  this->material->select();
+  static_cast<StaticModel*>(this->getModel())->draw();
+
+  glPopMatrix();
+
+}
+
+
+
Index: trunk/src/world_entities/weapons/fps_sniper_rifle.h
===================================================================
--- trunk/src/world_entities/weapons/fps_sniper_rifle.h	(revision 9002)
+++ trunk/src/world_entities/weapons/fps_sniper_rifle.h	(revision 9003)
@@ -35,4 +35,6 @@
 
 
+class Material;
+
 class FPSSniperRifle : public Weapon
   {
@@ -50,7 +52,11 @@
     virtual void fire();
 
+    virtual void draw() const;
+
+
 
   private:
-    int leftRight;   // this will become an enum
+    int              leftRight;   //!< this will become an enum
+    Material*        material;    //!< material
 
   };
Index: trunk/src/world_entities/world_entity.cc
===================================================================
--- trunk/src/world_entities/world_entity.cc	(revision 9002)
+++ trunk/src/world_entities/world_entity.cc	(revision 9003)
@@ -72,4 +72,5 @@
 
   this->objectListNumber = OM_INIT;
+  this->lastObjectListNumber = OM_INIT;
   this->objectListIterator = NULL;
 
@@ -78,4 +79,5 @@
     this->collisionHandles[i] = NULL;
   this->bReactive = false;
+  this->bOnGround = false;
 
   // registering default reactions:
@@ -613,6 +615,6 @@
     }
 
-    if( this->aabbNode != NULL)
-      this->aabbNode->drawBV(0, DRAW_BV_POLYGON, Vector(1, 0.6, 0.2), true);
+//     if( this->aabbNode != NULL)
+//       this->aabbNode->drawBV(0, DRAW_BV_POLYGON, Vector(1, 0.6, 0.2), true);
 
     glPopMatrix();
Index: trunk/src/world_entities/world_entity.h
===================================================================
--- trunk/src/world_entities/world_entity.h	(revision 9002)
+++ trunk/src/world_entities/world_entity.h	(revision 9003)
@@ -94,4 +94,9 @@
   CollisionHandle* getCollisionHandle(CREngine::CRType type) const { return this->collisionHandles[type]; }
 
+  /** @returns true if this entity is standing on ground (BSP model) */
+  bool isOnGround() const { return this->bOnGround; }
+  /** @param flag: marks if this entity is standing on ground */
+  void setOnGround(bool flag) { this->bOnGround = flag; }
+
   virtual void hit(float damage);
   virtual void destroy();
@@ -117,5 +122,5 @@
 
   void hide() { if( this->objectListNumber != OM_DEAD) this->lastObjectListNumber = this->objectListNumber; this->toList(OM_DEAD); }
-  void unhide() { this->toList(this->lastObjectListNumber); }
+  void unhide() { if( this->objectListNumber != this->lastObjectListNumber) this->toList(this->lastObjectListNumber); }
 
 
@@ -194,5 +199,5 @@
 
   PhysicsInterface        physicsInterface;                //!< the physics object of the WorldEntity
-
+  bool                    bOnGround;                       //!< true if this entity is standing on the ground
 
   protected:
