Index: code/trunk/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- code/trunk/src/orxonox/OrxonoxPrereqs.h	(revision 11020)
+++ code/trunk/src/orxonox/OrxonoxPrereqs.h	(revision 11052)
@@ -167,4 +167,5 @@
     class DefaultWeaponmodeLink;
     class Munition;
+    class ReplenishingMunition;
     class Weapon;
     class WeaponMode;
@@ -175,5 +176,4 @@
 
     // worldentities
-    class BigExplosion;
     class CameraPosition;
     class ControllableEntity;
Index: code/trunk/src/orxonox/controllers/ActionpointController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/ActionpointController.cc	(revision 11052)
+++ code/trunk/src/orxonox/controllers/ActionpointController.cc	(revision 11052)
@@ -0,0 +1,762 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ActionpointController.h"
+
+#include "core/XMLPort.h"
+#include <algorithm>
+#include "worldentities/Actionpoint.h"
+namespace orxonox
+{
+
+    RegisterClass(ActionpointController);
+
+    ActionpointController::ActionpointController(Context* context) : FightingController(context)
+    {
+        this->ticks_ = 0;
+        this->bPatrolling_ = false;
+        this->bInLoop_ = false;
+        this->bLoop_ = false;
+        this->bEndLoop_ = false;
+        loopActionpoints_.clear();
+        parsedActionpoints_.clear();
+        actionpoints_.clear();
+        this->bTakenOver_ = false;
+        this->action_ = Action::NONE;
+        this->squaredaccuracy_ = 2500;
+        this->bStartedDodging_ = false;
+        this->bDefaultPatrol_ = true;
+        this->bDefaultFightAll_ = true;
+        RegisterObject(ActionpointController);
+
+    }
+    void ActionpointController::XMLPort( Element& xmlelement, XMLPort::Mode mode )
+    {
+        SUPER( ActionpointController, XMLPort, xmlelement, mode );
+
+        XMLPortObject(ActionpointController, WorldEntity, "actionpoints", addActionpoint, getActionpoint,  xmlelement, mode);
+        XMLPortParam(ActionpointController, "defaultFightAll", setDefaultFightAll, getDefaultFightAll, xmlelement, mode).defaultValues(true);
+        XMLPortParam(ActionpointController, "defaultPatrol", setDefaultPatrol, getDefaultPatrol, xmlelement, mode).defaultValues(true);
+    }
+
+    ActionpointController::~ActionpointController()
+    {
+        loopActionpoints_.clear();
+        parsedActionpoints_.clear();
+        actionpoints_.clear();
+
+    }
+    void ActionpointController::tick(float dt)
+    {
+        if (!this || !this->getControllableEntity() || !this->isActive())
+            return;
+
+        //count ticks, ticks_ is unsigned, so overflow is not a problem
+        ++this->ticks_;
+        if (this->ticks_ == 1)
+        {
+            //those vectors are in reversed order after being set by XML.
+            std::reverse(parsedActionpoints_.begin(), parsedActionpoints_.end());
+            std::reverse(actionpoints_.begin(), actionpoints_.end());
+        }
+
+        if (!this || !this->getControllableEntity())
+            return;
+        //fly
+        if (this->bHasTargetPosition_)
+        {
+            this->moveToTargetPosition(dt);
+        }//or just rotate
+        else if (this->bLookAtTarget_)
+        {
+            this->lookAtTarget(dt);
+        }
+        
+
+        if (!this || !this->getControllableEntity())
+            return;
+        //don't fire rocket each tick
+        if (timeout_ <= 0)
+        {    
+            this->bFiredRocket_ = false;
+        }
+        else if (this->bFiredRocket_)
+        {
+            --this->timeout_;
+        }
+
+        if (!this || !this->getControllableEntity())
+            return;
+        //sometimes dodge, sometimes attack
+        if (this->ticks_ % 80 <= 10)
+        {
+            this->bDodge_ = false;
+        }
+        else
+        {
+            this->bDodge_ = true;
+        }
+
+        if (!this || !this->getControllableEntity())
+            return;
+        //fire if you can
+        if (this->bShooting_)
+        {
+            this->doFire();
+        }
+        SUPER(ActionpointController, tick, dt);
+    }
+     
+    /**
+    @brief
+        action() manages the state machine.
+    */
+
+    void ActionpointController::action()
+    {
+        if (!this || !this->getControllableEntity() || !this->isActive())
+            return;
+
+        //deltaHp is used to know if this got attacked
+        this->deltaHp = orxonox_cast<Pawn*> (this->getControllableEntity())->getHealth() - this->previousHp;
+        this->previousHp = orxonox_cast<Pawn*> (this->getControllableEntity())->getHealth();
+
+        //look out for enemies
+        if (this->bDefaultPatrol_ || (this->action_ != Action::FLY && this->action_ != Action::NONE))
+        {
+            this->startAttackingEnemiesThatAreClose();
+        }
+        if (!this || !this->getControllableEntity())
+            return;
+
+        //No action -> pop one from stack
+        if (this->action_ == Action::NONE || this->bTakenOver_)
+        {
+            //if default behaviour is fighting all, push it onto the stack
+            if (this->parsedActionpoints_.empty() && this->loopActionpoints_.empty() && this->bDefaultFightAll_)
+            {
+                if (!this || !this->getControllableEntity())
+                    return;
+                Point p = { Action::FIGHTALL, "", Vector3::ZERO, false };
+                this->parsedActionpoints_.push_back (p);
+            }
+            if (!this || !this->getControllableEntity())
+                return;
+            this->executeActionpoint();
+            if (!this || !this->getControllableEntity())
+                return;
+            this->bTakenOver_ = false;
+        }
+        if (!this || !this->getControllableEntity())
+            return;
+
+        //Action fightall -> fight till nobody alive
+        if (this->action_ == Action::FIGHTALL)
+        {
+
+            if (!this->hasTarget())
+            {
+                ControllableEntity* newTarget = this->closestTarget();    
+                if (newTarget)
+                {
+                    if (!this || !this->getControllableEntity())
+                        return;
+                    this->setAction (Action::FIGHTALL, newTarget);
+                }
+                else
+                {
+                    if (!this || !this->getControllableEntity())
+                        return;
+                    this->nextActionpoint();
+                    if (!this || !this->getControllableEntity())
+                        return;
+                    this->executeActionpoint();
+    
+                }
+            }
+        }
+        //Action fight -> fight as long as enemies in range
+        else if (this->action_ == Action::FIGHT)
+        {
+            if (!this->hasTarget() )
+            {
+                //----find a target----
+                ControllableEntity* newTarget = this->closestTarget();  
+                if (!this || !this->getControllableEntity())
+                    return;  
+                if (newTarget && 
+                        CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
+                {
+                    if (!this || !this->getControllableEntity())
+                        return;
+                    this->setAction (Action::FIGHT, newTarget);
+                }
+                else
+                {
+                    if (!this || !this->getControllableEntity())
+                        return;
+                    this->nextActionpoint();
+                    if (!this || !this->getControllableEntity())
+                        return;
+                    this->executeActionpoint();
+                }
+            }
+            else if (this->hasTarget())
+            {
+                //----fly in formation if far enough----
+                Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition();         
+                    
+                if (diffVector.length() > this->attackRange_)
+                {
+                    ControllableEntity* newTarget = this->closestTarget();
+                    if (!this || !this->getControllableEntity())
+                        return;
+                    if (newTarget && 
+                        CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
+                    {
+                        if (!this || !this->getControllableEntity())
+                            return;
+                        this->setAction (Action::FIGHT, newTarget);
+                    }
+                    else
+                    {
+                        if (!this || !this->getControllableEntity())
+                            return;
+                        this->nextActionpoint();
+                        if (!this || !this->getControllableEntity())
+                            return;
+                        this->executeActionpoint();
+                    }
+                }
+            }
+        }
+        else if (this->action_ == Action::FLY)
+        {
+            if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
+            {
+                if (!this || !this->getControllableEntity())
+                    return;
+                this->nextActionpoint();   
+                if (!this || !this->getControllableEntity())
+                    return;
+                this->executeActionpoint();
+            }
+        }
+        else if (this->action_ == Action::PROTECT)
+        {
+            if (!this->getProtect())
+            {
+                if (!this || !this->getControllableEntity())
+                    return;
+                this->nextActionpoint();
+                if (!this || !this->getControllableEntity())
+                    return;
+                this->executeActionpoint(); 
+            }
+            if (!this || !this->getControllableEntity())
+                return;
+            this->stayNearProtect();
+        }
+        else if (this->action_ == Action::ATTACK)
+        {   
+            if (!this || !this->getControllableEntity())
+                return;
+            if (!this->hasTarget())
+            {
+                if (!this || !this->getControllableEntity())
+                    return;
+                this->nextActionpoint();
+                if (!this || !this->getControllableEntity())
+                    return;
+                this->executeActionpoint();
+            }
+        }
+    }
+    /**
+    @brief
+        if action is protect, this follows protect_ and fights enemies that are close
+    */
+    void ActionpointController::setProtect (ControllableEntity* protect)
+    {
+        this->protect_ = protect;
+    }
+    ControllableEntity* ActionpointController::getProtect ()
+    {
+        return this->protect_;
+    }
+    //XML method
+    void ActionpointController::addActionpoint(WorldEntity* actionpoint)
+    {
+        std::string actionName;
+        Vector3 position;
+        std::string targetName;
+        bool inLoop = false;
+        Point p;
+        if (actionpoint->getIdentifier()->getName() == "Actionpoint")
+        {
+            Actionpoint* ap = orxonox_cast<Actionpoint*> (actionpoint);
+            actionName = ap->getActionXML();
+            targetName = ap->getName();
+            position = ap->getWorldPosition();
+
+            if (this->bEndLoop_)
+            {
+                this->bInLoop_ = false;
+            }
+            if (!this->bInLoop_ && ap->getLoopStart())
+            {
+                this->bInLoop_ = true;
+            }
+            if (this->bInLoop_ && ap->getLoopEnd())
+            {
+                this->bEndLoop_ = true;
+            }
+            inLoop = this->bInLoop_;
+
+            Action::Value value;
+            
+            if ( actionName == "FIGHT" )
+            { value = Action::FIGHT; }
+            else if ( actionName == "FLY" )
+            { value = Action::FLY; }
+            else if ( actionName == "PROTECT" )
+            { value = Action::PROTECT; }
+            else if ( actionName == "NONE" )
+            { value = Action::NONE; }
+            else if ( actionName == "FIGHTALL" )
+            { value = Action::FIGHTALL; }
+            else if ( actionName == "ATTACK" )
+            { value = Action::ATTACK; }
+            else
+                ThrowException( ParseError, std::string( "Attempting to set an unknown Action: '" )+ actionName + "'." );
+            p.action = value; p.name = targetName; p.position = position; p.inLoop = inLoop;
+        }
+        else
+        {
+            inLoop = true;
+            p.action = Action::FLY; p.name = ""; p.position = actionpoint->getWorldPosition(); p.inLoop = inLoop;
+        }
+            parsedActionpoints_.push_back(p);
+            this->actionpoints_.push_back(actionpoint);
+    }
+    //XML method
+    WorldEntity* ActionpointController::getActionpoint(unsigned int index) const
+    {
+        if (index < this->actionpoints_.size())
+            return this->actionpoints_[index];
+        else
+            return 0;
+    }
+    //XML method
+    Action::Value ActionpointController::getAction ()
+    {
+        return this->action_;
+    }
+    //XML method
+    std::string ActionpointController::getActionName()
+    {
+        switch ( this->action_ )
+        {
+            case Action::FIGHT:
+            { return "FIGHT"; }
+            case Action::FLY:
+            { return "FLY"; }
+            case Action::PROTECT:
+            { return "PROTECT"; }
+            case Action::NONE:
+            { return "NONE"; }
+            case Action::FIGHTALL:
+            { return "FIGHTALL"; }
+            case Action::ATTACK:
+            { return "ATTACK"; }
+            default:
+                return "NONE";
+                break;
+        }
+    }
+    //XML method
+    void ActionpointController::setAction (Action::Value action)
+    {
+        this->action_ = action;
+    }
+    //set action and target/protect
+    void ActionpointController::setAction (Action::Value action, ControllableEntity* target)
+    {
+        if (!this || !this->getControllableEntity())
+            return;
+        this->action_ = action;
+        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
+        {   
+            if (target)
+                this->setTarget (target);
+        }
+        else if (action == Action::PROTECT)
+        {
+            if (target)
+                this->setProtect (target);
+        }
+    }
+    //set action and target position
+    void ActionpointController::setAction (Action::Value action, const Vector3& target)
+    {
+        if (!this || !this->getControllableEntity())
+            return;
+        this->action_ = action;
+        if (action == Action::FLY)
+        {
+            this->setTargetPosition (target);
+        }
+    }
+    //set action and target position and orientation
+    void ActionpointController::setAction (Action::Value action, const Vector3& target,  const Quaternion& orient )
+    {
+        if (!this || !this->getControllableEntity())
+            return;
+        this->action_ = action;
+        if (action == Action::FLY)
+        {
+            this->setTargetPosition (target);
+            this->setTargetOrientation (orient);
+        }  
+    }
+    
+    //------------------------------------------------------------------------------
+    //------------------------------Actionpoint methods-----------------------------
+    //------------------------------------------------------------------------------
+
+    //POST: this starts doing what was asked by the last element of parsedActionpoints_,
+    //if last element was failed to be parsed, next element will be executed.
+    void ActionpointController::executeActionpoint()
+    {
+        if (!this || !this->getControllableEntity())
+            return;
+
+        Point p;
+        if (this->bLoop_ && !loopActionpoints_.empty())
+        {
+            p = loopActionpoints_.back();
+        }
+        else if (this->bLoop_)
+        {
+            this->bLoop_ = false;
+            return;
+        }
+        else if (!this->bLoop_ && !parsedActionpoints_.empty())
+        {
+            p = parsedActionpoints_.back();
+        }
+        else
+        {
+            if (!this || !this->getControllableEntity())
+                return;
+
+            this->setTarget(0);
+            this->setTargetPosition(this->getControllableEntity()->getWorldPosition());
+            this->action_ = Action::NONE;
+            return;
+        }
+        if (!this || !this->getControllableEntity())
+            return;
+        if (!this->bLoop_ && this->parsedActionpoints_.back().inLoop)
+        {
+            //MOVES all points that are in loop to a loop vector
+            this->fillLoop();
+            if (!this || !this->getControllableEntity())
+                return;
+            this->bLoop_ = true;
+            executeActionpoint();
+            return;
+        }
+        if (!this || !this->getControllableEntity())
+            return;
+        this->setAction (p.action);
+        if (!this || !this->getControllableEntity())
+            return;
+
+        switch (this->action_)
+        {
+            case Action::FIGHT:
+            {
+                std::string targetName = p.name;
+                if (targetName == "")
+                    break;
+                for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+                {
+                    if (!this || !this->getControllableEntity())
+                        return;
+                    if (CommonController::getName(*itP) == targetName)
+                    {
+                        this->setTarget (static_cast<ControllableEntity*>(*itP));
+                    }
+                }
+                break;
+            }
+            case Action::FLY:
+            {
+                this->setTargetPosition( p.position );
+                if (!this || !this->getControllableEntity())
+                    return;
+                if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
+                {
+                    if (!this || !this->getControllableEntity())
+                        return;
+                    this->nextActionpoint();
+                    if (!this || !this->getControllableEntity())
+                        return;
+                    this->executeActionpoint();
+                }
+                break;
+            }
+            case Action::PROTECT:
+            {
+                if (!this || !this->getControllableEntity())
+                    return;
+
+                std::string protectName = p.name;
+                if (protectName == "reservedKeyword:human")
+                {
+                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+                    {
+                        if (orxonox_cast<ControllableEntity*>(*itP) && ((*itP)->getController()) && ((*itP)->getController()->getIdentifier()->getName() == "NewHumanController"))
+                        {
+                            this->setProtect (static_cast<ControllableEntity*>(*itP));
+                        }
+                    }
+                }
+                else
+                {
+                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+                    {
+                        if (CommonController::getName(*itP) == protectName)
+                        {
+                            this->setProtect (static_cast<ControllableEntity*>(*itP));
+                        }
+                    }                            
+                }
+                if (!this->getProtect())
+                {
+                    this->nextActionpoint();
+                    this->executeActionpoint();
+                }
+                break;
+            }
+            case Action::NONE:
+            {
+                break;
+            }
+            case Action::FIGHTALL:
+            {
+                break;
+            }
+            case Action::ATTACK:
+            {
+                std::string targetName = p.name;
+
+                for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+                {
+                    if (CommonController::getName(*itP) == targetName)
+                    {
+                        if (!this || !this->getControllableEntity())
+                            return;
+                        this->setTarget (static_cast<ControllableEntity*>(*itP));
+                    }
+                }
+                if (!this->hasTarget())
+                {
+                    this->nextActionpoint();
+                    if (!this || !this->getControllableEntity())
+                        return;
+                    this->executeActionpoint();
+                }
+                break;
+            }
+            default:
+                break;
+        }   
+    }
+
+    //calculate where in world coordinates this ship has to be, so that it keeps distance to protect_, and fly there
+    void ActionpointController::stayNearProtect()
+    {
+        if (!this || !this->getControllableEntity())
+            return;
+
+        Vector3 targetRelativePosition(0, 300, 300);
+        if (!this->getProtect())
+        {
+            this->nextActionpoint();
+            return;
+        }  
+        Vector3 targetAbsolutePosition = ((this->getProtect()->getWorldPosition()) + 
+            (this->getProtect()->getWorldOrientation()* (targetRelativePosition)));
+        this->setTargetPosition(targetAbsolutePosition);
+        if (!this->getProtect())
+        {
+            this->nextActionpoint();
+            return;
+        }  
+        this->setTargetOrientation(this->getProtect()->getWorldOrientation());
+    }
+    //remove current point from the stack
+    void ActionpointController::nextActionpoint()
+    {
+        if (!this || !this->getControllableEntity())
+            return;
+        if (this->bLoop_)
+        {
+            if (this->bPatrolling_)
+            {
+                this->loopActionpoints_.pop_back();
+                this->bPatrolling_ = false;
+            }
+            else if (!this->loopActionpoints_.empty())
+            {
+                this->moveBackToTop();
+            }
+        }
+        else
+        {
+            if (!this->parsedActionpoints_.empty())
+            {
+                this->parsedActionpoints_.pop_back();
+            }            
+        }
+        this->setAction(Action::NONE);
+        this->bHasTargetPosition_ = false;
+    }
+    //if looping, instead of erasing point, move it to the top (back is what gets executed, so it's kinda reversed stack)
+    void ActionpointController::moveBackToTop()
+    {
+        if (!this || !this->getControllableEntity())
+            return;
+
+        Point temp = loopActionpoints_.back();
+        loopActionpoints_.pop_back();
+        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
+        loopActionpoints_.push_back(temp);
+        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
+    }
+    //POST: moves all consecutive points that are in loop to the loop stack
+    void ActionpointController::fillLoop()
+    {
+        loopActionpoints_.clear();
+        fillLoopReversed();
+        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
+    }
+    void ActionpointController::fillLoopReversed()
+    {
+        if (parsedActionpoints_.back().inLoop)
+        {
+            loopActionpoints_.push_back(parsedActionpoints_.back());
+            parsedActionpoints_.pop_back();
+        }
+        if (parsedActionpoints_.back().inLoop)
+        {
+            fillLoopReversed();
+        }
+    }
+    //copy other ship's stacks so that if it dies, this can finish that ship's actions
+    void ActionpointController::takeActionpoints (const std::vector<Point>& vector, const std::vector<Point>& loop, bool b)
+    {
+        if (!this || !this->getControllableEntity())
+            return;
+        this->parsedActionpoints_ = vector;
+        if (!this || !this->getControllableEntity())
+            return;
+        this->loopActionpoints_ = loop;
+        this->bLoop_ = b;
+        this->bTakenOver_ = true;
+    }
+    //attack closest target
+    void ActionpointController::setClosestTarget()
+    {
+        this->setTarget (static_cast<ControllableEntity*>( closestTarget() ) ); 
+    }
+    //find closest target
+    Pawn* ActionpointController::closestTarget()
+    {
+        if (!this || !this->getControllableEntity())
+            return 0;
+
+        Pawn* closestTarget = 0;
+        float minDistance =  std::numeric_limits<float>::infinity();
+        Gametype* gt = this->getGametype();
+        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+        {
+            if (!this || !this->getControllableEntity())
+                return 0;
+            if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
+                continue;
+
+            float distance = CommonController::distance (*itP, this->getControllableEntity());
+            if (distance < minDistance)
+            {
+                closestTarget = *itP;
+                minDistance = distance;
+            }
+        }
+        if (closestTarget)
+        {
+           return closestTarget;
+        } 
+        return 0;  
+    }
+    //push action FIGHT to the stack and set target to the closest enemy
+    void ActionpointController::startAttackingEnemiesThatAreClose()
+    {
+        if (!this || !this->getControllableEntity())
+            return;
+        
+        if (!this->target_ || (this->target_ && CommonController::distance (this->getControllableEntity(), this->target_) > this->attackRange_))
+        {
+            if (!this || !this->getControllableEntity())
+                return;
+            Pawn* newTarget = this->closestTarget();
+            if ( newTarget && 
+                CommonController::distance (this->getControllableEntity(), static_cast<ControllableEntity*>(newTarget))
+                    <= this->attackRange_ )
+            {
+                if (!this || !this->getControllableEntity())
+                    return;
+                this->setTarget(newTarget);
+                if (this->bLoop_ && !this->bPatrolling_)
+                {
+                    Point p = { Action::FIGHT, "", Vector3::ZERO, true };
+                    this->loopActionpoints_.push_back(p);
+                }
+                else if (!this->bPatrolling_)
+                {
+                    Point p = { Action::FIGHT, "", Vector3::ZERO, false };
+                    this->parsedActionpoints_.push_back(p);
+                }
+                this->bPatrolling_ = true;
+                this->executeActionpoint();
+            }
+        }
+    }
+}   
Index: code/trunk/src/orxonox/controllers/ActionpointController.h
===================================================================
--- code/trunk/src/orxonox/controllers/ActionpointController.h	(revision 11052)
+++ code/trunk/src/orxonox/controllers/ActionpointController.h	(revision 11052)
@@ -0,0 +1,261 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ActionpointController_H__
+#define _ActionpointController_H__
+
+#include "controllers/FightingController.h"
+#include "tools/Timer.h"
+#include "tools/interfaces/Tickable.h"
+#include "../modules/pickup/PickupSpawner.h"
+#include <map>
+
+#include <boost/shared_ptr.hpp>
+
+
+namespace orxonox
+{
+    /**
+    @brief
+        ActionpointController is a state machine with states:
+            1) NONE
+            2) FLY: fly towards a point
+            3) FIGHT: fight enemies that are in attackRange_ (see FightingController)
+            4) PROTECT: follow this->protect_
+            5) FIGHTALL: fight all enemies on the map
+            6) ATTACK: fight a specific spaceship
+        This controller always executes an action that is in the back of the vector being used.
+        After current this->action_ is completed, next action becomes the top action (one that will
+        be returned by someVector.back()), and current action either will be removed (if not looping),
+        or moved to the top (if looping).
+
+        Every second action(), which is once in two seconds, this searches the area for enemies that are in attack range, if finds anyone,
+        pushes Action::FIGHT to the stack. That makes spaceship fight enemies inside of a sphere, and when all enemies in range are dead,
+        Action::FIGHT is removed from the stack, and spaceship resumes doing whatever action was being executed before.
+
+        In XML one has to attack Actionpoints in order to achieve any complex behaviour, but in Controller all actionpoints are effectively 
+        being stored in an array of type Point::Value.
+    @note
+        ActionpointController will not work, if there is no MasterController in the level!
+        All the demos are in a file called AITest.oxw. In the menu look for New AI Testing Level.
+    */
+    namespace Action
+    {  
+        enum Value
+        {
+            NONE, FLY, FIGHT, PROTECT, FIGHTALL, ATTACK
+        };
+        
+    }
+    
+    struct Point {
+        Action::Value action;
+        std::string name;
+        Vector3 position;
+        bool inLoop;
+    } ;
+    namespace PickupType
+    {
+        enum Value
+        {  
+            NONE, DAMAGE, HEALTH, SPEED, PORTAL
+        };
+    }
+
+    class _OrxonoxExport ActionpointController : public FightingController, public Tickable
+    {
+        public:
+           
+            ActionpointController(Context* context);
+            virtual ~ActionpointController();
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);          
+               
+            /**
+            @brief
+                tick is called every tick by Game (?).
+                In tick ship flies and fires.
+            */
+            virtual void tick(float dt);   
+            /**
+            @brief
+                XML method, example XML usage:
+                <SpaceShip position="-2000, 1500, -1000" lookat="0,0,0" team=0 name="ss2">
+                  <templates>
+                    <Template link=spaceshipassff />
+                  </templates>
+                  <controller>
+                    <DivisionController team=0 formationMode="finger4">
+                      <actionpoints>
+                        <Actionpoint position="0,0,0" action="FLY" /> 
+                        <Actionpoint position="-1000,750,-500" action="ATTACK" attack="attack" />
+                        <Actionpoint position="-1000,750,-500" action="PROTECt" protectMe=true />
+                        <Actionpoint position="-1000,750,-500" action="PROTECt" protect="protect" /> 
+                        <Actionpoint position="-1000,750,-500" action="FIGHTALL" />
+                       </actionpoints>
+                    </DivisionController>
+                  </controller>
+                </SpaceShip>
+                
+                Full description:
+                Adds an Actionpoint to this->actionpoints_. Actionpoint can take arguments like action="attack" attack="name".
+                For documentation on Actionpoint XML arguments, check out Actionpoint.h class
+                If any WorldEntity that is not Actionpoint or its child being sent to actionpoints through XML,
+                action would be assumed to be Action::FLY and target position to be position of the entity. Also, if not Actionpoint
+                is passed, it is assumed to be in a loop. How it works is: in <actionpoints> first all Actionpoints between 
+                first Actionpoint with loopStart=true and first following Actionpoint with loopEnd=true are included in a single loop.
+                If they are adjacent (in the input array) with WorldEntity, then WorldEntity is also in a loop.
+                All the Worldentities are assumed to be in loop. 
+               
+                Loop example:
+                <SpaceShip position="-1500, 1500, -1000" lookat="0,0,0" team=0 name="ss1">
+                  <templates>
+                    <Template link=spaceshipassff />
+                  </templates>
+                  <controller>
+                    <DivisionController team=0 formationMode="wall">
+                      <actionpoints>
+                        <Actionpoint position="  0,2000,-600" action="FLY" loopStart=true/>
+                        <Actionpoint position="  0,2000,-1000" action="FLY"  />
+                        <Actionpoint position="400,2000,-1000" action="FLY" />
+                        <Actionpoint position="400,2000,-600" action="FLY" loopEnd=true />
+                      </actionpoints>
+                    </DivisionController>
+                  </controller>
+                </SpaceShip>
+               
+                other loop example:
+                <SpaceShip position="-1500, -1500, -1500" lookat="0,0,0" team=0 name="ss1">
+                  <templates>
+                    <Template link=spaceshipassff />
+                  </templates>
+                  <controller>
+                    <DivisionController team=0 formationMode="diamond">
+                      <actionpoints>
+                        <Model mesh="cube.mesh" scale=8 position="  0,2000,-600" />
+                        <Model mesh="cube.mesh" scale=8 position="  0,2000,-1000" />
+                        <Model mesh="cube.mesh" scale=8 position="400,2000,-1000" />
+                        <Model mesh="cube.mesh" scale=8 position="400,2000,-600" />
+                      </actionpoints>
+                    </DivisionController>
+                  </controller>
+                </SpaceShip> 
+
+            @note
+                Don't use several loops, and don't use WorldEntities as input to <actionpoints> as I didn't test it well, but you
+                can try if feeling lucky.  
+            */
+            void addActionpoint(WorldEntity* actionpoint); 
+            WorldEntity* getActionpoint(unsigned int index) const;    
+            void setDefaultFightAll(bool value)
+                { this->bDefaultFightAll_ = value; }
+            bool getDefaultFightAll ()
+                { return this->bDefaultFightAll_; }
+            void setDefaultPatrol(bool value)
+                { this->bDefaultPatrol_ = value; }
+            bool getDefaultPatrol ()
+                { return this->bDefaultPatrol_; }
+               
+
+            virtual void stayNearProtect();
+            virtual void action(); //<! action() is called in regular intervals managing the bot's behaviour. Only gets called by MasterController
+            virtual void takeActionpoints (const std::vector<Point>& vector, const std::vector<Point>& loop, bool b);
+
+            virtual Action::Value getAction ();
+            virtual std::string getActionName();
+
+            void setAction (Action::Value action);
+            void setAction (Action::Value action, ControllableEntity* target);
+            void setAction (Action::Value action, const Vector3& target);
+            void setAction (Action::Value action, const Vector3& target,  const Quaternion& orient );
+
+            virtual bool setWingman(ActionpointController* wingman)
+                { return false; }
+            virtual bool hasWingman()
+                { return true; }
+            virtual bool setFollower(ActionpointController* myFollower)
+                { return false; }
+            virtual bool hasFollower()
+                { return true; }
+
+
+        protected:
+                void startAttackingEnemiesThatAreClose();
+                WeakPtr<ActionpointController> myWingman_;
+                WeakPtr<ActionpointController> myFollower_;
+                WeakPtr<ActionpointController> myDivisionLeader_;
+            //----[Actionpoint information]----
+                Action::Value action_;
+                std::string protectName_;
+                std::string targetName_;
+                std::vector<WeakPtr<WorldEntity> > actionpoints_;
+                float squaredaccuracy_;
+                std::vector<Point > parsedActionpoints_;//<! actionpoints as they are stored here after being parsed from XML
+                std::vector<Point > loopActionpoints_;  //<! actionpoints that are to be looped
+                bool bInLoop_;                          //<! variable for addActionpoint method
+                bool bLoop_;                            //<! is state machine looping?
+                bool bEndLoop_;                         //<! variable for addActionpoint method
+                bool bTakenOver_;                       //<! are actionpoints taken over from the leader when he died? if yes, top actionpoint 
+                                                        //<! is to be executed for the state machine to start working
+            //----[/Actionpoint information]----
+                void setProtect (ControllableEntity* protect);
+                ControllableEntity* getProtect (); 
+                WeakPtr<ControllableEntity> protect_;   //<! entity that is to be protected if this->action_ == Action::PROTECT
+                void fillLoop();                        //<! moves actionpoints that are should be in loop from parsedActionpoints_ to loopActionpoints_
+                void fillLoopReversed();
+                void moveBackToTop();                   //<! analog of removing back actionpoint for loopActionpoints_: instead of removing it, 
+                                                        //<! move it to the top, so that it will be executed later on.
+                void setClosestTarget();
+                Pawn* closestTarget();
+            //----[Actionpoint methods]----
+                /**
+                @brief
+                    Sets this->target_, this->targetPosition_, this->protect_ and this->action_ depending
+                    on the current actionpoint in the vector parsedActionpoints_ if not looping or
+                    loopActionpoints_ if looping.
+                @note
+                */
+                void executeActionpoint();  
+                /**
+                @brief
+                    If this->bLoop_, move back action to top (back is the current one, top is the last),
+                    otherwise remove back actionpoint.
+                @note
+                    actionpoints_ is only used for XML, real state stacks are parsedActionpoints_ and loopActionpoints_
+                */            
+                void nextActionpoint();                 
+            //----[Actionpoint methods]----          
+
+                bool bDefaultFightAll_;     //<! if true, when no action set, this will fight all
+
+                bool bPatrolling_;        //<! true if current action_ is FIGHT because this found enemies that are close, need this to correctly go back to looping if was looping
+                bool bDefaultPatrol_;       //<! if true, this will look out for enemies that are close if this is just flying or doing nothing
+                unsigned int ticks_;     //<! local tick counter            
+    };
+}
+
+#endif /* _ActionpointController_H__ */
Index: code/trunk/src/orxonox/controllers/ArtificialController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/ArtificialController.cc	(revision 11020)
+++ code/trunk/src/orxonox/controllers/ArtificialController.cc	(revision 11052)
@@ -94,7 +94,7 @@
             return;
 
-        static const float hardcoded_projectile_speed = 750;
-
-        this->targetPosition_ = getPredictedPosition(this->getControllableEntity()->getWorldPosition(), hardcoded_projectile_speed, this->target_->getWorldPosition(), this->target_->getVelocity());
+        static const float HARDCODED_PROJECTILE_SPEED = 750;
+
+        this->targetPosition_ = getPredictedPosition(this->getControllableEntity()->getWorldPosition(), HARDCODED_PROJECTILE_SPEED, this->target_->getWorldPosition(), this->target_->getVelocity());
         this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO);
 
