Index: code/trunk/src/orxonox/worldentities/pawns/Pawn.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/Pawn.cc	(revision 8351)
+++ code/trunk/src/orxonox/worldentities/pawns/Pawn.cc	(revision 8706)
@@ -23,5 +23,5 @@
  *      Fabian 'x3n' Landau
  *   Co-authors:
- *      ...
+ *      Simon Miescher
  *
  */
@@ -64,6 +64,13 @@
         this->maxHealth_ = 0;
         this->initialHealth_ = 0;
+
         this->shieldHealth_ = 0;
+        this->initialShieldHealth_ = 0;
+        this->maxShieldHealth_ = 100; //otherwise shield might increase to float_max
         this->shieldAbsorption_ = 0.5;
+
+        this->reloadRate_ = 0;
+        this->reloadWaitTime_ = 1.0f;
+        this->reloadWaitCountdown_ = 0;
 
         this->lastHitOriginator_ = 0;
@@ -109,4 +116,6 @@
 
         XMLPortParam(Pawn, "shieldhealth", setShieldHealth, getShieldHealth, xmlelement, mode).defaultValues(0);
+        XMLPortParam(Pawn, "initialshieldhealth", setInitialShieldHealth, getInitialShieldHealth, xmlelement, mode).defaultValues(0);
+        XMLPortParam(Pawn, "maxshieldhealth", setMaxShieldHealth, getMaxShieldHealth, xmlelement, mode).defaultValues(100);
         XMLPortParam(Pawn, "shieldabsorption", setShieldAbsorption, getShieldAbsorption, xmlelement, mode).defaultValues(0);
 
@@ -118,4 +127,7 @@
         XMLPortObject(Pawn, WeaponSet, "weaponsets", addWeaponSet, getWeaponSet, xmlelement, mode);
         XMLPortObject(Pawn, WeaponPack, "weapons", addWeaponPackXML, getWeaponPack, xmlelement, mode);
+
+        XMLPortParam(Pawn, "reloadrate", setReloadRate, getReloadRate, xmlelement, mode).defaultValues(0);
+        XMLPortParam(Pawn, "reloadwaittime", setReloadWaitTime, getReloadWaitTime, xmlelement, mode).defaultValues(1.0f);
     }
 
@@ -124,6 +136,7 @@
         registerVariable(this->bAlive_,           VariableDirection::ToClient);
         registerVariable(this->health_,           VariableDirection::ToClient);
-        registerVariable(this->initialHealth_,    VariableDirection::ToClient);
+        registerVariable(this->maxHealth_,        VariableDirection::ToClient);
         registerVariable(this->shieldHealth_,     VariableDirection::ToClient);
+        registerVariable(this->maxShieldHealth_,  VariableDirection::ToClient);
         registerVariable(this->shieldAbsorption_, VariableDirection::ToClient);
         registerVariable(this->bReload_,          VariableDirection::ToServer);
@@ -137,10 +150,23 @@
         this->bReload_ = false;
 
+        // TODO: use the existing timer functions instead
+        if(this->reloadWaitCountdown_ > 0)
+        {
+            this->decreaseReloadCountdownTime(dt);
+        }
+        else
+        {
+            this->addShieldHealth(this->getReloadRate() * dt);
+            this->resetReloadCountdown();
+        }
+
         if (GameMode::isMaster())
+        {
             if (this->health_ <= 0 && bAlive_)
             {
-                this->fireEvent(); // Event to notify anyone who want's to know about the death.
+                this->fireEvent(); // Event to notify anyone who wants to know about the death.
                 this->death();
             }
+        }
     }
 
@@ -168,60 +194,88 @@
     }
 
