Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/towerdefenseFS15/src/modules/towerdefense/TowerDefense.cc @ 10368

Last change on this file since 10368 was 10368, checked in by erbj, 9 years ago

added timer in tick function to pause for 10 seconds between waves , trying to solve the problem, that towers are shooting at (0,0,0) (center point). The Problem seems to be in the sameteam function as the turret and the pawn at the position (0,0,0) should have the same team

  • Property svn:eol-style set to native
File size: 15.7 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *  Author:
23 *
24 *   Co-authors:
25 *      ...
26 *
27 *NACHRICHT:
28 *
29 * Hier empfehle ich euch die gesamte Spielogik unter zu bringen. Viele Funktionen werden automatisch
30 * bei gewissen Ereignissen aufgerufen bzw. lösen Ereignisse aus
31 *
32 *Z.B:
33 * start() //wird aufgerufen, bevor das Spiel losgeht
34 * end() //wenn man diese Funktion aufruft wird
35 * pawnKilled() // wird aufgerufen, wenn ein Pawn stirbt (z.B: wenn )
36 * playerScored() // kann man aufrufen um dem Spieler Punkte zu vergeben.
37 *
38 *
39 *
40 *TIPP: Eclipse hilft euch schnell auf bereits vorhanden Funktionen zuzugreifen:
41 * einfach "this->" eingeben und kurz warten. Dann tauch eine Liste mit Vorschlägen auf. Wenn ihr jetzt weiter
42 * tippt, werden die Vorschläge entsprechend gefiltert.
43 *
44 *
45 *TIPP: schaut euch mal Tetris::createStone() an. Dort wird ein TetrisStone-Objekt (ControllableEntity) erzeugt,
46 * ihm ein Template zugewiesen (welches vorher im Level definiert wurde und dem CenterPoint übergeben wurde)
47 * Ähnlich könnt ihr vorgehen, um einen Turm zu erzeugen. (Zusätzlich braucht ein Turm noch einen Controller)
48 * z.B: WaypointPatrolController. Wenn kein Team zugewiesen wurde bekämpft ein WaypointPatrolController alles,
49 * was in seiner Reichweite liegt.
50 *
51 *
52 *HUD:
53 * Ein Gametype kann ein HUD (Head up Display haben.) Z.B: hat Pong eine Anzeige welcher Spieler wieviele Punkte hat.
54 * Generell kann man a) Grafiken oder b) Zeichen in einer HUD anzeigen.
55 * Fuer den ersten Schritt reicht reiner Text.
56 *
57 * a)
58 * PongScore.cc uebernehmen und eigene Klasse draus machen.
59 * Wenn ihr bloss anzeigen wollt wieviele Punkte der Spieler bereits erspielt hat (Punkte = Kapital fuer neue Tuerme) dann orientiert ihr euch an
60 * TetrisScore.cc (im pCuts branch): http://www.orxonox.net/browser/code/branches/pCuts/src/modules/tetris/TetrisScore.cc
61 * Ich habe TetrisScore lediglich dazu gebraucht, um eine Variable auf dem HUD auszugeben. Ein Objekt fuer statischen Text gibt es bereits.
62 *
63 * b)
64 * Im naesten Schritt erstellt man die Vorlage fuer das HUD-Objekt: siehe /data/overlays/pongHUD
65 * OverlayText ist eine Vorlage fuer statischen text zb: "Points Scored:". Aus mir nicht erklaerlichen Gruenden sollte man die OverlayText
66 * Objekte immer erst nach dem PongScore anlegen.
67 *
68 * c)  Im TowerDefense gamtype muss im Constructor noch das HUD-Template gesetzt werden.
69 *
70 * d) in CMakeLists.txt noch das Module includen das fuer die Overlays zustaendig ist. Siehe das gleiche File im Pong module.
71 *
72 *
73 *
74 */
75#include "TowerDefense.h"
76#include "TowerDefenseTower.h"
77#include "TowerDefenseCenterpoint.h"
78//#include "TDCoordinate.h"
79#include "worldentities/SpawnPoint.h"
80#include "worldentities/pawns/Pawn.h"
81#include "worldentities/pawns/SpaceShip.h"
82#include "controllers/WaypointController.h"
83#include "graphics/Model.h"
84#include "infos/PlayerInfo.h"
85#include "chat/ChatManager.h"
86#include "core/CoreIncludes.h"
87/* Part of a temporary hack to allow the player to add towers */
88#include "core/command/ConsoleCommand.h"
89
90namespace orxonox
91{
92    static const std::string __CC_addTower_name  = "addTower";
93    static const std::string __CC_upgradeTower_name = "upgradeTower";
94
95    SetConsoleCommand("TowerDefense", __CC_addTower_name,  &TowerDefense::addTower ).addShortcut().defaultValues(1);
96    SetConsoleCommand("TowerDefense", __CC_upgradeTower_name, &TowerDefense::upgradeTower).addShortcut().defaultValues(0);
97
98    RegisterUnloadableClass(TowerDefense);
99
100    TowerDefense::TowerDefense(Context* context) : TeamDeathmatch(context)
101    {
102        RegisterObject(TowerDefense);
103/*
104        for (int i=0; i < 16 ; i++){
105            for (int j = 0; j< 16 ; j++){
106                towermatrix[i][j] = NULL;
107            }
108        }*/
109
110        selectedPos = new TDCoordinate(0,0);
111//        TowerDefenseSelecter Selecter = new TowerDefenseSelecter();
112
113
114        this->setHUDTemplate("TowerDefenseHUD");
115        this->nextwaveTimer_.setTimer(10, false, createExecutor(createFunctor(&TowerDefense::nextwave, this)));
116        this->nextwaveTimer_.stopTimer();
117        this->waves_ = 0;
118        this->time = 0;
119        this->credit_ = 0;
120        this->lifes_ = 0;
121
122        //this->stats_ = new TowerDefensePlayerStats();
123
124        ModifyConsoleCommand(__CC_addTower_name).setObject(this);
125        ModifyConsoleCommand(__CC_upgradeTower_name).setObject(this);
126    }
127
128    TowerDefense::~TowerDefense()
129    {
130        /* Part of a temporary hack to allow the player to add towers */
131        if (this->isInitialized())
132        {
133            ModifyConsoleCommand(__CC_addTower_name).setObject(NULL);
134            ModifyConsoleCommand(__CC_upgradeTower_name).setObject(NULL);
135        }
136    }
137
138    void TowerDefense::setCenterpoint(TowerDefenseCenterpoint *centerpoint)
139    {
140        orxout() << "Centerpoint now setting..." << endl;
141        this->center_ = centerpoint;
142        orxout() << "Centerpoint now set..." << endl;
143    }
144
145    void TowerDefense::start()
146    {
147
148        TeamDeathmatch::start();
149
150// Waypoints: [1,3] [10,3] [10,11] [13,11] -> add the points to a matrix so the player cant place towers on the path
151        for (int i=0; i < 16 ; i++){
152            for (int j = 0; j< 16 ; j++){
153                towerModelMatrix[i][j] = NULL;
154                towerTurretMatrix[i][j] = NULL;
155            }
156        }
157
158        Model* dummyModel = new Model(this->center_->getContext());
159
160        //the path of the spacehips has to be blocked, so that no towers can be build there
161        for (int k=0; k<3; k++)
162            towerModelMatrix[1][k]=dummyModel;
163        for (int l=1; l<11; l++)
164                towerModelMatrix[l][3]=dummyModel;
165        for (int m=3; m<12; m++)
166                towerModelMatrix[10][m]=dummyModel;
167        for (int n=10; n<14; n++)
168                towerModelMatrix[n][11]=dummyModel;
169        for (int o=13; o<16; o++)
170                towerModelMatrix[13][o]=dummyModel;
171
172
173        //set initial credits, lifes and WaveNumber
174        this->setCredit(1000);
175        this->setLifes(100);
176        this->setWaveNumber(0);
177        time=0.0;
178
179        /*
180        //adds initial towers
181        for (int i=0; i <7; i++){
182            addTower(i+3,4);
183        }
184                */
185    }
186
187    // Generates a TowerDefenseEnemy. Uses Template "enemytowerdefense". Sets position at first waypoint of path.
188    void TowerDefense::addTowerDefenseEnemy(std::vector<TDCoordinate*> path, int templatenr){
189
190
191        TowerDefenseEnemy* en1 = new TowerDefenseEnemy(this->center_->getContext());
192       
193        switch(templatenr)
194        {
195        case 1 :
196            en1->addTemplate("enemytowerdefense1");
197            en1->setScale(3);
198            en1->setHealth(en1->getHealth() + this->getWaveNumber()*4);
199            break;
200
201        case 2 :
202            en1->addTemplate("enemytowerdefense2");
203            en1->setScale(2);
204            en1->setHealth(en1->getHealth() + this->getWaveNumber()*4);
205            //  en1->setShieldHealth(en1->getShield() = this->getWaveNumber()*2))
206            break;
207
208        case 3 :
209            en1->addTemplate("enemytowerdefense3");
210            en1->setScale(1);
211            en1->setHealth(en1->getHealth() + this->getWaveNumber()*4);
212            break;
213        }
214
215        en1->setTeam(2);
216        en1->getController();
217        en1->setPosition(path.at(0)->get3dcoordinate());
218        TowerDefenseEnemyvector.push_back(en1);
219
220        for(unsigned int i = 0; i < path.size(); ++i)
221        {
222            en1->addWaypoint((path.at(i)));
223        }
224    }
225
226
227    void TowerDefense::end()
228    {
229
230        TeamDeathmatch::end();
231        ChatManager::message("Match is over! Gameover!");
232
233    }
234
235    //not working yet
236    void TowerDefense::upgradeTower(int x,int y)
237    {
238        const int upgradeCost = 20;
239
240        if (!this->hasEnoughCreditForTower(upgradeCost))
241        {
242            orxout() << "not enough credit: " << (this->getCredit()) << " available, " << upgradeCost << " needed.";
243            return;
244        }
245
246
247        Model* dummyModel2 = new Model(this->center_->getContext());
248
249        if (towerModelMatrix [x][y] == NULL || (towerModelMatrix [x][y])->getMeshSource() == dummyModel2->getMeshSource())
250        {
251            orxout() << "no tower on this position" << endl;
252            return;
253        }
254
255        else
256        {
257            (towerTurretMatrix [x][y])->upgradeTower();
258            this->buyTower(upgradeCost);
259        }
260    }
261
262    /*adds Tower at Position (x,y) and reduces credit and adds the point to the towermatrix. template ("towerturret")
263    so towers have ability if the turrets
264
265    */
266    void TowerDefense::addTower(int x, int y)
267    {
268        const int towerCost = 20;
269
270        if (!this->hasEnoughCreditForTower(towerCost))
271        {
272            orxout() << "not enough credit: " << (this->getCredit()) << " available, " << towerCost << " needed.";
273            return;
274        }
275
276        if (towerModelMatrix [x][y]!=NULL)
277        {
278            orxout() << "not possible to put tower here!!" << endl;
279            return;
280        }
281
282/*
283        unsigned int width = this->center_->getWidth();
284        unsigned int height = this->center_->getHeight();
285*/
286
287        int tileScale = (int) this->center_->getTileScale();
288
289        if (x > 15 || y > 15 || x < 0 || y < 0)
290        {
291            //Hard coded: TODO: let this depend on the centerpoint's height, width and fieldsize (fieldsize doesn't exist yet)
292            orxout() << "Can not add Tower: x and y should be between 0 and 15" << endl;
293            return;
294        }
295
296        orxout() << "Will add tower at (" << (x-8) * tileScale << "," << (y-8) * tileScale << ")" << endl;
297
298
299
300        //Create Model
301        Model* newtowermodel = new Model(this->center_->getContext());
302        newtowermodel->setMeshSource("Tower.mesh");
303        newtowermodel->setScale(45);
304        newtowermodel->setPosition(static_cast<float>((x-8) * tileScale), static_cast<float>((y-8) * tileScale), 50);
305
306
307
308        //Creates tower
309        TowerDefenseTower* towernew = new TowerDefenseTower(this->center_->getContext());
310        towernew->setPosition(static_cast<float>((x-8) * tileScale), static_cast<float>((y-8) * tileScale), 275);
311        towernew->setGame(this);
312        towernew->setTeam(1);
313
314        //Reduce credit
315         this->buyTower(towerCost);
316         towerModelMatrix [x][y]= newtowermodel;
317         towerTurretMatrix [x][y]= towernew;
318    }
319
320    bool TowerDefense::hasEnoughCreditForTower(int towerCost)
321    {
322        return ((this->getCredit()) >= towerCost);
323    }
324
325
326    bool TowerDefense::hasEnoughCreditForUpgrade()
327    {
328        return true;
329    }
330
331 
332    void TowerDefense::tick(float dt)
333    {
334        SUPER(TowerDefense, tick, dt);
335        time +=dt;
336
337        TDCoordinate* coord1 = new TDCoordinate(1,1);
338        std::vector<TDCoordinate*> path;
339        path.push_back(coord1);
340        if(time>=TowerDefenseEnemyvector.size() && TowerDefenseEnemyvector.size() < 30)
341        {
342            //adds different types of enemys depending on the WaveNumber
343            addTowerDefenseEnemy(path, this->getWaveNumber() % 3 +1 );
344        }
345
346        Vector3* endpoint = new Vector3(500, 700, 150);
347        //if ships are at the end they get destroyed
348        for(unsigned int i =0; i < TowerDefenseEnemyvector.size(); ++i)
349        {
350            if(TowerDefenseEnemyvector.at(i) != NULL && TowerDefenseEnemyvector.at(i)->isAlive())
351            {
352                //destroys enemys at the end of the path and reduces the life by 1. no credits gifted
353
354                Vector3 ship = TowerDefenseEnemyvector.at(i)->getRVWorldPosition();
355                float distance = ship.distance(*endpoint);
356
357                if(distance <50){
358                    TowerDefenseEnemyvector.at(i)->destroy();
359                    this->reduceLifes(1);
360                    this->buyTower(1);
361                    if (this->getLifes()==0)
362                    {
363                        this->end();
364                    }
365                }
366            }
367        }
368
369        //goes thorugh vector to see if an enemy is still alive. if not next wave is launched
370        int count= 0;
371        for(unsigned int i =0; i < TowerDefenseEnemyvector.size(); ++i)
372        {
373            if(TowerDefenseEnemyvector.at(i)!= NULL)
374            {
375                ++count;
376            }
377        }
378
379        if (count == 0 && !this->nextwaveTimer_.isActive())
380            this->nextwaveTimer_.startTimer();
381
382/*            time2 +=dt;
383        if(count== 0)
384        {
385            if(time2 > 10)
386            {
387                TowerDefenseEnemyvector.clear();
388                this->nextwave();
389                time=0;
390                time2=0;
391            }
392        }
393*/
394
395    }
396
397    // Function to test if we can add waypoints using code only. Doesn't work yet
398
399    // THE PROBLEM: WaypointController's getControllableEntity() returns null, so it won't track. How do we get the controlableEntity to NOT BE NULL???
400    /*
401    void TowerDefense::addWaypointsAndFirstEnemy()
402    {
403        SpaceShip *newShip = new SpaceShip(this->center_);
404        newShip->addTemplate("spaceshipassff");
405
406        WaypointController *newController = new WaypointController(newShip);
407        newController->setAccuracy(3);
408
409        Model *wayPoint1 = new Model(newController);
410        wayPoint1->setMeshSource("crate.mesh");
411        wayPoint1->setPosition(7,-7,5);
412        wayPoint1->setScale(0.2);
413
414        Model *wayPoint2 = new Model(newController);
415        wayPoint2->setMeshSource("crate.mesh");
416        wayPoint2->setPosition(7,7,5);
417        wayPoint2->setScale(0.2);
418
419        newController->addWaypoint(wayPoint1);
420        newController->addWaypoint(wayPoint2);
421
422        // The following line causes the game to crash
423
424        newShip->setController(newController);
425//        newController -> getPlayer() -> startControl(newShip);
426        newShip->setPosition(-7,-7,5);
427        newShip->setScale(0.1);
428        //newShip->addSpeed(1);
429
430
431
432//      this->center_->attach(newShip);
433    }
434    */
435    /*
436    void TowerDefense::playerEntered(PlayerInfo* player)
437    {
438        TeamDeathmatch::playerEntered(player);
439
440        const std::string& message = player->getName() + " entered the game";
441        ChatManager::message(message);
442    }
443
444    bool TowerDefense::playerLeft(PlayerInfo* player)
445    {
446        bool valid_player = TeamDeathmatch::playerLeft(player);
447
448        if (valid_player)
449        {
450            const std::string& message = player->getName() + " left the game";
451            ChatManager::message(message);
452        }
453
454        return valid_player;
455    }
456
457
458    void TowerDefense::pawnKilled(Pawn* victim, Pawn* killer)
459    {
460        if (victim && victim->getPlayer())
461        {
462            std::string message;
463            if (killer)
464            {
465                if (killer->getPlayer())
466                    message = victim->getPlayer()->getName() + " was killed by " + killer->getPlayer()->getName();
467                else
468                    message = victim->getPlayer()->getName() + " was killed";
469            }
470            else
471                message = victim->getPlayer()->getName() + " died";
472
473            ChatManager::message(message);
474        }
475
476        TeamDeathmatch::pawnKilled(victim, killer);
477    }
478
479    void TowerDefense::playerScored(PlayerInfo* player, int score)
480    {
481        Gametype::playerScored(player, score);
482    }*/
483}
Note: See TracBrowser for help on using the repository browser.