Index: code/trunk/src/orxonox/controllers/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/controllers/CMakeLists.txt	(revision 11020)
+++ code/trunk/src/orxonox/controllers/CMakeLists.txt	(revision 11052)
@@ -11,3 +11,11 @@
   FormationController.cc
   ControllerDirector.cc
+  DivisionController.cc
+  WingmanController.cc
+  SectionController.cc
+  CommonController.cc
+  ActionpointController.cc
+  FlyingController.cc
+  FightingController.cc
+  MasterController.cc
 )
Index: code/trunk/src/orxonox/controllers/CommonController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/CommonController.cc	(revision 11052)
+++ code/trunk/src/orxonox/controllers/CommonController.cc	(revision 11052)
@@ -0,0 +1,216 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option)any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+#include "controllers/CommonController.h"
+
+//here starts stuff for sameTeam function copied from FormationController
+#include "gametypes/TeamDeathmatch.h"
+#include "gametypes/Gametype.h"
+#include "controllers/DroneController.h"
+#include "gametypes/Dynamicmatch.h"
+
+#include "worldentities/pawns/TeamBaseMatchBase.h"
+
+namespace orxonox
+{
+    const float CommonController::HARDCODED_PROJECTILE_SPEED = 750;
+
+    RegisterClass(CommonController);
+    CommonController::CommonController(Context* context): Controller(context)
+    {
+        RegisterObject(CommonController);
+    }
+    CommonController::~CommonController() 
+    {
+        //no member variables - nothing to destroy
+    }
+    /**
+    @brief
+      PRE: a < b.
+      returns random float between a and b.
+    */
+    float CommonController::randomInRange(float a, float b)
+    {
+        return a + rnd(1.0f) * (b - a);
+    }
+    /**
+    @brief
+      returns distance between two entities, if either is zero pointer, returns infinity
+    */    
+    float CommonController::distance (const ControllableEntity* entity1, const ControllableEntity* entity2)
+    {
+        if (!entity1 || !entity2)
+            return std::numeric_limits<float>::infinity();
+        return (entity1->getPosition() - entity2->getPosition()).length();
+    }
+    /**
+    @brief
+      bad function from FormationController that returns true if both entities have same team
+    */    
+    bool CommonController::sameTeam (ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)
+    {
+        
+        if (!entity1 || !entity2)
+            return false;
+        if (entity1 == entity2)
+            return true;
+
+        int team1 = entity1->getTeam();
+        int team2 = entity2->getTeam();
+
+        Controller* controller = 0;
+        if (entity1->getController())
+            controller = entity1->getController();
+        else
+            controller = entity1->getXMLController();
+        if (controller)
+        {
+            if (controller->getIdentifier()->getName() == "MasterController")
+                return true;
+            CommonController* ac = orxonox_cast<CommonController*>(controller);
+            if (ac)
+                team1 = ac->getTeam();
+        }
+
+        if (entity2->getController())
+            controller = entity2->getController();
+        else
+            controller = entity2->getXMLController();
+        if (controller)
+        {
+            if (controller->getIdentifier()->getName() == "MasterController")
+                return true;
+            CommonController* ac = orxonox_cast<CommonController*>(controller);
+            if (ac)
+                team2 = ac->getTeam();
+        }
+
+        TeamGametype* tdm = orxonox_cast<TeamGametype*>(gametype);
+        if (tdm)
+        {
+            if (entity1->getPlayer())
+                team1 = tdm->getTeam(entity1->getPlayer());
+
+            if (entity2->getPlayer())
+                team2 = tdm->getTeam(entity2->getPlayer());
+        }
+
+        TeamBaseMatchBase* base = 0;
+        base = orxonox_cast<TeamBaseMatchBase*>(entity1);
+        if (base)
+        {
+            switch (base->getState())
+            {
+                case BaseState::ControlTeam1:
+                    team1 = 0;
+                    break;
+                case BaseState::ControlTeam2:
+                    team1 = 1;
+                    break;
+                case BaseState::Uncontrolled:
+                default:
+                    team1 = -1;
+            }
+        }
+        base = orxonox_cast<TeamBaseMatchBase*>(entity2);
+        if (base)
+        {
+            switch (base->getState())
+            {
+                case BaseState::ControlTeam1:
+                    team2 = 0;
+                    break;
+                case BaseState::ControlTeam2:
+                    team2 = 1;
+                    break;
+                case BaseState::Uncontrolled:
+                default:
+                    team2 = -1;
+            }
+        }
+
+        DroneController* droneController = 0;
+        droneController = orxonox_cast<DroneController*>(entity1->getController());
+        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2)
+            return true;
+        droneController = orxonox_cast<DroneController*>(entity2->getController());
+        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1)
+            return true;
+        DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController());
+        DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController());
+        if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner())
+            return true;
+
+        Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype);
+        if (dynamic)
+        {
+            if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;}
+
+            if (entity1->getPlayer())
+                team1 = dynamic->getParty(entity1->getPlayer());
+
+            if (entity2->getPlayer())
+                team2 = dynamic->getParty(entity2->getPlayer());
+
+            if (team1 ==-1 ||team2 ==-1) {return false;}
+            else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;}
+            else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;}
+            else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;}
+            else return true;
+        }
+
+        return (team1 == team2 && team1 != -1);
+    }
+    /**
+    @brief
+      returns true if entityThatLooks does look at entityBeingLookeAt with a tolerance of angle.
+    */    
+    bool CommonController::isLooking(const ControllableEntity* entityThatLooks, const ControllableEntity* entityBeingLookedAt, float angle)
+    {
+        if (!entityThatLooks || !entityBeingLookedAt)
+            return false;
+        return (getAngle(entityThatLooks ->getPosition() , 
+            entityThatLooks->getOrientation()  * WorldEntity::FRONT, 
+            entityBeingLookedAt->getWorldPosition()) < angle);
+    }
+    /**
+    @brief
+      returns a name of a Pawn entity, if no name set, returns string representing address of the Pawn.
+    */    
+    std::string CommonController::getName(const Pawn* entity)
+    {
+        std::string name = entity->getName();
+        if (name == "")
+        {
+            const void * address = static_cast<const void*>(entity);
+            std::stringstream ss;
+            ss << address;  
+            name = ss.str();            
+        }
+        return name;
+    }
+}
Index: code/trunk/src/orxonox/controllers/CommonController.h
===================================================================
--- code/trunk/src/orxonox/controllers/CommonController.h	(revision 11052)
+++ code/trunk/src/orxonox/controllers/CommonController.h	(revision 11052)
@@ -0,0 +1,59 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _CommonController_H__
+#define _CommonController_H__
+
+
+#include "controllers/Controller.h"                 //that's what I inherit from
+
+#include <limits>                                   //I use limits pretty much in every class, so might as well include it in the parent class
+
+#include "worldentities/ControllableEntity.h"       //same for ControllableEntity
+#include "worldentities/pawns/Pawn.h"               //and Pawn
+
+
+namespace orxonox
+{
+    class _OrxonoxExport CommonController : public Controller
+    {
+
+        public:
+            static const float HARDCODED_PROJECTILE_SPEED; //<! FightingController uses it to predict enemy position
+
+            CommonController(Context* context);
+            virtual ~CommonController();
+            static float randomInRange(float a, float b);   //<! returns random number from a to b
+            static float distance(const ControllableEntity* entity1, const ControllableEntity* entity2);    //<! returns distance between arguments
+            static bool sameTeam (ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gt);
+            static bool isLooking(const ControllableEntity* entityThatLooks, const ControllableEntity* entityBeingLookedAt, float angle) ;
+            static std::string getName(const Pawn* entity) ;           
+    };
+}
+
+#endif /* _CommonController_H__ */
Index: code/trunk/src/orxonox/controllers/DivisionController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/DivisionController.cc	(revision 11052)
+++ code/trunk/src/orxonox/controllers/DivisionController.cc	(revision 11052)
@@ -0,0 +1,148 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DivisionController.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+
+    RegisterClass(DivisionController);
+
+    //Leaders share the fact that they have Wingmans
+    DivisionController::DivisionController(Context* context) : ActionpointController(context)
+    {
+        RegisterObject(DivisionController);
+        this->setFormationMode(FormationMode::DIAMOND);
+        this->target_ = 0;
+        this->myFollower_ = 0;
+        this->myWingman_ = 0;
+    }
+
+    DivisionController::~DivisionController()
+    {
+        for (size_t i = 0; i < this->actionpoints_.size(); ++i)
+        {
+            if(this->actionpoints_[i])
+                this->actionpoints_[i]->destroy();
+        }
+        this->parsedActionpoints_.clear();
+        this->actionpoints_.clear();
+    } 
+
+    void DivisionController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(DivisionController, XMLPort, xmlelement, mode);
+        
+    }
+    void DivisionController::tick(float dt)
+    {   
+        if (!this->isActive())
+            return;   
+        
+        SUPER(DivisionController, tick, dt);
+        
+    }
+    void DivisionController::action()
+    {   
+        if (!this || !this->getControllableEntity() || !this->isActive())
+            return;
+        
+        ActionpointController::action();
+        if (!this || !this->getControllableEntity())
+            return;
+        if (!(this->parsedActionpoints_.empty() && this->loopActionpoints_.empty()))
+        {
+            //when this dies, its follower will execute all its actionpoints, if follower dies before this, wingman will do this
+            if (this->myFollower_)
+            {
+                this->myFollower_->takeActionpoints(this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+            }
+            else if (this->myWingman_)
+            {
+                this->myWingman_->takeActionpoints(this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+            }    
+        }
+
+        
+    }
+    //I wanted to do it different here, but at this point I think nothing will change if I delete that method
+    void DivisionController::stayNearProtect()
+    {
+        ActionpointController::stayNearProtect();
+    }
+    
+    bool DivisionController::setWingman(ActionpointController* newWingman)
+    {
+        if (!this->myWingman_)
+        {
+            this->myWingman_ = newWingman;
+            if (!this->hasFollower())
+                newWingman->takeActionpoints (this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+    bool DivisionController::setFollower(ActionpointController* newFollower)
+    {
+        if (!this->myFollower_)
+        {
+            this->myFollower_ = newFollower;
+            if (this->hasWingman())
+            {
+                this->myWingman_->takeActionpoints (std::vector<Point>(), std::vector<Point>(), false);
+            }
+
+            newFollower->takeActionpoints (this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+            
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+    bool DivisionController::hasWingman()
+    {
+        if (this->myWingman_)
+            return true;
+        else
+            return false;
+    }
+    bool DivisionController::hasFollower()
+    {
+        if (this->myFollower_)
+            return true;
+        
+        return false;
+    }
+
+}
Index: code/trunk/src/orxonox/controllers/DivisionController.h
===================================================================
--- code/trunk/src/orxonox/controllers/DivisionController.h	(revision 11052)
+++ code/trunk/src/orxonox/controllers/DivisionController.h	(revision 11052)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DivisionController_H__
+#define _DivisionController_H__
+
+#include "controllers/ActionpointController.h"
+
+
+
+namespace orxonox
+{
+    /**
+        @note
+        ActionpointController will not work, if there is no MasterController in the level!
+        All the demos are in a file called AITest.oxw. In the menu look for New AI Testing Level.
+    */
+    class _OrxonoxExport DivisionController : public ActionpointController
+    {
+        public:
+            //----[language demanded functions]----            
+                DivisionController(Context* context);
+
+                virtual ~DivisionController();
+            //----[/language demanded functions]----            
+
+            //----[orxonox demanded functions]----
+                virtual void tick(float dt); 
+
+                virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);          
+            //----[orxonox demanded functions]----
+
+            //----[own functions]----
+                virtual bool setFollower(ActionpointController* newFollower);
+                virtual bool setWingman(ActionpointController* newWingman);
+                virtual bool hasWingman();
+                virtual bool hasFollower();
+                
+            //----[/own functions]----
+            virtual void stayNearProtect();
+
+        protected:
+            //----action must only be managed by this----
+            virtual void action(); //<! action() is called in regular intervals managing the bot's behaviour.
+
+        private:
+            //----private variables-----
+            Timer actionTimer_; //<! Regularly calls action().
+   
+
+    };
+}
+
+#endif /* _DivisionController_H__ */
Index: code/trunk/src/orxonox/controllers/FightingController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/FightingController.cc	(revision 11052)
+++ code/trunk/src/orxonox/controllers/FightingController.cc	(revision 11052)
@@ -0,0 +1,372 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or ( at your option )any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      Fabian 'x3n' Landau, Dominik Solenicki
+ *
+ */
+#include "controllers/FightingController.h"
+#include "core/XMLPort.h"
+#include "util/Math.h"
+
+
+#include "worldentities/pawns/SpaceShip.h"
+
+#include "weaponsystem/WeaponMode.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/Weapon.h"
+#include "weaponsystem/WeaponSlot.h"
+#include "weaponsystem/WeaponSystem.h"
+#include "weaponsystem/Munition.h"
+
+namespace orxonox
+{
+
+    RegisterClass (FightingController);
+    
+    FightingController::FightingController( Context* context ): FlyingController( context )
+    {
+        this->attackRange_ = 2500;
+        this->stopLookingAtTarget();
+        this->bSetupWorked = false;
+        this->timeout_ = 0;
+        RegisterObject( FightingController );
+    }
+    FightingController::~FightingController() 
+    {
+        
+    }
+    void FightingController::XMLPort( Element& xmlelement, XMLPort::Mode mode )
+    {
+        SUPER( FightingController, XMLPort, xmlelement, mode );
+    }
+    void FightingController::lookAtTarget(float dt)
+    {
+        if (!this || !this->getControllableEntity())
+            return;
+        ControllableEntity* entity = this->getControllableEntity();
+        if ( !entity )
+            return;
+        Vector2 coord = get2DViewCoordinates
+            ( entity->getPosition() , 
+            entity->getOrientation()  * WorldEntity::FRONT, 
+            entity->getOrientation()  * WorldEntity::UP, 
+            positionOfTarget_ );
+
+        //rotates should be in range [-1,+1], clamp cuts off all that is not
+        float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );
+        float rotateY = clamp( coord.y * 10, -1.0f, 1.0f ); 
+   
+        //Yaw and Pitch are enough to start facing the target
+        this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt );
+        this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt );
+    }
+    void FightingController::stopLookingAtTarget()
+    {
+        this->bLookAtTarget_ = false;
+    }
+    void FightingController::startLookingAtTarget()
+    {
+        this->bLookAtTarget_ = true;
+    }
+    bool FightingController::hasTarget() const
+    {
+        if ( this->target_ )
+            return true;
+        return false;
+    }
+
+    void FightingController::setTarget( ControllableEntity* target )
+    {
+        this->target_ = target;        
+        if ( this->target_ )
+        {
+            this->setPositionOfTarget( target_->getWorldPosition() );
+        }
+    }
+    void FightingController::setPositionOfTarget( const Vector3& target )
+    {
+        this->positionOfTarget_ = target;
+        this->bHasPositionOfTarget_ = true;
+    }
+    void FightingController::setOrientationOfTarget( const Quaternion& orient )
+    {
+        this->orientationOfTarget_=orient;
+        this->bHasOrientationOfTarget_=true;
+    }
+    
+    void FightingController::maneuver() 
+    {
+        if ( !this->target_ || !this->getControllableEntity())
+            return;
+
+
+        Vector3 thisPosition = this->getControllableEntity()->getWorldPosition();
+        this->setPositionOfTarget(this->target_->getWorldPosition());
+        //this->setOrientationOfTarget(this->target_->getOrientation());
+        Vector3 diffVector = this->positionOfTarget_ - thisPosition;
+        float diffLength = diffVector.length();
+        Vector3 diffUnit = diffVector/diffLength;
+
+        if (!this || !this->getControllableEntity())
+            return;
+
+        //too far? well, come closer then
+        if (diffLength > this->attackRange_)
+        {
+            this->spread_ = 400;
+            this->formationMode_ = FormationMode::DIAMOND;
+            this->bKeepFormation_ = true;
+            
+            this->setTargetPosition(this->positionOfTarget_ - diffUnit * 100.0f);
+        }
+        else
+        {   
+            bool bTargetIsLookingAtThis = CommonController::isLooking (this->target_, this->getControllableEntity(), math::pi/20.0f)
+                || this->deltaHp < 0;
+            this->bKeepFormation_ = false;
+
+            if (!this || !this->getControllableEntity())
+                return;
+            if (!this->bDodge_)
+            {
+                this->bStartedDodging_ = false;
+
+                this->setTargetPosition(this->positionOfTarget_ - diffUnit * 50.0f);   
+                return;
+            }
+            else if (bTargetIsLookingAtThis || diffLength < 700.0f)
+            {
+                if (!this->bStartedDodging_)
+                {
+                    this->bStartedDodging_ = true;
+                    dodge(thisPosition, diffLength, diffUnit);        
+                }
+            }
+            else
+            {
+                if (diffLength < 1000)
+                {
+                    this->stopMoving();
+                    this->startLookingAtTarget();
+
+                }
+                else
+                {
+                    this->setTargetPosition(this->positionOfTarget_ - diffUnit * 300.0f);
+                }
+            }
+        }
+    }
+    
+    void FightingController::dodge(const Vector3& thisPosition, float diffLength, Vector3& diffUnit)
+    {
+        //d.x*x + d.y*y + d.z*z == 0
+        //z = 1/d.z * (-d.y*y - d.x * x)
+        float x = CommonController::randomInRange (300, 800) * (CommonController::randomInRange(0,1) <= 0.5 ? 1 : -1);
+        float y = CommonController::randomInRange (300, 800) * (CommonController::randomInRange(0,1) <= 0.5 ? 1 : -1);
+        float z = diffUnit.z == 0 ? 0 : (1/diffUnit.z) * (-x * diffUnit.x - y * diffUnit.y);
+        if (diffLength < 150.0f)
+        {
+            this->setTargetPosition(this->positionOfTarget_ + Vector3(z,x,y));
+        }
+        else
+        {
+        this->setTargetPosition(thisPosition + Vector3(x,y,z) + (this->deltaHp < 0 ? -diffUnit * 450.0f : 
+            (diffLength < 700.0f ? -diffUnit*700.0f : diffUnit * 50.0f)));
+
+        }
+        this->boostControl();
+
+    }
+    bool FightingController::canFire() 
+    {
+        //no target? why fire?
+        if (!this->target_ || !this->getControllableEntity())
+            return false;
+        Vector3 newPositionOfTarget = getPredictedPosition(this->getControllableEntity()->getWorldPosition(), 
+                                                           HARDCODED_PROJECTILE_SPEED, this->target_->getWorldPosition(),
+                                                           this->target_->getVelocity());
+        if (!this->target_ || !this->getControllableEntity())
+            return false;
+        //Vector3.isNaN() is what I used on my machine and it worked...
+        if (!(std::isnan(newPositionOfTarget.x) || std::isnan(newPositionOfTarget.y) || std::isnan(newPositionOfTarget.z)))
+        {
+            this->setPositionOfTarget(newPositionOfTarget);
+        }
+
+        return squaredDistanceToTarget() < this->attackRange_*this->attackRange_ && this->isLookingAtTarget(math::pi / 20.0f);
+    }
+
+
+    float FightingController::squaredDistanceToTarget()  const
+    {
+        if (!this || !this->getControllableEntity())
+            return 0;
+        if (!this->target_ || !this->getControllableEntity())
+            return (this->getControllableEntity()->getPosition().squaredDistance(this->targetPosition_));
+        else
+            return (this->getControllableEntity()->getPosition().squaredDistance(this->positionOfTarget_));
+    }
+    bool FightingController::isLookingAtTarget( float angle ) const
+    {
+        if ( !this->getControllableEntity()  || !this->target_ )
+            return false;
+        return CommonController::isLooking(this->getControllableEntity(), this->getTarget(), angle);
+    }
+    void FightingController::setClosestTarget()
+    {
+        this->setTarget (static_cast<ControllableEntity*>( closestTarget() ) ); 
+    }
+    
+    Pawn* FightingController::closestTarget() const
+    {
+        if (!this || !this->getControllableEntity())
+            return 0;
+
+        Pawn* closestTarget = 0;
+        float minDistance =  std::numeric_limits<float>::infinity();
+        Gametype* gt = this->getGametype();
+        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+        {
+            if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
+                continue;
+
+            float distance = CommonController::distance (*itP, this->getControllableEntity());
+            if (distance < minDistance)
+            {
+                closestTarget = *itP;
+                minDistance = distance;
+            }
+        }
+        if (closestTarget)
+        {
+           return closestTarget;
+        } 
+        return 0;  
+    }
+    //I checked it out, rockets DO NOT cause any problems! this->getControllableEntity() is always a SpaceShip
+    void FightingController::doFire()
+    {
+        if (!this->bSetupWorked)
+        {
+            this->setupWeapons();
+        }
+        if (!this->target_ || !this->getControllableEntity())
+        {
+            return;
+        }
+
+        Pawn* pawn = orxonox_cast<Pawn*> (this->getControllableEntity());
+        if (pawn)
+            pawn->setAimPosition (this->positionOfTarget_);
+
+        int firemode;
+        float distance = CommonController::distance (this->getControllableEntity(), this->target_);
+
+
+       
+        if (distance < 1500)
+        {
+            if (this->rocketsLeft_ > 0 && !this->bFiredRocket_)
+            {
+                firemode = getFiremode ("RocketFire");
+            }
+            else
+            {
+                if (distance > 800)
+                    firemode = getFiremode ("HsW01");
+                else
+                    firemode = getFiremode ("LightningGun");
+            }
+
+        } 
+    
+
+        else if (distance < 2000)
+        {
+            firemode = getFiremode ("HsW01");
+        }
+        else
+        {
+            firemode = getFiremode ("LightningGun");
+        }
+        if (firemode < 0)
+        {
+            //assuming there is always some weapon with index 0
+            firemode = 0;
+        }
+        if (firemode == getFiremode("RocketFire"))
+        {
+            this->timeout_ = 5;
+            this->rocketsLeft_--;
+            this->bFiredRocket_ = true;
+        }
+        if (firemode == getFiremode("SimpleRocketFire"))
+        {
+            this->rocketsLeft_--;
+        }
+              
+        this->getControllableEntity()->fire(firemode);
+        
+    }
+    void FightingController::setupWeapons() //TODO: Make this function generic!! (at the moment is is based on conventions)
+    {
+        this->bSetupWorked = false;
+        if(this->getControllableEntity())
+        {
+            Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
+            if(pawn && pawn->isA(Class(SpaceShip))) //fix for First Person Mode: check for SpaceShip
+            {
+                this->weaponModes_.clear(); // reset previous weapon information
+                WeaponSlot* wSlot = 0;
+                for(int l=0; (wSlot = pawn->getWeaponSlot(l)) ; l++)
+                {
+                    WeaponMode* wMode = 0;
+                    for(int i=0; (wMode = wSlot->getWeapon()->getWeaponmode(i)) ; i++)
+                    {
+                        std::string wName = wMode->getIdentifier()->getName();
+                        // SubclassIdentifier<Munition> munition =  ClassByString(wName);
+                        if (wName == "RocketFire")
+                            this->rocketsLeft_ = 10;
+                        if(this->getFiremode(wName) == -1) //only add a weapon, if it is "new"
+                            weaponModes_[wName] = wMode->getMode();
+                    }
+                }
+                if(weaponModes_.size())//at least one weapon detected
+                    this->bSetupWorked = true;
+            }
+        }
+
+    }
+
+    int FightingController::getFiremode(std::string name)
+    {
+        for (std::map< std::string, int >::iterator it = this->weaponModes_.begin(); it != this->weaponModes_.end(); ++it)
+        {
+            if (it->first == name)
+                return it->second;
+        }
+        return -1;
+    }
+}
Index: code/trunk/src/orxonox/controllers/FightingController.h
===================================================================
--- code/trunk/src/orxonox/controllers/FightingController.h	(revision 11052)
+++ code/trunk/src/orxonox/controllers/FightingController.h	(revision 11052)
@@ -0,0 +1,106 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      Fabian 'x3n' Landau, Dominik Solenicki
+ *
+ */
+
+#ifndef _FightingController_H__
+#define _FightingController_H__
+
+
+#include "controllers/FlyingController.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        FightingController stores all the fighting methods and member variables of AI.
+        Main methods here are maneuver() and dodge().
+    
+    @note
+        ActionpointController will not work, if there is no MasterController in the level!
+    */
+    class _OrxonoxExport FightingController : public FlyingController
+    {
+
+        public:
+            FightingController(Context* context);
+            virtual ~FightingController();
+            
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+       
+            float squaredDistanceToTarget() const;
+            bool isLookingAtTarget(float angle) const;
+            bool hasTarget() const;
+            ControllableEntity* getTarget() const
+                { return this->target_; }
+            bool bKeepFormation_;   //even if action_ == FIGHT, you might still want to keep formation if far enough form the target
+            virtual void maneuver(); //<! sets this->targetPosition_, which is a Vector3 of where this ship flies. Decision is made based on
+                             //<! the distance to enemy, if being attacked, dodge() is called, otherwise ship just flies towards this->target_.
+            bool bShooting_;    //<! if true, ship shoots each tick
+            bool canFire(); //<! check if target_ is in radius and if this is looking at target_
+        protected:
+            void setTarget(ControllableEntity* target); //set a target to shoot at
+
+            void setPositionOfTarget(const Vector3& target);    //good to know where target is
+            void setOrientationOfTarget(const Quaternion& orient);  //I don't really use that
+            void stopLookingAtTarget();     //<! target dead -> you need to be able to fly
+            void startLookingAtTarget();    //<! if close to target, no need to fly, just rotate yourself
+            void lookAtTarget(float dt);    //<! rotate yourself towards target
+
+            void dodge(const Vector3& thisPosition, float diffLength,  Vector3& diffUnit); //<! choose a random Vector3 perpendicular to the difference vector between
+                                                                        //<! this and target_ plus or minus some amount in difference vector direction,
+                                                                        //<! depending on whether it is better to close up or survive.
+            void dodgeTowards (Vector3& position);  //fly towards position and awoid being hit
+            void doFire();  //<! choose weapon, set aim at target_ and fire
+            WeakPtr<ControllableEntity> target_;
+            void setClosestTarget();
+         
+            bool bHasPositionOfTarget_;
+            Vector3 positionOfTarget_;
+            bool bHasOrientationOfTarget_;
+            Quaternion orientationOfTarget_;
+            Pawn* closestTarget() const;
+
+            bool bDodge_;
+            int attackRange_;
+            bool bLookAtTarget_; 
+            float deltaHp;
+            float previousHp;
+            bool bStartedDodging_;
+            //WEAPONSYSTEM DATA
+            int rocketsLeft_;
+            int timeout_;
+            bool bFiredRocket_;
+            std::map<std::string, int> weaponModes_; //<! Links each "weapon" to it's weaponmode - managed by setupWeapons()
+            //std::vector<int> projectiles_; //<! Displays amount of projectiles of each weapon. - managed by setupWeapons()
+            void setupWeapons(); //<! Defines which weapons are available for a bot. Is recalled whenever a bot was killed.
+            bool bSetupWorked; //<! If false, setupWeapons() is called.
+            int getFiremode(std::string name);
+          
+    };
+}
+
+#endif /* _FightingController_H__ */
Index: code/trunk/src/orxonox/controllers/FlyingController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/FlyingController.cc	(revision 11052)
+++ code/trunk/src/orxonox/controllers/FlyingController.cc	(revision 11052)
@@ -0,0 +1,289 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option)any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+
+ *   Co-authors:
+ *   ...
+ *
+ */
+#include <OgreMatrix3.h>                        //for Quaternion manipulations
+
+#include "util/Math.h"                          
+#include "core/XMLPort.h"
+#include "controllers/FlyingController.h"
+
+#include "worldentities/pawns/SpaceShip.h"      //for boosting
+
+namespace orxonox
+{    
+    const float FlyingController::SPEED = 0.9f/0.02f;
+    const float FlyingController::ROTATEFACTOR = 0.6f/0.02f;
+
+    RegisterClass (FlyingController);
+    
+    FlyingController::FlyingController(Context* context): CommonController(context)
+    {
+        RegisterObject(FlyingController);        
+        this->rotationProgress_ = 0;
+        this->spread_ = 200;
+        this->tolerance_ = 80;
+        this->bCopyOrientation_ = true;
+    }
+    FlyingController::~FlyingController() 
+    {
+    }
+
+    void FlyingController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        XMLPortParam(FlyingController, "spread", setSpread, getSpread,  xmlelement, mode);
+        XMLPortParam(FlyingController, "formationMode", setFormationModeXML, getFormationModeXML,  xmlelement, mode);
+        SUPER(FlyingController, XMLPort, xmlelement, mode);
+    }
+   
+    void FlyingController::setFormationModeXML(std::string val)
+    {
+        const std::string valUpper = getUppercase(val);
+        FormationMode::Value value;
+        
+        if (valUpper == "WALL")
+            value = FormationMode::WALL;
+        else if (valUpper == "FINGER4")
+            value = FormationMode::FINGER4;
+        else if (valUpper == "DIAMOND")
+            value = FormationMode::DIAMOND;
+        else
+            ThrowException(ParseError, std::string("Attempting to set an unknown FormationMode: '")+ val + "'.");
+        this->setFormationMode(value);
+    }
+    std::string FlyingController::getFormationModeXML() const
+    {
+        switch (this->formationMode_)
+        {
+            case FormationMode::WALL:
+            { return "WALL"; }
+            case FormationMode::FINGER4:
+            { return "FINGER4"; }
+            case FormationMode::DIAMOND:
+            { return "DIAMOND"; }
+            default:
+                return "DIAMOND";
+        }
+    }
+    void FlyingController::stopMoving()
+    {
+        this->bHasTargetPosition_ = false;
+    }
+    /**
+    @brief
+      if distance to targetPosition is smaller than this->tolerance_, no moving should be made, otherwise
+      find amount of yaw and pitch that have to be applied, so that ship looks at targetPosition, then
+      ship is moved forward towards targetPosition. Also target orientation is being applied.
+    */
+    void FlyingController::moveToPosition(const Vector3& targetPosition, float dt)
+    {
+        if (!this->getControllableEntity())
+            return;
+        ControllableEntity* entity = this->getControllableEntity();
+
+        float distance = (targetPosition - entity->getPosition()).length();
+
+        if (distance >= this->tolerance_)
+        {
+            //function that calculates how much yaw and pitch are to be applied
+            Vector2 coord = get2DViewCoordinates
+                (entity->getPosition() , 
+                entity->getOrientation()  * WorldEntity::FRONT, 
+                entity->getOrientation()  * WorldEntity::UP, 
+                targetPosition);
+            //limit yaw and pitch by [-1,1]
+            float rotateX = -clamp(coord.x * 10, -1.0f, 1.0f);
+            float rotateY = clamp(coord.y * 10, -1.0f, 1.0f);
+
+            if (!entity)
+                return;
+
+            //apply yaw and pitch
+            entity->rotateYaw(ROTATEFACTOR * rotateX * dt);
+            entity->rotatePitch(ROTATEFACTOR * rotateY * dt);
+            
+            if (!entity)
+                return;
+           
+            //only move either if ship looks at target with a certain tolerance, or if ship is far enough for it to be ok to move in a curve.
+            if (distance > this->tolerance_*1.5f || (rotateX > -0.03 && rotateX < 0.03 && rotateY > -0.03 && rotateY < 0.03))
+                entity->moveFrontBack(SPEED * dt);
+            //roll
+            copyTargetOrientation(dt);
+        }
+        else
+        {      
+            bHasTargetPosition_ = false;
+        }
+    }
+    /**
+    @brief
+      fly towards a preset targetPosition_
+    */
+    void FlyingController::moveToTargetPosition(float dt)
+    {
+        this->moveToPosition (this->targetPosition_, dt);
+    }
+    /**
+    @brief
+      roll ship so that it has same roll as orient
+    */
+    void FlyingController::copyOrientation(const Quaternion& orient, float dt)
+    {
+        //copied from
+        //http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Quaternion+and+Rotation+Primer&structure=Tutorials#Q._How_can_I_make_my_objects_rotate_smoothly_You_mentioned_slerp_etc_
+        //how can I make my objects rotate smoothly?
+        if (!this->getControllableEntity())
+            return;
+        Quaternion myOrient = this->getControllableEntity()->getOrientation();
+        this->rotationProgress_ += dt;
+
+        if (this->rotationProgress_ > 1)
+        {
+            this->rotationProgress_ = 0;
+            this->bHasTargetOrientation_ = false;
+        }
+        else
+        {
+            Quaternion deltaOrientation = Quaternion::Slerp(rotationProgress_, myOrient, orient, true);
+            
+            Matrix3 deltaMatrix, myMatrix;
+
+            deltaOrientation.ToRotationMatrix(deltaMatrix);
+            myOrient.ToRotationMatrix (myMatrix);
+
+            Radian yawDelta, pitchDelta, rollDelta, yawMy, pitchMy, rollMy;
+            deltaMatrix.ToEulerAnglesYXZ(yawDelta, pitchDelta, rollDelta);
+            myMatrix.ToEulerAnglesYXZ (yawMy, pitchMy, rollMy);
+
+            if (!this->getControllableEntity())
+                return;
+            this->getControllableEntity()->rotateRoll ((rollDelta.valueRadians() - rollMy.valueRadians())*ROTATEFACTOR*dt);
+        }
+    }
+    /**
+    @brief
+      roll ship so that it has same roll as a preset targetOrientation_
+    */
+    void FlyingController::copyTargetOrientation(float dt)
+    {
+        if (bHasTargetOrientation_)
+        {   
+            this->copyOrientation(targetOrientation_, dt);
+        }
+    }
+    /**
+    @brief
+      set Vector to fly to
+    */
+    void FlyingController::setTargetPosition(const Vector3& target)
+    {
+        this->targetPosition_ = target;
+        this->bHasTargetPosition_ = true;
+    }
+    /**
+    @brief
+      set orientation to apply
+    */
+    void FlyingController::setTargetOrientation(const Quaternion& orient)
+    {
+        this->targetOrientation_=orient;
+        this->bHasTargetOrientation_=true;
+    }
+    /**
+    @brief
+      set orientation to apply
+    */
+    void FlyingController::setTargetOrientation(ControllableEntity* target)
+    {
+        if (target)
+            this->setTargetOrientation(target->getOrientation());
+    }
+    /**
+    @brief
+      boost if you can
+    */
+    void FlyingController::boostControl()
+    {
+        if (!this->getControllableEntity())
+            return;
+        SpaceShip* ship = orxonox_cast<SpaceShip*>(this->getControllableEntity());
+        if(ship == NULL) return;
+        if(ship->getBoostPower()*1.5f > ship->getInitialBoostPower()) //upper limit ->boost
+        {
+            this->getControllableEntity()->boost(true);
+        }
+        else if(ship->getBoostPower()*4.0f < ship->getInitialBoostPower()) //lower limit ->do not boost
+        {
+           this->getControllableEntity()->boost(false);
+        }
+    }
+    /**
+    @brief
+      keep this ship in a formation with its division
+    */
+    void FlyingController::keepFormation(const ControllableEntity* leaderEntity, Vector3& targetRelativePosition)
+    {
+        if (!this->getControllableEntity())
+            return;
+        ControllableEntity* myEntity = this->getControllableEntity();
+        Vector3 myPosition = myEntity->getWorldPosition();
+
+        if (!leaderEntity)
+        {
+            return;
+        }
+        Quaternion orient = leaderEntity->getWorldOrientation();
+        Vector3 leaderPosition = leaderEntity->getWorldPosition();
+
+        if (!leaderEntity)
+        {
+            return;
+        }
+        //calculate where in world coordinates this ship should fly
+        Vector3 targetAbsolutePosition = 
+            (leaderPosition + (orient*WorldEntity::FRONT) * (leaderEntity->getVelocity().length()/5)
+             + (orient* (targetRelativePosition)));
+        //let ship finish rotating. also don't call copyOrientation too often as it is a slow function. Don't know how to do it different
+        if (this->bCopyOrientation_)
+            this->setTargetOrientation (orient);
+        //set a position to fly to
+        this->setTargetPosition (targetAbsolutePosition);
+
+        //boost if too far
+        if ((targetAbsolutePosition - myPosition).length() > this->tolerance_ * 1.5f)
+        {
+            this->boostControl();
+        }
+        else
+        {
+            if (!this->getControllableEntity())
+                return;
+            this->getControllableEntity()->boost(false);
+        }
+    }
+}
Index: code/trunk/src/orxonox/controllers/FlyingController.h
===================================================================
--- code/trunk/src/orxonox/controllers/FlyingController.h	(revision 11052)
+++ code/trunk/src/orxonox/controllers/FlyingController.h	(revision 11052)
@@ -0,0 +1,105 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      Dominik Solenicki
+ *
+ */
+
+#ifndef _FlyingController_H__
+#define _FlyingController_H__
+
+
+#include "controllers/CommonController.h"
+
+namespace orxonox
+{   
+    /**
+    @brief
+        FlyingController stores all the flying methods and member variables of AI.
+    */
+
+    //Formation mode for the divisions
+    namespace FormationMode
+    {
+        enum Value
+        {
+            FINGER4, DIAMOND, WALL
+        };
+    }
+
+    class _OrxonoxExport FlyingController : public CommonController
+    {
+
+        public:
+            static const float SPEED;              //<! ship's speed
+            static const float ROTATEFACTOR;       //<! ship's rotation factor
+ 
+            FlyingController(Context* context);
+            virtual ~FlyingController();
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void setSpread (int spread)                         //<! spread is a multiplier for formation flight, should be bigger than 100
+                { this->spread_ = spread; }
+            int getSpread () const                              
+                { return this->spread_; }
+
+            void setFormationModeXML(std::string val);
+            std::string getFormationModeXML() const;
+
+            void setFormationMode(FormationMode::Value val)
+                { this->formationMode_ = val; }
+            FormationMode::Value getFormationMode() const
+                { return this->formationMode_; }
+            bool bCopyOrientation_;                             //<! set to true by default, MasterController sets it in its tick(),
+                                                                //<! if true, this will set its leader orientation as target orientation in action()
+        protected:
+            void stopMoving();                                  //<! don't call moveToTargetPosition() in tick, call lookAtTarget() from FightingController instead
+
+            void moveToPosition(const Vector3& target, float dt);   //<! move towards a vector
+            void moveToTargetPosition(float dt);                    //<! move to the preset position. Don't mix with positionOfTarget!
+
+            void copyOrientation(const Quaternion& orient, float dt);   //<! roll to have same roll as orient
+            void copyTargetOrientation(float dt);                       //<! roll to have a preset orient
+
+            void setTargetPosition(const Vector3& target);              //<! preset a Vector to fly to
+            void setTargetOrientation(const Quaternion& orient);        //<! preset a desired orientation
+            void setTargetOrientation(ControllableEntity* target);      //<! preset a desired orientation
+            virtual void boostControl();                                //<! boost if you can
+            void keepFormation (const ControllableEntity* leaderEntity, 
+                                Vector3& targetRelativePosition);   //<! preset targetPosition, so that 
+                                                                    //<! this stays in a certain position relative to leader      
+            
+            FormationMode::Value formationMode_;
+          
+            float rotationProgress_;    //<! for slerping 
+            bool bHasTargetPosition_;
+            Vector3 targetPosition_;    //<! vector to fly to
+            bool bHasTargetOrientation_;
+            Quaternion targetOrientation_;  //<! orientation to take
+            int spread_;                //<! spread is a multiplier for formation flight, should be bigger than 100
+            int tolerance_;             //<! if this ship is tolerance_ away from targetPosition_, ship decides that it finished moving
+    };
+}
+
+#endif /* _FlyingController_H__ */
Index: code/trunk/src/orxonox/controllers/FormationController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/FormationController.cc	(revision 11020)
+++ code/trunk/src/orxonox/controllers/FormationController.cc	(revision 11052)
@@ -277,5 +277,5 @@
         }
 