+
     void Pawn::setHealth(float health)
     {
-        this->health_ = std::min(health, this->maxHealth_);
-    }
-
-    void Pawn::damage(float damage, Pawn* originator)
+        this->health_ = std::min(health, this->maxHealth_); //Health can't be set to a value bigger than maxHealth, otherwise it will be reduced at first hit
+    }
+
+    void Pawn::setShieldHealth(float shieldHealth)
+    {
+        this->shieldHealth_ = std::min(shieldHealth, this->maxShieldHealth_);
+    }
+
+    void Pawn::setMaxShieldHealth(float maxshieldhealth)
+    {
+        this->maxShieldHealth_ = maxshieldhealth;
+    }
+
+    void Pawn::setReloadRate(float reloadrate)
+    {
+        this->reloadRate_ = reloadrate;
+    }
+
+    void Pawn::setReloadWaitTime(float reloadwaittime)
+    {
+        this->reloadWaitTime_ = reloadwaittime;
+    }
+
+    void Pawn::decreaseReloadCountdownTime(float dt)
+    {
+        this->reloadWaitCountdown_ -= dt;
+    }
+
+    void Pawn::damage(float damage, float healthdamage, float shielddamage, Pawn* originator)
     {
         if (this->getGametype() && this->getGametype()->allowPawnDamage(this, originator))
         {
-            //share the dealt damage to the shield and the Pawn.
-            float shielddamage = damage*this->shieldAbsorption_;
-            float healthdamage = damage*(1-this->shieldAbsorption_);
-
-            // In case the shield can not take all the shield damage.
-            if (shielddamage > this->getShieldHealth())
+            if (shielddamage >= this->getShieldHealth())
             {
-                healthdamage += shielddamage-this->getShieldHealth();
                 this->setShieldHealth(0);
+                this->setHealth(this->health_ - (healthdamage + damage));
             }
-
-            this->setHealth(this->health_ - healthdamage);
-
-            if (this->getShieldHealth() > 0)
+            else
             {
                 this->setShieldHealth(this->shieldHealth_ - shielddamage);
+
+                // remove remaining shieldAbsorpton-Part of damage from shield
+                shielddamage = damage * this->shieldAbsorption_;
+                shielddamage = std::min(this->getShieldHealth(),shielddamage);
+                this->setShieldHealth(this->shieldHealth_ - shielddamage);
+
+                // set remaining damage to health
+                this->setHealth(this->health_ - (damage - shielddamage) - healthdamage);
             }
 
             this->lastHitOriginator_ = originator;
-
-            // play damage effect
-        }
-    }
-
-    void Pawn::hit(Pawn* originator, const Vector3& force, float damage)
+        }
+    }
+
+// TODO: Still valid?
+/* HIT-Funktionen
+    Die hit-Funktionen muessen auch in src/orxonox/controllers/Controller.h angepasst werden! (Visuelle Effekte)
+
+*/
+
+    void Pawn::hit(Pawn* originator, const Vector3& force, float damage, float healthdamage, float shielddamage)
     {
         if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
         {
-            this->damage(damage, originator);
+            this->damage(damage, healthdamage, shielddamage, originator);
             this->setVelocity(this->getVelocity() + force);
-
-            // play hit effect
-        }
-    }
-
-    void Pawn::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
+        }
+    }
+
+
+    void Pawn::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage, float healthdamage, float shielddamage)
     {
         if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
         {
-            this->damage(damage, originator);
+            this->damage(damage, healthdamage, shielddamage, originator);
 
             if ( this->getController() )
-                this->getController()->hit(originator, contactpoint, damage);
-
-            // play hit effect
-        }
-    }
+                this->getController()->hit(originator, contactpoint, damage); // changed to damage, why shielddamage?
+        }
+    }
+
 
     void Pawn::kill()
Index: code/trunk/src/orxonox/worldentities/pawns/Pawn.h
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/Pawn.h	(revision 8351)
+++ code/trunk/src/orxonox/worldentities/pawns/Pawn.h	(revision 8706)
@@ -72,8 +72,28 @@
                 { return this->initialHealth_; }
 
-            inline void setShieldHealth(float shieldHealth)
-            { this->shieldHealth_ = shieldHealth; }
+            virtual void setShieldHealth(float shieldHealth);
+
             inline float getShieldHealth()
             { return this->shieldHealth_; }
