Index: /code/branches/presentation3/src/orxonox/controllers/AIController.cc
===================================================================
--- /code/branches/presentation3/src/orxonox/controllers/AIController.cc	(revision 7065)
+++ /code/branches/presentation3/src/orxonox/controllers/AIController.cc	(revision 7066)
@@ -127,16 +127,5 @@
 
             if  (this->specificMasterAction_ != NONE) 
-            {
                     this->specificMasterActionHold();
-
-//                 if (this->specificMasterAction_  == TURN180)
-//                     this->turn180Init();
-
-//                 if (this->specificMasterAction_ == SPIN)
-//                     this->spinInit();
-
-//                 if (this->specificMasterAction_ == FOLLOWHUMAN)
-//                     this->followHuman(this->HumanToFollow_, false);
-            }
 
             else {
@@ -151,4 +140,9 @@
                 if (random < 5)
                    this->spinInit();
+
+                // follow a randomly chosen human - a specific Master Action
+                random = rnd(1000.0f);
+                if (random < 1)
+                   this->followRandomHumanInit();
 
                  // lose master status (only if less than 4 slaves in formation)
@@ -230,5 +224,5 @@
             if (this->specificMasterAction_ == SPIN)
                     this->spin();
-            if (this->specificMasterAction_ == FOLLOWHUMAN)
+            if (this->specificMasterAction_ == FOLLOW)
                     this->follow();
         }
Index: /code/branches/presentation3/src/orxonox/controllers/ArtificialController.cc
===================================================================
--- /code/branches/presentation3/src/orxonox/controllers/ArtificialController.cc	(revision 7065)
+++ /code/branches/presentation3/src/orxonox/controllers/ArtificialController.cc	(revision 7066)
@@ -54,4 +54,5 @@
 
     static const unsigned int STANDARD_MAX_FORMATION_SIZE = 7;
+    static const int RADIUS_TO_SEARCH_FOR_MASTERS = 5000;
     static const int FORMATION_LENGTH =  130;
     static const int FORMATION_WIDTH =  110;
@@ -61,5 +62,5 @@
     static const float SPEED_FREE = 0.8f;
     static const float ROTATEFACTOR_FREE = 0.8f;
-    static const int SECONDS_TO_FOLLOW_HUMAN = 100;
+
 
     ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator)
@@ -79,6 +80,6 @@
         this->bShooting_ = false;
         this->bHasTargetPosition_ = false;
+        this->speedCounter_ = 0.2f;
         this->targetPosition_ = Vector3::ZERO;
-        this->humanToFollow_ = NULL;
 
         this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this));
@@ -94,6 +95,6 @@
 
         XMLPortParam(ArtificialController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(-1);
-        XMLPortParam(ArtificialController, "formationflight", setFormationFlight, getFormationFlight, xmlelement, mode).defaultValues(true);
-        XMLPortParam(ArtificialController, "formation_size", setFormationSize, getFormationSize, xmlelement, mode).defaultValues(STANDARD_MAX_FORMATION_SIZE);
+        XMLPortParam(ArtificialController, "formationFlight", setFormationFlight, getFormationFlight, xmlelement, mode).defaultValues(true);
+        XMLPortParam(ArtificialController, "formationSize", setFormationSize, getFormationSize, xmlelement, mode).defaultValues(STANDARD_MAX_FORMATION_SIZE);
     }
 
@@ -104,5 +105,5 @@
         @param form activate formflight if form is true
     */