-        Vector2 coord = get2DViewcoordinates(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
+        Vector2 coord = get2DViewCoordinates(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
         float distance = (target - this->getControllableEntity()->getPosition()).length();
         float rotateX = clamp(coord.x * 10, -1.0f, 1.0f);
@@ -970,4 +970,6 @@
         if (controller)
         {
+            if (controller->getIdentifier()->getName() == "MasterController")
+                return true;
             FormationController* ac = orxonox_cast<FormationController*>(controller);
             if (ac)
@@ -981,4 +983,6 @@
         if (controller)
         {
+            if (controller->getIdentifier()->getName() == "MasterController")
+                return true;
             FormationController* ac = orxonox_cast<FormationController*>(controller);
             if (ac)
@@ -1069,5 +1073,5 @@
             return;
 
-        Vector2 coord = get2DViewcoordinates(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
+        Vector2 coord = get2DViewCoordinates(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
         float distance = (target - this->getControllableEntity()->getPosition()).length();
 
Index: code/trunk/src/orxonox/controllers/HumanController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/HumanController.cc	(revision 11020)
+++ code/trunk/src/orxonox/controllers/HumanController.cc	(revision 11052)
@@ -199,5 +199,5 @@
     @brief
         Starts the boosting mode.
-        Resets the boosting timeout and ells the ControllableEntity to boost (or not boost anymore).
+        Resets the boosting timeout and tells the ControllableEntity to boost (or not boost anymore).
     */
     void HumanController::startBoosting(void)
Index: code/trunk/src/orxonox/controllers/MasterController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/MasterController.cc	(revision 11052)
+++ code/trunk/src/orxonox/controllers/MasterController.cc	(revision 11052)
@@ -0,0 +1,129 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "MasterController.h"
+#include "controllers/ActionpointController.h"
+namespace orxonox
+{
+
+    RegisterClass(MasterController);
+
+    //Leaders share the fact that they have Wingmans
+    MasterController::MasterController(Context* context) : Controller(context)
+    {
+        RegisterObject(MasterController);
+        this->controllers_.clear();
+        this->numberOfTicksPassedSinceLastActionCall_ = 0;
+        this->indexOfCurrentController_ = 0;
+        this->ticks_ = 0;
+    }
+
+    MasterController::~MasterController()
+    {
+        this->controllers_.clear();
+    } 
+    /*HACK*/
+    //the whole idea is a hack
+    void MasterController::tick(float dt)
+    {   
+        if (!this->isActive())
+            return;  
+        ++this->ticks_;
+        if (this->ticks_ == 1)
+        {
+            //fill the vector in the first tick
+            for (ObjectList<ActionpointController>::iterator it = ObjectList<ActionpointController>::begin(); it; ++it)
+            {
+                //----0ptr?----
+                if (!it)
+                    continue;
+                this->controllers_.push_back(*it);
+            }
+        }
+        else
+        {
+            if (this->controllers_.empty())
+                return;
+
+            //iterate over vecotr with the index, keep index in boundaries 
+            if (this->indexOfCurrentController_ >= this->controllers_.size())
+            {
+                this->indexOfCurrentController_ = 0;
+            }
+            //each 9 ticks index is incremented
+            if (this->numberOfTicksPassedSinceLastActionCall_ >= 9)
+            {
+                this->numberOfTicksPassedSinceLastActionCall_ = 0;
+            }
+
+            if (this->numberOfTicksPassedSinceLastActionCall_ > 0)
+            {
+                if (this->numberOfTicksPassedSinceLastActionCall_ == 3)
+                {
+                    //check if 0ptr
+                    if (!this->controllers_.at(this->indexOfCurrentController_))
+                    {
+                        this->controllers_.erase(this->controllers_.begin() + this->indexOfCurrentController_);
+                        return;
+                    }
+                    //call maneuver for current index
+                    this->controllers_.at(this->indexOfCurrentController_)->maneuver();
+                }
+                else if (this->numberOfTicksPassedSinceLastActionCall_ == 6)
+                {
+                    //check if 0ptr
+                    if (!this->controllers_.at(this->indexOfCurrentController_))
+                    {
+                        this->controllers_.erase(this->controllers_.begin() + this->indexOfCurrentController_);
+                        return;
+                    }
+                    //call canFire for current index
+                    this->controllers_.at(this->indexOfCurrentController_)->bShooting_ = this->controllers_.at(this->indexOfCurrentController_)->canFire();   
+                }
+                ++this->numberOfTicksPassedSinceLastActionCall_;
+            }
+            else
+            {
+                //check if 0ptr
+                if (!this->controllers_.at(this->indexOfCurrentController_))
+                {
+                    this->controllers_.erase(this->controllers_.begin() + this->indexOfCurrentController_);
+                    return;
+                }
+                //call action for current index
+                this->controllers_.at(this->indexOfCurrentController_)->action();   
+                 
+                //bCopyOrientation makes ship oscillate like crazy if set to true all the time.s
+                this->controllers_.at(this->indexOfCurrentController_)->bCopyOrientation_ = this->ticks_ % 3 == 0;
+
+                ++this->numberOfTicksPassedSinceLastActionCall_;
+                ++this->indexOfCurrentController_;
+            }
+        }
+    }
+}
Index: code/trunk/src/orxonox/controllers/MasterController.h
===================================================================
--- code/trunk/src/orxonox/controllers/MasterController.h	(revision 11052)
+++ code/trunk/src/orxonox/controllers/MasterController.h	(revision 11052)
@@ -0,0 +1,78 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MasterController_H__
+#define _MasterController_H__
+
+#include "controllers/Controller.h"
+#include "controllers/ActionpointController.h"
+#include "tools/interfaces/Tickable.h"
+
+
+
+namespace orxonox
+{
+    /**
+    @brief
+      calles action(), maneuver() and canFire() methods of all the ActionpointControllers in level.
+      Only one instance of MasterController is to be placed in level.
+      If no MasterController is initialized, none of ActionpointControllers will work.
+      Example:
+      <Pawn position = "100000, 100000, 100000">
+        <controller>
+          <MasterController>
+          </MasterController>
+        </controller>
+      </Pawn>
+    */
+    class _OrxonoxExport MasterController : public Controller, public Tickable
+    {
+        public:
+            //----[language demanded functions]----            
+                MasterController(Context* context);
+
+                virtual ~MasterController();
+            //----[/language demanded functions]----            
+
+            //----[orxonox demanded functions]----
+                virtual void tick(float dt); 
+
+            //----[orxonox demanded functions]----
+
+        protected:
+          
+        private:
+            std::vector<WeakPtr<ActionpointController> > controllers_;  //<! vector of controllers, which action(), canFire() and maneuver() methods are to be called
+            size_t indexOfCurrentController_;                        //<! index of current controller
+            unsigned int numberOfTicksPassedSinceLastActionCall_;
+            unsigned int ticks_;                                     //<! local tick counter            
+
+    };
+}
+
+#endif /* _MasterController_H__ */
Index: code/trunk/src/orxonox/controllers/SectionController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/SectionController.cc	(revision 11052)
+++ code/trunk/src/orxonox/controllers/SectionController.cc	(revision 11052)
@@ -0,0 +1,285 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SectionController.h"
+
+namespace orxonox
+{
+
+    RegisterClass(SectionController);
+
+    //Leaders share the fact that they have Wingmans
+    SectionController::SectionController(Context* context) : ActionpointController(context)
+    {
+        RegisterObject(SectionController);
+        this->setFormationMode(FormationMode::FINGER4);
+
+        this->myWingman_ = 0;
+        this->myDivisionLeader_ = 0;
+        this->bFirstAction_ = true;
+
+    }
+   
+    SectionController::~SectionController()
+    {
+       for (size_t i = 0; i < this->actionpoints_.size(); ++i)
+        {
+            if(this->actionpoints_[i])
+                this->actionpoints_[i]->destroy();
+        }
+        this->parsedActionpoints_.clear();
+        this->actionpoints_.clear();
+    }
+    void SectionController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(SectionController, XMLPort, xmlelement, mode);
+    }
+
+    //----in tick, move (or look) and shoot----
+    void SectionController::tick(float dt)
+    {
+        if (!this->isActive())
+            return;
+   
+        SUPER(SectionController, tick, dt);
+        
+    }
+
+    void SectionController::action()
+    {
+        if (!this || !this->getControllableEntity() || !this->isActive())
+            return;
+
+        //----If no leader, find one----  
+        if (!myDivisionLeader_)
+        {
+            ActionpointController* newDivisionLeader = findNewDivisionLeader();
+            if (!this || !this->getControllableEntity())
+                return;
+
+            this->myDivisionLeader_ = newDivisionLeader;
+        }
+        //----If have leader----
+        else
+        {
+        }
+        if (!myDivisionLeader_)
+        {
+            ActionpointController::action();
+            if (!this || !this->getControllableEntity())
+                return;
+            if (!(this->parsedActionpoints_.empty() && this->loopActionpoints_.empty()))
+            {
+                if (this->myWingman_)
+                {
+                    this->myWingman_->takeActionpoints(this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+                }    
+            }
+        }
+        else if (myDivisionLeader_)
+        {
+            if (this->myDivisionLeader_->bKeepFormation_ || !(this->myDivisionLeader_->getAction() == Action::FIGHT 
+                || this->myDivisionLeader_->getAction() == Action::FIGHTALL
+                || this->myDivisionLeader_->getAction() == Action::ATTACK))
+            {
+                this->keepFormation();
+            }
+            else if (!this->myDivisionLeader_->bKeepFormation_)
+            {
+                if (!this || !this->getControllableEntity())
+                    return;
+
+                if (!this->hasTarget())
+                {
+                    this->chooseTarget(); 
+                }
+
+            }
+        }
+
+    }
+
+    
+    //PRE: myDivisionLeader_ != 0 && myDivisionLeader_->action_ == Action::FIGHT
+    //POST: this->target_ is set unless division leader doesn't have one
+    void SectionController::chooseTarget()
+    {
+        //----If division leader fights, cover him by fighting emenies close to his target----
+        Action::Value action = this->myDivisionLeader_->getAction();
+
+        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
+        {
+            Pawn* target;
+            //----if he has a target----
+            if (this->myDivisionLeader_->hasTarget())
+            {
+                //----try to find a new target if division leader has wingman (doing fine) and no good target already set----
+                if ( this->myDivisionLeader_->hasWingman() && 
+                    !( this->hasTarget() && this->getTarget() != this->myDivisionLeader_->getTarget() ) )
+                {
+                    bool foundTarget = false;
+                    //----new target should be close to division's target----
+                    Vector3 divisionTargetPosition = this->myDivisionLeader_->getTarget()->getWorldPosition();
+                    Gametype* gt = this->getGametype();
+                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+                    {
+                        //----is enemy?----
+                        if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
+                            continue;           
+                        //----in range?----
+                        if (((*itP)->getWorldPosition() - divisionTargetPosition).length() < 3000 && 
+                            (*itP) != this->myDivisionLeader_->getTarget())
+                        {
+                            foundTarget = true;
+                            target =  (*itP);
+                            break; 
+                        }
+                    }
+                    //----no target? then attack same target as division leader----
+                    if (!foundTarget)
+                    {
+                        target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
+                    }
+                }
+                //----if division leader doesn't have a wingman, support his fire----
+                else
+                {
+                    target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
+                }
+            }
+            //----If he fights but doesn't have a target, wait for him to get one----
+            else
+            {
+
+            }
+            this->setTarget (orxonox_cast<ControllableEntity*>(target));
+        }
+        else
+        {
+        } 
+    }
+    Vector3 SectionController::getFormationPosition ()
+    {
+        this->setFormationMode( this->myDivisionLeader_->getFormationMode() );
+        this->spread_ = this->myDivisionLeader_->getSpread();
+        Vector3* targetRelativePosition;
+        switch (this->formationMode_){
+            case FormationMode::WALL:
+            {
+                targetRelativePosition = new Vector3 (-2.0f*this->spread_, 0, 0);   
+                break;
+            }
+            case FormationMode::FINGER4: 
+            {
+                targetRelativePosition = new Vector3 (-2.0f*this->spread_, 0, 1.0f*this->spread_);   
+                break;
+            }
+            
+            case FormationMode::DIAMOND: 
+            {
+                targetRelativePosition = new Vector3 (-2.0f*this->spread_, 0, 1.0f*this->spread_);
+                break;
+            }
+        }
+        Vector3 result = *targetRelativePosition;
+        delete targetRelativePosition;
+        return result;
+    }
+
+    void SectionController::keepFormation()
+    {
+        this->bKeepFormation_ = true;
+        ControllableEntity* leaderEntity = this->myDivisionLeader_->getControllableEntity();
+        Vector3 targetRelativePosition = this->getFormationPosition();
+        if (!leaderEntity)
+            return;
+        FlyingController::keepFormation(leaderEntity, targetRelativePosition);
+    }
+
+    ActionpointController* SectionController::findNewDivisionLeader()
+    {
+
+        if (!this->getControllableEntity())
+            return 0;
+
+        ActionpointController* closestLeader = 0;
+        float minDistance =  std::numeric_limits<float>::infinity();
+        //go through all pawns
+        for (ObjectList<ActionpointController>::iterator it = ObjectList<ActionpointController>::begin(); it; ++it)
+        {
+            //0ptr or not DivisionController?
+            if (!(it) || !((it)->getIdentifier()->getName() == "DivisionController") || !(it->getControllableEntity()))
+                continue;
+            //same team?
+            if ((this->getControllableEntity()->getTeam() != (it)->getControllableEntity()->getTeam()))
+                continue;
+
+            //is equal to this?
+            if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity())
+                continue;
+
+            float distance = CommonController::distance (it->getControllableEntity(), this->getControllableEntity());
+            
+            if (distance < minDistance && !(it->hasFollower()))
+            {
+                closestLeader = *it;
+                minDistance = distance;
+            }
+          
+        }
+        if (closestLeader)
+        {
+            if (closestLeader->setFollower(this))
+                return closestLeader;
+        }
+        return 0;
+    }
+
+    bool SectionController::setWingman(ActionpointController* newWingman)
+    {
+
+        if (!this->myWingman_)
+        {
+            this->myWingman_ = newWingman;
+            newWingman->takeActionpoints (this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+    
+    bool SectionController::hasWingman()
+    {
+        if (this->myWingman_)
+            return true;
+        else
+            return false;
+    }
+}
Index: code/trunk/src/orxonox/controllers/SectionController.h
===================================================================
--- code/trunk/src/orxonox/controllers/SectionController.h	(revision 11052)
+++ code/trunk/src/orxonox/controllers/SectionController.h	(revision 11052)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _SectionController_H__
+#define _SectionController_H__
+
+#include "controllers/ActionpointController.h"
+
+
+namespace orxonox
+{
+    /**
+        @note
+        ActionpointController will not work, if there is no MasterController in the level!
+        All the demos are in a file called AITest.oxw. In the menu look for New AI Testing Level.
+    */
+    class _OrxonoxExport SectionController : public ActionpointController
+    {
+        public:
+            //----[language demanded functions]----            
+                SectionController(Context* context);
+
+                virtual ~SectionController();
+            //----[/language demanded functions]----
+            
+            //----[orxonox demanded functions]----
+                virtual void tick(float dt); 
+                
+                virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            //----[/orxonox demanded functions]----
+            
+            //----[own functions]----
+                ActionpointController* findNewDivisionLeader();
+
+                virtual bool setWingman(ActionpointController* newWingman);
+                virtual bool hasWingman();
+                virtual bool hasFollower()
+                    { return false; }
+                void chooseTarget();
+            //----[/own functions]----
+
+        protected:       
+            //----action must only be managed by this----     
+                virtual void action(); //<! action() is called in regular intervals by MasterController managing the bot's behaviour.
+                Vector3 getFormationPosition ();
+                void keepFormation();
+        private:
+            //----private variables-----
+                bool bFirstAction_;
+                
+    };
+}
+
+#endif /* _SectionController_H__ */
Index: code/trunk/src/orxonox/controllers/WingmanController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/WingmanController.cc	(revision 11052)
+++ code/trunk/src/orxonox/controllers/WingmanController.cc	(revision 11052)
@@ -0,0 +1,227 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WingmanController.h"
+
+
+namespace orxonox
+{
+
+    RegisterClass(WingmanController);
+    
+    //ActionpointController contains all common functionality of AI Controllers
+    WingmanController::WingmanController(Context* context) : ActionpointController(context)
+    {
+        RegisterObject(WingmanController);
+        this->myLeader_ = 0;
+        this->bFirstAction_ = true;
+
+    }
+
+    WingmanController::~WingmanController()
+    {
+        for (size_t i = 0; i < this->actionpoints_.size(); ++i)
+        {
+            if(this->actionpoints_[i])
+                this->actionpoints_[i]->destroy();
+        }
+        this->parsedActionpoints_.clear();
+        this->actionpoints_.clear();
+    }
+  
+    void WingmanController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(WingmanController, XMLPort, xmlelement, mode);
+    }
+    
+    //----in tick, move (or look) and shoot----
+    void WingmanController::tick(float dt)
+    {   
+        if (!this->isActive())
+            return; 
+        
+        SUPER(WingmanController, tick, dt);
+
+    }
+    
+    //----action for hard calculations----
+    void WingmanController::action()
+    {
+        if (!this || !this->getControllableEntity() || !this->isActive())
+            return;
+        //----If no leader, find one----
+        if (!this->myLeader_)
+        {
+            ActionpointController* newLeader = (findNewLeader());
+            if (!this || !this->getControllableEntity())
+                return;
+
+            this->myLeader_ = newLeader;
+            if (this->myLeader_)
+            {
+               
+            }
+        }
+        //----If have leader, he will deal with logic----
+        else
+        {
+
+        }
+        if (!this->myLeader_)
+        {
+            ActionpointController::action();
+        }
+        else if (this->myLeader_)
+        {
+            if (this->myLeader_->bKeepFormation_ || !(this->myLeader_->getAction() == Action::FIGHT 
+                || this->myLeader_->getAction() == Action::FIGHTALL
+                || this->myLeader_->getAction() == Action::ATTACK))
+            {
+                this->keepFormation();
+            }
+            else if (!this->myLeader_->bKeepFormation_)
+            {
+                if (!this || !this->getControllableEntity())
+                    return;
+
+                if (!this->hasTarget())
+                {
+                    this->setTarget(this->myLeader_->getTarget());
+                }
+                
+            }
+        }
+    }
+     
+   
+    Vector3 WingmanController::getFormationPosition ()
+    {
+
+
+        this->setFormationMode( this->myLeader_->getFormationMode() );
+        Vector3* targetRelativePosition;
+        this->spread_ = this->myLeader_->getSpread();
+        if (this->myLeader_->getIdentifier()->getName() == "DivisionController")
+        {
+            switch (this->formationMode_){
+                case FormationMode::WALL:
+                {
+                    targetRelativePosition = new Vector3 (2.0f*this->spread_, 0, 0 - 1.0f*this->tolerance_);
+                    break;
+                }
+                case FormationMode::FINGER4: 
+                {
+                    targetRelativePosition = new Vector3 (2.0f*this->spread_, 0, this->spread_ - 1.0f*this->tolerance_);
+                    break;
+                }
+                case FormationMode::DIAMOND: 
+                {
+                    targetRelativePosition = new Vector3 (2.0f*this->spread_, 0, this->spread_ - 1.0f*this->tolerance_);
+                    break;
+                }
+            }
+        }
+        else
+        {
+            switch (this->formationMode_){
+                case FormationMode::WALL:
+                {
+                    targetRelativePosition = new Vector3 (-2.0f*this->spread_, 0, 0 - 1.0f*this->tolerance_);
+                    break;
+                }
+                case FormationMode::FINGER4: 
+                {
+                    targetRelativePosition = new Vector3 (-2.0f*this->spread_, 0, this->spread_ - 1.0f*this->tolerance_);
+                    break;
+                }
+                case FormationMode::DIAMOND: 
+                {
+                    targetRelativePosition = new Vector3 (2.0f*this->spread_, -1.0f*this->spread_, 0 - 1.0f*this->tolerance_);
+                    break;
+                }
+            }
+        }
+        Vector3 result = *targetRelativePosition;
+        delete targetRelativePosition;
+        return result;
+    }
+    void WingmanController::keepFormation()
+    {
+        this->bKeepFormation_ = true;
+        ControllableEntity* leaderEntity = this->myLeader_->getControllableEntity();
+        Vector3 targetRelativePosition = this->getFormationPosition();
+        if (!leaderEntity)
+            return;
+        FlyingController::keepFormation (leaderEntity, targetRelativePosition);
+    }
+    //----POST: closest leader that is ready to take a new wingman is returned----
+    ActionpointController* WingmanController::findNewLeader()
+    {
+
+        if (!this->getControllableEntity())
+            return 0;
+
+        //----vars for finding the closest leader----
+        ActionpointController* closestLeader = 0;
+        float minDistance =  std::numeric_limits<float>::infinity();
+        Gametype* gt = this->getGametype();
+
+        for (ObjectList<ActionpointController>::iterator it = ObjectList<ActionpointController>::begin(); it; ++it)
+        {
+            //----0ptr or not a leader or dead?----
+            if (!it || 
+                (it->getIdentifier()->getName() != "SectionController" && it->getIdentifier()->getName() != "DivisionController") || 
+                !(it->getControllableEntity()))
+                continue;
+            
+            //----same team?----
+            if ( !CommonController::sameTeam (this->getControllableEntity(), (it)->getControllableEntity(), gt) )
+                continue;
+            
+            //----check distance----
+            float distance = CommonController::distance (it->getControllableEntity(), this->getControllableEntity());
+            if (distance < minDistance && !(it->hasWingman()))
+            {
+                closestLeader = *it;
+                minDistance = distance;
+            }
+        }
+        if (closestLeader)
+        {
+            //----Racing conditions----
+            /*TODO: racing condition check is wrong and redundant, as there is no multithreading here, ticks get called one after another,
+            so it can be simplified to a check of whether leader got a wingman*/
+            if (closestLeader->setWingman(orxonox_cast<ActionpointController*>(this)))
+            {
+                return closestLeader;
+            }
+        }
+        return 0;
+    }
+
+}
Index: code/trunk/src/orxonox/controllers/WingmanController.h
===================================================================
--- code/trunk/src/orxonox/controllers/WingmanController.h	(revision 11052)
+++ code/trunk/src/orxonox/controllers/WingmanController.h	(revision 11052)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _WingmanController_H__
+#define _WingmanController_H__
+
+
+#include "controllers/ActionpointController.h"
+
+
+namespace orxonox
+{
+    /**
+        @note
+        ActionpointController will not work, if there is no MasterController in the level!
+        All the demos are in a file called AITest.oxw. In the menu look for New AI Testing Level.
+    */
+    class _OrxonoxExport WingmanController : public ActionpointController
+    {
+        public:
+            //----[language demanded functions]----
+                WingmanController(Context* context);
+
+                virtual ~WingmanController();
+            //----[/language demanded functions]----
+            
+            //----[orxonox demanded functions]----
+                virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+                virtual void tick(float dt); 
+                virtual bool hasWingman()
+                    { return false; }
+                virtual bool hasFollower()
+                    { return false; }
+            //----[/orxonox demanded functions]----
+
+            //----[own functions]----
+               ActionpointController* findNewLeader();
+            //----[/own functions]----
+
+        protected:
+            //----action must only be managed by this----
+                virtual void action(); //<! action() is called in regular intervals managing the bot's behaviour.
+                Vector3 getFormationPosition ();
+                void keepFormation();
+                
+        private:
+            //----private variables-----
+                WeakPtr<ActionpointController> myLeader_;
+                bool bFirstAction_;
+
+
+    };
+}
+
+#endif /* _WingmanController_H__ */
Index: code/trunk/src/orxonox/gametypes/Dynamicmatch.cc
===================================================================
--- code/trunk/src/orxonox/gametypes/Dynamicmatch.cc	(revision 11020)
+++ code/trunk/src/orxonox/gametypes/Dynamicmatch.cc	(revision 11052)
@@ -86,4 +86,10 @@
     }
 
+    Dynamicmatch::~Dynamicmatch()
+    {
+        for (std::set<Timer*>::iterator it = this->piggyTimers_.begin(); it != this->piggyTimers_.end(); ++it)
+            delete (*it);
+    }
+
     void Dynamicmatch::setConfigValues()
     {
@@ -312,6 +318,8 @@
             spaceship->addSpeedFactor(5);
             ExecutorPtr executor = createExecutor(createFunctor(&Dynamicmatch::resetSpeedFactor, this));
-            executor->setDefaultValue(0, spaceship);
-            new Timer(10, false, executor, true);
+            Timer* timer = new Timer(10, false, executor);
+            executor->setDefaultValue(0, spaceship); // TODO: use WeakPtr because spaceship can be destroyed in the meantime
+            executor->setDefaultValue(1, timer);
+            this->piggyTimers_.insert(timer);
         }
     }
@@ -590,5 +598,5 @@
     }
 
-    void Dynamicmatch::resetSpeedFactor(SpaceShip* spaceship)// helper function
+    void Dynamicmatch::resetSpeedFactor(SpaceShip* spaceship, Timer* timer)// helper function
     {
         if (spaceship)
@@ -596,4 +604,7 @@
             spaceship->addSpeedFactor(1.0f/5.0f);
         }
+
+        this->piggyTimers_.erase(timer);
+        delete timer;
     }
 
Index: code/trunk/src/orxonox/gametypes/Dynamicmatch.h
===================================================================
--- code/trunk/src/orxonox/gametypes/Dynamicmatch.h	(revision 11020)
+++ code/trunk/src/orxonox/gametypes/Dynamicmatch.h	(revision 11052)
@@ -33,4 +33,5 @@
 
 #include <map>
+#include <set>
 #include <vector>
 
@@ -45,5 +46,5 @@
         public:
             Dynamicmatch(Context* context);
-            virtual ~Dynamicmatch() {}
+            virtual ~Dynamicmatch();
 
             bool notEnoughPigs;
@@ -77,5 +78,5 @@
             virtual void rewardPig();
             void grantPigBoost(SpaceShip* spaceship); // Grant the piggy a boost.
-            void resetSpeedFactor(SpaceShip* spaceship);
+            void resetSpeedFactor(SpaceShip* spaceship, Timer* timer);
             void tick (float dt);// used to end the game
             SpawnPoint* getBestSpawnPoint(PlayerInfo* player) const;
@@ -88,4 +89,5 @@
             std::map< PlayerInfo*, int > playerParty_; //player's parties are recorded here
             std::vector<ColourValue> partyColours_; //aus TeamDeathmatch
+            std::set<Timer*> piggyTimers_;
             unsigned int numberOf[3]; //array to count number of chasers, pigs, killers
             float pointsPerTime;
Index: code/trunk/src/orxonox/infos/PlayerInfo.cc
===================================================================
--- code/trunk/src/orxonox/infos/PlayerInfo.cc	(revision 11020)
+++ code/trunk/src/orxonox/infos/PlayerInfo.cc	(revision 11052)
@@ -202,4 +202,8 @@
 
         this->changedControllableEntity();
+
+         // HACK-ish
+        if(this->isHumanPlayer())
+            entity->createHud();
     }
 
@@ -252,4 +256,6 @@
         if( !entity || this->previousControllableEntity_.size() == 0 )
             return;
+
+        entity->destroyHud(); // HACK-ish
 
         this->controllableEntity_->setController(0);
Index: code/trunk/src/orxonox/items/ShipPart.cc
===================================================================
--- code/trunk/src/orxonox/items/ShipPart.cc	(revision 11020)
+++ code/trunk/src/orxonox/items/ShipPart.cc	(revision 11052)
@@ -41,5 +41,4 @@
 #include "worldentities/StaticEntity.h"
 #include "items/PartDestructionEvent.h"
-#include "worldentities/BigExplosion.h"
 #include "chat/ChatManager.h"
 
@@ -105,8 +104,8 @@
     void ShipPart::explode()
     {
-        BigExplosion* chunk = new BigExplosion(this->getContext());
-        chunk->setPosition(this->parent_->getPosition() + this->parent_->getOrientation() * (this->explosionPosition_));
-        //chunk->setPosition(this->parent_->getPosition() + this->parent_->getOrientation() * Vector3(this->entityList_[0]->getLocalInertia()));
-        chunk->setVelocity(this->parent_->getVelocity());
+        // BigExplosion* chunk = new BigExplosion(this->getContext());
+        // chunk->setPosition(this->parent_->getPosition() + this->parent_->getOrientation() * (this->explosionPosition_));
+        // //chunk->setPosition(this->parent_->getPosition() + this->parent_->getOrientation() * Vector3(this->entityList_[0]->getLocalInertia()));
+        // chunk->setVelocity(this->parent_->getVelocity());
 
         // this->explosionSound_->setPosition(this->parent_->getPosition());
Index: code/trunk/src/orxonox/overlays/OrxonoxOverlay.cc
===================================================================
--- code/trunk/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 11020)
+++ code/trunk/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 11052)
@@ -450,3 +450,11 @@
         tempTx->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, colour);
     }