+
+            inline void addShieldHealth(float amount)
+            { this->setShieldHealth(this->shieldHealth_ + amount); }
+
+            inline bool hasShield()
+            { return (this->getShieldHealth() > 0); }
+
+            virtual void setMaxShieldHealth(float maxshieldhealth);
+            inline float getMaxShieldHealth() const
+                { return this->maxShieldHealth_; }
+
+            inline void setInitialShieldHealth(float initialshieldhealth)
+                { this->initialShieldHealth_ = initialshieldhealth; this->setShieldHealth(initialshieldhealth); }
+            inline float getInitialShieldHealth() const
+                { return this->initialShieldHealth_; }
+
+            inline void restoreInitialShieldHealth()
+                { this->setShieldHealth(this->initialShieldHealth_); }
+            inline void restoreMaxShieldHealth()
+                { this->setShieldHealth(this->maxShieldHealth_); }
 
             inline void setShieldAbsorption(float shieldAbsorption)
@@ -82,9 +102,29 @@
             { return this->shieldAbsorption_; }
 
+            // TODO: Rename to shieldRechargeRate
+            virtual void setReloadRate(float reloadrate);
+            inline float getReloadRate() const
+                { return this->reloadRate_; }
+
+            virtual void setReloadWaitTime(float reloadwaittime);
+            inline float getReloadWaitTime() const
+                { return this->reloadWaitTime_; }
+
+            inline void resetReloadCountdown()
+            { this->reloadWaitCountdown_ = 0; }
+
+            inline void startReloadCountdown()
+            { this->reloadWaitCountdown_ = this->getReloadWaitTime(); } // TODO: Implement in Projectile.cc
+
+            virtual void decreaseReloadCountdownTime(float dt);
+
             inline ControllableEntity* getLastHitOriginator() const
                 { return this->lastHitOriginator_; }
 
-            virtual void hit(Pawn* originator, const Vector3& force, float damage);
-            virtual void hit(Pawn* originator, btManifoldPoint& contactpoint, float damage);
+            //virtual void hit(Pawn* originator, const Vector3& force, float damage);
+            //virtual void hit(Pawn* originator, btManifoldPoint& contactpoint, float damage);
+            virtual void hit(Pawn* originator, const Vector3& force, float damage, float healthdamage = 0.0f, float shielddamage = 0.0f);
+            virtual void hit(Pawn* originator, btManifoldPoint& contactpoint, float damage, float healthdamage = 0.0f, float shielddamage = 0.0f);
+
             virtual void kill();
 
@@ -142,5 +182,6 @@
             virtual void spawneffect();
 
-            virtual void damage(float damage, Pawn* originator = 0);
+            //virtual void damage(float damage, Pawn* originator = 0);
+            virtual void damage(float damage, float healthdamage = 0.0f, float shielddamage = 0.0f, Pawn* originator = NULL);
 
             bool bAlive_;
@@ -154,6 +195,12 @@
             float maxHealth_;
             float initialHealth_;
+            
             float shieldHealth_;
+            float maxShieldHealth_;
+            float initialShieldHealth_;
             float shieldAbsorption_; // Has to be between 0 and 1
+            float reloadRate_;
+            float reloadWaitTime_;
+            float reloadWaitCountdown_;
 
             WeakPtr<Pawn> lastHitOriginator_;
Index: code/trunk/src/orxonox/worldentities/pawns/SpaceShip.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/SpaceShip.cc	(revision 8351)
+++ code/trunk/src/orxonox/worldentities/pawns/SpaceShip.cc	(revision 8706)
@@ -35,5 +35,13 @@
 #include "core/Template.h"
 #include "core/XMLPort.h"
+#include "tools/Shader.h"
+#include "util/Debug.h" // TODO: Needed?
+#include "util/Math.h"
+
+#include "graphics/Camera.h"
 #include "items/Engine.h"
+
+#include "CameraManager.h"
+#include "Scene.h"
 
 namespace orxonox
@@ -42,5 +50,5 @@
     CreateFactory(SpaceShip);
 
