Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gamecontent/src/orxonox/gametypes/TeamGametype.cc @ 8904

Last change on this file since 8904 was 8904, checked in by jo, 13 years ago

On the way to a multiplayer gametype basceclass.

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