+
+    void OrxonoxOverlay::setZOrder(unsigned short order)
+    {
+        if (this->overlay_)
+        {
+            this->overlay_->setZOrder(order);
+        }
+    }
 }
Index: code/trunk/src/orxonox/overlays/OrxonoxOverlay.h
===================================================================
--- code/trunk/src/orxonox/overlays/OrxonoxOverlay.h	(revision 11020)
+++ code/trunk/src/orxonox/overlays/OrxonoxOverlay.h	(revision 11052)
@@ -65,5 +65,5 @@
           only for displaying a picture).
         - Reacts to changes of the window aspect
-        - Last but not least: On demand you can tell the overlay to automatically resale to correct for
+        - Last but not least: On demand you can tell the overlay to automatically rescale to correct for
           aspect distortion. E.g. if you play 1024x768 you wouldn't want a round object to be oval.
           Remark: This can (due to the Ogre::Overlay transformation order) only work for angle that are
@@ -186,4 +186,5 @@
         virtual void changedOverlayGroup()
             { this->changedVisibility(); }
+        virtual void setZOrder(unsigned short order);
 
     protected:
Index: code/trunk/src/orxonox/overlays/OverlayGroup.cc
===================================================================
--- code/trunk/src/orxonox/overlays/OverlayGroup.cc	(revision 11020)
+++ code/trunk/src/orxonox/overlays/OverlayGroup.cc	(revision 11052)
@@ -42,10 +42,25 @@
 namespace orxonox
 {
+    namespace autocompletion
+    {
+        /**
+            @brief Returns the names of all currently existing OverlayGroups.
+        */
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(overlaygroupnames)();
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(overlaygroupnames)()
+        {
+            ArgumentCompletionList names;
+            for (ObjectList<OverlayGroup>::iterator it = ObjectList<OverlayGroup>::begin(); it; ++it)
+                names.push_back(ArgumentCompletionListElement(it->getName(), getLowercase(it->getName())));
+            return names;
+        }
+    }
+
+    SetConsoleCommand("OverlayGroup", "toggleVisibility", &OverlayGroup::toggleVisibility).argumentCompleter(0, autocompletion::overlaygroupnames());
+    SetConsoleCommand("OverlayGroup", "show",             &OverlayGroup::show            ).argumentCompleter(0, autocompletion::overlaygroupnames());
+    SetConsoleCommand("OverlayGroup", "scaleGroup",       &OverlayGroup::scaleGroup      ).argumentCompleter(0, autocompletion::overlaygroupnames());
+    SetConsoleCommand("OverlayGroup", "scrollGroup",      &OverlayGroup::scrollGroup     ).argumentCompleter(0, autocompletion::overlaygroupnames());
+
     RegisterClass(OverlayGroup);
-
-    SetConsoleCommand("OverlayGroup", "toggleVisibility", &OverlayGroup::toggleVisibility);
-    SetConsoleCommand("OverlayGroup", "show", &OverlayGroup::show);
-    SetConsoleCommand("OverlayGroup", "scaleGroup",       &OverlayGroup::scaleGroup);
-    SetConsoleCommand("OverlayGroup", "scrollGroup",      &OverlayGroup::scrollGroup);
 
     OverlayGroup::OverlayGroup(Context* context)
Index: code/trunk/src/orxonox/weaponsystem/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/weaponsystem/CMakeLists.txt	(revision 11020)
+++ code/trunk/src/orxonox/weaponsystem/CMakeLists.txt	(revision 11052)
@@ -1,4 +1,5 @@
 ADD_SOURCE_FILES(ORXONOX_SRC_FILES
   Munition.cc
+  ReplenishingMunition.cc
   Weapon.cc
   WeaponMode.cc
Index: code/trunk/src/orxonox/weaponsystem/Munition.cc
===================================================================
--- code/trunk/src/orxonox/weaponsystem/Munition.cc	(revision 11020)
+++ code/trunk/src/orxonox/weaponsystem/Munition.cc	(revision 11052)
@@ -24,5 +24,5 @@
  *      Fabian 'x3n' Landau
  *   Co-authors:
- *      ...
+ *      Fabien Vultier
  *
  */
@@ -32,4 +32,5 @@
 #include "core/CoreIncludes.h"
 #include "core/command/Executor.h"
+#include "core/XMLPort.h"
 
 namespace orxonox
@@ -43,23 +44,33 @@
         this->maxMunitionPerMagazine_ = 10;
         this->maxMagazines_ = 10;
-        this->magazines_ = 10;
-
-        this->bUseSeparateMagazines_ = false;
-        this->bStackMunition_ = true;
+        this->unassignedMagazines_ = 10;
+
+        this->deployment_ = MunitionDeployment::Stack;
         this->bAllowMunitionRefilling_ = true;
         this->bAllowMultiMunitionRemovementUnderflow_ = true;
 
-        this->reloadTime_ = 0;
+        this->reloadTime_ = 0.5f;
+
+        this->lastFilledWeaponMode_ = NULL;
     }
 
     Munition::~Munition()
     {
-        for (std::map<WeaponMode*, Magazine*>::iterator it = this->currentMagazines_.begin(); it != this->currentMagazines_.end(); ++it)
+        for (std::map<WeaponMode*, Magazine*>::iterator it = this->assignedMagazines_.begin(); it != this->assignedMagazines_.end(); ++it)
             delete it->second;
     }
 
+    void Munition::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Munition, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Munition, "initialmagazines", setNumMagazines, getNumMagazines, xmlelement, mode);
+        XMLPortParam(Munition, "maxmagazines", setMaxMagazines, getMaxMagazines, xmlelement, mode);
+        XMLPortParam(Munition, "munitionpermagazine", setMaxMunitionPerMagazine, getMaxMunitionPerMagazine, xmlelement, mode);
+    }
+
     Munition::Magazine* Munition::getMagazine(WeaponMode* user) const
     {
-        if (this->bUseSeparateMagazines_)
+        if (deployment_ == MunitionDeployment::Separate)
         {
             // For separated magazines we definitively need a given user
@@ -68,6 +79,6 @@
 
             // Use the map to get the magazine assigned to the given user
-            std::map<WeaponMode*, Magazine*>::const_iterator it = this->currentMagazines_.find(user);
-            if (it != this->currentMagazines_.end())
+            std::map<WeaponMode*, Magazine*>::const_iterator it = this->assignedMagazines_.find(user);
+            if (it != this->assignedMagazines_.end())
                 return it->second;
         }
@@ -75,6 +86,6 @@
         {
             // We don't use separate magazines for each user, so just take the first magazine
-            if (this->currentMagazines_.size() > 0)
-                return this->currentMagazines_.begin()->second;
+            if (this->assignedMagazines_.size() > 0)
+                return this->assignedMagazines_.begin()->second;
         }
 
@@ -87,7 +98,7 @@
         if (magazine)
         {
-            if (this->bStackMunition_)
+            if (deployment_ == MunitionDeployment::Stack)
                 // With stacked munition every magazine contributes to the total amount
-                return this->maxMunitionPerMagazine_ * this->magazines_ + magazine->munition_;
+                return this->maxMunitionPerMagazine_ * this->unassignedMagazines_ + magazine->munition_;
             else
                 // Wihtout stacked munition we just consider the current magazine
@@ -109,18 +120,23 @@
     unsigned int Munition::getNumMagazines() const
     {
-        if (this->bStackMunition_)
+        if (deployment_ == MunitionDeployment::Stack)
         {
             // If we stack munition and the current magazine is still full, it counts too
             Magazine* magazine = this->getMagazine(0);
             if (magazine && magazine->munition_ == this->maxMunitionPerMagazine_)
-                return this->magazines_ + 1;
-        }
-
-        return this->magazines_;
+                return this->unassignedMagazines_ + 1;
+        }
+
+        return this->unassignedMagazines_;
+    }
+
+    void Munition::setNumMagazines(unsigned int numMagazines)
+    {
+        this->unassignedMagazines_ = numMagazines;
     }
 
     unsigned int Munition::getMaxMunition() const
     {
-        if (this->bStackMunition_)
+        if (deployment_ == MunitionDeployment::Stack)
             return this->maxMunitionPerMagazine_ * this->maxMagazines_;
         else
@@ -135,17 +151,26 @@
             unsigned int munition = magazine->munition_;
 
-            // If we stack munition, we con't care about the current magazine - we just need enough munition in total
-            if (this->bStackMunition_)
-                munition += this->maxMunitionPerMagazine_ * this->magazines_;
+            // If we stack munition, we don't care about the current magazine - we just need enough munition in total
+            if (deployment_ == MunitionDeployment::Stack)
+            {
+                munition += this->maxMunitionPerMagazine_ * this->unassignedMagazines_;
+            }
 
             if (munition == 0)
+            {
                 // Absolutely no munition - no chance to take munition
                 return false;
+            }
             else if (this->bAllowMultiMunitionRemovementUnderflow_)
+            {
                 // We're not empty AND we allow underflow, so this will always work
                 return true;
+            }
             else
+            {
                 // We don't allow underflow, so we have to check the amount
                 return (munition >= amount);
+            }
+
         }
         return false;
@@ -169,5 +194,5 @@
             {
                 // Not enough munition
-                if (this->bStackMunition_)
+                if (deployment_ == MunitionDeployment::Stack)
                 {
                     // We stack munition, so just take what we can and then load the next magazine
@@ -175,5 +200,5 @@
                     magazine->munition_ = 0;
 
-                    if (this->reload(0))
+                    if (this->reload(NULL))
                         // Successfully reloaded, continue recursively
                         return this->takeMunition(amount, 0);
@@ -199,5 +224,5 @@
     {
         // As long as we have enough magazines (and don't stack munition) we can reload
-        return (this->magazines_ > 0 && !this->bStackMunition_);
+        return (this->unassignedMagazines_ > 0 && deployment_ != MunitionDeployment::Stack);
     }
 
@@ -207,5 +232,5 @@
         if (magazine)
         {
-            if (this->bStackMunition_)
+            if (deployment_ == MunitionDeployment::Stack)
                 // With stacked munition, we never have to reload
                 return false;
@@ -227,26 +252,32 @@
 
         // Check if we actually can reload
-        if (this->magazines_ == 0)
+        if (this->unassignedMagazines_ == 0)
             return false;
 
         // If we use separate magazines for each user, we definitively need a user given
-        if (this->bUseSeparateMagazines_ && !user)
+        if (deployment_ == MunitionDeployment::Separate && !user)
             return false;
 
         // If we don't use separate magazines, set user to 0
-        if (!this->bUseSeparateMagazines_)
-            user = 0;
+        if (deployment_ != MunitionDeployment::Separate)
+        {
+            user = NULL;
+        }
 
         // Remove the current magazine for the given user
-        std::map<WeaponMode*, Magazine*>::iterator it = this->currentMagazines_.find(user);
-        if (it != this->currentMagazines_.end())
-        {
+        std::map<WeaponMode*, Magazine*>::iterator it = this->assignedMagazines_.find(user);
+        if (it != this->assignedMagazines_.end())
+        {
+            if (it->first == lastFilledWeaponMode_)
+            {
+                lastFilledWeaponMode_ = NULL;
+            }            
             delete it->second;
-            this->currentMagazines_.erase(it);
+            this->assignedMagazines_.erase(it);
         }
 
         // Load a new magazine
-        this->currentMagazines_[user] = new Magazine(this, bUseReloadTime);
-        this->magazines_--;
+        this->assignedMagazines_[user] = new Magazine(this, bUseReloadTime);
+        this->unassignedMagazines_--;
 
         return true;
@@ -260,5 +291,5 @@
             return false;
 
-        if (this->bStackMunition_)
+        if (deployment_ == MunitionDeployment::Stack)
         {
             // If we stack munition, we can always add munition until we reach the limit
@@ -268,5 +299,5 @@
         {
             // Return true if any of the current magazines is not full (loading counts as full although it returns 0 munition)
-            for (std::map<WeaponMode*, Magazine*>::const_iterator it = this->currentMagazines_.begin(); it != this->currentMagazines_.end(); ++it)
+            for (std::map<WeaponMode*, Magazine*>::const_iterator it = this->assignedMagazines_.begin(); it != this->assignedMagazines_.end(); ++it)
                 if (it->second->munition_ < this->maxMunitionPerMagazine_ && it->second->bLoaded_)
                     return true;
@@ -281,8 +312,8 @@
             return false;
 
-        if (this->bStackMunition_)
+        if (deployment_ == MunitionDeployment::Stack)
         {
             // Stacking munition means, if a magazine gets full, the munition adds to a new magazine
-            Magazine* magazine = this->getMagazine(0);
+            Magazine* magazine = this->getMagazine(NULL);
             if (magazine)
             {
@@ -294,11 +325,11 @@
                 {
                     magazine->munition_ -= this->maxMunitionPerMagazine_;
-                    this->magazines_++;
+                    this->unassignedMagazines_++;
                 }
 
-                // If we reached the limit, reduze both magazines and munition to the maximum
-                if (this->magazines_ >= this->maxMagazines_)
-                {
-                    this->magazines_ = this->maxMagazines_ - 1;
+                // If we reached the limit, reduce both magazines and munition to the maximum
+                if (this->unassignedMagazines_ >= this->maxMagazines_)
+                {
+                    this->unassignedMagazines_ = this->maxMagazines_;
                     magazine->munition_ = this->maxMunitionPerMagazine_;
                 }
@@ -312,9 +343,24 @@
         else
         {
+            std::map<WeaponMode*, Magazine*>::iterator it;
+
+            // If the pointer to the weapon mode whose magazine got munition added to is NULL, then set the iterator to the beginning of the map
+            // Otherwise set it to the next weapon mode
+            if (lastFilledWeaponMode_ == NULL)
+            {
+                it = this->assignedMagazines_.begin();
+            }
+            else
+            {
+                it = this->assignedMagazines_.find(lastFilledWeaponMode_);
+                ++ it;
+            }
+
             // Share the munition equally to the current magazines
+            bool firstLoop = true;
             while (amount > 0)
             {
                 bool change = false;
-                for (std::map<WeaponMode*, Magazine*>::iterator it = this->currentMagazines_.begin(); it != this->currentMagazines_.end(); ++it)
+                while (it != this->assignedMagazines_.end())
                 {
                     // Add munition if the magazine isn't full (but only to loaded magazines)
@@ -323,11 +369,20 @@
                         it->second->munition_++;
                         amount--;
+                        lastFilledWeaponMode_ = it->first;
                         change = true;
                     }
+
+                    ++it;
                 }
 
                 // If there was no change in a loop, all magazines are full (or locked due to loading)
-                if (!change)
+                // Because the first loop does not start at the beginning of the map we have to treat is separately
+                if (!change && !firstLoop)
+                {
                     break;
+                }                    
+
+                it = this->assignedMagazines_.begin();
+                firstLoop = false;
             }
 
@@ -340,34 +395,38 @@
         // TODO: 'amount' is not used
 
-        if (this->bStackMunition_)
+        if (deployment_ == MunitionDeployment::Stack)
             // If we stack munition, we can always add new magazines because they contribute directly to the munition
             return (this->getNumMunition(0) < this->getMaxMunition());
         else
             // If we don't stack munition, we're more limited
-            return ((this->currentMagazines_.size() + this->magazines_) < this->maxMagazines_);
-    }
-
-    bool Munition::addMagazines(unsigned int amount)
-    {
+            return ((this->assignedMagazines_.size() + this->unassignedMagazines_) < this->maxMagazines_);
+    }
+
+    unsigned int Munition::addMagazines(unsigned int amount)
+    {
+        unsigned int addedMagazines = 0;
+
         if (!this->canAddMagazines(amount))
-            return false;
+            return 0;
 
         // Calculate how many magazines are needed
-        int needed_magazines = this->maxMagazines_ - this->magazines_ - this->currentMagazines_.size();
+        int needed_magazines = this->maxMagazines_ - this->unassignedMagazines_ - this->assignedMagazines_.size();
 
         // If zero or less magazines are needed, we definitively don't need more magazines (unless we stack munition - then a magazine contributes directly to the munition)
-        if (needed_magazines <= 0 && !this->bStackMunition_)
-            return false;
+        if (needed_magazines <= 0 && deployment_ != MunitionDeployment::Stack)
+            return 0;
 
         if (amount <= static_cast<unsigned int>(needed_magazines))
         {
             // We need more magazines than we get, so just add them
-            this->magazines_ += amount;
+            this->unassignedMagazines_ += amount;
+            addedMagazines = amount;
         }
         else
         {
             // We get more magazines than we need, so just add the needed amount
-            this->magazines_ += needed_magazines;
-            if (this->bStackMunition_)
+            this->unassignedMagazines_ += needed_magazines;
+            addedMagazines = needed_magazines;
+            if (deployment_ == MunitionDeployment::Stack)
             {
                 // We stack munition, so the additional amount contributes directly to the munition of the current magazine
@@ -378,17 +437,31 @@
         }
 
-        return true;
+        // Reload as many empty magazines as possible
+        // Double loop and break is needed because the reload function changes the assigned magazines. This may confuse the iterator.
+        for (unsigned int i = 0; i < addedMagazines; ++i)
+        {
+            for (std::map<WeaponMode*, Magazine*>::iterator it = this->assignedMagazines_.begin(); it != this->assignedMagazines_.end(); ++it)
+            {
+                if (needReload(it->first))
+                {
+                    reload(it->first);
+                    break;
+                }
+            }
+        }
+
+        return addedMagazines;
     }
 
     bool Munition::canRemoveMagazines(unsigned int amount) const
     {
-        if (this->bStackMunition_)
-        {
-            if (this->magazines_ >= amount)
+        if (deployment_ == MunitionDeployment::Stack)
+        {
+            if (this->unassignedMagazines_ >= amount)
             {
                 // We have enough magazines
                 return true;
             }
-            else if (this->magazines_ == amount - 1)
+            else if (this->unassignedMagazines_ == amount - 1)
             {
                 // We lack one magazine, check if the current magazine is still full, if yes we're fine
@@ -406,5 +479,5 @@
         {
             // In case we're not stacking munition, just check the number of magazines
-            return (this->magazines_ >= amount);
+            return (this->unassignedMagazines_ >= amount);
         }
 
@@ -417,13 +490,13 @@
             return false;
 
-        if (this->magazines_ >= amount)
+        if (this->unassignedMagazines_ >= amount)
         {
             // We have enough magazines, just remove the amount
-            this->magazines_ -= amount;
-        }
-        else if (this->bStackMunition_)
+            this->unassignedMagazines_ -= amount;
+        }
+        else if (deployment_ == MunitionDeployment::Stack)
         {
             // We don't have enough magazines, but we're stacking munition, so additionally remove the bullets from the current magazine
-            this->magazines_ = 0;
+            this->unassignedMagazines_ = 0;
             Magazine* magazine = this->getMagazine(0);
             if (magazine)
@@ -437,17 +510,21 @@
     {
         // If we use separate magazines, we need a user
-        if (this->bUseSeparateMagazines_ && !user)
+        if (deployment_ == MunitionDeployment::Separate && !user)
             return false;
 
         // If we don't use separate magazines, set user to 0
-        if (!this->bUseSeparateMagazines_)
-            user = 0;
+        if (deployment_ != MunitionDeployment::Separate)
+            user = NULL;
 
         // Remove the current magazine for the given user
-        std::map<WeaponMode*, Magazine*>::iterator it = this->currentMagazines_.find(user);
-        if (it != this->currentMagazines_.end())
-        {
+        std::map<WeaponMode*, Magazine*>::iterator it = this->assignedMagazines_.find(user);
+        if (it != this->assignedMagazines_.end())
+        {
+            if (it->first == lastFilledWeaponMode_)
+            {
+                lastFilledWeaponMode_ = NULL;
+            }
             delete it->second;
-            this->currentMagazines_.erase(it);
+            this->assignedMagazines_.erase(it);           
             return true;
         }
@@ -465,5 +542,5 @@
         this->bLoaded_ = false;
 
-        if (bUseReloadTime && munition->reloadTime_ > 0 && !munition->bStackMunition_)
+        if (bUseReloadTime && munition->reloadTime_ > 0 && munition->deployment_ != MunitionDeployment::Stack)
         {
             const ExecutorPtr& executor = createExecutor(createFunctor(&Magazine::loaded, this));
Index: code/trunk/src/orxonox/weaponsystem/Munition.h
===================================================================
--- code/trunk/src/orxonox/weaponsystem/Munition.h	(revision 11020)
+++ code/trunk/src/orxonox/weaponsystem/Munition.h	(revision 11052)
@@ -24,5 +24,5 @@
  *      Fabian 'x3n' Landau
  *   Co-authors:
- *      ...
+ *      Fabien Vultier
  *
  */
@@ -39,6 +39,16 @@
 namespace orxonox
 {
+    namespace MunitionDeployment
+    {
+        enum Value
+        {
+            Separate, // Every comsuming weapon mode has its own magazine. It is possible that one weapon mode is out of ammo while another still has some.
+            Share, // All comsuming weapon modes take their munition from the same magazine. If this magazine is empty a new one is loaded.
+            Stack // There is only one magazine where all the munition is stored. Use this deployment mode for heavy weapons loke rockets, bombs, ...
+        };
+    }
+
     class _OrxonoxExport Munition : public BaseObject
-    {
+    {        
         struct Magazine
         {
@@ -59,4 +69,6 @@
             virtual ~Munition();
 
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
             unsigned int getNumMunition(WeaponMode* user) const;
             unsigned int getNumMunitionInCurrentMagazine(WeaponMode* user) const;
@@ -68,4 +80,7 @@
             inline unsigned int getMaxMunitionPerMagazine() const
                 { return this->maxMunitionPerMagazine_; }
+            inline MunitionDeployment::Value getMunitionDeployment() const
+                { return deployment_; }
+
 
             bool canTakeMunition(unsigned int amount, WeaponMode* user) const;
@@ -82,5 +97,10 @@
 
             bool canAddMagazines(unsigned int amount) const;
-            bool addMagazines(unsigned int amount);
+            /**
+            @brief Try to add magazines.
+            @param amount The amount of magazines tried to add.
+            @return The amount of magazines sucessfully added.
+            */
+            unsigned int addMagazines(unsigned int amount);
 
             bool canRemoveMagazines(unsigned int amount) const;
@@ -92,16 +112,22 @@
             unsigned int maxMunitionPerMagazine_;
             unsigned int maxMagazines_;
-            unsigned int magazines_;
-            std::map<WeaponMode*, Magazine*> currentMagazines_;
+            unsigned int unassignedMagazines_; // Number of magazines that are not assigned to a weapon mode. These are alway treated as full.
+            std::map<WeaponMode*, Magazine*> assignedMagazines_; // Maps weapon modes to magazines that are currently used.
 
-            bool bUseSeparateMagazines_;
-            bool bStackMunition_;
+            MunitionDeployment::Value deployment_; // Defines the behaviour how munition and magazines are distributed to the consuming weapon modes.
+
             bool bAllowMunitionRefilling_;
             bool bAllowMultiMunitionRemovementUnderflow_;
 
-            float reloadTime_;
+            float reloadTime_; // The time needed to replace a magazine by a new one.
+            WeaponMode* lastFilledWeaponMode_; // Pointer to the weapon mode that got the last munition during the last call of addMunition.
 
         private:
             Magazine* getMagazine(WeaponMode* user) const;
+            inline void setMaxMagazines(unsigned int maxMagazines)
+                { this->maxMagazines_ = maxMagazines; }
+            inline void setMaxMunitionPerMagazine(unsigned int maxMunitionPerMagazine)
+                { this->maxMunitionPerMagazine_ = maxMunitionPerMagazine; }
+            void setNumMagazines(unsigned int numMagazines);
     };
 }
Index: code/trunk/src/orxonox/weaponsystem/ReplenishingMunition.cc
===================================================================
--- code/trunk/src/orxonox/weaponsystem/ReplenishingMunition.cc	(revision 11052)
+++ code/trunk/src/orxonox/weaponsystem/ReplenishingMunition.cc	(revision 11052)
@@ -0,0 +1,92 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file ReplenishingMunition.h
+    @brief Implementation of the ReplenishingMunition class.
+*/
+
+#include "ReplenishingMunition.h"
+
+#include "core/CoreIncludes.h"
+#include "core/command/Executor.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    RegisterClass(ReplenishingMunition);
+
+    ReplenishingMunition::ReplenishingMunition(Context* context) : Munition(context)
+    {
+        RegisterObject(ReplenishingMunition);
+
+        this->replenishInterval_ = 1.0f;
+        this->replenishAmount_ = 1;
+
+        // Use the timer to initialize itself after the first tick (because the real values for
+        // replenishIntervall_ and replenishMunitionAmount_ will be set in the constructor of the
+        // inheriting class, which comes after this constructor)
+        this->replenishingTimer_.setTimer(0.0f, false, createExecutor(createFunctor(&ReplenishingMunition::initializeTimer, this)));
+    }
+
+    void ReplenishingMunition::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(ReplenishingMunition, XMLPort, xmlelement, mode);
+
+        XMLPortParam(ReplenishingMunition, "replenishamount", setReplenishAmount, getReplenishAmount, xmlelement, mode);
+        XMLPortParam(ReplenishingMunition, "replenishinterval", setReplenishInterval, getReplenishInterval, xmlelement, mode);
+    }    
+
+    float ReplenishingMunition::getProgress()
+    {
+        return replenishingTimer_.getRemainingTime()/this->replenishInterval_;
+    }
+
+    void ReplenishingMunition::initializeTimer()
+    {
+        // Initialize the timer
+        this->replenishingTimer_.setTimer(this->replenishInterval_, true, createExecutor(createFunctor(&ReplenishingMunition::replenish, this)));
+    }
+
+    void ReplenishingMunition::replenish()
+    {
+        if (this->canAddMagazines(this->replenishAmount_))
+        {
+            // Make a temporary copy of bAllowMunitionRefilling_, because this might be disallowed in every
+            // case except the internal munition replenishing
+            bool temp = this->bAllowMunitionRefilling_;
+            this->bAllowMunitionRefilling_ = true;
+
+            // Replenish munition
+            this->addMagazines(this->replenishAmount_);
+
+            // Write back the temporary value
+            this->bAllowMunitionRefilling_ = temp;            
+        }
+    }
+}
Index: code/trunk/src/orxonox/weaponsystem/ReplenishingMunition.h
===================================================================
--- code/trunk/src/orxonox/weaponsystem/ReplenishingMunition.h	(revision 11052)
+++ code/trunk/src/orxonox/weaponsystem/ReplenishingMunition.h	(revision 11052)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file ReplenishingMunition.h
+    @brief Definition of the ReplenishingMunition class.
+*/
+
+#ifndef _ReplenishingMunition_H__
+#define _ReplenishingMunition_H__
+
+#include "tools/Timer.h"
+#include "Munition.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        Munition that is replenished by a certain amount each time interval.
+    @author
+        Fabian 'x3n' Landau
+    @ingroup WeaponsMunitions
+    */
+    class _OrxonoxExport ReplenishingMunition : public Munition
+    {
+        public:
+            ReplenishingMunition(Context* context);
+            virtual ~ReplenishingMunition() {}
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            
+            virtual float getProgress();
+            inline unsigned int getReplenishAmount() const
+                { return replenishAmount_; }
+            inline float getReplenishInterval() const
+                { return replenishInterval_; }
+
+        protected:                          
+            float replenishInterval_; //!< The interval in which the munition is replenished.
+            unsigned int replenishAmount_; //!< The amount of magazines by which it is replenished.
+
+        private:
+            void replenish(); //!< Every call of this function replenishes the munition. This function is called by the timer.
+            void initializeTimer();
+
+            Timer replenishingTimer_; //!< Timer to do the replenishing.
+
+            inline void setReplenishAmount(unsigned int replenishAmount)
+                { this->replenishAmount_ = replenishAmount; }
+            inline void setReplenishInterval(float replenishInterval)
+                { this->replenishInterval_ = replenishInterval; }              
+    };
+}
+
+#endif /* _ReplenishingMunition_H__ */
Index: code/trunk/src/orxonox/weaponsystem/Weapon.cc
===================================================================
--- code/trunk/src/orxonox/weaponsystem/Weapon.cc	(revision 11020)
+++ code/trunk/src/orxonox/weaponsystem/Weapon.cc	(revision 11052)
@@ -134,4 +134,8 @@
     }
 
+    /**
+    @brief
+        Reload all @ref orxonox::WeaponMode weapon modes of this weapon.
+    */
     void Weapon::reload()
     {
@@ -151,3 +155,9 @@
             it->second->setWeapon(this);
     }
+
+    void Weapon::updateMunition()
+    {
+        for (std::multimap<unsigned int, WeaponMode*>::iterator it = this->weaponmodes_.begin(); it != this->weaponmodes_.end(); ++it)
+            it->second->updateMunition();
+    }
 }
Index: code/trunk/src/orxonox/weaponsystem/Weapon.h
===================================================================
--- code/trunk/src/orxonox/weaponsystem/Weapon.h	(revision 11020)
+++ code/trunk/src/orxonox/weaponsystem/Weapon.h	(revision 11052)
@@ -57,4 +57,8 @@
             void addWeaponmode(WeaponMode* weaponmode);
             WeaponMode* getWeaponmode(unsigned int index) const;
+            inline std::multimap<unsigned int, WeaponMode*>* getAllWeaponmodes()
+                { return &weaponmodes_; }
+            inline int getNumWeaponModes() const
+                { return weaponmodes_.size(); }
 
             /**
@@ -75,4 +79,5 @@
             inline WeaponSlot * getWeaponSlot() const
                 { return this->weaponSlot_; }
+            void updateMunition();
 
         private:
Index: code/trunk/src/orxonox/weaponsystem/WeaponMode.cc
===================================================================
--- code/trunk/src/orxonox/weaponsystem/WeaponMode.cc	(revision 11020)
+++ code/trunk/src/orxonox/weaponsystem/WeaponMode.cc	(revision 11052)
@@ -75,4 +75,6 @@
         this->muzzleOrientation_ = Quaternion::IDENTITY;
 
+        hudImageString_ = "Orxonox/WSHUD_WM_Unknown";
+
         if( GameMode::isMaster() )
         {
@@ -125,5 +127,6 @@
             this->bSoundAttached_ = true;
         }
-
+        
+        // Fireing is only possible if this weapon mode is not reloading and there is enough munition
         if (!this->bReloading_ && this->munition_ && this->munition_->takeMunition(this->munitionPerShot_, this))
         {
@@ -134,11 +137,19 @@
                 if (this->munition_->reload(this))
                 {
+                    // If true, the weapon reloads in parallel to the magazine reloading
                     if (this->bParallelReload_)
+                    {
+                        // The time needed to reload is the maximum of the reload time of the weapon mode and the magazine.
                         tempReloadtime = std::max(this->reloadTime_, this->munition_->getReloadTime());
+                    }                        
                     else
+                    {
+                        // The time needed to reload is the sum of the reload time of the weapon mode and the magazine.
                         tempReloadtime = this->reloadTime_ + this->munition_->getReloadTime();
+                    }                        
                 }
             }
 
+            // Mark this weapon mode as reloading and start the reload timer
             this->bReloading_ = true;
             this->reloadTimer_.setInterval(tempReloadtime);
@@ -232,5 +243,7 @@
         }
         else
-            this->munition_ = 0;
+        {
+            this->munition_ = NULL;
+        }
     }
 
@@ -283,6 +296,8 @@
     }
 
-    void WeaponMode::setDefaultSoundWithVolume(const std::string& soundPath, const float soundVolume){
-        if (this->defSndWpnFire_) {
+    void WeaponMode::setDefaultSoundWithVolume(const std::string& soundPath, const float soundVolume)
+    {
+        if (this->defSndWpnFire_)
+        {
             this->defSndWpnFire_->setSource(soundPath);
             this->defSndWpnFire_->setVolume(soundVolume);
Index: code/trunk/src/orxonox/weaponsystem/WeaponMode.h
===================================================================
--- code/trunk/src/orxonox/weaponsystem/WeaponMode.h	(revision 11020)
+++ code/trunk/src/orxonox/weaponsystem/WeaponMode.h	(revision 11052)
@@ -38,4 +38,5 @@
 #include "core/class/SubclassIdentifier.h"
 #include "tools/Timer.h"
+#include "Munition.h"
 
 namespace orxonox
@@ -104,4 +105,6 @@
             inline bool getParallelReload() const
                 { return this->bParallelReload_; }
+            inline bool getReloading() const
+                { return this->bReloading_; }
 
 
@@ -147,4 +150,8 @@
             Vector3 getTarget();
 
+            inline const std::string& getHUDImageString() const
+                { return this->hudImageString_; }            
+
+            void updateMunition();
         protected:
             virtual void fire() = 0;
@@ -155,6 +162,6 @@
 
             float reloadTime_;
-            bool bAutoReload_;
-            bool bParallelReload_;
+            bool bAutoReload_; // If true, the weapon reloads the magazine automatically.
+            bool bParallelReload_; // If true, the weapon reloads in parallel to the magazine reloading.
 
             float damage_;
@@ -163,6 +170,7 @@
             Vector3 muzzleOffset_;
 
-        private:
-            void updateMunition();
+            std::string hudImageString_;
+
+        private:            
             void reloaded();
 
@@ -175,5 +183,5 @@
 
             Timer reloadTimer_;
-            bool bReloading_;
+            bool bReloading_; // If true, this weapon mode is marked as reloading.
 
             Vector3 muzzlePosition_;
@@ -181,5 +189,5 @@
 
             WorldSound* defSndWpnFire_;
-            bool        bSoundAttached_;
+            bool bSoundAttached_;
     };
 }
Index: code/trunk/src/orxonox/weaponsystem/WeaponPack.cc
===================================================================
--- code/trunk/src/orxonox/weaponsystem/WeaponPack.cc	(revision 11020)
+++ code/trunk/src/orxonox/weaponsystem/WeaponPack.cc	(revision 11052)
@@ -124,4 +124,9 @@
     }
 
+    std::vector<Weapon*>* WeaponPack::getAllWeapons()
+    {
+        return &weapons_;        
+    }    
+
     void WeaponPack::addDefaultWeaponmodeLink(DefaultWeaponmodeLink* link)
     {
@@ -156,3 +161,9 @@
             (*it)->setWeaponPack(this);
     }
+
+    void WeaponPack::updateMunition()
+    {
+        for (std::vector<Weapon *>::const_iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
+            (*it)->updateMunition();
+    }
 }
Index: code/trunk/src/orxonox/weaponsystem/WeaponPack.h
===================================================================
--- code/trunk/src/orxonox/weaponsystem/WeaponPack.h	(revision 11020)
+++ code/trunk/src/orxonox/weaponsystem/WeaponPack.h	(revision 11052)
@@ -52,4 +52,5 @@
             void removeWeapon(Weapon * weapon);
             Weapon * getWeapon(unsigned int index) const;
+            std::vector<Weapon*>* getAllWeapons();
 
             inline size_t getNumWeapons() const
@@ -65,4 +66,5 @@
             inline WeaponSystem * getWeaponSystem() const
                 { return this->weaponSystem_; }
+            void updateMunition();
 
         private:
Index: code/trunk/src/orxonox/weaponsystem/WeaponSystem.cc
===================================================================
--- code/trunk/src/orxonox/weaponsystem/WeaponSystem.cc	(revision 11020)
+++ code/trunk/src/orxonox/weaponsystem/WeaponSystem.cc	(revision 11052)
@@ -240,4 +240,9 @@
     }
 
+    std::vector<WeaponPack *> * WeaponSystem::getAllWeaponPacks()
+    {
+        return &weaponPacks_;
+    }    
+
     bool WeaponSystem::swapWeaponSlots(WeaponSlot * wSlot1, WeaponSlot * wSlot2)
     {
@@ -310,13 +315,35 @@
             return it->second;
         }
-        else if (identifier->getIdentifier()->isA(Class(Munition)))
-        {
-            Munition* munition = identifier->fabricate(this->getContext());
-            this->munitions_[identifier->getIdentifier()] = munition;
-            return munition;
-        }
         else
         {
-            return 0;
+            return NULL;
+        }
+    }
+
+    void WeaponSystem::addMunition(Munition* munition)
+    {
+        if (munition == NULL)
+        {
+            return;
+        }
+
+        SubclassIdentifier<Munition> identifier = munition->getIdentifier();
+
+        if (identifier)
+        {
+            this->munitions_[identifier] = munition;
+            updateMunition();
+        }
+        else
+        {
+            orxout(internal_warning) << "Adding munition failed. identifier == NULL " << endl;
+        }
+    }
+
+    void WeaponSystem::updateMunition()
+    {
+        for (std::vector<WeaponPack*>::iterator it = this->weaponPacks_.begin(); it != this->weaponPacks_.end(); ++it)
+        {
+            (*it)->updateMunition();
         }
     }
Index: code/trunk/src/orxonox/weaponsystem/WeaponSystem.h
===================================================================
--- code/trunk/src/orxonox/weaponsystem/WeaponSystem.h	(revision 11020)
+++ code/trunk/src/orxonox/weaponsystem/WeaponSystem.h	(revision 11052)
@@ -67,4 +67,5 @@
             void removeWeaponPack(WeaponPack * wPack);
             WeaponPack * getWeaponPack(unsigned int index) const;
+            std::vector<WeaponPack *> * getAllWeaponPacks();
 
             // configure slots and firemodes
@@ -76,4 +77,5 @@
 
             Munition * getMunition(SubclassIdentifier<Munition> * identifier);
+            void addMunition(Munition* munition);
 
             inline void setPawn(Pawn * pawn)
@@ -95,4 +97,6 @@
 
         private:
+            void updateMunition();
+            
             std::map<unsigned int, WeaponSet *> weaponSets_;
             std::vector<WeaponSlot *> weaponSlots_;
Index: code/trunk/src/orxonox/worldentities/Actionpoint.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/Actionpoint.cc	(revision 11052)
+++ code/trunk/src/orxonox/worldentities/Actionpoint.cc	(revision 11052)
@@ -0,0 +1,85 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Actionpoint.h"
+
+namespace orxonox
+{
+    RegisterClass(Actionpoint);
+
+    Actionpoint::Actionpoint(Context* context) : StaticEntity(context)
+    {
+        RegisterObject(Actionpoint);
+        
+        this->actionName_ = "";
+        this->name_ = "";
+        
+        this->bLoopStart_ = false;
+        this->bLoopEnd_ = false;
+        this->bProtectMe_ = false;
+    }
+    
+    void Actionpoint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Actionpoint, XMLPort, xmlelement, mode);
+        
+        XMLPortParam(Actionpoint, "action", setActionXML, getActionXML,  xmlelement, mode);
+        XMLPortParam(Actionpoint, "protect", setProtectXML, getProtectXML,  xmlelement, mode);
+        XMLPortParam(Actionpoint, "attack", setAttackXML, getAttackXML,  xmlelement, mode);
+        XMLPortParam(Actionpoint, "protectMe", setProtectMeXML, getProtectMeXML,  xmlelement, mode).defaultValues(false);
+        XMLPortParam(Actionpoint, "loopStart", setLoopStart, getLoopStart,  xmlelement, mode).defaultValues(false);
+        XMLPortParam(Actionpoint, "loopEnd", setLoopEnd, getLoopEnd,  xmlelement, mode).defaultValues(false);
+    }
+    /**
+    @brief
+        action is ATTACK -> returns name of object to attack
+        action is PROTECT -> returns name of object to protect 
+        if asked to protect human, returns a special string.
+    @return
+        name of an object to interact with.
+    @note
+        never use more than one of following arguments for XMLPort:
+        attack, protect, protectMe or
+        loopStart and loopEnd.
+    */
+    std::string Actionpoint::getName() const
+    {
+        if (this->name_ != "")
+        {
+            return this->name_;
+        }
+        else if (this->bProtectMe_)
+        {
+            return "reservedKeyword:human";
+        }
+        else
+        {
+            return "";
+        }
+    }    
+}
Index: code/trunk/src/orxonox/worldentities/Actionpoint.h
===================================================================
--- code/trunk/src/orxonox/worldentities/Actionpoint.h	(revision 11052)
+++ code/trunk/src/orxonox/worldentities/Actionpoint.h	(revision 11052)
@@ -0,0 +1,156 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Gani Aliguzhinov
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Actionpoint_H__
+#define _Actionpoint_H__
+
+#include <string>                           //need string for XML input
+
+#include "core/XMLPort.h"                   //need XMLPort
+#include "worldentities/StaticEntity.h"     //this is a child of StaticEntity
+
+namespace orxonox
+{ 
+    /**
+    @brief
+        Actionpoints are used by ActionpointController and all derived classes.
+        Such classes will execute actions set in Actionpoints.
+
+        In XML file one can pass an array of Actionpoints to a controller. Each
+        Actionpoint can take action type, string and boolean or 
+        action and two booleans as an argument.
+        If action is set to fly, Actionpoint's position is assumed to be the desired
+        location.
+        Example XML code:
+
+        <SpaceShip position="-2000, 1500, -1000" lookat="0,0,0" team=0 name="thisShipName">
+          <templates>
+            <Template link=spaceshipassff />
+          </templates>
+          <controller>
+            <DivisionController team=0 formationMode="WALL">
+              <actionpoints>
+                <Actionpoint position="0,0,0" action="FLY" /> 
+                <Actionpoint position="-1000,750,-500" action="ATTACK" attack="someShipName" />
+                <Actionpoint position="-1000,750,-500" action="PROTECT" protectMe=true />
+                <Actionpoint position="-1000,750,-500" action="PROTECT" protect="otherShipName" /> 
+                <Actionpoint position="-1000,750,-500" action="FIGHTALL" />
+               </actionpoints>
+            </DivisionController>
+          </controller>
+        </SpaceShip>
+        
+        Example with loops:
+
+        <SpaceShip position="-1500, 1500, -1000" lookat="0,0,0" team=0 name="thisShipName">
+          <templates>
+            <Template link=spaceshipassff />
+          </templates>
+          <controller>
+            <DivisionController team=0 formationMode="finger4">
+              <actionpoints>
+                <Actionpoint position="  0,2000,-600" action="FLY" loopStart=true/>
+                <Actionpoint position="  0,2000,-700" action="FLY"  />
+                <Actionpoint position="100,2000,-700" action="FLY" />
+                <Actionpoint position="100,2000,-600" action="FLY" loopEnd=true />
+              </actionpoints>
+            </DivisionController>
+          </controller>
+        </SpaceShip>
+        
+        One can also use other Worldentities instead of Actionpoints just like Waypoints, but those points
+        will be included in loop.
+        For more information read descriptions of the methods.
+    */
+    class _OrxonoxExport Actionpoint : public StaticEntity
+    {
+        public:
+            Actionpoint(Context* context);
+            virtual ~Actionpoint() {}
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            /** @brief Decides what AI will do. @param val action to execute */
+            void setActionXML(std::string val)
+                { this->actionName_ = getUppercase (val); }
+            std::string getActionXML() const
+                { return this->actionName_; }
+
+            /** @brief Makes AI follow an entity. @param val name of entity to protect */
+            void setProtectXML(std::string val)
+                { this->name_ = val; }
+            std::string getProtectXML() const
+                { return this->name_; }
+
+            /** @brief Makes AI attack an entity. @param val name of entity to attack */
+            void setAttackXML(std::string val)
+                { this->name_ = val; }
+            std::string getAttackXML() const
+                { return this->name_; }
+
+            /** @brief Makes AI follow human player. @param c protect Human? */
+            void setProtectMeXML(bool c)
+                { this->bProtectMe_ = c; }
+            bool getProtectMeXML() const
+                { return this->bProtectMe_; }
+
+            /** @brief Starts a loop of Actionpoints. @param value start loop? */
+            void setLoopStart(bool value)
+                { this->bLoopStart_ = value; }
+            bool getLoopStart() const
+                { return this->bLoopStart_; }
+            /** @brief Ends a loop of Actionpoints. @param value end loop? */
+            void setLoopEnd (bool value)
+                { this->bLoopEnd_ = value; }
+            bool getLoopEnd() const
+                { return this->bLoopEnd_; }
+
+            std::string getName() const;
+
+        private:    
+            std::string actionName_;    //!< can be set to "FLY", "ATTACK",
+                                        //!< "PROTECT", "FIGHT", "FIGHTALL"
+                                        //!< or "NONE".
+
+            std::string name_;          //!< name of the ship that is to be
+                                        //!< attacked or protected.
+
+            bool bLoopStart_;           //!< if true, this and all following Actionpoints
+                                        //!< until the first Actionpoint with bLoopEnd_
+                                        //!< set to true are executed in a loop.
+
+            bool bLoopEnd_;             //!< if true, this is the last element of
+                                        //!< a loop started by loopStart=true argument
+
+            bool bProtectMe_;           //!< if player is to be protected,
+                                        //!< instead of passing name, one has
+                                        //!< to set protectMe to true.
+    };
+}
+
+#endif /* _Actionpoint_H__ */
Index: code/trunk/src/orxonox/worldentities/BigExplosion.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/BigExplosion.cc	(revision 11020)
+++ 	(revision )
@@ -1,345 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   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
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Benjamin de Capitani
- *   Co-authors:
- *      ...
- *
- */
-
-#include "BigExplosion.h"
-
-#include "util/Exception.h"
-#include "core/CoreIncludes.h"
-#include "core/GameMode.h"
-#include "core/command/Executor.h"
-#include "tools/ParticleInterface.h"
-#include "Scene.h"
-#include "graphics/ParticleSpawner.h"
-#include "graphics/Model.h"
-#include "MovableEntity.h"
-
-namespace orxonox
-{
-    RegisterClass(BigExplosion);
-
-    BigExplosion::BigExplosion(Context* context) : MobileEntity(context)
-    {
-        RegisterObject(BigExplosion);
-
-        if ( GameMode::showsGraphics() && ( !this->getScene() || !this->getScene()->getSceneManager() ) )
-            ThrowException(AbortLoading, "Can't create BigExplosion, no scene or no scene manager given.");
-
-        this->bStop_ = false;
-        this->LOD_ = LODParticle::Normal;
-
-        if ( GameMode::showsGraphics() )
-        {
-            try
-            {
-                this->init();
-            }
-            catch (const std::exception& ex)
-            {
-                orxout(internal_error) << "Couldn't load particle effect in BigExplosion: " << ex.what() << endl;
-                this->initZero();
-            }
-        }
-        else
-        {
-            this->initZero();
-        }
-
-        if (GameMode::isMaster())
-        {
-            this->destroyTimer_.setTimer(rnd(2, 4), false, createExecutor(createFunctor(&BigExplosion::stop, this)));
-        }
-
-        this->registerVariables();
-    }
-
-    void BigExplosion::init()
-    {
-        this->debrisEntity1_ = new MovableEntity(this->getContext());
-        this->debrisEntity2_ = new MovableEntity(this->getContext());
-        this->debrisEntity3_ = new MovableEntity(this->getContext());
-        this->debrisEntity4_ = new MovableEntity(this->getContext());
-
-        this->debrisEntity1_->setSyncMode(0);
-        this->debrisEntity2_->setSyncMode(0);
-        this->debrisEntity3_->setSyncMode(0);
-        this->debrisEntity4_->setSyncMode(0);
-
-        this->debris1_ = new Model(this->getContext());
-        this->debris2_ = new Model(this->getContext());
-        this->debris3_ = new Model(this->getContext());
-        this->debris4_ = new Model(this->getContext());
-
-        this->debris1_->setSyncMode(0);
-        this->debris2_->setSyncMode(0);
-        this->debris3_->setSyncMode(0);
-        this->debris4_->setSyncMode(0);
-
-        this->explosion_ = new StaticEntity(this->getContext());
-        this->explosion_->setSyncMode(0);
-
-        this->debrisSmoke1_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/smoke7", this->LOD_);
-        this->debrisSmoke2_ =  new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/smoke7", this->LOD_);
-        this->debrisSmoke3_ =  new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/smoke7", this->LOD_);
-        this->debrisSmoke4_ =  new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/smoke7", this->LOD_);
-
-        this->debrisFire1_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/fire4", this->LOD_);
-        this->debrisFire2_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/fire4", this->LOD_);
-        this->debrisFire3_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/fire4", this->LOD_);
-        this->debrisFire4_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/fire4", this->LOD_);
-
-        this->debris1_->attachOgreObject(this->debrisSmoke1_->getParticleSystem());
-        this->debris1_->attachOgreObject(this->debrisFire1_->getParticleSystem());
-        this->debris2_->attachOgreObject(this->debrisSmoke2_->getParticleSystem());
-        this->debris2_->attachOgreObject(this->debrisFire2_->getParticleSystem());
-        this->debris3_->attachOgreObject(this->debrisSmoke3_->getParticleSystem());
-        this->debris3_->attachOgreObject(this->debrisFire3_->getParticleSystem());
-        this->debris4_->attachOgreObject(this->debrisSmoke4_->getParticleSystem());
-        this->debris4_->attachOgreObject(this->debrisFire4_->getParticleSystem());
-
-        this->debris1_->setMeshSource("CockpitDebris.mesh");
-        this->debris2_->setMeshSource("WingDebris1.mesh");
-        this->debris3_->setMeshSource("BodyDebris1.mesh");
-        this->debris4_->setMeshSource("WingDebris2.mesh");
-
-        this->debrisEntity1_->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(50,100));
-        this->debrisEntity1_->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
-        this->debrisEntity1_->setScale(4);
-
-        this->debrisEntity2_->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(50,100));
-        this->debrisEntity2_->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
-        this->debrisEntity2_->setScale(4);
-
-        this->debrisEntity3_->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(50,100));
-        this->debrisEntity3_->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
-        this->debrisEntity3_->setScale(4);
-
-        this->debrisEntity4_->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(50,100));
-        this->debrisEntity4_->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
-        this->debrisEntity4_->setScale(4);
-
-        this->debrisEntity1_->attach(debris1_);
-        this->debrisEntity2_->attach(debris2_);
-        this->debrisEntity3_->attach(debris3_);
-        this->debrisEntity4_->attach(debris4_);
-
-        ParticleSpawner* effect = new ParticleSpawner(this->getContext());
-        effect->setDestroyAfterLife(true);
-        effect->setSource("Orxonox/explosion2b");
-        effect->setLifetime(4.0f);
-        effect->setSyncMode(0);
-
-        ParticleSpawner* effect2 = new ParticleSpawner(this->getContext());
-        effect2->setDestroyAfterLife(true);
-        effect2->setSource("Orxonox/smoke6");
-        effect2->setLifetime(4.0f);
-        effect2->setSyncMode(0);
-
-        this->explosion_->attach(effect);
-        this->explosion_->attach(effect2);
-
-        this->attach(explosion_);
-        this->attach(debrisEntity1_);
-        this->attach(debrisEntity2_);
-        this->attach(debrisEntity3_);
-        this->attach(debrisEntity4_);
-
-
-        for(int i=0;i<10;i++)
-        {
-            Model* part1 = new Model(this->getContext());
-            Model* part2 = new Model(this->getContext());
-
-            MovableEntity* partEntity1 = new MovableEntity(this->getContext());
-            MovableEntity* partEntity2 = new MovableEntity(this->getContext());
-
-            part1->setSyncMode(0);
-            part2->setSyncMode(0);
-            partEntity1->setSyncMode(0);
-            partEntity2->setSyncMode(0);
-
-            partEntity1->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(10,100));
-            partEntity1->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
-            partEntity1->setScale(rnd(1, 3));
-
-            partEntity2->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(10, 100));
-            partEntity2->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
-            partEntity2->setScale(rnd(1, 3));
-
-            part1->setMeshSource("SmallPart1.mesh");
-            part2->setMeshSource("SmallPart2.mesh");
-
-            partEntity1->attach(part1);
-            partEntity2->attach(part2);
-
-            this->attach(partEntity1);
-            this->attach(partEntity2);
-        }
-    }
-
-    void BigExplosion::initZero()
-    {
-        this->debrisFire1_ = 0;
-        this->debrisFire2_ = 0;
-        this->debrisFire3_ = 0;
-        this->debrisFire4_ = 0;
-
-        this->debrisSmoke1_ = 0;
-        this->debrisSmoke2_ = 0;
-        this->debrisSmoke3_ = 0;
-        this->debrisSmoke4_ = 0;
-
-        this->explosionSmoke_=0;
-        this->explosionFire_=0;
-    }
-
-    BigExplosion::~BigExplosion()
-    {
-        if (this->isInitialized())
-        {
-            if (this->debrisFire1_)
-            {
-                this->debris1_->detachOgreObject(this->debrisFire1_->getParticleSystem());
-                delete this->debrisFire1_;
-            }
-            if (this->debrisSmoke1_)
-            {
-                this->debris1_->detachOgreObject(this->debrisSmoke1_->getParticleSystem());
-                delete this->debrisSmoke1_;
-            }
-
-            if (this->debrisFire2_)
-            {
-                this->debris2_->detachOgreObject(this->debrisFire2_->getParticleSystem());
-                delete this->debrisFire2_;
-            }
-            if (this->debrisSmoke2_)
-            {
-                this->debris2_->detachOgreObject(this->debrisSmoke2_->getParticleSystem());
-                delete this->debrisSmoke2_;
-            }
-
-            if (this->debrisFire3_)
-            {
-                this->debris3_->detachOgreObject(this->debrisFire3_->getParticleSystem());
-                delete this->debrisFire3_;
-            }
-            if (this->debrisSmoke3_)
-            {
-                this->debris3_->detachOgreObject(this->debrisSmoke3_->getParticleSystem());
-                delete this->debrisSmoke3_;
-            }
-
-            if (this->debrisFire4_)
-            {
-                this->debris4_->detachOgreObject(this->debrisFire4_->getParticleSystem());
-                delete this->debrisFire4_;
-            }
-            if (this->debrisSmoke4_)
-            {
-                this->debris4_->detachOgreObject(this->debrisSmoke4_->getParticleSystem());
-                delete this->debrisSmoke4_;
-            }
-        }
-    }
-
-    void BigExplosion::registerVariables()
-    {
-        registerVariable((int&)(this->LOD_), VariableDirection::ToClient, new NetworkCallback<BigExplosion>(this, &BigExplosion::LODchanged));
-        registerVariable(this->bStop_,       VariableDirection::ToClient, new NetworkCallback<BigExplosion>(this, &BigExplosion::checkStop));
-    }
-
-    void BigExplosion::LODchanged()
-    {
-        if (this->debrisFire1_)
-            this->debrisFire1_->setDetailLevel(this->LOD_);
-        if (this->debrisSmoke1_)
-            this->debrisSmoke1_->setDetailLevel(this->LOD_);
-
-        if (this->debrisFire2_)
-            this->debrisFire2_->setDetailLevel(this->LOD_);
-        if (this->debrisSmoke2_)
-            this->debrisSmoke2_->setDetailLevel(this->LOD_);
-
-        if (this->debrisFire3_)
-            this->debrisFire3_->setDetailLevel(this->LOD_);
-        if (this->debrisSmoke3_)
-            this->debrisSmoke3_->setDetailLevel(this->LOD_);
-
-        if (this->debrisFire4_)
-            this->debrisFire4_->setDetailLevel(this->LOD_);
-        if (this->debrisSmoke4_)
-            this->debrisSmoke4_->setDetailLevel(this->LOD_);
-    }
-
-    void BigExplosion::checkStop()
-    {
-        if (this->bStop_)
-            this->stop();
-    }
-
-    void BigExplosion::stop()
-    {
-        if (this->debrisFire1_)
-            this->debrisFire1_->setEnabled(false);
-        if (this->debrisSmoke1_)
-            this->debrisSmoke1_->setEnabled(false);
-
-        if (this->debrisFire2_)
-            this->debrisFire2_->setEnabled(false);
-        if (this->debrisSmoke2_)
-            this->debrisSmoke2_->setEnabled(false);
-
-        if (this->debrisFire3_)
-            this->debrisFire3_->setEnabled(false);
-        if (this->debrisSmoke3_)
-            this->debrisSmoke3_->setEnabled(false);
-
-        if (this->debrisFire4_)
-            this->debrisFire4_->setEnabled(false);
-        if (this->debrisSmoke4_)
-            this->debrisSmoke4_->setEnabled(false);
-
-        if (GameMode::isMaster())
-        {
-            this->bStop_ = true;
-            this->destroyTimer_.setTimer(1.0f, false, createExecutor(createFunctor(&BigExplosion::destroy, this)));
-        }
-    }
-
-/* TODO
-
-    void BigExplosion::setDebrisMeshes()
-    {
-
-    }
-    void BigExplosion::getDebrisMeshes()
-    {
-
-    }
-*/
-}
Index: code/trunk/src/orxonox/worldentities/BigExplosion.h
===================================================================
--- code/trunk/src/orxonox/worldentities/BigExplosion.h	(revision 11020)
+++ 	(revision )
@@ -1,94 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   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
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Benjamin de Capitani
- *   Co-authors:
- *      ...
- *
- */
-
-#ifndef _BigExplosion_H__
-#define _BigExplosion_H__
-
-#include "OrxonoxPrereqs.h"
-
-#include "tools/Timer.h"
-#include "MobileEntity.h"
-
-namespace orxonox
-{
-    class _OrxonoxExport BigExplosion : public MobileEntity
-    {
-        public:
-            BigExplosion(Context* context);
-            virtual ~BigExplosion();
-
-            inline void setLOD(LODParticle::Value level)
-                { this->LOD_ = level; this->LODchanged(); }
-            inline LODParticle::Value getLOD() const
-                { return this->LOD_; }
-
-        private:
-            void registerVariables();
-
-            void LODchanged();
-            void checkStop();
-            void stop();
-            void init();
-            void initZero();
-
-
-            bool                  bStop_;
-
-            StaticEntity*         explosion_;
-
-            MovableEntity*        debrisEntity1_;
-            MovableEntity*        debrisEntity2_;
-            MovableEntity*        debrisEntity3_;
-            MovableEntity*        debrisEntity4_;
-
-            Model*                debris1_;
-            Model*                debris2_;
-            Model*                debris3_;
-            Model*                debris4_;
-
-
-
-            ParticleInterface*    debrisSmoke1_;
-            ParticleInterface*    debrisSmoke2_;
-            ParticleInterface*    debrisSmoke3_;
-            ParticleInterface*    debrisSmoke4_;
-
-            ParticleInterface*    debrisFire1_;
-            ParticleInterface*    debrisFire2_;
-            ParticleInterface*    debrisFire3_;
-            ParticleInterface*    debrisFire4_;
-
-            ParticleInterface*    explosionSmoke_;
-            ParticleInterface*    explosionFire_;
-
-            LODParticle::Value    LOD_;
-            Timer                 destroyTimer_;
-    };
-}
-
-#endif /* _BigExplosion_H__ */
Index: code/trunk/src/orxonox/worldentities/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/worldentities/CMakeLists.txt	(revision 11020)
+++ code/trunk/src/orxonox/worldentities/CMakeLists.txt	(revision 11052)
@@ -6,5 +6,4 @@
   ControllableEntity.cc
   Drone.cc
-  BigExplosion.cc
   EffectContainer.cc
   ExplosionChunk.cc
@@ -12,4 +11,6 @@
   SpawnPoint.cc
   TeamSpawnPoint.cc
+  ExplosionPart.cc
+  Actionpoint.cc
 )
 
Index: code/trunk/src/orxonox/worldentities/ExplosionPart.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/ExplosionPart.cc	(revision 11052)
+++ code/trunk/src/orxonox/worldentities/ExplosionPart.cc	(revision 11052)
@@ -0,0 +1,260 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Vedat Aydin
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+
+#include "ExplosionPart.h"
+#include "core/XMLPort.h"
+
+
+namespace orxonox
+{
+
+    RegisterClass(ExplosionPart);
+
+    ExplosionPart::ExplosionPart(Context* context) : MovableEntity(context)
+    {
+        RegisterObject(ExplosionPart);
+        this->bStop_ = false;
+        this->LOD_ = LODParticle::Normal;
+        this->mesh_ = "";
+        this->effect1_ = "";
+        this->effect2_ = "";
+        this->model_= new Model(this->getContext());
+        this->effect1Particle_= NULL;
+        this->effect2Particle_= NULL;
+        this->explosionEntity_ = new MovableEntity(this->getContext());
+        this->posOffset_ = Vector3::ZERO;
+
+
+
+    }
+
+
+    ExplosionPart::~ExplosionPart()
+    {
+        if (this->isInitialized())
+        {
+            if (this->effect1Particle_)
+            {
+                this->model_->detachOgreObject(this->effect1Particle_->getParticleSystem());
+                delete this->effect1Particle_;
+            }
+            if (this->effect2Particle_)
+            {
+                this->model_->detachOgreObject(this->effect2Particle_->getParticleSystem());
+                delete this->effect2Particle_;
+            }
+        }
+    }
+
+
+    void ExplosionPart::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(ExplosionPart, XMLPort, xmlelement, mode);
+
+        XMLPortParam(ExplosionPart, "mesh", setMesh, getMesh, xmlelement, mode).defaultValues(""); //Define mesh file, that is going to fly out
+        XMLPortParam(ExplosionPart, "minspeed", setMinSpeed, getMinSpeed, xmlelement, mode).defaultValues(50); //Minimum velocity at which parts fly out
+        XMLPortParam(ExplosionPart, "maxspeed", setMaxSpeed, getMaxSpeed, xmlelement, mode).defaultValues(100); //Maximum velocity at which parts fly out, set both minspeed and maxspeed to 0 to have stationary effects
+        XMLPortParam(ExplosionPart, "effect1", setEffect1, getEffect1, xmlelement, mode).defaultValues(""); //particle effect 1
+        XMLPortParam(ExplosionPart, "effect2", setEffect2, getEffect2, xmlelement, mode).defaultValues(""); //particle effect 2
+        XMLPortParam(ExplosionPart, "offset", setOffset, getOffset, xmlelement, mode).defaultValues(Vector3::ZERO); //Offset of the position if you need to have an explosion off-center
+        XMLPortParam(ExplosionPart, "direction", setDirection, getDirection, xmlelement, mode).defaultValues(Vector3(1,1,1)); //general direction the parts fly in
+        XMLPortParam(ExplosionPart, "angle", setAngle, getAngle, xmlelement, mode).defaultValues(180); //defines a cone shape with direction "direction" and angle "angle" inside which the parts fly out of
+        XMLPortParam(ExplosionPart, "delay", setDelay, getDelay, xmlelement, mode).defaultValues(0); //delay to the explosion in seconds
+    }
+
+
+    void ExplosionPart::Explode()
+    {
+        this->destroyTimer_.setTimer(delay_, false, createExecutor(createFunctor(&ExplosionPart::ActuallyExplode, this)));
+    }
+
+    void ExplosionPart::stop()
+    {
+        if (this->effect1Particle_)
+            this->effect1Particle_->setEnabled(false);
+        if (this->effect2Particle_)
+            this->effect2Particle_->setEnabled(false);
+        if (this->model_)
+            this->model_->setVisible(false);
+
+        if (GameMode::isMaster())
+        {
+            this->bStop_ = true;
+            this->destroyTimer_.setTimer(1.0f, false, createExecutor(createFunctor(&ExplosionPart::destroy, this)));
+        }
+    }
+
+    void ExplosionPart::ActuallyExplode()
+    {
+        this->model_->setVisible(true);
+
+        //this->explosionEntity_->setSyncMode(0);
+
+        //this->model_->setSyncMode(0);
+
+
+        if(effect1_ != "")
+        {
+            this->effect1Particle_ = new ParticleInterface(this->getScene()->getSceneManager(), effect1_, this->LOD_);
+            this->effect1Particle_->setDimensions(this->getScale());
+            this->model_->attachOgreObject(this->effect1Particle_->getParticleSystem());
+        }
+
+        if(effect2_ != "")
+        {
+            this->effect2Particle_ = new ParticleInterface(this->getScene()->getSceneManager(), effect2_, this->LOD_);
+            this->effect2Particle_->setDimensions(this->getScale());
+            this->model_->attachOgreObject(this->effect2Particle_->getParticleSystem());
+        }
+
+
+
+
+        Vector3 velocityOffset = direction_.perpendicular();
+        velocityOffset.normalise();
+        Degree offsetDirection = Degree(rnd(0,360));
+        velocityOffset = Quaternion(offsetDirection, direction_.normalisedCopy()) * velocityOffset;
+        velocityOffset.normalise();
+        direction_.normalise();
+
+        Vector3 finalDirection = direction_ + sin((rnd(0, angle_))*math::pi/180)*velocityOffset;
+
+        this->explosionEntity_->setVelocity(finalDirection*rnd(minSpeed_,maxSpeed_));
+        this->explosionEntity_->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
+        this->explosionEntity_->setScale(this->getScale() * 4);
+
+
+        this->explosionEntity_->attach(model_);
+
+
+        this->attach(explosionEntity_);
+
+        if (GameMode::isMaster())
+        {
+            this->destroyTimer_.setTimer(rnd(2, 4), false, createExecutor(createFunctor(&ExplosionPart::stop, this)));
+        }
+    }
+
+
+
+
+    void ExplosionPart::setMesh(const std::string& newString)
+    {
+        if(newString != "")
+        {
+            this->mesh_ = newString;
+            this->model_->setMeshSource(mesh_);
+            this->model_->setVisible(false);
+        }
+    }
+
+    void ExplosionPart::setEffect1(const std::string& newString)
+    {
+        this->effect1_ = newString;
+    }
+
+    void ExplosionPart::setEffect2(const std::string& newString)
+    {
+        this->effect2_ = newString;
+    }
+
+    void ExplosionPart::setMinSpeed(float speed)
+    {
+        this->minSpeed_ = speed;
+    }
+
+    void ExplosionPart::setMaxSpeed(float speed)
+    {
+        this->maxSpeed_ = speed;
+    }
+
+    void ExplosionPart::setOffset(Vector3 newVector)
+    {
+        this->posOffset_ = newVector;
+        this->explosionEntity_->setPosition(this->getPosition() + this->posOffset_ / this->getScale());
+    }
+
+    void ExplosionPart::setDirection(Vector3 newDirection)
+    {
+        this->direction_ = newDirection;
+    }
+
+    void ExplosionPart::setAngle(float newAngle)
+    {
+        this->angle_ = newAngle;
+    }
+
+    void ExplosionPart::setDelay(float newDelay)
+    {
+        this->delay_ = newDelay;
+    }
+
+    std::string& ExplosionPart::getMesh()
+    { return this->mesh_; }
+
+    std::string& ExplosionPart::getEffect1()
+    { return this->effect1_; }
+
+    std::string& ExplosionPart::getEffect2()
+    { return this->effect2_; }
+
+    float ExplosionPart::getMinSpeed()
+    {
+        return this->minSpeed_;
+    }
+
+    float ExplosionPart::getMaxSpeed()
+    {
+        return this->maxSpeed_;
+    }
+
+    Vector3 ExplosionPart::getOffset()
+    {
+        return this->posOffset_;
+    }
+
+    Vector3 ExplosionPart::getDirection()
+    {
+        return direction_;
+    }
+
+    float ExplosionPart::getAngle()
+    {
+        return angle_;
+    }
+
+    float ExplosionPart::getDelay()
+    {
+        return delay_;
+    }
+
+
+
+}
Index: code/trunk/src/orxonox/worldentities/ExplosionPart.h
===================================================================
--- code/trunk/src/orxonox/worldentities/ExplosionPart.h	(revision 11052)
+++ code/trunk/src/orxonox/worldentities/ExplosionPart.h	(revision 11052)
@@ -0,0 +1,108 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Vedat Aydin
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ExplosionPart_H__
+#define _ExplosionPart_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "graphics/Model.h"
+#include "tools/ParticleInterface.h"
+#include "MovableEntity.h"
+#include "graphics/ParticleSpawner.h"
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "util/Exception.h"
+#include "core/command/Executor.h"
+#include "Scene.h"
+#include "tools/Timer.h"
+
+
+ namespace orxonox
+{
+    class _OrxonoxExport ExplosionPart : public MovableEntity
+    {
+        public:
+            ExplosionPart(Context* context);
+            ~ExplosionPart();
+            void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void Explode();
+            void stop();
+            void ActuallyExplode();
+
+            void setMesh(const std::string& newString);
+            std::string& getMesh();
+            void setEffect1(const std::string& newString);
+            std::string& getEffect1();
+            void setEffect2(const std::string& newString);
+            std::string& getEffect2();
+            void setMinSpeed(float speed);
+            float getMinSpeed();
+            void setMaxSpeed(float speed);
+            float getMaxSpeed();
+            void setOffset(Vector3 newVector);
+            Vector3 getOffset();
+            void setDirection(Vector3 newDirection);
+            Vector3 getDirection();
+            void setAngle(float newAgnle);
+            float getAngle();
+            void setDelay(float newDelay);
+            float getDelay();
+         
+
+        private:
+
+            bool bStop_;
+            LODParticle::Value LOD_;
+
+
+            Model* model_;
+            ParticleInterface* effect1Particle_;
+            ParticleInterface* effect2Particle_;
+
+
+            float minSpeed_;
+            float maxSpeed_;
+            std::string mesh_;
+            std::string effect1_;
+            std::string effect2_;
+            Vector3 posOffset_;
+            Vector3 direction_;
+            float angle_;
+            float delay_;
+
+            MovableEntity* explosionEntity_;
+
+            Timer destroyTimer_;
+
+
+
+    };
+}
+
+#endif /* _ExplosionPart_H__ */
Index: code/trunk/src/orxonox/worldentities/MobileEntity.h
===================================================================
--- code/trunk/src/orxonox/worldentities/MobileEntity.h	(revision 11020)
+++ code/trunk/src/orxonox/worldentities/MobileEntity.h	(revision 11052)
@@ -47,4 +47,6 @@
         linear velocity. Then the linear velocity is multiplied by the time since the last call of tick and then added to the position. The same happens with
         the angular acceleration and velocity. With this procedure MobileEntities can change their position and orientation with time.
+
+        A MobileEntity can only have the collisition type WorldEntity::None, WorldEntity::Dynamic or WorldEntity::Kinematic. The collsion type WorldEntity::Static is illegal.
     */
 
Index: code/trunk/src/orxonox/worldentities/SpawnPoint.h
===================================================================
--- code/trunk/src/orxonox/worldentities/SpawnPoint.h	(revision 11020)
+++ code/trunk/src/orxonox/worldentities/SpawnPoint.h	(revision 11052)
@@ -55,5 +55,5 @@
                 { return this->template_; }
 
-            Pawn* spawn();
+            virtual Pawn* spawn();
             void spawn(ControllableEntity* entity);
 
Index: code/trunk/src/orxonox/worldentities/StaticEntity.h
===================================================================
--- code/trunk/src/orxonox/worldentities/StaticEntity.h	(revision 11020)
+++ code/trunk/src/orxonox/worldentities/StaticEntity.h	(revision 11052)
@@ -44,4 +44,6 @@
         it is called StaticEntity. It will keep the same position (always with respect to its parent) forever unless you call the
         function @see setPosition to changee it.
+
+        A StaticEntity can only have the collisition type WorldEntity::None or WorldEntity::Static. The collsion types WorldEntity::Dynamic and WorldEntity::Kinematic are illegal.
     */
 
Index: code/trunk/src/orxonox/worldentities/TeamSpawnPoint.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/TeamSpawnPoint.cc	(revision 11020)
+++ code/trunk/src/orxonox/worldentities/TeamSpawnPoint.cc	(revision 11052)
@@ -49,3 +49,9 @@
         XMLPortParam(TeamSpawnPoint, "team", setTeamNumber, getTeamNumber, xmlelement, mode).defaultValues(0);
     }
+    Pawn* TeamSpawnPoint::spawn()
+    {
+        Pawn* entity = SpawnPoint::spawn();
+        static_cast<ControllableEntity*>(entity)->setTeam (this->teamNumber_);
+        return entity;
+    }
 }
Index: code/trunk/src/orxonox/worldentities/TeamSpawnPoint.h
===================================================================
--- code/trunk/src/orxonox/worldentities/TeamSpawnPoint.h	(revision 11020)
+++ code/trunk/src/orxonox/worldentities/TeamSpawnPoint.h	(revision 11052)
@@ -49,7 +49,8 @@
             unsigned int getTeamNumber() const
                 { return this->teamNumber_; }
+            virtual Pawn* spawn();
 
         private:
-            unsigned int teamNumber_;
+            int teamNumber_;
     };
 }
Index: code/trunk/src/orxonox/worldentities/pawns/Pawn.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/Pawn.cc	(revision 11020)
+++ code/trunk/src/orxonox/worldentities/pawns/Pawn.cc	(revision 11052)
@@ -34,4 +34,5 @@
 #include "core/GameMode.h"
 #include "core/XMLPort.h"
+#include "core/EventIncludes.h"
 #include "network/NetworkFunction.h"
 
@@ -41,9 +42,10 @@
 #include "graphics/ParticleSpawner.h"
 #include "worldentities/ExplosionChunk.h"
-#include "worldentities/BigExplosion.h"
+#include "worldentities/ExplosionPart.h"
 #include "weaponsystem/WeaponSystem.h"
 #include "weaponsystem/WeaponSlot.h"
 #include "weaponsystem/WeaponPack.h"
 #include "weaponsystem/WeaponSet.h"
+#include "weaponsystem/Munition.h"
 #include "sound/WorldSound.h"
 
@@ -61,5 +63,5 @@
 
         this->bAlive_ = true;
-        this->bReload_ = false;
+        this->bVulnerable_ = true;
 
         this->health_ = 0;
@@ -71,8 +73,7 @@
         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->shieldRechargeRate_ = 0;
+        this->shieldRechargeWaitTime_ = 1.0f;
+        this->shieldRechargeWaitCountdown_ = 0;
 
         this->lastHitOriginator_ = 0;
@@ -84,4 +85,6 @@
 
         this->aimPosition_ = Vector3::ZERO;
+
+        //this->explosionPartList_ = NULL;
 
         if (GameMode::isMaster())
@@ -135,14 +138,18 @@
         XMLPortParam(Pawn, "shieldabsorption", setShieldAbsorption, getShieldAbsorption, xmlelement, mode).defaultValues(0);
 
+        XMLPortParam(Pawn, "vulnerable", setVulnerable, isVulnerable, xmlelement, mode).defaultValues(true);
+
         XMLPortParam(Pawn, "spawnparticlesource", setSpawnParticleSource, getSpawnParticleSource, xmlelement, mode);
         XMLPortParam(Pawn, "spawnparticleduration", setSpawnParticleDuration, getSpawnParticleDuration, xmlelement, mode).defaultValues(3.0f);
-        XMLPortParam(Pawn, "explosionchunks", setExplosionChunks, getExplosionChunks, xmlelement, mode).defaultValues(7);
+        XMLPortParam(Pawn, "explosionchunks", setExplosionChunks, getExplosionChunks, xmlelement, mode).defaultValues(0);
 
         XMLPortObject(Pawn, WeaponSlot, "weaponslots", addWeaponSlot, getWeaponSlot, xmlelement, mode);
         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);