-    SpaceShip::SpaceShip(BaseObject* creator) : Pawn(creator)
+    SpaceShip::SpaceShip(BaseObject* creator) : Pawn(creator), boostBlur_(NULL)
     {
         RegisterObject(SpaceShip);
@@ -53,7 +61,5 @@
         this->localAngularAcceleration_.setValue(0, 0, 0);
         this->bBoost_ = false;
-        this->bPermanentBoost_ = false;
         this->steering_ = Vector3::ZERO;
-        this->engine_ = 0;
 
         this->boostPower_ = 10.0f;
@@ -64,4 +70,7 @@
         this->bBoostCooldown_ = false;
 
+        this->lift_ = 1.0f;                         // factor of the lift, standard is 1
+        this->stallSpeed_ = 220.0f;                 // max speed where lift is added
+
         this->bInvertYAxis_ = false;
 
@@ -74,12 +83,25 @@
         this->enableCollisionCallback();
 
+        this->engineTicksNotDone = 0;
         this->setConfigValues();
         this->registerVariables();
+        
+        this->cameraOriginalPosition_ = Vector3::UNIT_SCALE;
+        this->cameraOriginalOrientation_ = Quaternion::IDENTITY;
+
+        this->shakeFrequency_ = 15;
+        this->shakeAmplitude_ = 5;
+        this->shakeDt_ = 0;
     }
 
     SpaceShip::~SpaceShip()
     {
-        if (this->isInitialized() && this->engine_)
-            this->engine_->destroy();
+        if (this->isInitialized())
+        {
+            this->removeAllEngines();
+        
+            if (this->boostBlur_)
+                this->boostBlur_->destroy();
+        }
     }
 
@@ -88,5 +110,5 @@
         SUPER(SpaceShip, XMLPort, xmlelement, mode);
 
-        XMLPortParam(SpaceShip, "engine",            setEngineTemplate,    getEngineTemplate,    xmlelement, mode);
+        //XMLPortParam(SpaceShip, "engine",            setEngineTemplate,    getEngineTemplate,    xmlelement, mode);
         XMLPortParamVariable(SpaceShip, "primaryThrust",  primaryThrust_,  xmlelement, mode);
         XMLPortParamVariable(SpaceShip, "auxilaryThrust", auxilaryThrust_, xmlelement, mode);
@@ -96,4 +118,10 @@
         XMLPortParamVariable(SpaceShip, "boostRate", boostRate_, xmlelement, mode);
         XMLPortParamVariable(SpaceShip, "boostCooldownDuration", boostCooldownDuration_, xmlelement, mode);
+        XMLPortParamVariable(SpaceShip, "shakeFrequency", shakeFrequency_, xmlelement, mode);
+        XMLPortParamVariable(SpaceShip, "shakeAmplitude", shakeAmplitude_, xmlelement, mode);
+        XMLPortParamVariable(SpaceShip, "lift", lift_, xmlelement, mode);
+        XMLPortParamVariable(SpaceShip, "stallSpeed", stallSpeed_, xmlelement, mode);
+
+        XMLPortObject(SpaceShip, Engine, "engines", addEngine, getEngine, xmlelement, mode);
     }
 
@@ -103,4 +131,13 @@
         registerVariable(this->auxilaryThrust_, VariableDirection::ToClient);
         registerVariable(this->rotationThrust_, VariableDirection::ToClient);
+        // TODO: Synchronization of boost needed?
+        registerVariable(this->boostPower_, VariableDirection::ToClient);
+        registerVariable(this->boostPowerRate_, VariableDirection::ToClient);
+        registerVariable(this->boostRate_, VariableDirection::ToClient);
+        registerVariable(this->boostCooldownDuration_, VariableDirection::ToClient);
+        registerVariable(this->shakeFrequency_, VariableDirection::ToClient);
+        registerVariable(this->shakeAmplitude_, VariableDirection::ToClient);
+        registerVariable(this->lift_, VariableDirection::ToClient);
+        registerVariable(this->stallSpeed_, VariableDirection::ToClient);
     }
 
@@ -108,4 +145,10 @@
     {
         SetConfigValue(bInvertYAxis_, false).description("Set this to true for joystick-like mouse behaviour (mouse up = ship down).");
+        
+        SetConfigValueExternal(bEnableMotionBlur_, "GraphicsSettings", "enableMotionBlur", true)
+            .description("Enable or disable the motion blur effect when moving very fast")
+            .callback(this, &SpaceShip::changedEnableMotionBlur);
+        SetConfigValueExternal(blurStrength_, "GraphicsSettings", "blurStrength", 3.0f)
+            .description("Defines the strength of the motion blur effect");
     }
 
