Index: code/branches/ai2/src/orxonox/controllers/ArtificialController.cc
===================================================================
--- code/branches/ai2/src/orxonox/controllers/ArtificialController.cc	(revision 8844)
+++ code/branches/ai2/src/orxonox/controllers/ArtificialController.cc	(revision 8845)
@@ -405,4 +405,29 @@
     }
 
+    void ArtificialController::absoluteMoveToPosition(const Vector3& target)
+    {
+        float minDistance = 40.0f;
+        if (!this->getControllableEntity())
+            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();
+
+            if (this->target_ || distance > minDistance)
+            {
+                // 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);
+                this->getControllableEntity()->moveFrontBack(SPEED_FREE);
+            }
+
+
+        if (distance < minDistance)
+        {
+            this->positionReached();
+        }
+    }
+
+
     void ArtificialController::moveToTargetPosition()
     {
Index: code/branches/ai2/src/orxonox/controllers/ArtificialController.h
===================================================================
--- code/branches/ai2/src/orxonox/controllers/ArtificialController.h	(revision 8844)
+++ code/branches/ai2/src/orxonox/controllers/ArtificialController.h	(revision 8845)
@@ -113,4 +113,5 @@
             void moveToPosition(const Vector3& target);
             void moveToTargetPosition();
+            void absoluteMoveToPosition(const Vector3& target);
 
             virtual void positionReached() {}
Index: code/branches/ai2/src/orxonox/controllers/DroneController.cc
===================================================================
--- code/branches/ai2/src/orxonox/controllers/DroneController.cc	(revision 8844)
+++ code/branches/ai2/src/orxonox/controllers/DroneController.cc	(revision 8845)
@@ -52,4 +52,6 @@
         this->drone_ = 0;
         this->isShooting_ = false;
+        //this->criticalDistance_ = 1000.0f;
+        this->setAccuracy(10);
 
         this->actionTimer_.setTimer(ACTION_INTERVAL, true, createExecutor(createFunctor(&DroneController::action, this)));
@@ -92,47 +94,76 @@
         The duration of the tick.
     */
+    /* PORTALS workaround:
+    if the owner uses a portal -> distance between owner and drone is huge -> is detected by drone
+    -> drone searches for portal -> drone adds portal as waypoint -> drone flies towards portal //ignores owner
+    -> if the drone used a portal, then the distance to the owner is small -> remove waypoint // back to normal mode
+
+    */
     void DroneController::tick(float dt)
     {
         if (this->getDrone() && this->getOwner())
         {
-            if (this->target_)
+            if (this->waypoints_.size() > 0 ) //Waypoint functionality: Drone should follow it's master through portals
+            {// Idea: after using the the portal, the master is far away.
+                WorldEntity* wPoint = this->waypoints_[this->waypoints_.size()-1];
+                if(wPoint)
+                {
+                    float distanceToOwnerSquared = (this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength();
+                    this->absoluteMoveToPosition(wPoint->getWorldPosition()); //simplified function - needs WORKAROUND
+                    if (distanceToOwnerSquared <= 90000.0f) //WORKAROUND: if the Drone is again near its owner, the portal has been used correctly.
+                    {
+                        this->waypoints_.pop_back(); // if goal is reached, remove it from the list
+                        this->positionReached(); //needed??
+                    }
+
+                }
+                else
+                    this->waypoints_.pop_back(); // remove invalid waypoints
+            }
+            else
             {
-                float distanceToTargetSquared = (this->getDrone()->getWorldPosition() - this->target_->getWorldPosition()).squaredLength();
-                if (distanceToTargetSquared < (this->getDrone()->getMaxShootingRange()*this->getDrone()->getMaxShootingRange()))
-                {
-                    this->isShooting_ = true;
-                    this->aimAtTarget();
-		    if(!this->friendlyFire())
-                        this->getDrone()->fire(0);
-                }
+                if (this->target_)
+                {
+                    float distanceToTargetSquared = (this->getDrone()->getWorldPosition() - this->target_->getWorldPosition()).squaredLength();
+                    if (distanceToTargetSquared < (this->getDrone()->getMaxShootingRange()*this->getDrone()->getMaxShootingRange()))
+                    {
+                       this->isShooting_ = true;
+                       this->aimAtTarget();
+                       if(!this->friendlyFire())
+                           this->getDrone()->fire(0);
+                    }
+               }
+
+
+                float maxDistanceSquared = this->getDrone()->getMaxDistanceToOwner()*this->getDrone()->getMaxDistanceToOwner();
+                float minDistanceSquared = this->getDrone()->getMinDistanceToOwner()*this->getDrone()->getMinDistanceToOwner();
+                if((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength()  > 20.0f*maxDistanceSquared)
+                {//FIX: if the drone's owner uses portal, the drone searches for the portal & adds it as a waypoint.
+                    this->updatePointsOfInterest("PortalEndPoint", 500.0f); //possible conflict: speed-pickup
+                }
+                if ((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength()  > maxDistanceSquared)
+                {
+                    this->moveToPosition(this->getOwner()->getWorldPosition()); //fly towards owner
+                }
+                else if((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength() < minDistanceSquared)
+                {
+                    this->moveToPosition(-this->getOwner()->getWorldPosition()); //fly away from owner
+                }
+                else if (!this->isShooting_)
+                {
+                    float random = rnd(2.0f);
+                    float randomSelection = rnd(6.0f);
+                    if((int)randomSelection==0) drone_->moveUpDown(random);
+                    else if((int)randomSelection==1) drone_->moveRightLeft(random);
+                    else if((int)randomSelection==2) drone_->moveFrontBack(random);
+                    else if((int)randomSelection==3) drone_->rotateYaw(random);
+                    else if((int)randomSelection==4) drone_->rotatePitch(random);
+                    else if((int)randomSelection==5) drone_->rotateRoll(random);
+                }
+
+                this->isShooting_ = false;
             }
-
-            float maxDistanceSquared = this->getDrone()->getMaxDistanceToOwner()*this->getDrone()->getMaxDistanceToOwner();
-            float minDistanceSquared = this->getDrone()->getMinDistanceToOwner()*this->getDrone()->getMinDistanceToOwner();
-            if ((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength()  > maxDistanceSquared)
-            {
-                this->moveToPosition(this->getOwner()->getWorldPosition()); //fly towards owner
-            }
-            else if((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength() < minDistanceSquared)
-            {
-                this->moveToPosition(-this->getOwner()->getWorldPosition()); //fly away from owner
-            }
-            else if (!this->isShooting_)
-            {
-                float random = rnd(2.0f);
-                float randomSelection = rnd(6.0f);
-                if((int)randomSelection==0) drone_->moveUpDown(random);
-                else if((int)randomSelection==1) drone_->moveRightLeft(random);
-                else if((int)randomSelection==2) drone_->moveFrontBack(random);
-                else if((int)randomSelection==3) drone_->rotateYaw(random);
-                else if((int)randomSelection==4) drone_->rotatePitch(random);
-                else if((int)randomSelection==5) drone_->rotateRoll(random);
-            }
-
-            this->isShooting_ = false;
         }
-
         SUPER(AIController, tick, dt);
-
     }
 
Index: code/branches/ai2/src/orxonox/controllers/DroneController.h
===================================================================
--- code/branches/ai2/src/orxonox/controllers/DroneController.h	(revision 8844)
+++ code/branches/ai2/src/orxonox/controllers/DroneController.h	(revision 8845)
@@ -66,5 +66,5 @@
             virtual void action();
             void ownerDied();
-	    bool friendlyFire(); //< returns true if the owner_ would be hit.
+            bool friendlyFire(); //<! returns true if the owner_ would be hit.
             bool isShooting_;
 