+        XMLPortObject(Pawn, WeaponPack, "weaponpacks", addWeaponPackXML, getWeaponPack, xmlelement, mode);
+        XMLPortObject(Pawn, Munition, "munition", addMunitionXML, getMunitionXML, xmlelement, mode);
+
+        XMLPortObject(Pawn, ExplosionPart, "explosion", addExplosionPart, getExplosionPart, xmlelement, mode);
+        XMLPortParam(Pawn, "shieldrechargerate", setShieldRechargeRate, getShieldRechargeRate, xmlelement, mode).defaultValues(0);
+        XMLPortParam(Pawn, "shieldrechargewaittime", setShieldRechargeWaitTime, getShieldRechargeWaitTime, xmlelement, mode).defaultValues(1.0f);
 
         XMLPortParam(Pawn, "explosionSound",  setExplosionSound,  getExplosionSound,  xmlelement, mode);
@@ -151,31 +158,37 @@
     }
 
+    void Pawn::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Pawn, XMLEventPort, xmlelement, mode);
+
+        XMLPortEventState(Pawn, BaseObject, "vulnerability", setVulnerable, xmlelement, mode);
+    }
+
     void Pawn::registerVariables()
     {
-        registerVariable(this->bAlive_,           VariableDirection::ToClient);
-        registerVariable(this->health_,           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);
-        registerVariable(this->aimPosition_,      VariableDirection::ToServer);  // For the moment this variable gets only transfered to the server
+        registerVariable(this->bAlive_,            VariableDirection::ToClient);
+        registerVariable(this->health_,            VariableDirection::ToClient);
+        registerVariable(this->maxHealth_,         VariableDirection::ToClient);
+        registerVariable(this->shieldHealth_,      VariableDirection::ToClient);
+        registerVariable(this->maxShieldHealth_,   VariableDirection::ToClient);
+        registerVariable(this->shieldAbsorption_,  VariableDirection::ToClient);
+        registerVariable(this->aimPosition_,       VariableDirection::ToServer);  // For the moment this variable gets only transfered to the server
     }
 
     void Pawn::tick(float dt)
     {
+        //BigExplosion* chunk = new BigExplosion(this->getContext());
         SUPER(Pawn, tick, dt);
 
-        this->bReload_ = false;
-
+        // Recharge the shield
         // TODO: use the existing timer functions instead
-        if(this->reloadWaitCountdown_ > 0)
-        {
-            this->decreaseReloadCountdownTime(dt);
-        }
-        else
-        {
-            this->addShieldHealth(this->getReloadRate() * dt);
-            this->resetReloadCountdown();
+        if(this->shieldRechargeWaitCountdown_ > 0)
+        {
+            this->decreaseShieldRechargeCountdownTime(dt);
+        }
+        else
+        {
+            this->addShieldHealth(this->getShieldRechargeRate() * dt);
+            this->resetShieldRechargeCountdown();
         }
 
@@ -229,21 +242,32 @@
     }
 
-    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::setShieldRechargeRate(float shieldRechargeRate)
+    {
+        this->shieldRechargeRate_ = shieldRechargeRate;
+    }
+
+    void Pawn::setShieldRechargeWaitTime(float shieldRechargeWaitTime)
+    {
+        this->shieldRechargeWaitTime_ = shieldRechargeWaitTime;
+    }
+
+    void Pawn::decreaseShieldRechargeCountdownTime(float dt)
+    {
+        this->shieldRechargeWaitCountdown_ -= dt;
+    }
+
+    void Pawn::changedVulnerability()
+    {
+
     }
 
     void Pawn::damage(float damage, float healthdamage, float shielddamage, Pawn* originator, const btCollisionShape* cs)
     {
+        // A pawn can only get damaged if it is vulnerable
+        if (!isVulnerable())
+        {
+            return;
+        }
+
         // Applies multiplier given by the DamageBoost Pickup.
         if (originator)
@@ -252,4 +276,8 @@
         if (this->getGametype() && this->getGametype()->allowPawnDamage(this, originator))
         {
+            // Health-damage cannot be absorbed by shields.
+            // Shield-damage only reduces shield health. 
+            // Normal damage can be (partially) absorbed by shields.
+
             if (shielddamage >= this->getShieldHealth())
             {
@@ -366,5 +394,4 @@
             if (GameMode::isMaster())
             {
-                this->deatheffect();
                 this->goWithStyle();
             }
@@ -373,99 +400,25 @@
     void Pawn::goWithStyle()
     {
+
         this->bAlive_ = false;
         this->setDestroyWhenPlayerLeft(false);
 
-        BigExplosion* chunk = new BigExplosion(this->getContext());
-        chunk->setPosition(this->getPosition());
-        chunk->setVelocity(this->getVelocity());
+        while(!explosionPartList_.empty())
+        {
+            explosionPartList_.back()->setPosition(this->getPosition());
+            explosionPartList_.back()->setVelocity(this->getVelocity());
+            explosionPartList_.back()->setOrientation(this->getOrientation());
+            explosionPartList_.back()->Explode();
+            explosionPartList_.pop_back();
+        }
+
+        for (unsigned int i = 0; i < this->numexplosionchunks_; ++i)
+        {
+            ExplosionChunk* chunk = new ExplosionChunk(this->getContext());
+            chunk->setPosition(this->getPosition());
+        }
 
         this->explosionSound_->setPosition(this->getPosition());
         this->explosionSound_->play();
-    }
-    void Pawn::deatheffect()
-    {
-        // play death effect
-        /*{
-            ParticleSpawner* effect = new ParticleSpawner(this->getContext());
-            effect->setPosition(this->getPosition());
-            effect->setOrientation(this->getOrientation());
-            effect->setDestroyAfterLife(true);
-            effect->setSource("Orxonox/explosion2b");
-            effect->setLifetime(4.0f);
-        }
-        {
-            ParticleSpawner* effect = new ParticleSpawner(this->getContext());
-            effect->setPosition(this->getPosition());
-            effect->setOrientation(this->getOrientation());
-            effect->setDestroyAfterLife(true);
-            effect->setSource("Orxonox/smoke6");
-            effect->setLifetime(4.0f);
-        }
-        {
-            ParticleSpawner* effect = new ParticleSpawner(this->getContext());
-            effect->setPosition(this->getPosition());
-            effect->setOrientation(this->getOrientation());
-            effect->setDestroyAfterLife(true);
-            effect->setSource("Orxonox/sparks");
-            effect->setLifetime(4.0f);
-        }*/
-        
-        
-        {
-            ParticleSpawner* effect = new ParticleSpawner(this->getContext());
-            effect->setPosition(this->getPosition());
-            effect->setOrientation(this->getOrientation());
-            effect->setDestroyAfterLife(true);
-            effect->setSource("orxonox/explosion_flash2");
-            effect->setLifetime(5.0f);
-        }
-        {
-            ParticleSpawner* effect = new ParticleSpawner(this->getContext());
-            effect->setPosition(this->getPosition());
-            effect->setOrientation(this->getOrientation());
-            effect->setDestroyAfterLife(true);
-            effect->setSource("orxonox/explosion_flame2");
-            effect->setLifetime(5.0f);
-        }
-        {
-            ParticleSpawner* effect = new ParticleSpawner(this->getContext());
-            effect->setPosition(this->getPosition());
-            effect->setOrientation(this->getOrientation());
-            effect->setDestroyAfterLife(true);
-            effect->setSource("orxonox/explosion_shockwave2");
-            effect->scale(20);
-            effect->setLifetime(5.0f);
-        }{
-            ParticleSpawner* effect = new ParticleSpawner(this->getContext());
-            effect->setPosition(this->getPosition());
-            effect->setOrientation(this->getOrientation());
-            effect->setDestroyAfterLife(true);
-            effect->setSource("orxonox/explosion_sparks2");
-            effect->setLifetime(5.0f);
-        }
-        {
-            ParticleSpawner* effect = new ParticleSpawner(this->getContext());
-            effect->setPosition(this->getPosition());
-            effect->setOrientation(this->getOrientation());
-            effect->setDestroyAfterLife(true);
-            effect->setSource("orxonox/explosion_streak2");
-            effect->setLifetime(5.0f);
-        }
-        {
-            ParticleSpawner* effect = new ParticleSpawner(this->getContext());
-            effect->setPosition(this->getPosition());
-            effect->setOrientation(this->getOrientation());
-            effect->setDestroyAfterLife(true);
-            effect->setSource("orxonox/explosion_afterglow");
-            effect->scale(20);
-            effect->setLifetime(5.0f);
-        }
-        
-        
-        for (unsigned int i = 0; i < this->numexplosionchunks_; ++i)
-        {
-            ExplosionChunk* chunk = new ExplosionChunk(this->getContext());
-            chunk->setPosition(this->getPosition());
-        }
     }
 
@@ -474,13 +427,9 @@
         Check whether the Pawn has a @ref Orxonox::WeaponSystem and fire it with the specified firemode if it has one.
     */
+
     void Pawn::fired(unsigned int firemode)
     {
         if (this->weaponSystem_)
             this->weaponSystem_->fire(firemode);
-    }
-
-    void Pawn::reload()
-    {
-        this->bReload_ = true;
     }
 
@@ -491,4 +440,14 @@
             this->spawneffect();
     }
+
+
+    void Pawn::addExplosionPart(ExplosionPart* ePart)
+    {this->explosionPartList_.push_back(ePart);}
+
+
+    ExplosionPart * Pawn::getExplosionPart()
+    {return this->explosionPartList_.back();}
+
+
 
     /* WeaponSystem:
@@ -554,8 +513,39 @@
     }
 
+    std::vector<WeaponPack *> * Pawn::getAllWeaponPacks()
+    {
+        if (this->weaponSystem_)
+            return this->weaponSystem_->getAllWeaponPacks();
+        else
+            return 0;        
+    }
+
+    void Pawn::addMunitionXML(Munition* munition)
+    {
+        if (this->weaponSystem_ && munition)
+        {
+            this->weaponSystem_->addMunition(munition);
+        }
+    }
+
+    Munition* Pawn::getMunitionXML() const
+    {
+        return NULL;
+    }
+
+    Munition* Pawn::getMunition(SubclassIdentifier<Munition> * identifier)
+    {
+        if (weaponSystem_)
+        {
+            return weaponSystem_->getMunition(identifier);
+        }
+
+        return NULL;
+    }
+
     //Tell the Map (RadarViewable), if this is a playership
     void Pawn::startLocalHumanControl()
     {
-//        SUPER(ControllableEntity, changedPlayer());
+//        SUPER(ControllableEntity, startLocalHumanControl());
         ControllableEntity::startLocalHumanControl();
         this->isHumanShip_ = true;
Index: code/trunk/src/orxonox/worldentities/pawns/Pawn.h
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/Pawn.h	(revision 11020)
+++ code/trunk/src/orxonox/worldentities/pawns/Pawn.h	(revision 11052)
@@ -33,7 +33,9 @@
 
 #include <string>
+#include <vector>
 #include "interfaces/PickupCarrier.h"
 #include "interfaces/RadarViewable.h"
 #include "worldentities/ControllableEntity.h"
+#include "worldentities/ExplosionPart.h"
 
 
@@ -42,9 +44,9 @@
     /**
     @brief
-        Everything in Orxonoy that has a health attribute is a Pawn. After a Pawn is spawned its health is set to
+        Everything in Orxonox that has a health attribute is a Pawn. After a Pawn is spawned its health is set to
         its initial health. In every call of the Pawns tick function the game checks whether the pawns health is at
         or below zero. If it is, the pawn gets killed.
 
-        Pawns can carry pickups and fire weapons. The can also have shields.
+        Pawns can carry pickups and fire weapons. They can also have shields.
 
         Notice that every Pawn is a ControllableEntity.
@@ -62,4 +64,5 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
             virtual void tick(float dt);
 
@@ -116,26 +119,37 @@
                 { 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);
+            virtual void setShieldRechargeRate(float shieldRechargeRate);
+            inline float getShieldRechargeRate() const
+                { return this->shieldRechargeRate_; }
+
+            virtual void setShieldRechargeWaitTime(float shieldRechargeWaitTime);
+            inline float getShieldRechargeWaitTime() const
+                { return this->shieldRechargeWaitTime_; }
+
+            inline void resetShieldRechargeCountdown()
+                { this->shieldRechargeWaitCountdown_ = 0; }
+
+            inline void startShieldRechargeCountdown()
+                { this->shieldRechargeWaitCountdown_ = this->getShieldRechargeWaitTime(); } // TODO: Implement in Projectile.cc
+
+            virtual void decreaseShieldRechargeCountdownTime(float dt);
+
+            /** @brief Sets the state of the pawns vulnerability. @param bVulnerable */
+            inline void setVulnerable(bool bVulnerable)
+            {
+                if (this->bVulnerable_ != bVulnerable)
+                {
+                    this->bVulnerable_ = bVulnerable;
+                    this->changedVulnerability();
+                }
+            }
+            /** @brief Returns the state of the pawns vulnerability. @return The state of the vulnerability */
+            inline const bool& isVulnerable() const { return this->bVulnerable_; }
+            /** @brief This function gets called if the vulnerability of the pawn changes. */
+            virtual void changedVulnerability();
 
             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, const btCollisionShape* cs, float damage, float healthdamage = 0.0f, float shielddamage = 0.0f);
             virtual void hit(Pawn* originator, btManifoldPoint& contactpoint, const btCollisionShape* cs, float damage, float healthdamage = 0.0f, float shielddamage = 0.0f);
@@ -144,6 +158,8 @@
 
             virtual void fired(unsigned int firemode);
-            virtual void reload();
             virtual void postSpawn();
+
+            void addExplosionPart(ExplosionPart* ePart);
+            ExplosionPart * getExplosionPart();
 
             void addWeaponSlot(WeaponSlot * wSlot);
@@ -154,4 +170,10 @@
             void addWeaponPackXML(WeaponPack * wPack);
             WeaponPack * getWeaponPack(unsigned int index) const;
+            std::vector<WeaponPack *> * getAllWeaponPacks();
+
+            void addMunitionXML(Munition* munition);
+            Munition* getMunitionXML() const;
+            
+            Munition* getMunition(SubclassIdentifier<Munition> * identifier);
 
             virtual void addedWeaponPack(WeaponPack* wPack) {}
@@ -194,4 +216,7 @@
             const std::string& getExplosionSound();
 
+            virtual const WeaponSystem* getWeaponSystem() const
+                { return this->weaponSystem_; }
+
         protected:
             virtual void preDestroy();
@@ -204,11 +229,10 @@
             virtual Controller* getSlave();
             virtual void goWithStyle();
-            virtual void deatheffect();
             virtual void spawneffect();
 
-            //virtual void damage(float damage, Pawn* originator = 0);
             virtual void damage(float damage, float healthdamage = 0.0f, float shielddamage = 0.0f, Pawn* originator = NULL, const btCollisionShape* cs = NULL);
 
             bool bAlive_;
+            bool bVulnerable_; ///< If false the pawn may not ged damaged
 
             virtual std::vector<PickupCarrier*>* getCarrierChildren(void) const
@@ -226,7 +250,7 @@
             float initialShieldHealth_;
             float shieldAbsorption_; ///< Has to be between 0 and 1
-            float reloadRate_;
-            float reloadWaitTime_;
-            float reloadWaitCountdown_;
+            float shieldRechargeRate_;
+            float shieldRechargeWaitTime_;
+            float shieldRechargeWaitCountdown_;
 
             float damageMultiplier_; ///< Used by the Damage Boost Pickup.
@@ -235,9 +259,10 @@
 
             WeaponSystem* weaponSystem_;
-            bool bReload_;
 
             std::string spawnparticlesource_;
             float spawnparticleduration_;
             unsigned int numexplosionchunks_;
+
+            std::vector<ExplosionPart*> explosionPartList_;
 
         private:
Index: code/trunk/src/orxonox/worldentities/pawns/SpaceShip.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/SpaceShip.cc	(revision 11020)
+++ code/trunk/src/orxonox/worldentities/pawns/SpaceShip.cc	(revision 11052)
@@ -115,4 +115,6 @@
 
         XMLPortObject(SpaceShip, Engine, "engines", addEngine, getEngine, xmlelement, mode);
+
+        
     }
 
@@ -297,4 +299,22 @@
         }
     }