@@ -128,14 +171,5 @@
         if (this->hasLocalController())
         {
-/*
-            this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() * getMass() * this->auxilaryThrust_);
-            this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() * getMass() * this->auxilaryThrust_);
-            if (this->localLinearAcceleration_.z() > 0)
-                this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->auxilaryThrust_);
-            else
-                this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->primaryThrust_);
-            this->physicalBody_->applyCentralForce(physicalBody_->getWorldTransform().getBasis() * this->localLinearAcceleration_);
-            this->localLinearAcceleration_.setValue(0, 0, 0);
-*/
+            // Handle mouse look
             if (!this->isInMouseLook())
             {
@@ -143,11 +177,12 @@
                 this->physicalBody_->applyTorque(physicalBody_->getWorldTransform().getBasis() * this->localAngularAcceleration_);
             }
-
             this->localAngularAcceleration_.setValue(0, 0, 0);
 
+            // Charge boostPower
             if(!this->bBoostCooldown_ && this->boostPower_ < this->initialBoostPower_)
             {
                 this->boostPower_ += this->boostPowerRate_*dt;
             }
+            // Use boostPower
             if(this->bBoost_)
             {
@@ -155,9 +190,103 @@
                 if(this->boostPower_ <= 0.0f)
                 {
-                    this->bBoost_ = false;
+                    this->boost(false);
                     this->bBoostCooldown_ = true;
                     this->timer_.setTimer(this->boostCooldownDuration_, false, createExecutor(createFunctor(&SpaceShip::boostCooledDown, this)));
                 }
-            }
+
+                this->shakeCamera(dt);
+            }
+
+            // Enable Blur depending on settings
+            if (this->bEnableMotionBlur_ && !this->boostBlur_ && this->hasLocalController() && this->hasHumanController())
+            {
+                this->boostBlur_ = new Shader(this->getScene()->getSceneManager());
+                this->boostBlur_->setCompositorName("Radial Blur");
+            }
+
+            if (this->boostBlur_) // && this->maxSpeedFront_ != 0 && this->boostFactor_ != 1)
+            {
+                // TODO: this->maxSpeedFront_ gets fastest engine
+                float blur = this->blurStrength_ * clamp((-this->getLocalVelocity().z - 0.0f /*this->maxSpeedFront_*/) / ((150.0f /*boostFactor_*/ - 1) * 1.5f /*this->maxSpeedFront_*/), 0.0f, 1.0f);
+
+                // Show and hide blur effect depending on state of booster
+                if(this->bBoost_)
+                    this->boostBlur_->setVisible(blur > 0);
+                else
+                    this->boostBlur_->setVisible(false);
+
+                this->boostBlur_->setParameter(0, 0, "sampleStrength", blur);
+            }
+        }
+    }
+
+    void SpaceShip::moveFrontBack(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() - value.x);
+        this->steering_.z -= value.x;
+    }
+
+    void SpaceShip::moveRightLeft(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() + value.x);
+        this->steering_.x += value.x;
+    }
+
+    void SpaceShip::moveUpDown(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() + value.x);
+        this->steering_.y += value.x;
+    }
+
+    void SpaceShip::rotateYaw(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setY(this->localAngularAcceleration_.y() + value.x);
+
+        Pawn::rotateYaw(value);
+
+        //This function call adds a lift to the ship when it is rotating to make it's movement more "realistic" and enhance the feeling.
+        if (abs(this-> getLocalVelocity().z) < stallSpeed_)  {this->moveRightLeft(-lift_ / 5 * value * sqrt(abs(this-> getLocalVelocity().z)));}
+    }
+
+    void SpaceShip::rotatePitch(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setX(this->localAngularAcceleration_.x() + value.x*0.8f);
+
+        Pawn::rotatePitch(value);
+
+        //This function call adds a lift to the ship when it is pitching to make it's movement more "realistic" and enhance the feeling.
+        if (abs(this-> getLocalVelocity().z) < stallSpeed_)  {this->moveUpDown(lift_ / 5 * value * sqrt(abs(this-> getLocalVelocity().z)));}
+    }
+
+    void SpaceShip::rotateRoll(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setZ(this->localAngularAcceleration_.z() + value.x);
+
+        Pawn::rotateRoll(value);
+    }
+
+    void SpaceShip::fire()
+    {
+    }
+
+    /**
+    @brief
+        Starts or stops boosting.
+    @param bBoost
+        Whether to start or stop boosting.
+    */
+    void SpaceShip::boost(bool bBoost)
+    {
+        if(bBoost && !this->bBoostCooldown_)
+        {
+            this->bBoost_ = true;
+            Camera* camera = CameraManager::getInstance().getActiveCamera();
+            this->cameraOriginalPosition_ = camera->getPosition();
+            this->cameraOriginalOrientation_ = camera->getOrientation();
+        }
+        if(!bBoost)
+        {
+            this->bBoost_ = false;
+            this->resetCamera();
         }
     }
