Index: code/branches/towerdefenseFabien/src/modules/towerdefense/TowerDefense.cc
===================================================================
--- code/branches/towerdefenseFabien/src/modules/towerdefense/TowerDefense.cc	(revision 10585)
+++ code/branches/towerdefenseFabien/src/modules/towerdefense/TowerDefense.cc	(revision 10586)
@@ -37,5 +37,4 @@
  *
  *
- *
  *TIPP: Eclipse hilft euch schnell auf bereits vorhanden Funktionen zuzugreifen:
  * einfach "this->" eingeben und kurz warten. Dann tauch eine Liste mit Vorschlägen auf. Wenn ihr jetzt weiter
@@ -76,9 +75,5 @@
 #include "TowerDefenseTower.h"
 #include "TowerDefenseCenterpoint.h"
-//#include "TDCoordinate.h"
-#include "TowerTurret.h"
 #include "worldentities/SpawnPoint.h"
-#include "worldentities/pawns/Pawn.h"
-#include "worldentities/pawns/SpaceShip.h"
 #include "controllers/WaypointController.h"
 #include "graphics/Model.h"
@@ -89,34 +84,41 @@
 #include "core/command/ConsoleCommand.h"
 
+
 namespace orxonox
 {
+    static const std::string __CC_addTower_name  = "addTower";
+    static const std::string __CC_upgradeTower_name = "upgradeTower";
+
+    SetConsoleCommand("TowerDefense", __CC_addTower_name,  &TowerDefense::addTower ).addShortcut().defaultValues(1);
+    SetConsoleCommand("TowerDefense", __CC_upgradeTower_name, &TowerDefense::upgradeTower).addShortcut().defaultValues(0);
+
     RegisterUnloadableClass(TowerDefense);
 
-    TowerDefense::TowerDefense(Context* context) : Deathmatch(context)
+    TowerDefense::TowerDefense(Context* context) : TeamDeathmatch(context)
     {
         RegisterObject(TowerDefense);
-/*
-        for (int i=0; i < 16 ; i++){
-            for (int j = 0; j< 16 ; j++){
-                towermatrix[i][j] = NULL;
-            }
-        }*/
-
+
+        selecter = NULL;
+        this->player_ = NULL;        
         this->setHUDTemplate("TowerDefenseHUD");
+        this->nextwaveTimer_.setTimer(10, false, createExecutor(createFunctor(&TowerDefense::nextwave, this)));
+        this->nextwaveTimer_.stopTimer();
+        this->waves_ = 0;
+        this->time = 0;
+        this->credit_ = 0;
+        this->lifes_ = 0;
 
         //this->stats_ = new TowerDefensePlayerStats();
 
-        /* Temporary hack to allow the player to add towers and upgrade them */
-        this->dedicatedAddTower_ = createConsoleCommand( "addTower", createExecutor( createFunctor(&TowerDefense::addTower, this) ) );
-        this->dedicatedUpgradeTower_ = createConsoleCommand( "upgradeTower", createExecutor( createFunctor(&TowerDefense::upgradeTower, this) ) );
+        ModifyConsoleCommand(__CC_addTower_name).setObject(this);
+        ModifyConsoleCommand(__CC_upgradeTower_name).setObject(this);
     }
 
     TowerDefense::~TowerDefense()
-    {
-        /* Part of a temporary hack to allow the player to add towers */
+    {        /* Part of a temporary hack to allow the player to add towers */
         if (this->isInitialized())
         {
-            if( this->dedicatedAddTower_ )
-                delete this->dedicatedAddTower_;
+            ModifyConsoleCommand(__CC_addTower_name).setObject(NULL);
+            ModifyConsoleCommand(__CC_upgradeTower_name).setObject(NULL);
         }
     }
@@ -124,50 +126,44 @@
     void TowerDefense::setCenterpoint(TowerDefenseCenterpoint *centerpoint)
     {
-        orxout() << "Centerpoint now setting..." << endl;
         this->center_ = centerpoint;
-        orxout() << "Centerpoint now set..." << endl;
     }
 
     void TowerDefense::start()
-    {
-
-        Deathmatch::start();
-
-// Waypoints: [1,3] [10,3] [10,11] [13,11] -> add the points to a matrix so the player cant place towers on the path
-        for (int i=0; i < 16 ; i++){
-            for (int j = 0; j< 16 ; j++){
-                towermatrix[i][j] = false;
-            }
-        }
-
-        for (int k=0; k<3; k++)
-            towermatrix[1][k]=true;
-        for (int l=1; l<11; l++)
-            towermatrix[l][3]=true;
-        for (int m=3; m<12; m++)
-            towermatrix[10][m]=true;
-        for (int n=10; n<14; n++)
-            towermatrix[n][11]=true;
-        for (int o=13; o<16; o++)
-            towermatrix[13][o]=true;
+    {        
+        if (center_ != NULL) // There needs to be a TowerDefenseCenterpoint, i.e. the area the game takes place.
+        {
+            if (selecter == NULL)
+            {
+                selecter = new TowerDefenseSelecter(this->center_->getContext());                
+            }
+            selecter->addTemplate(center_->getSelecterTemplate());
+            center_->attach(selecter);
+        }
+        else // If no centerpoint was specified, an error is thrown and the level is exited.
+        {
+            orxout(internal_error) << "Jump: No Centerpoint specified." << endl;
+            return;
+        }
+
+        enemies_.clear();
+
+        createFields();
+
+        TeamDeathmatch::start();
+
+        // Waypoints: [1,3] [10,3] [10,11] [13,11] -> add the points to a matrix so the player cant place towers on the path
+        
 
         //set initial credits, lifes and WaveNumber
-        this->setCredit(200);
-        this->setLifes(50);
+        this->setCredit(1000);
+        this->setLifes(100);
         this->setWaveNumber(0);
-        time=0.0;
-
-        //adds initial towers
-        for (int i=0; i <7; i++){
-            addTower(i+3,4);
-        }/*
-        for (int j=0; j < 7; j++){
-            addTower(9,j+5);
-        }*/
+        time = 0.0;
     }
 
     // Generates a TowerDefenseEnemy. Uses Template "enemytowerdefense". Sets position at first waypoint of path.
-    void TowerDefense::addTowerDefenseEnemy(std::vector<TDCoordinate*> path, int templatenr){
-
+    void TowerDefense::addTowerDefenseEnemy(int templatenr)
+    {
+        orxout() << "addTowerDefenseEnemy" << endl;
 
         TowerDefenseEnemy* en1 = new TowerDefenseEnemy(this->center_->getContext());
@@ -185,5 +181,4 @@
             en1->setScale(2);
             en1->setHealth(en1->getHealth() + this->getWaveNumber()*4);
-            //  en1->setShieldHealth(en1->getShield() = this->getWaveNumber()*2))
             break;
 
@@ -193,14 +188,30 @@
             en1->setHealth(en1->getHealth() + this->getWaveNumber()*4);
             break;
-        }
-
-        en1->getController();
-        en1->setPosition(path.at(0)->get3dcoordinate());
-        TowerDefenseEnemyvector.push_back(en1);
-
-        for(unsigned int i = 0; i < path.size(); ++i)
-        {
-            en1->addWaypoint((path.at(i)));
-        }
+        }        
+
+        en1->setTeam(2);
+
+        //orxonox::WeakPtr<WaypointController> controller = new WaypointController(this->center_->getContext());
+        //controller->setControllableEntity(en1);
+        //en1->setController(controller);
+
+        WaypointController* controller = (WaypointController*)(en1->getXMLController());
+
+        if (controller != NULL && waypoints_.size() > 1)
+        {
+            en1->setPosition(waypoints_.at(0)->getPosition());
+            en1->setOrientation(Vector3(0,0,10), Degree(0));
+            en1->setDirection(Vector3(0,1,0));
+            en1->lookAt(waypoints_.at(1)->getPosition());
+
+            for (unsigned int i = 0; i < waypoints_.size(); ++ i)
+            {
+                orxonox::WeakPtr<MovableEntity> waypoint = new MovableEntity(this->center_->getContext());
+                waypoint->setPosition(waypoints_.at(i)->getPosition());
+                controller->addWaypoint(waypoints_.at(i));
+            }
+        }
+
+        enemies_.push_back(en1);
     }
 
@@ -209,195 +220,216 @@
     {
 
-        Deathmatch::end();
+        TeamDeathmatch::end();
         ChatManager::message("Match is over! Gameover!");
 
     }
 
+    void TowerDefense::spawnPlayer(PlayerInfo* player)
+    {
+        assert(player);
+        player_ = player;
+
+        orxout() << "spawnPlayer" << endl;
+
+        if (selecter->getPlayer() == NULL)
+        {
+            player_->startControl(selecter);
+            players_[player].state_ = PlayerState::Alive;
+        } 
+    }
+
+    /**
+    @brief
+        Get the player.
+    @return
+        Returns a pointer to the player. If there is no player, NULL is returned.
+    */
+    PlayerInfo* TowerDefense::getPlayer(void) const
+    {
+        return this->player_;
+    }
+
     //not working yet
-    void TowerDefense::upgradeTower(int x,int y)
-    {/*
-        const int upgradeCost = 20;
-
-        if (!this->hasEnoughCreditForTower(upgradeCost))
-        {
-            orxout() << "not enough credit: " << (this->getCredit()) << " available, " << upgradeCost << " needed.";
-            return;
-        }
-
-        if (towermatrix [x][y] == NULL)
-        {
-            orxout() << "no tower on this position" << endl;
-            return;
-        }
-
-        else
-        {
-            (towermatrix [x][y])->upgradeTower();
-        }*/
+    void TowerDefense::addTower(int x,int y)
+    {
+        TDCoordinate* coord = new TDCoordinate(x,y);
+        x = coord->GetX();
+        y = coord->GetY();
+
+        int cost = center_->getTowerCost(1);
+
+        if (fields_[x][y]->isFree() == true && getCredit() >= cost)
+        {
+            payCredit(cost);
+            fields_[x][y]->createTower(1);
+        }
     }
 
     /*adds Tower at Position (x,y) and reduces credit and adds the point to the towermatrix. template ("towerturret")
     so towers have ability if the turrets
-
     */
-    void TowerDefense::addTower(int x, int y)
-    {
-        const int towerCost = 20;
-
-        if (!this->hasEnoughCreditForTower(towerCost))
-        {
-            orxout() << "not enough credit: " << (this->getCredit()) << " available, " << towerCost << " needed.";
+
+    void TowerDefense::upgradeTower(int x, int y)
+    {    
+        TDCoordinate* coord = new TDCoordinate(x,y);
+        x = coord->GetX();
+        y = coord->GetY();     
+
+        int cost = center_->getTowerCost(fields_[x][y]->getUpgrade() + 1);
+
+        if (fields_[x][y]->isFree() == false && fields_[x][y]->canUpgrade() == true && getCredit() >= cost)
+        {
+            payCredit(cost);
+            fields_[x][y]->upgrade();
+        }
+    }    
+
+    void TowerDefense::tick(float dt)
+    {
+        //orxout() << "tick1" << endl;
+        SUPER(TowerDefense, tick, dt);
+        //orxout() << "tick2" << endl;
+
+        if (hasStarted() == false || player_ == NULL)
+        {
             return;
         }
-
-        if (towermatrix [x][y]==true)
-        {
-            orxout() << "not possible to put tower here!!" << endl;
-            return;
-        }
-
-/*
-        unsigned int width = this->center_->getWidth();
-        unsigned int height = this->center_->getHeight();
-*/
-
-        int tileScale = (int) this->center_->getTileScale();
-
-        if (x > 15 || y > 15 || x < 0 || y < 0)
-        {
-            //Hard coded: TODO: let this depend on the centerpoint's height, width and fieldsize (fieldsize doesn't exist yet)
-            orxout() << "Can not add Tower: x and y should be between 0 and 15" << endl;
-            return;
-        }
-
-        orxout() << "Will add tower at (" << (x-8) * tileScale << "," << (y-8) * tileScale << ")" << endl;
-
-       //Reduce credit
-        this->buyTower(towerCost);
-        towermatrix [x][y]=true;
-
-        //Creates tower
-        TowerDefenseTower* towernew = new TowerDefenseTower(this->center_->getContext());
-        towernew->addTemplate("towerturret");
-        towernew->setPosition(static_cast<float>((x-8) * tileScale), static_cast<float>((y-8) * tileScale), 75);
-        towernew->setGame(this);
-    }
-
-    bool TowerDefense::hasEnoughCreditForTower(int towerCost)
-    {
-        return ((this->getCredit()) >= towerCost);
-    }
-
-
-    bool TowerDefense::hasEnoughCreditForUpgrade()
-    {
-        return true;
-    }
-
- 
-    void TowerDefense::tick(float dt)
-    {
-        SUPER(TowerDefense, tick, dt);
-        time +=dt;
-
-        TDCoordinate* coord1 = new TDCoordinate(1,1);
-        std::vector<TDCoordinate*> path;
-        path.push_back(coord1);
-        if(time>1 && TowerDefenseEnemyvector.size() < 30)
+        time += dt;       
+
+        //build/upgrade tower at selecter position
+        if (selecter != NULL && selecter->buildTower_ == true)
+        {
+            selecter->buildTower_ = false;
+
+            if (getField(selecter->selectedPos_)->canUpgrade() == true)
+            {
+                upgradeTower(selecter->selectedPos_->GetX(), selecter->selectedPos_->GetY());
+            }
+            else
+            {
+                addTower(selecter->selectedPos_->GetX(), selecter->selectedPos_->GetY());
+            }            
+        }
+
+        if (time >= 1.3 * enemies_.size() && enemies_.size() < 10)
         {
             //adds different types of enemys depending on the WaveNumber
-            addTowerDefenseEnemy(path, this->getWaveNumber() % 3 +1 );
-            time = time-1;
-        }
-
-        Vector3* endpoint = new Vector3(500, 700, 150);
+            addTowerDefenseEnemy(this->getWaveNumber() % 3 +1 );
+        }
+
         //if ships are at the end they get destroyed
-        for(unsigned int i =0; i < TowerDefenseEnemyvector.size(); ++i)
-        {
-            if(TowerDefenseEnemyvector.at(i) != NULL && TowerDefenseEnemyvector.at(i)->isAlive())
-            {
-                //destroys enemys at the end of teh path and reduces the life by 1. no credits gifted
-
-                Vector3 ship = TowerDefenseEnemyvector.at(i)->getRVWorldPosition();
-                float distance = ship.distance(*endpoint);
-
-                if(distance <50){
-                    TowerDefenseEnemyvector.at(i)->destroy();
-                    this->reduceLifes(1);
-                    this->buyTower(1);
-                    if (this->getLifes()==0)
-                    {
-                        this->end();
-                    }
+
+        std::vector<orxonox::WeakPtr<TowerDefenseEnemy> >::iterator itBegin = enemies_.begin();
+        std::vector<orxonox::WeakPtr<TowerDefenseEnemy> >::iterator it = itBegin;
+        std::vector<orxonox::WeakPtr<TowerDefenseEnemy> >::iterator itEnd = enemies_.end();
+
+        while(it != itEnd)
+        {
+            //destroys enemys at the end of the path and reduces the life by 1. No credits gifted
+            Vector3 ship = (*it)->getRVWorldPosition();
+            float distance = ship.distance(endpoint_);
+            if(distance < 50)
+            {
+                std::vector<orxonox::WeakPtr<TowerDefenseEnemy> >::iterator itTemp = it;
+                ++ it;
+                orxout() << "enemy deleted" << endl;                
+                enemies_.erase(itTemp);
+                (*itTemp)->destroy();
+                this->reduceLifes(1);
+                if (this->getLifes() == 0)
+                {
+                    this->end();
                 }
             }
-        }
-        //goes thorugh vector to see if an enemy is still alive. if not next wave is launched
-        int count= 0;
-        for(unsigned int i =0; i < TowerDefenseEnemyvector.size(); ++i)
-        {
-            if(TowerDefenseEnemyvector.at(i)!= NULL)
-            {
-                ++count;
-            }
-        }
-
-        if(count== 0)
-        {
-            time2 +=dt;
-            if(time2 > 10)
-            {
-                TowerDefenseEnemyvector.clear();
-                this->nextwave();
-                time=0;
-                time2=0;
-            }
-        }
-
-
-    }
-
-    // Function to test if we can add waypoints using code only. Doesn't work yet
-
-    // THE PROBLEM: WaypointController's getControllableEntity() returns null, so it won't track. How do we get the controlableEntity to NOT BE NULL???
-    /*
-    void TowerDefense::addWaypointsAndFirstEnemy()
-    {
-        SpaceShip *newShip = new SpaceShip(this->center_);
-        newShip->addTemplate("spaceshipassff");
-
-        WaypointController *newController = new WaypointController(newShip);
-        newController->setAccuracy(3);
-
-        Model *wayPoint1 = new Model(newController);
-        wayPoint1->setMeshSource("crate.mesh");
-        wayPoint1->setPosition(7,-7,5);
-        wayPoint1->setScale(0.2);
-
-        Model *wayPoint2 = new Model(newController);
-        wayPoint2->setMeshSource("crate.mesh");
-        wayPoint2->setPosition(7,7,5);
-        wayPoint2->setScale(0.2);
-
-        newController->addWaypoint(wayPoint1);
-        newController->addWaypoint(wayPoint2);
-
-        // The following line causes the game to crash
-
-        newShip->setController(newController);
-//        newController -> getPlayer() -> startControl(newShip);
-        newShip->setPosition(-7,-7,5);
-        newShip->setScale(0.1);
-        //newShip->addSpeed(1);
-
-
-
-//      this->center_->attach(newShip);
-    }
-    */
+            else
+            {
+                ++ it;
+            }
+        }        
+
+        if (enemies_.size() == 0 && !this->nextwaveTimer_.isActive())
+        {
+            this->nextwaveTimer_.startTimer();
+        }
+    }
+
+    void TowerDefense::createFields()
+    {
+        assert(center_);
+        TDCoordinate coord(0,0);
+        TDCoordinate startCoord(0,0);
+
+        std::string fields = center_->getFields();
+        int pos = 0;
+        for (int j = 15; j >= 0; --j)
+        {
+            for (int i = 0; i < 16; ++i)
+            {
+                coord.Set(i,j);
+                fields_[i][j] = new TowerDefenseField(center_->getContext());
+                fields_[i][j]->setCenterpoint(center_);
+                center_->attach(fields_[i][j]);
+                fields_[i][j]->setPosition(coord.get3dcoordinate());                
+                fields_[i][j]->create(fields.at(pos), fields.at(pos+1));           
+                pos += 2;
+                if (fields_[i][j]->getType() == START)
+                {
+                    startCoord.Set(i,j);
+                    waypoints_.push_back(fields_[i][j]);
+                }
+            }
+        }
+
+        //Place waypoints along the street for the waypoint controllers of the enemies
+        TDCoordinate* thisCoord = &startCoord;
+        TDCoordinate* nextCoord;
+        while ((nextCoord = getNextStreetCoord(thisCoord)) != NULL)
+        {
+            waypoints_.push_back(fields_[nextCoord->GetX()][nextCoord->GetY()]);            
+            thisCoord = nextCoord;
+            endpoint_ = nextCoord->get3dcoordinate();
+        }
+
+    }
+
+    TDCoordinate* TowerDefense::getNextStreetCoord(TDCoordinate* thisCoord)
+    {        
+        TowerDefenseField* thisField = fields_[thisCoord->GetX()][thisCoord->GetY()];
+        TDCoordinate* nextCoord = new TDCoordinate(0,0);
+
+        if (thisField->getType() != STREET && thisField->getType() != START)
+        {
+            return NULL;
+        }
+
+        if (thisField->getAngle() == 0)
+        {
+            nextCoord->Set(thisCoord->GetX(), thisCoord->GetY() - 1);
+        }
+        else if (thisField->getAngle() == 1)
+        {
+            nextCoord->Set(thisCoord->GetX() + 1, thisCoord->GetY());
+        }
+        else if (thisField->getAngle() == 2)
+        {
+            nextCoord->Set(thisCoord->GetX(), thisCoord->GetY() + 1);
+        }
+        else if (thisField->getAngle() == 3)
+        {
+            nextCoord->Set(thisCoord->GetX() - 1, thisCoord->GetY());
+        }
+
+        if (thisCoord->GetX() != nextCoord->GetX() || thisCoord->GetY() != nextCoord->GetY())
+        {
+            return nextCoord;
+        }
+
+        return NULL;
+    }
+
     /*
     void TowerDefense::playerEntered(PlayerInfo* player)
     {
-        Deathmatch::playerEntered(player);
+        TeamDeathmatch::playerEntered(player);
 
         const std::string& message = player->getName() + " entered the game";
@@ -407,5 +439,5 @@
     bool TowerDefense::playerLeft(PlayerInfo* player)
     {
-        bool valid_player = Deathmatch::playerLeft(player);
+        bool valid_player = TeamDeathmatch::playerLeft(player);
 
         if (valid_player)
@@ -437,5 +469,5 @@
         }
 
-        Deathmatch::pawnKilled(victim, killer);
+        TeamDeathmatch::pawnKilled(victim, killer);
     }
 
