Index: code/trunk/src/modules/towerdefense/TowerDefense.cc
===================================================================
--- code/trunk/src/modules/towerdefense/TowerDefense.cc	(revision 10624)
+++ code/trunk/src/modules/towerdefense/TowerDefense.cc	(revision 10629)
@@ -75,8 +75,5 @@
 #include "TowerDefenseTower.h"
 #include "TowerDefenseCenterpoint.h"
-//#include "TDCoordinate.h"
 #include "worldentities/SpawnPoint.h"
-#include "worldentities/pawns/Pawn.h"
-#include "worldentities/pawns/SpaceShip.h"
 #include "controllers/WaypointController.h"
 #include "graphics/Model.h"
@@ -84,23 +81,7 @@
 #include "chat/ChatManager.h"
 #include "core/CoreIncludes.h"
-/* Part of a temporary hack to allow the player to add towers */
-#include "core/command/ConsoleCommandIncludes.h"
-#include <cmath>
-
 
 namespace orxonox
 {
-    static const std::string __CC_addTower_name  = "addTower";
-    static const std::string __CC_upgradeTower_name = "upgradeTower";
-    static const int upgradeCost = 20;
-    static const int towerCost = 20;
-    unsigned int maxspaceships = 30;
-    int maxspaceshipsstandard = 30;
-
-
-
-    SetConsoleCommand("TowerDefense", __CC_addTower_name,  &TowerDefense::addTower ).addShortcut().defaultValues(1);
-    SetConsoleCommand("TowerDefense", __CC_upgradeTower_name, &TowerDefense::upgradeTower).addShortcut().defaultValues(0);
-
     RegisterUnloadableClass(TowerDefense);
 
@@ -108,39 +89,22 @@
     {
         RegisterObject(TowerDefense);
-/*
-        for (int i=0; i < 16 ; i++){
-            for (int j = 0; j< 16 ; j++){
-                towermatrix[i][j] = NULL;
-            }
-        }*/
-
-        //Timer for the waves (10 seconds between the waves)
+
         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->waveNumber_ = 0;
+        this->timeSinceLastSpawn_ = 0.0;
+        this->timeUntilNextWave_ = 0.0;
         this->credit_ = 0;
         this->lifes_ = 0;
-        this->timeSetTower_ = 0;
-        spaceships =15;
-        eggs=3;
-        ufos=7;
-        randomships=5;
-
-
-        ModifyConsoleCommand(__CC_addTower_name).setObject(this);
-        ModifyConsoleCommand(__CC_upgradeTower_name).setObject(this);
+        this->waveSize_ = 0;
+        offset_ = Vector3(0,0,10);
     }
 
     TowerDefense::~TowerDefense()
     {
-        /* Part of a temporary hack to allow the player to add towers */
         if (this->isInitialized())
         {
-            ModifyConsoleCommand(__CC_addTower_name).setObject(NULL);
-            ModifyConsoleCommand(__CC_upgradeTower_name).setObject(NULL);
+
         }
     }
@@ -148,11 +112,9 @@
     void TowerDefense::setCenterpoint(TowerDefenseCenterpoint *centerpoint)
     {
-        orxout() << "Centerpoint now setting..." << endl;
         this->center_ = centerpoint;
-        orxout() << "Centerpoint now set..." << endl;
     }
 
     void TowerDefense::start()
-    {
+    {        
         if (center_ != NULL) // There needs to be a TowerDefenseCenterpoint, i.e. the area the game takes place.
         {
@@ -170,61 +132,21 @@
         }
 
+        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
-        for (int i=0; i < 16 ; i++)
-        {
-            for (int j = 0; j< 16 ; j++)
-            {
-                towerModelMatrix[i][j] = NULL;
-                towerTurretMatrix[i][j] = NULL;
-            }
-        }
-
-        
-
-        if (player_ != NULL)
-        {
-            //this->player_->startControl(selecter);
-        }
-        else
-        {
-            orxout() << "player=NULL" << endl;
-        }
-
-
-        Model* dummyModel = new Model(this->center_->getContext());
-
-        //the path of the spacehips has to be blocked, so that no towers can be build there
-        for (int k=0; k<3; k++)
-            towerModelMatrix[1][k]=dummyModel;
-        for (int l=1; l<11; l++)
-        	towerModelMatrix[l][3]=dummyModel;
-        for (int m=3; m<12; m++)
-        	towerModelMatrix[10][m]=dummyModel;
-        for (int n=10; n<14; n++)
-        	towerModelMatrix[n][11]=dummyModel;
-        for (int o=13; o<16; o++)
-        	towerModelMatrix[13][o]=dummyModel;
-
-
         //set initial credits, lifes and WaveNumber
-        this->setCredit(100);
-        this->setLifes(100);
+        this->setCredit(1000);
+        this->setLifes(100);        
+        this->timeSinceLastSpawn_ = 0.0;
+        this->timeUntilNextWave_ = 5.0;
+        this->waveSize_ = 0;
         this->setWaveNumber(0);
-        time=0.0;
-
-        /*
-        //adds initial towers
-        for (int i=0; i <7; i++){
-            addTower(i+3,4);
-        }
-		*/
     }
 
     // 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)
+    {
         TowerDefenseEnemy* en1 = new TowerDefenseEnemy(this->center_->getContext());
         
@@ -234,6 +156,5 @@
             en1->addTemplate("enemytowerdefense1");
             en1->setScale(3);
-            en1->lookAt(Vector3(0,0,100000));
-            en1->setHealth(en1->getHealth() +50 + this->getWaveNumber()*4);
+            en1->setHealth(en1->getHealth() + this->getWaveNumber()*4);
             break;
 
@@ -241,8 +162,5 @@
             en1->addTemplate("enemytowerdefense2");
             en1->setScale(2);
-            en1->lookAt(Vector3(0,0,100000));
-            en1->roll(Degree(120));
-            en1->setHealth(en1->getHealth() -30 + this->getWaveNumber()*4);
-            //  en1->setShieldHealth(en1->getShield() = this->getWaveNumber()*2))
+            en1->setHealth(en1->getHealth() + this->getWaveNumber()*4);
             break;
 
@@ -250,19 +168,28 @@
             en1->addTemplate("enemytowerdefense3");
             en1->setScale(1);
-            en1->lookAt(Vector3(0,0,100000));
-            en1->roll(Degree(120));
-            en1->setHealth(en1->getHealth() -10 + this->getWaveNumber()*4);
+            en1->setHealth(en1->getHealth() + this->getWaveNumber()*4);
             break;
-        }
+        }        
 
         en1->setTeam(2);
-        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)));
-        }
+
+        WaypointController* controller = (WaypointController*)(en1->getXMLController());
+
+        if (controller != NULL && waypoints_.size() > 1)
+        {
+            en1->setPosition(waypoints_.at(0)->getPosition() + offset_);
+            en1->setOrientation(Vector3(0,0,10), Degree(0));
+            en1->setDirection(Vector3(0,1,0));
+            en1->lookAt(waypoints_.at(1)->getPosition() + offset_);
+
+            for (unsigned int i = 0; i < waypoints_.size(); ++ i)
+            {
+                orxonox::WeakPtr<MovableEntity> waypoint = new MovableEntity(this->center_->getContext());
+                waypoint->setPosition(waypoints_.at(i)->getPosition() + offset_);
+                controller->addWaypoint(waypoint);
+            }
+        }
+
+        enemies_.push_back(en1);
     }
 