@@ -167,102 +296,132 @@
         this->bBoostCooldown_ = false;
     }
-
-    void SpaceShip::moveFrontBack(const Vector2& value)
-    {
-        this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() - value.x);
-        this->steering_.z = -value.x;
-    }
-
-    void SpaceShip::moveRightLeft(const Vector2& value)
-    {
-        this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() + value.x);
-        this->steering_.x = value.x;
-    }
-
-    void SpaceShip::moveUpDown(const Vector2& value)
-    {
-        this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() + value.x);
-        this->steering_.y = value.x;
-    }
-
-    void SpaceShip::rotateYaw(const Vector2& value)
-    {
-        this->localAngularAcceleration_.setY(this->localAngularAcceleration_.y() + value.x);
-
-        Pawn::rotateYaw(value);
-    }
-
-    void SpaceShip::rotatePitch(const Vector2& value)
-    {
-        this->localAngularAcceleration_.setX(this->localAngularAcceleration_.x() + value.x);
-
-        Pawn::rotatePitch(value);
-    }
-
-    void SpaceShip::rotateRoll(const Vector2& value)
-    {
-        this->localAngularAcceleration_.setZ(this->localAngularAcceleration_.z() + value.x);
-
-        Pawn::rotateRoll(value);
-    }
-
-    // TODO: something seems to call this function every tick, could probably handled a little more efficiently!
-    void SpaceShip::setBoost(bool bBoost)
-    {
-        if(bBoost == this->bBoost_)
+    
+    void SpaceShip::shakeCamera(float dt)
+    {
+        //make sure the ship is only shaking if it's moving
+        if (this->getVelocity().squaredLength() > 80.0f)
+        {
+            this->shakeDt_ += dt;
+    
+            float frequency = this->shakeFrequency_ * (this->getVelocity().squaredLength());
+    
+            if (this->shakeDt_ >= 1.0f/frequency)
+            {
+                this->shakeDt_ -= 1.0f/frequency;
+            }
+    
+            Degree angle = Degree(sin(this->shakeDt_ *2.0f* math::pi * frequency) * this->shakeAmplitude_);
+    
+            //COUT(0) << "Angle: " << angle << std::endl;
+            Camera* camera = this->getCamera();
+
+            //Shaking Camera effect
+            if (camera != 0)
+            {
+                camera->setOrientation(Vector3::UNIT_X, angle);
+            }
+        }
+    }
+
+    void SpaceShip::resetCamera()
+    {
+        Camera *camera = this->getCamera();
+
+        if (camera == 0)
+        {
+            COUT(2) << "Failed to reset camera!";
             return;
-
-        if(bBoost)
-            this->boost();
+        }
+    
+        this->shakeDt_ = 0;
+        camera->setPosition(this->cameraOriginalPosition_);
+        camera->setOrientation(this->cameraOriginalOrientation_);
+    }
+
+    void SpaceShip::backupCamera()
+    {
+        Camera* camera = CameraManager::getInstance().getActiveCamera();
+        if(camera != NULL)
+        {
+            this->cameraOriginalPosition_ = camera->getPosition();
+            this->cameraOriginalOrientation_ = camera->getOrientation();
+        }
+    }
+
+    void SpaceShip::addEngine(orxonox::Engine* engine)
+    {
+        //COUT(0)<<"Adding an Engine: " << engine << endl;
+        this->engineList_.push_back(engine);
+        engine->addToSpaceShip(this);
+        this->resetEngineTicks();
+    }
+
+    bool SpaceShip::hasEngine(Engine* engine)
+    {
+        for(unsigned int i=0; i<this->engineList_.size(); i++)
+        {
+            if(this->engineList_[i]==engine)
+                return true;
+        }
+        return false;
+    }
+
+    Engine* SpaceShip::getEngine(unsigned int i)
+    {
+        if(this->engineList_.size()>=i)
+            return 0;
         else
-        {
-            this->bBoost_ = false;
-        }
-    }
-
-    void SpaceShip::fire()
-    {
-    }
-
-    void SpaceShip::boost()
-    {
-        if(!this->bBoostCooldown_)
-            this->bBoost_ = true;
-    }
-
-    void SpaceShip::loadEngineTemplate()
-    {
-        if (!this->enginetemplate_.empty())
-        {
-            Template* temp = Template::getTemplate(this->enginetemplate_);
-
-            if (temp)
-            {
-                Identifier* identifier = temp->getBaseclassIdentifier();
-
-                if (identifier)
-                {
-                    BaseObject* object = identifier->fabricate(this);
-                    this->engine_ = orxonox_cast<Engine*>(object);
-
-                    if (this->engine_)
-                    {
-                        this->engine_->addTemplate(temp);
-                        this->engine_->addToSpaceShip(this);
-                    }
-                    else
-                    {
-                        object->destroy();
-                    }
-                }
-            }
-        }
-    }
-
-    void SpaceShip::setEngine(Engine* engine)
-    {
-        this->engine_ = engine;
-        if (engine && engine->getShip() != this)
-            engine->addToSpaceShip(this);
+            return this->engineList_[i];
+    }
+
+    void SpaceShip::removeAllEngines()
+    {
+        while(this->engineList_.size())
+            this->engineList_.back()->destroy();
+    }
+    
+    void SpaceShip::removeEngine(Engine* engine)
+    {
+        for(std::vector<Engine*>::iterator it=this->engineList_.begin(); it!=this->engineList_.end(); ++it)
+        {
+            if(*it==engine)
+            {
+                this->engineList_.erase(it);
+                return;
+            }
+        }
+    }
+
+    void SpaceShip::setSpeedFactor(float factor)
+    {
+        for(unsigned int i=0; i<this->engineList_.size(); i++)
+            this->engineList_[i]->setSpeedFactor(factor);
+    }
+    float SpaceShip::getSpeedFactor() // Calculate mean SpeedFactor.
+    {
+        float ret = 0; unsigned int i = 0;
+        for(; i<this->engineList_.size(); i++)
+            ret += this->engineList_[i]->getSpeedFactor();
+        ret /= (float)i;
+        return ret;
+    }
+    float SpaceShip::getMaxSpeedFront()
+    {
+        float ret=0;
+        for(unsigned int i=0; i<this->engineList_.size(); i++)
+        {
+            if(this->engineList_[i]->getMaxSpeedFront() > ret)
+                ret = this->engineList_[i]->getMaxSpeedFront();
+        }
+        return ret;
+    }
+
+    float SpaceShip::getBoostFactor()
+    {
+        float ret = 0; unsigned int i=0;
+        for(; i<this->engineList_.size(); i++)
+            ret += this->engineList_[i]->getBoostFactor();
+        ret /= (float)i;
+        return ret;
     }
 
@@ -270,6 +429,17 @@
     {
         std::vector<PickupCarrier*>* list = new std::vector<PickupCarrier*>();
-        list->push_back(this->engine_);
+        for(unsigned int i=0; i<this->engineList_.size(); i++)
+            list->push_back(this->engineList_[i]);
         return list;
     }
+    
+    void SpaceShip::changedEnableMotionBlur()
+    {
+        if (!this->bEnableMotionBlur_)
+        {
+            this->boostBlur_->destroy();
+            this->boostBlur_ = 0;
+        }
+    }
+
 }
