Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/gametypes/TeamDeathmatch.cc @ 7163

Last change on this file since 7163 was 7163, checked in by dafrick, 14 years ago

Merged presentation3 branch into trunk.

  • Property svn:eol-style set to native
File size: 7.6 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 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "TeamDeathmatch.h"
30
31#include "core/CoreIncludes.h"
32#include "core/ConfigValueIncludes.h"
33#include "interfaces/TeamColourable.h"
34#include "worldentities/TeamSpawnPoint.h"
35#include "worldentities/pawns/Pawn.h"
36
37namespace orxonox
38{
39    CreateUnloadableFactory(TeamDeathmatch);
40
41    TeamDeathmatch::TeamDeathmatch(BaseObject* creator) : Deathmatch(creator)
42    {
43        RegisterObject(TeamDeathmatch);
44
45        this->teams_ = 2;
46
47        this->setConfigValues();
48    }
49
50    void TeamDeathmatch::setConfigValues()
51    {
52        SetConfigValue(teams_, 2);
53
54        static ColourValue colours[] =
55        {
56            ColourValue(1.0f, 0.3f, 0.3f),
57            ColourValue(0.3f, 0.3f, 1.0f),
58            ColourValue(0.3f, 1.0f, 0.3f),
59            ColourValue(1.0f, 1.0f, 0.0f)
60        };
61        static std::vector<ColourValue> defaultcolours(colours, colours + sizeof(colours) / sizeof(ColourValue));
62
63        SetConfigValue(teamcolours_, defaultcolours);
64    }
65
66    void TeamDeathmatch::playerEntered(PlayerInfo* player)
67    {
68        Deathmatch::playerEntered(player);
69
70        std::vector<unsigned int> playersperteam(this->teams_, 0);
71
72        for (std::map<PlayerInfo*, int>::iterator it = this->teamnumbers_.begin(); it != this->teamnumbers_.end(); ++it)
73            if (it->second < static_cast<int>(this->teams_) && it->second >= 0)
74                playersperteam[it->second]++;
75
76        unsigned int minplayers = static_cast<unsigned int>(-1);
77        size_t minplayersteam = 0;
78        for (size_t i = 0; i < this->teams_; ++i)
79        {
80            if (playersperteam[i] < minplayers)
81            {
82                minplayers = playersperteam[i];
83                minplayersteam = i;
84            }
85        }
86
87        this->teamnumbers_[player] = minplayersteam;
88    }
89
90    bool TeamDeathmatch::playerLeft(PlayerInfo* player)
91    {
92        bool valid_player = Deathmatch::playerLeft(player);
93
94        if (valid_player)
95            this->teamnumbers_.erase(player);
96
97        return valid_player;
98    }
99
100    bool TeamDeathmatch::allowPawnHit(Pawn* victim, Pawn* originator)
101    {
102        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
103    }
104
105    bool TeamDeathmatch::allowPawnDamage(Pawn* victim, Pawn* originator)
106    {
107        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
108    }
109
110    bool TeamDeathmatch::allowPawnDeath(Pawn* victim, Pawn* originator)
111    {
112        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
113    }
114
115    SpawnPoint* TeamDeathmatch::getBestSpawnPoint(PlayerInfo* player) const
116    {
117        int desiredTeamNr = -1;
118        std::map<PlayerInfo*, int>::const_iterator it_player = this->teamnumbers_.find(player);
119        if (it_player != this->teamnumbers_.end())
120            desiredTeamNr = it_player->second;
121
122        // Only use spawnpoints of the own team (or non-team-spawnpoints)
123        std::set<SpawnPoint*> teamSpawnPoints = this->spawnpoints_;
124        for (std::set<SpawnPoint*>::iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); )
125        {
126            if ((*it)->isA(Class(TeamSpawnPoint)))
127            {
128                TeamSpawnPoint* tsp = orxonox_cast<TeamSpawnPoint*>(*it);
129                if (tsp && static_cast<int>(tsp->getTeamNumber()) != desiredTeamNr)
130                {
131                    teamSpawnPoints.erase(it++);
132                    continue;
133                }
134            }
135
136            ++it;
137        }
138
139        SpawnPoint* fallbackSpawnPoint = NULL;
140        if (teamSpawnPoints.size() > 0)
141        {
142            unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(teamSpawnPoints.size())));
143            unsigned int index = 0;
144            // Get random fallback spawnpoint in case there is no active SpawnPoint.
145            for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); ++it)
146            {
147                if (index == randomspawn)
148                {
149                    fallbackSpawnPoint = (*it);
150                    break;
151                }
152
153                ++index;
154            }
155
156            // Remove all inactive SpawnPoints from the list.
157            for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); )
158            {
159                if(!(*it)->isActive())
160                {
161                    teamSpawnPoints.erase(it++);
162                    continue;
163                }
164
165                ++it;
166            }
167
168            randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(teamSpawnPoints.size())));
169            index = 0;
170            for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); ++it)
171            {
172                if (index == randomspawn)
173                    return (*it);
174
175                ++index;
176            }
177
178            return fallbackSpawnPoint;
179        }
180
181        return 0;
182    }
183
184    void TeamDeathmatch::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
185    {
186        if (!player)
187            return;
188
189        // Set the team colour
190        std::map<PlayerInfo*, int>::const_iterator it_player = this->teamnumbers_.find(player);
191        if (it_player != this->teamnumbers_.end() && it_player->second >= 0 && it_player->second < static_cast<int>(this->teamcolours_.size()))
192        {
193            if (pawn)
194            {
195                pawn->setRadarObjectColour(this->teamcolours_[it_player->second]);
196
197                std::set<WorldEntity*> pawnAttachments = pawn->getAttachedObjects();
198                for (std::set<WorldEntity*>::iterator it = pawnAttachments.begin(); it != pawnAttachments.end(); ++it)
199                {
200                    if ((*it)->isA(Class(TeamColourable)))
201                    {
202                        TeamColourable* tc = orxonox_cast<TeamColourable*>(*it);
203                        tc->setTeamColour(this->teamcolours_[it_player->second]);
204                    }
205                }
206            }
207        }
208    }
209
210    bool TeamDeathmatch::pawnsAreInTheSameTeam(Pawn* pawn1, Pawn* pawn2)
211    {
212        if (pawn1 && pawn2)
213        {
214            std::map<PlayerInfo*, int>::const_iterator it1 = this->teamnumbers_.find(pawn1->getPlayer());
215            std::map<PlayerInfo*, int>::const_iterator it2 = this->teamnumbers_.find(pawn2->getPlayer());
216
217            if (it1 != this->teamnumbers_.end() && it2 != this->teamnumbers_.end())
218                return (it1->second == it2->second);
219        }
220        return false;
221    }
222
223    int TeamDeathmatch::getTeam(PlayerInfo* player)
224    {
225        std::map<PlayerInfo*, int>::const_iterator it_player = this->teamnumbers_.find(player);
226        if (it_player != this->teamnumbers_.end())
227            return it_player->second;
228        else
229            return -1;
230    }
231}
Note: See TracBrowser for help on using the repository browser.