@@ -279,10 +206,9 @@
     {
         assert(player);
-        this->player_ = player;
+        player_ = player;
 
         if (selecter->getPlayer() == NULL)
         {
-            this->player_ = player;
-            player->startControl(selecter);
+            player_->startControl(selecter);
             players_[player].state_ = PlayerState::Alive;
         } 
@@ -301,48 +227,16 @@
 
     //not working yet
-    void TowerDefense::upgradeTower(int x,int y)
+    void TowerDefense::addTower(int x,int y)
     {
         TDCoordinate* coord = new TDCoordinate(x,y);
         x = coord->GetX();
         y = coord->GetY();
-        
-
-        if (!this->hasEnoughCreditForTower(upgradeCost))
-        {
-            orxout() << "not enough credit: " << (this->getCredit()) << " available, " << upgradeCost << " needed.";
-            return;
-        }
-
-
-        Model* dummyModel2 = new Model(this->center_->getContext());
-
-        if (towerModelMatrix [x][y] == NULL || (towerModelMatrix [x][y])->getMeshSource() == dummyModel2->getMeshSource())
-        {
-            orxout() << "no tower on this position" << endl;
-            return;
-        }
-
-        else
-        {
-            (towerTurretMatrix [x][y])->upgradeTower();
-            switch(towerTurretMatrix[x][y]->upgrade)
-                   {
-                   case 1 :
-                	   towerModelMatrix[x][y]->setMeshSource("TD_T2.mesh");
-                	   break;
-
-                   case 2 :
-                	   towerModelMatrix[x][y]->setMeshSource("TD_T3.mesh");
-                	   break;
-                   case 3 :
-                	   towerModelMatrix[x][y]->setMeshSource("TD_T4.mesh");
-                	   break;
-                   case 4 :
-                	   towerModelMatrix[x][y]->setMeshSource("TD_T5.mesh");
-                	   break;
-
-                   }
-
-            this->buyTower(upgradeCost);
+
+        int cost = center_->getTowerCost(1);
+
+        if (fields_[x][y]->isFree() == true && getCredit() >= cost)
+        {
+            payCredit(cost);
+            fields_[x][y]->createTower(1);
         }
     }
@@ -352,342 +246,165 @@
     */
 
-    void TowerDefense::addTower(int x, int y)
-    {        
+    void TowerDefense::upgradeTower(int x, int y)
+    {    
         TDCoordinate* coord = new TDCoordinate(x,y);
         x = coord->GetX();
-        y = coord->GetY();
-
-
-        if (!this->hasEnoughCreditForTower(towerCost))
-        {
-            orxout() << "not enough credit: " << (this->getCredit()) << " available, " << towerCost << " needed.";
+        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)
+    {
+        SUPER(TowerDefense, tick, dt);
+
+        if (hasStarted() == false || player_ == NULL)
+        {
             return;
         }
-
-        if (towerModelMatrix [x][y]!=NULL)
-        {
-            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;
-        orxout() << "Will add tower at (" << x << "," << y << ")" << endl;
-
-
-        //Create Model
-        Model* newTowerModel = new Model(this->center_->getContext());
-        newTowerModel->setMeshSource("TD_T1.mesh");
-        newTowerModel->setScale(30);
-        newTowerModel->pitch(Degree(90));
-        newTowerModel->setPosition(static_cast<float>((x-8) * tileScale), static_cast<float>((y-8) * tileScale), 80);
-
-        //Creates tower
-        TowerDefenseTower* towernew = new TowerDefenseTower(this->center_->getContext());
-        towernew->setPosition(static_cast<float>((x-8) * tileScale), static_cast<float>((y-8) * tileScale), 275);
-        towernew->setGame(this);
-        towernew->setTeam(1);
-
-        //Reduce credit
-         this->buyTower(towerCost);
-         towerModelMatrix [x][y]= newTowerModel;
-         towerTurretMatrix [x][y]= towernew;
-    }    
-
-    bool TowerDefense::hasEnoughCreditForTower(int towerCost)
-    {
-        return ((this->getCredit()) >= towerCost);
-    }
-
-
-    bool TowerDefense::hasEnoughCreditForUpgrade()
-    {
-        return true;
-    }
-
- 
-    void TowerDefense::nextwave()
-    {
-
-    	orxout() << "newwave" << endl;
-    	TowerDefenseEnemyvector.clear();
-    	waves_++;
-        //maxspaceships = round(maxspaceshipsstandard + 0.25*(waves_));
-    	time=0;
-
-    	int helpnumber = 40 -(waves_);
-    	if(helpnumber <= 0) {helpnumber =1;}
-        float numSpaceships = std::abs((rand() % 100)*5.0f*(helpnumber));
-        float numEggs = std::abs((rand() % 100)*1.0f*(waves_));
-        float numUfos = std::abs((rand() % 100)*1.5f*(0.5f*(waves_))) ;
-
-        float totalnumber = (numSpaceships + numEggs + numUfos)*1.3f;
-
-        int newspaceships = (int)(maxspaceships* numSpaceships / totalnumber);
-        int neweggs = (int)(maxspaceships*numEggs / totalnumber);
-        int newufos = (int)(maxspaceships*numUfos / totalnumber);
-        int newrandomships = maxspaceships -newspaceships - neweggs - newufos;
-        spaceships =newspaceships;
-        eggs=neweggs;
-        ufos=newufos;
-        randomships=newrandomships;
-
-        orxout() << spaceships << endl;
-        orxout() << eggs << endl;
-        orxout() << ufos << endl;
-        orxout() << randomships << endl;
-
-
-
-
-
-    }
-
-    void TowerDefense::tick(float dt)
-    {
-        SUPER(TowerDefense, tick, dt);
-        time +=dt;
-        timeSetTower_ +=dt;
-
-        //Check if tower has to be set (because TowerDefenseSelecter asks for it)
-        if(timeSetTower_ >= 0.25)
-        {
-        	timeSetTower_ =0;
-			if(selecter != NULL && selecter->firePressed_)
-			{
-
-				int x = selecter->selectedPos_->GetX();
-				int y = selecter->selectedPos_->GetY();
-				Model* dummyModel2 = new Model(this->center_->getContext());
-
-
-
-				if(towerModelMatrix[x][y] == NULL)
-				{
-					addTower(x,y);
-				}
-				else
-				{
-					if(!((towerModelMatrix [x][y])->getMeshSource() == dummyModel2->getMeshSource()))
-					{
-						towerTurretMatrix[x][y]->upgradeTower();
-				        if(towerTurretMatrix[x][y]->upgrade < towerTurretMatrix[x][y]->upgradeMax)
-				        {
-				        	int specificupgradecost = (int)(upgradeCost*(std::pow(1.5,towerTurretMatrix[x][y]->upgrade)));
-				        	if(this->credit_ >= specificupgradecost)
-				        	{
-					        	this->buyTower(specificupgradecost);
-								switch(towerTurretMatrix[x][y]->upgrade)
-							   {
-								   case 1 :
-									   towerModelMatrix[x][y]->setMeshSource("TD_T2.mesh");
-									   break;
-
-								   case 2 :
-									   towerModelMatrix[x][y]->setMeshSource("TD_T3.mesh");
-									   break;
-				                   case 3 :
-				                	   towerModelMatrix[x][y]->setMeshSource("TD_T4.mesh");
-				                	   break;
-				                   case 4 :
-				                	   towerModelMatrix[x][y]->setMeshSource("TD_T5.mesh");
-				                	   break;
-
-							   }
-				        	}
-
-
-				        }
-					}
-				}
-				selecter->firePressed_ = false;
-			}
-        }
-
-        TDCoordinate* coord1 = new TDCoordinate(1,1);
-        std::vector<TDCoordinate*> path;
-        path.push_back(coord1);
-
-
-
-
-
-        if(time>=TowerDefenseEnemyvector.size() && TowerDefenseEnemyvector.size() < maxspaceships)
-		{
-
-        	//adds different types of enemys depending on the WaveNumber progressively making the combination of enemys more difficult
-        	if(spaceships>0)
-        	{
-    			addTowerDefenseEnemy(path, 1);
-    			spaceships--;
-
-        	}else if(ufos>0)
-        	{
-    			addTowerDefenseEnemy(path, 3);
-    			ufos--;
-        	}else if(eggs>0)
-        	{
-    			addTowerDefenseEnemy(path, 2);
-    			eggs--;
-        	}else if(randomships>0)
-        	{
-    			addTowerDefenseEnemy(path, rand() % 3 +1);
-    			randomships--;
-
-        	}
-
-		}
-
-
-        Vector3* endpoint = new Vector3(500, 700, 150);
-        //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 the 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();
+        timeUntilNextWave_ -= dt;
+        timeSinceLastSpawn_ += 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());
+            }            
+        }
+        
+        for (std::list<WeakPtr<TowerDefenseEnemy> >::iterator it = enemies_.begin(); it != enemies_.end(); )
+        {
+            if (*it == NULL)
+            {
+                // the enemy was destroyed by a tower - remove it from the list
+                enemies_.erase(it++);
+                addCredit(1);
+            }
+            else
+            {
+                //if ships are at the end they get destroyed
+                Vector3 ship = (*it)->getRVWorldPosition();
+                float distance = ship.distance(endpoint_);
+                if(distance < 40)
+                {
+                    (*it)->destroy();
+                    enemies_.erase(it++);
                     this->reduceLifes(1);
-                    this->buyTower(1);
-                    if (this->getLifes()==0)
+                    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 && !this->nextwaveTimer_.isActive())
-            this->nextwaveTimer_.startTimer();
-
-/*            time2 +=dt;
-        if(count== 0)
-        {
-            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);
-    }
-    */
-    /*
-    void TowerDefense::playerEntered(PlayerInfo* player)
-    {
-        TeamDeathmatch::playerEntered(player);
-
-        const std::string& message = player->getName() + " entered the game";
-        ChatManager::message(message);
-    }
-
-    bool TowerDefense::playerLeft(PlayerInfo* player)
-    {
-        bool valid_player = TeamDeathmatch::playerLeft(player);
-
-        if (valid_player)
-        {
-            const std::string& message = player->getName() + " left the game";
-            ChatManager::message(message);
-        }
-
-        return valid_player;
-    }
-
-
-    void TowerDefense::pawnKilled(Pawn* victim, Pawn* killer)
-    {
-        if (victim && victim->getPlayer())
-        {
-            std::string message;
-            if (killer)
-            {
-                if (killer->getPlayer())
-                    message = victim->getPlayer()->getName() + " was killed by " + killer->getPlayer()->getName();
                 else
-                    message = victim->getPlayer()->getName() + " was killed";
-            }
-            else
-                message = victim->getPlayer()->getName() + " died";
-
-            ChatManager::message(message);
-        }
-
-        TeamDeathmatch::pawnKilled(victim, killer);
-    }
-
-    void TowerDefense::playerScored(PlayerInfo* player, int score)
-    {
-        Gametype::playerScored(player, score);
-    }*/
+                {
+                    ++ it;
+                }
+            }
+        }  
+
+        // Add new enemy?
+        if (timeSinceLastSpawn_ >= 1.0 && waveSize_ > 0)
+        {
+            // Add new enemy
+            timeSinceLastSpawn_ -= 1.0;
+            -- waveSize_;
+            addTowerDefenseEnemy(this->getWaveNumber() % 3 + 1);
+        }
+        else if (timeUntilNextWave_ <= 0.0 && waveSize_ <= 0)
+        {
+            //New wave
+            ++ waveNumber_;
+            timeSinceLastSpawn_ = 0.0;
+
+            timeUntilNextWave_ = waveNumber_+20;
+            waveSize_ = waveNumber_+5;
+        }
+
+    }
+
+    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;
+    }
 }