Index: code/trunk/src/orxonox/worldentities/pawns/SpaceShip.h
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/SpaceShip.h	(revision 8351)
+++ code/trunk/src/orxonox/worldentities/pawns/SpaceShip.h	(revision 8706)
@@ -59,9 +59,18 @@
 
             virtual void fire();
-            virtual void boost();
+            virtual void boost(bool bBoost); // Starts or stops boosting.
 
-            void setEngine(Engine* engine);
-            inline Engine* getEngine() const
-                { return this->engine_; }
+            void addEngine(Engine* engine);
+            bool hasEngine(Engine* engine);
+            Engine* getEngine(unsigned int i); // This one's for XMLPort
+            inline const std::vector<Engine*>& getEngineList()
+                { return this->engineList_; }
+            void removeEngine(Engine* engine);
+            void removeAllEngines();
+
+            void setSpeedFactor(float factor);
+            float getSpeedFactor(); // Gets mean speed factor
+            float getMaxSpeedFront(); // gets largest speed forward
+            float getBoostFactor(); // gets mean boost factor
 
             inline void setSteeringDirection(const Vector3& direction)
@@ -69,18 +78,21 @@
             inline const Vector3& getSteeringDirection() const
                 { return this->steering_; }
+            inline void resetEngineTicks()
+                { this->engineTicksNotDone = this->engineList_.size(); }
+            inline void oneEngineTickDone()
+                { this->engineTicksNotDone--; }
+            inline bool hasEngineTicksRemaining()
+                { return (this->engineTicksNotDone>0); }
 
