Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/captureTheFlag/src/modules/gametypes/captureTheFlag.cc @ 9218

Last change on this file since 9218 was 9218, checked in by ninow, 12 years ago

Forgot to add Files

File size: 11.0 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 *      Nino Weingart
24 *   Co-authors:
25 *      ...
26 *
27 */
28#include "CaptureTheFlag.h"
29
30#include "core/CoreIncludes.h"
31#include "core/ConfigValueIncludes.h"
32#include "interfaces/TeamColourable.h"
33#include "worldentities/TeamSpawnPoint.h"
34#include "worldentities/pawns/Pawn.h"
35
36namespace orxonox
37{
38    CreateUnloadableFactory(CaptureTheFlag);
39
40    CaptureTheFlag::CaptureTheFlag(BaseObject* creator) : Deathmatch(creator)
41    {
42        RegisterObject(CaptureTheFlag);
43        //flagTeamBlue = new FlagPickup;
44        //flagTeamRed = new FlagPickup;
45
46        this->scoreTimer_.setTimer(10, true, createExecutor(createFunctor(&TeamBaseMatch::winPoints, this)));
47        this->outputTimer_.setTimer(10, true, createExecutor(createFunctor(&TeamBaseMatch::showPoints, this)));
48       
49        this->teams_ = 2;
50        this->pointsTeam1_ = 0;
51        this->pointsTeam2_ = 0;
52
53        this->setConfigValues();
54    }
55
56    void tick(float dt){
57        if(flagTeamBlue->teamScore_ > pointsTeam1_){
58                pointsTeam1_ = flagTeamBlue->teamScore_;
59        }
60        if(flagTeamRed->teamScore_ > pointsTeam2_){
61                pointsTeam2_ = flagTeamRed->teamScore_;
62        }
63    }
64    void CaptureTheFlag::setConfigValues()
65    {
66        SetConfigValue(teams_, 2);
67
68        static ColourValue colours[] =
69        {
70            ColourValue(1.0f, 0.3f, 0.3f),
71            ColourValue(0.3f, 0.3f, 1.0f),
72            ColourValue(0.3f, 1.0f, 0.3f),
73            ColourValue(1.0f, 1.0f, 0.0f)
74        };
75        static std::vector<ColourValue> defaultcolours(colours, colours + sizeof(colours) / sizeof(ColourValue));
76
77        SetConfigValue(teamcolours_, defaultcolours);
78    }
79
80    void CaptureTheFlag::playerEntered(PlayerInfo* player)
81    {
82        Deathmatch::playerEntered(player);
83
84        std::vector<unsigned int> playersperteam(this->teams_, 0);
85
86        for (std::map<PlayerInfo*, int>::iterator it = this->teamnumbers_.begin(); it != this->teamnumbers_.end(); ++it)
87            if (it->second < static_cast<int>(this->teams_) && it->second >= 0)
88                playersperteam[it->second]++;
89
90        unsigned int minplayers = static_cast<unsigned int>(-1);
91        size_t minplayersteam = 0;
92        for (size_t i = 0; i < this->teams_; ++i)
93        {
94            if (playersperteam[i] < minplayers)
95            {
96                minplayers = playersperteam[i];
97                minplayersteam = i;
98            }
99        }
100
101        this->teamnumbers_[player] = minplayersteam;
102    }
103
104    bool CaptureTheFlag::playerLeft(PlayerInfo* player)
105    {
106        bool valid_player = Deathmatch::playerLeft(player);
107
108        if (valid_player)
109            this->teamnumbers_.erase(player);
110
111        return valid_player;
112    }
113
114    bool CaptureTheFlag::allowPawnHit(Pawn* victim, Pawn* originator)
115    {
116        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
117    }
118
119    bool CaptureTheFlag::allowPawnDamage(Pawn* victim, Pawn* originator)
120    {
121        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
122    }
123
124    bool CaptureTheFlag::allowPawnDeath(Pawn* victim, Pawn* originator)
125    {
126        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
127    }
128
129    // collect Points for killing oppenents
130        void TeamBaseMatch::playerScored(PlayerInfo* player)
131        {
132            int teamnr = this->getTeam(player);
133            this->addTeamPoints(teamnr, 5);
134        }
135       
136       
137        // show points or each interval of time
138        void TeamBaseMatch::showPoints()
139        {
140            if (!this->hasStarted() || this->hasEnded())
141                return;
142
143            orxout(message) << "Points standing:" << '\n' << "Team Blue: "<< pointsTeam1_ << '\n' << "Team Red: " << pointsTeam2_ << endl;
144            if(pointsTeam1_ >=1700 && pointsTeam1_ < 2000) orxout(message) << "Team Blue is near victory!" << endl;
145            if(pointsTeam2_ >=1700 && pointsTeam2_ < 2000) orxout(message) << "Team Red is near victory!" << endl;
146        }
147       
148        // end game if one team reaches 2000 points
149        void TeamBaseMatch::endGame()
150        {
151            if (this->pointsTeam1_ >= 2000 || this->pointsTeam2_ >= 2000)
152            {
153                int winningteam = -1;
154
155                if (this->pointsTeam1_ > this->pointsTeam2_)
156                {
157                    orxout(message) << "Team Blue has won the match" << endl;
158                    winningteam = 0;
159                }
160                else
161                {
162                    orxout(message) << "Team Red has won the match" << endl;
163                    winningteam = 1;
164                }
165
166                for (std::map<PlayerInfo*, int>::iterator it = this->teamnumbers_.begin(); it != this->teamnumbers_.end(); ++it)
167                {
168                    if (it->first->getClientID() == NETWORK_PEER_ID_UNKNOWN)
169                        continue;
170
171                    if (it->second == winningteam)
172                        this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID());
173                    else
174                        this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID());
175                }
176
177                this->end();
178                this->scoreTimer_.stopTimer();
179                this->outputTimer_.stopTimer();
180            }
181        }
182       
183        // this function is called by the function winPoints() which adds points to the teams for every base and killed openents at a certain time
184        void TeamBaseMatch::addTeamPoints(int team, int points)
185        {
186            if(team == 0)
187            {
188                this->pointsTeam1_ += points;
189            }
190            if(team == 1)
191            {
192                this->pointsTeam2_ += points;
193            }
194
195            this->endGame();
196        }
197
198        int TeamBaseMatch::getTeamPoints(int team)
199        {
200            if(team == 0)
201            {
202                return this->pointsTeam1_;
203            }
204            if(team == 1)
205            {
206                return this->pointsTeam2_;
207            }
208
209            return 0;
210        }
211       
212    SpawnPoint* CaptureTheFlag::getBestSpawnPoint(PlayerInfo* player) const
213    {
214        int desiredTeamNr = -1;
215        std::map<PlayerInfo*, int>::const_iterator it_player = this->teamnumbers_.find(player);
216        if (it_player != this->teamnumbers_.end())
217            desiredTeamNr = it_player->second;
218
219        // Only use spawnpoints of the own team (or non-team-spawnpoints)
220        std::set<SpawnPoint*> teamSpawnPoints = this->spawnpoints_;
221        for (std::set<SpawnPoint*>::iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); )
222        {
223            if ((*it)->isA(Class(TeamSpawnPoint)))
224            {
225                TeamSpawnPoint* tsp = orxonox_cast<TeamSpawnPoint*>(*it);
226                if (tsp && static_cast<int>(tsp->getTeamNumber()) != desiredTeamNr)
227                {
228                    teamSpawnPoints.erase(it++);
229                    continue;
230                }
231            }
232
233            ++it;
234        }
235
236        SpawnPoint* fallbackSpawnPoint = NULL;
237        if (teamSpawnPoints.size() > 0)
238        {
239            unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(teamSpawnPoints.size())));
240            unsigned int index = 0;
241            // Get random fallback spawnpoint in case there is no active SpawnPoint.
242            for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); ++it)
243            {
244                if (index == randomspawn)
245                {
246                    fallbackSpawnPoint = (*it);
247                    break;
248                }
249
250                ++index;
251            }
252
253            // Remove all inactive SpawnPoints from the list.
254            for (std::set<SpawnPoint*>::iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); )
255            {
256                if(!(*it)->isActive())
257                {
258                    teamSpawnPoints.erase(it++);
259                    continue;
260                }
261
262                ++it;
263            }
264
265            randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(teamSpawnPoints.size())));
266            index = 0;
267            for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); ++it)
268            {
269                if (index == randomspawn)
270                    return (*it);
271
272                ++index;
273            }
274
275            return fallbackSpawnPoint;
276        }
277
278        return 0;
279    }
280
281    void CaptureTheFlag::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
282    {
283        if (!player)
284            return;
285
286        // Set the team colour
287        std::map<PlayerInfo*, int>::const_iterator it_player = this->teamnumbers_.find(player);
288        if (it_player != this->teamnumbers_.end() && it_player->second >= 0 && it_player->second < static_cast<int>(this->teamcolours_.size()))
289        {
290            if (pawn)
291            {
292                pawn->setRadarObjectColour(this->teamcolours_[it_player->second]);
293
294                std::set<WorldEntity*> pawnAttachments = pawn->getAttachedObjects();
295                for (std::set<WorldEntity*>::iterator it = pawnAttachments.begin(); it != pawnAttachments.end(); ++it)
296                {
297                    if ((*it)->isA(Class(TeamColourable)))
298                    {
299                        TeamColourable* tc = orxonox_cast<TeamColourable*>(*it);
300                        tc->setTeamColour(this->teamcolours_[it_player->second]);
301                    }
302                }
303            }
304        }
305    }
306
307    bool CaptureTheFlag::pawnsAreInTheSameTeam(Pawn* pawn1, Pawn* pawn2)
308    {
309        if (pawn1 && pawn2)
310        {
311            std::map<PlayerInfo*, int>::const_iterator it1 = this->teamnumbers_.find(pawn1->getPlayer());
312            std::map<PlayerInfo*, int>::const_iterator it2 = this->teamnumbers_.find(pawn2->getPlayer());
313
314            if (it1 != this->teamnumbers_.end() && it2 != this->teamnumbers_.end())
315                return (it1->second == it2->second);
316        }
317        return false;
318    }
319
320    int CaptureTheFlag::getTeam(PlayerInfo* player)
321    {
322        std::map<PlayerInfo*, int>::const_iterator it_player = this->teamnumbers_.find(player);
323        if (it_player != this->teamnumbers_.end())
324            return it_player->second;
325        else
326            return -1;
327    }
328}
Note: See TracBrowser for help on using the repository browser.