+
+    void SpaceShip::gainBoostPower(float gainedBoostPower)
+    {
+        this->boostPower_ += gainedBoostPower;
+        
+        if (this->boostPower_ > this->initialBoostPower_)
+        {
+            this->boostPower_ = this->initialBoostPower_;
+        }
+
+        // If the booster is in cooldown mode and we gained boost power, the abort the cooldown.
+        if (this->isBoostCoolingDown() && this->boostPower_ > 0.0f)
+        {
+            timer_.stopTimer();
+            this->boostCooledDown();
+        }
+    }
+
     /**
     @brief
Index: code/trunk/src/orxonox/worldentities/pawns/SpaceShip.h
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/SpaceShip.h	(revision 11020)
+++ code/trunk/src/orxonox/worldentities/pawns/SpaceShip.h	(revision 11052)
@@ -53,5 +53,7 @@
         - The <b>boost</b>, there are quite some parameters pertaining to boosting. The boost is a special move of the SpaceShip, where, for a limited amount of time, it can fly considerably faster than usual. The <b>boostPower</b> is the amount of power available for boosting. The <b>boostPowerRate</b> is the rate at which the boost power is replenished. The <b>boostRate</b> is the rate at which boosting uses power. And the <b>boostCooldownDuration</b> is the time the SpaceShip cannot boost, once all the boost power has been used up. Naturally all of these parameters must be non-negative.
         - The <b>boost shaking</b>, when the SpaceShip boosts, the camera shakes to create a more immersive effect. Two parameters can be used to adjust the effect. The <b>shakeFrequency</b> is the frequency with which the camera shakes. And the <b>shakeAmplitude</b> is the amount with which the camera shakes. Again these parameters must bee non-negative.
-        - The <b>lift</b> creates a more natural flight feeling through the addition of a lift force. There are again tow parameters that can be specified. The <b>lift</b> which is the lift force that is applied. And the <b>stallSpeed</b> which is the forward speed after which no more lift is generated.
+        - The <b>lift</b> creates a more natural flight feeling through the addition of a lift force. There are again two parameters that can be specified. The <b>lift</b> which is the lift force that is applied. And the <b>stallSpeed</b> which is the forward speed after which no more lift is generated.
+
+        A spaceship always needs to have the collision type "dynamic". Other collision types are illegal.
 
         As mentioned @ref orxonox::Engine Engines can be mounted on the SpaceShip. Here is a (primitive) example of a SpaceShip defined in XML:
@@ -250,4 +252,9 @@
             inline float getShakeAmplitude() const
                 { return this->shakeAmplitude_; }
+            /**
+            @brief Add boost power. Is non-negative.
+            @return Returns the current boost power.
+            */
+            void gainBoostPower(float gainedBoostPower);
 
         protected:
@@ -262,5 +269,5 @@
             bool bBoostCooldown_;         //!< Whether the SpaceShip is currently in boost cooldown, during which boosting is impossible.
             float initialBoostPower_;     //!< The initial (and maximal) boost power.
-            float boostPower_;            //!< The current boost power.
+            float boostPower_;            //!< The current boost power. If the boost power is reduced to zero the boost cooldown will start.
             float boostPowerRate_;        //!< The rate at which the boost power is recharged.
             float boostRate_;             //!< The rate at which boost power is used up.
@@ -289,5 +296,5 @@
             std::vector<Engine*> engineList_; //!< The list of all Engines mounted on this SpaceShip.
 
-            Timer timer_;                          //!< Timer for the cooldown duration.
+            Timer timer_;                          //!< Timer for the cooldown of the boost.
             float shakeDt_;                        //!< Temporary variable for the shaking of the camera.
             Vector3 cameraOriginalPosition_;       //!< The original position of the camera before shaking it.