-            void setBoost(bool bBoost);
             inline bool getBoost() const
                 { return this->bBoost_; }
 
-            inline void setEngineTemplate(const std::string& temp)
-                { this->enginetemplate_ = temp; this->loadEngineTemplate(); }
-            inline const std::string& getEngineTemplate() const
-                { return this->enginetemplate_; }
+            inline float getBoostPower() const
+                { return this->boostPower_; }
+            inline float getInitialBoostPower() const
+                { return this->initialBoostPower_; }
 
-            inline void setPermanentBoost(bool bPermanent)
-                { this->bPermanentBoost_ = bPermanent; }
-            inline bool getPermanentBoost() const
-                { return this->bPermanentBoost_; }
+            inline bool isBoostCoolingDown() const
+                { return bBoostCooldown_; }
 
         protected:
@@ -90,5 +102,4 @@
             bool bBoost_;
             bool bBoostCooldown_;
-            bool bPermanentBoost_;
             float boostPower_;
             float initialBoostPower_;
@@ -96,4 +107,6 @@
             float boostPowerRate_;
             float boostCooldownDuration_;
+            float lift_;
+            float stallSpeed_;
             Vector3 steering_;
             float primaryThrust_;
@@ -103,15 +116,30 @@
             btVector3 localAngularAcceleration_;
 
+            float shakeFrequency_;
+            float shakeAmplitude_;
+
         private:
             void registerVariables();
             virtual bool isCollisionTypeLegal(WorldEntity::CollisionType type) const;
+            
+            //All things booster
+            void changedEnableMotionBlur();
+            void boostCooledDown(void);
+        
+            void resetCamera();
+            void backupCamera();
+            void shakeCamera(float dt);
 
-            void loadEngineTemplate();
-            
-            void boostCooledDown(void);
+            Shader* boostBlur_;
+            float blurStrength_;
+            bool bEnableMotionBlur_;
 
-            std::string enginetemplate_;
-            Engine* engine_;
+            std::vector<Engine*> engineList_;
+            int engineTicksNotDone; // Used for knowing when to reset temporary variables.
             Timer timer_;
+            Vector3 cameraOriginalPosition_;
+            Quaternion cameraOriginalOrientation_;
+        
+            float shakeDt_;
     };
 }