-    void ArtificialController::formationflight(bool form)
+    void ArtificialController::formationflight(const bool form)
     {
         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
@@ -129,5 +130,5 @@
         @param action which action to perform (integer, so it can be called with a console command (tmp solution))
     */
-    void ArtificialController::masteraction(int action)
+    void ArtificialController::masteraction(const int action)
     {
         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
@@ -149,5 +150,5 @@
 
     /**
-        @brief A human player gets followed by its nearest master. Initiated by console command, intended for demonstration puproses. Does not work at the moment.
+        @brief A human player gets followed by its nearest master. Initiated by console command, so far intended for demonstration puproses (possible future pickup).
     */
     void ArtificialController::followme()
@@ -169,5 +170,5 @@
             ArtificialController *aiController = orxonox_cast<ArtificialController*>(it->getController());
 
-            if(aiController || aiController->state_ == MASTER)
+            if(aiController && aiController->state_ == MASTER)
                 allMasters.push_back(aiController);
 
@@ -182,11 +183,11 @@
                 int i = 0;
 
-                for(std::vector<ArtificialController*>::iterator it = allMasters.begin(); it != allMasters.end(); it++)
+                for(std::vector<ArtificialController*>::iterator it = allMasters.begin(); it != allMasters.end(); it++, i++)
                     {
+                        if (!ArtificialController::sameTeam((*it)->getControllableEntity(), humanPawn, (*it)->getGametype())) continue;
                         distance = posHuman - (*it)->getControllableEntity()->getPosition().length();
                         if(distance < minDistance) index = i;
                     }
-                allMasters[index]->humanToFollow_ = humanPawn;
-//                allMasters[index]->followHuman(humanPawn, false);
+                allMasters[index]->followInit(humanPawn);
             }
 
@@ -197,5 +198,5 @@
         @param passive if true, bots won't shoot.
     */
-    void ArtificialController::passivebehaviour(bool passive)
+    void ArtificialController::passivebehaviour(const bool passive)
     {
         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
@@ -218,5 +219,5 @@
         @param size maximal formation size.
     */
-    void ArtificialController::formationsize(int size)
+    void ArtificialController::formationsize(const int size)
     {
         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
@@ -242,7 +243,8 @@
         {
         if (this->state_ == SLAVE) unregisterSlave();
-         if (this->state_ == MASTER) setNewMasterWithinFormation();
+        if (this->state_ == MASTER) setNewMasterWithinFormation();
         this->slaves_.clear();
         this->state_ = FREE;
+        this->specificMasterAction_ = NONE;
 
         }
@@ -255,4 +257,11 @@
             return;
 
+        // Slave uses special movement if its master is in FOLLOW mode
+        if(this->state_ == SLAVE && this->myMaster_ && this->myMaster_->specificMasterAction_ == FOLLOW)
+        {
+//             this->followForSlaves(target);
+//             return;
+        }
+
         Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
         float distance = (target - this->getControllableEntity()->getPosition()).length();
@@ -263,5 +272,5 @@
             if (this->target_ || distance > 10)
             {
-                // Multiply with 0.8 to make them a bit slower
+                // Multiply with ROTATEFACTOR_FREE to make them a bit slower
                 this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_FREE * sgn(coord.x) * coord.x*coord.x);
                 this->getControllableEntity()->rotatePitch(ROTATEFACTOR_FREE * sgn(coord.y) * coord.y*coord.y);
@@ -316,11 +325,7 @@
     }
 
-    int ArtificialController::getState()
-    {
-        return this->state_;
-    }
-
-    /**
-        @brief Unregisters a slave from its master. Called by a slave.
+
+    /**
+        @brief Unregisters a slave from its master. Initiated by a slave.
     */
     void ArtificialController::unregisterSlave() {
@@ -363,5 +368,5 @@
 
             //is it a master?
-            if (!newMaster || newMaster->getState() != MASTER)
+            if (!newMaster || newMaster->state_ != MASTER)
                 continue;
 
@@ -369,5 +374,5 @@
 
             // is pawn in range?
-            if (distance < 5000)
+            if (distance < RADIUS_TO_SEARCH_FOR_MASTERS)
             {
                 if(newMaster->slaves_.size() > this->maxFormationSize_) continue;
@@ -393,5 +398,5 @@
 
     /**
-        @brief Commands the slaves of a master into a formation. Called by a master.
+        @brief Commands the slaves of a master into a formation. Sufficiently fast not to be called within tick. Initiated by a master.
     */
     void ArtificialController::commandSlaves() 
@@ -452,4 +457,5 @@
 
         this->slaves_.clear();
+        this->specificMasterAction_ = NONE;
         this->state_ = SLAVE;
         this->myMaster_ = newMaster;
@@ -463,5 +469,5 @@
 
     /**
-        @brief Frees all slaves form a master. Called by a master.
+        @brief Frees all slaves form a master. Initiated by a master.
     */
     void ArtificialController::freeSlaves()
@@ -538,5 +544,4 @@
     void ArtificialController::turn180Init()
     {
-        COUT(0) << "~turnInit" << std::endl;
         if(this->state_ != MASTER) return;
 
@@ -564,9 +569,8 @@
 
     /**
-        @brief Master initializes a spin around its looking direction axis. Leads to a "specific master action". Not yet implemented.
+        @brief Master initializes a spin around its looking direction axis. Leads to a "specific master action".
     */
     void ArtificialController::spinInit()
     {
-        COUT(0) << "~spinInit" << std::endl;
         if(this->state_ != MASTER) return;
         this->specificMasterAction_ = SPIN;
@@ -584,19 +588,18 @@
 
     /**
-        @brief Master begins to follow a human player. Is a "specific master action".
-        @param humanController human to follow.
-        @param alaways follows human forever if true, else it follows it for @var SECONDS_TO_FOLLOW_HUMAN seconds.
-    */
-    void ArtificialController::followHumanInit(Pawn* human, bool always)
-    {
-        COUT(0) << "~followInit" << std::endl;
-        if (human == NULL || this->state_ != MASTER)
+        @brief Master begins to follow a pawn. Is a "specific master action".
+        @param pawn pawn to follow.
+        @param alaways follows pawn forever if true (false if omitted).
+        @param secondsToFollow seconds to follow the pawn if always is false. Will follow pawn 100 seconds if omitted (set in header).
+    */
+    void ArtificialController::followInit(Pawn* pawn, const bool always, const int secondsToFollow)
+    {
+        if (pawn == NULL || this->state_ != MASTER)
             return;
-
-        this->specificMasterAction_  =  FOLLOWHUMAN;
-
-        this->setTarget(human);
+        this->specificMasterAction_  =  FOLLOW;
+
+        this->setTarget(pawn);
         if (!always)
-            this->specificMasterActionHoldCount_ = SECONDS_TO_FOLLOW_HUMAN;
+            this->specificMasterActionHoldCount_ = secondsToFollow;
         else 
             this->specificMasterActionHoldCount_ = INT_MAX; //for now...
@@ -604,12 +607,122 @@
     }
 
-    /**
-        @brief Follows target with adjusted speed. Called within tick.
+
+    /**
+        @brief Master begins to follow a randomly chosen human player of the same team. Is a "specific master action".
+    */
+    void ArtificialController::followRandomHumanInit()
+    {
+
+        Pawn *humanPawn = NULL;
+        NewHumanController *currentHumanController = NULL;
+
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
+        {
+            if (!it->getController())
+                continue;
+
+            currentHumanController = orxonox_cast<NewHumanController*>(it->getController());
+            if(currentHumanController) 
+            {
+                if (!ArtificialController::sameTeam(this->getControllableEntity(), *it, this->getGametype())) continue;
+                humanPawn = *it;
+                break;
+            }
+        }
+
+        if((humanPawn != NULL))
+                this->followInit(humanPawn);
+    }
+
+    /**
+        @brief Master follows target with adjusted speed. Called within tick.
     */
     void ArtificialController::follow()
     {
-        this->moveToTargetPosition(); //standard position apprach for now.
-    }
-
+        this->moveToPosition(this->target_->getPosition());
+/*
+        if (!this->getControllableEntity())
+            return;
+
+        float distance = (this->target_->getPosition() - this->getControllableEntity()->getPosition()).length();
+
+        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->target_->getPosition());
+
+
+        this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x);
+        this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y);
+
+        float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->target_->getVelocity().squaredLength();
+
+COUT(0) << "~follow distance: " << distance << "SpeedCounter: " << this->speedCounter_ << "~speedDiv: " << speedDiv << std::endl;
+        if (distance < 800)
+        {
+            if (distance < 200)
+            {
+                this->speedCounter_ -= 0.5f;
+                if(this->speedCounter_ < 0) this->speedCounter_ = 0.0f;
+                this->getControllableEntity()->moveFrontBack(speedCounter_);
+            } else {
+                if(speedDiv < 0)
+                    this->speedCounter_ +=  0.01f;
+                else
+                    this->speedCounter_ -= 0.05f;
+                this->getControllableEntity()->moveFrontBack(speedCounter_);
+            }
+
+        } else {
+            this->speedCounter_ += 0.05f;
+            this->getControllableEntity()->moveFrontBack(speedCounter_ + distance/300.0f);
+        }
+//         if (this->getControllableEntity()->getVelocity().squaredLength() > 50.0f) this->speedCounter_ = 0;
+
+*/
+    }
+
+
+    /**
+        @brief Slave moving behaviour when master is following a pawn, gets redirected from moveToPosition(const Vector3& target)). Called within tick.
+    */
+    void ArtificialController::followForSlaves(const Vector3& target)
+    {
+
+/*
+        if (!this->getControllableEntity() && !this->myMaster_ && this->myMaster_->state_ != FOLLOW && !this->myMaster_->target_)
+            return;
+
+        float distance = (target - this->getControllableEntity()->getPosition()).length();
+
+        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
+
+
+        this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x);
+        this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y);
+
+
+        float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->myMaster_->target_->getVelocity().squaredLength();
+
+
+         if (distance < 800)
+        {
+            if (distance < 200)
+            {
+                this->speedCounter_ -= 5.0f;
+                if(this->speedCounter_ < 0) this->speedCounter_ = 0.0f;
+                this->getControllableEntity()->moveFrontBack(speedCounter_);
+            } else {
+                if(speedDiv < 0)
+                    this->speedCounter_ +=  0.01f;
+                else
+                    this->speedCounter_ -= 0.05f;
+                this->getControllableEntity()->moveFrontBack(speedCounter_);
+            }
+
+        } else {
+            this->speedCounter_ += 0.05f;
+            this->getControllableEntity()->moveFrontBack(speedCounter_ + distance/300.0f);
+        }
+//         if (this->getControllableEntity()->getVelocity().squaredLength() > 50.0f) this->speedCounter_ = 0;
+*/
+    }
 
 
Index: /code/branches/presentation3/src/orxonox/controllers/ArtificialController.h
===================================================================
--- /code/branches/presentation3/src/orxonox/controllers/ArtificialController.h	(revision 7065)
+++ /code/branches/presentation3/src/orxonox/controllers/ArtificialController.h	(revision 7066)
@@ -54,19 +54,22 @@
             inline int getTeam() const
                 { return this->team_; }
+
             inline void setFormationFlight(bool formation)
                 { this->formationFlight_ = formation; }
             inline bool getFormationFlight() const
                 { return this->formationFlight_; }
+
             inline void setFormationSize(int size)
                 { this->maxFormationSize_ = size; }
             inline int getFormationSize() const
                 { return this->maxFormationSize_; }
+
             virtual void changedControllableEntity();
 
-            static void formationflight(bool form);
-            static void masteraction(int action);
+            static void formationflight(const bool form);
+            static void masteraction(const int action);
             static void followme();
-            static void passivebehaviour(bool passive);
-            static void formationsize(int size);
+            static void passivebehaviour(const bool passive);
+            static void formationsize(const int size);
 
         protected:
@@ -81,15 +84,11 @@
             std::vector<ArtificialController*> slaves_;
             ArtificialController *myMaster_;
-            enum SpecificMasterAction {NONE, HOLD, SPIN, TURN180, FOLLOWHUMAN};
+            enum SpecificMasterAction {NONE, HOLD, SPIN, TURN180, FOLLOW};
             SpecificMasterAction specificMasterAction_;
             int specificMasterActionHoldCount_;
-            Pawn* humanToFollow_;
-
-            void targetDied();
+            float speedCounter_; //for speed adjustment when following
 
             void moveToPosition(const Vector3& target);
             void moveToTargetPosition();
-
-            int getState();
 
             void unregisterSlave();
@@ -109,6 +108,8 @@
             void spinInit();
             void spin();
-            void followHumanInit(Pawn* human, bool always);
+            void followInit(Pawn* pawn, const bool always = false, const int secondsToFollow = 100);
+            void followRandomHumanInit();
             void follow();
+            void followForSlaves(const Vector3& target);
 
             void setTargetPosition(const Vector3& target);
@@ -122,4 +123,6 @@
             bool isCloseAtTarget(float distance) const;
             bool isLookingAtTarget(float angle) const;
+
+            void targetDied();
 
             static bool sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype); // hack
