Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/infos/GametypeInfo.cc @ 8706

Last change on this file since 8706 was 8706, checked in by dafrick, 13 years ago

Merging presentation branch back into trunk.
There are many new features and also a lot of other changes and bugfixes, if you want to know, digg through the svn log.
Not everything is yet working as it should, but it should be fairly stable. If you habe any bug reports, just send me an email.

  • Property svn:eol-style set to native
File size: 16.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 *      Damian 'Mozork' Frick
26 *
27 */
28
29/**
30    @file GametypeInfo.cc
31    @brief Implementation of the GametypeInfo class
32*/
33
34#include "GametypeInfo.h"
35
36#include "core/CoreIncludes.h"
37#include "core/GameMode.h"
38#include "network/Host.h"
39#include "network/NetworkFunction.h"
40#include "util/Convert.h"
41
42#include "controllers/HumanController.h"
43#include "interfaces/GametypeMessageListener.h"
44#include "interfaces/NotificationListener.h"
45
46#include "PlayerInfo.h"
47
48namespace orxonox
49{
50    CreateUnloadableFactory(GametypeInfo);
51
52    registerMemberNetworkFunction(GametypeInfo, dispatchAnnounceMessage);
53    registerMemberNetworkFunction(GametypeInfo, dispatchKillMessage);
54    registerMemberNetworkFunction(GametypeInfo, dispatchDeathMessage);
55    registerMemberNetworkFunction(GametypeInfo, dispatchStaticMessage);
56    registerMemberNetworkFunction(GametypeInfo, dispatchFadingMessage);
57
58    registerMemberNetworkFunction(GametypeInfo, changedReadyToSpawn);
59    registerMemberNetworkFunction(GametypeInfo, changedSpawned);
60
61    /*static*/ const std::string GametypeInfo::NOTIFICATION_SENDER("gameinfo");
62
63    /**
64    @brief
65        Registers and initializes the object.
66    */
67    GametypeInfo::GametypeInfo(BaseObject* creator) : Info(creator)
68    {
69        RegisterObject(GametypeInfo);
70       
71        this->bStarted_ = false;
72        this->bEnded_ = false;
73        this->startCountdown_ = 0.0f;
74        this->bStartCountdownRunning_ = false;
75        this->counter_ = 0;
76        this->spawned_ = false;
77        this->readyToSpawn_ = false;
78
79        this->registerVariables();
80    }
81
82    GametypeInfo::~GametypeInfo()
83    {
84    }
85
86    void GametypeInfo::registerVariables()
87    {
88        registerVariable(this->bStarted_,               VariableDirection::ToClient, new NetworkCallback<GametypeInfo>(this, &GametypeInfo::changedStarted));
89        registerVariable(this->bEnded_,                 VariableDirection::ToClient, new NetworkCallback<GametypeInfo>(this, &GametypeInfo::changedEnded));
90        registerVariable(this->bStartCountdownRunning_, VariableDirection::ToClient, new NetworkCallback<GametypeInfo>(this, &GametypeInfo::changedStartCountdownRunning));
91        registerVariable(this->startCountdown_,         VariableDirection::ToClient);
92        registerVariable(this->counter_,                VariableDirection::ToClient, new NetworkCallback<GametypeInfo>(this, &GametypeInfo::changedCountdownCounter));
93        registerVariable(this->hudtemplate_,            VariableDirection::ToClient);
94    }
95
96    /**
97    @brief
98        Is called when the game has changed to started.
99    */
100    void GametypeInfo::changedStarted(void)
101    {
102        NotificationListener::sendCommand("clear", GametypeInfo::NOTIFICATION_SENDER);
103    }
104
105    /**
106    @brief
107        Is called when the game has changed to ended.
108    */
109    void GametypeInfo::changedEnded(void)
110    {
111        // If the game has ended, a "Game has ended" notification is displayed.
112        if(this->hasEnded())
113            NotificationListener::sendNotification("Game has ended", GametypeInfo::NOTIFICATION_SENDER);
114    }
115
116    /**
117    @brief
118        Is called when the start countdown has been either started or stopped.
119    */
120    void GametypeInfo::changedStartCountdownRunning(void)
121    {
122        // Send first countdown notification if the countdown has started.
123        if(this->isReadyToSpawn() && !this->hasStarted() && this->isStartCountdownRunning() && !this->hasEnded())
124            NotificationListener::sendNotification(multi_cast<std::string>(this->counter_), GametypeInfo::NOTIFICATION_SENDER);
125    }
126
127    /**
128    @brief
129        Is called when the start countdown counter has changed.
130    */
131    void GametypeInfo::changedCountdownCounter(void)
132    {
133        // Send countdown notification if the counter has gone down.
134        if(this->isReadyToSpawn() &&  !this->hasStarted() && this->isStartCountdownRunning() && !this->hasEnded())
135            NotificationListener::sendNotification(multi_cast<std::string>(this->counter_), GametypeInfo::NOTIFICATION_SENDER);
136    }
137
138    /**
139    @brief
140        Inform the GametypeInfo that the local player has changed its ready to spawn status.
141    @param ready
142        Whether the player has become ready to spawn or not.
143    */
144    void GametypeInfo::changedReadyToSpawn(bool ready)
145    {
146        if(this->readyToSpawn_ == ready)
147            return;
148
149        this->readyToSpawn_ = ready;
150
151        // Send "Waiting for other players" if the player is ready to spawn but the game has not yet started nor is the countdown running.
152        if(this->readyToSpawn_ && !this->hasStarted() && !this->isStartCountdownRunning() && !this->hasEnded())
153            NotificationListener::sendNotification("Waiting for other players", GametypeInfo::NOTIFICATION_SENDER);
154        // Send current countdown if the player is ready to spawn and the countdown has already started.
155        else if(this->readyToSpawn_ && !this->hasStarted() && this->isStartCountdownRunning() && !this->hasEnded())
156            NotificationListener::sendNotification(multi_cast<std::string>(this->counter_), GametypeInfo::NOTIFICATION_SENDER);
157    }
158
159    /**
160    @brief
161        Inform the GametypeInfo that the game has started.
162    */
163    void GametypeInfo::start(void)
164    {
165        if(this->bStarted_)
166            return;
167       
168        this->bStarted_ = true;
169        this->changedStarted();
170    }
171
172    /**
173    @brief
174        Inform the GametypeInfo that the game has ended.
175    */
176    void GametypeInfo::end(void)
177    {
178        if(this->bEnded_)
179            return;
180
181        this->bEnded_ = true;
182        this->changedEnded();
183    }
184
185    /**
186    @brief
187        Set the start countdown to the input value.
188    @param countdown
189        The countdown to be set.
190    */
191    void GametypeInfo::setStartCountdown(float countdown)
192    {
193        if(this->startCountdown_ == countdown || countdown < 0.0f)
194            return;
195       
196        this->startCountdown_ = countdown;
197        // Set the counter to the ceiling of the current countdown.
198        this->counter_ = std::ceil(countdown);
199        this->changedCountdownCounter();
200    }
201
202    /**
203    @brief
204        Count down the start countdown by the specified value.
205    @param countDown
206        The amount by which we count down.
207    */
208    void GametypeInfo::countdownStartCountdown(float countDown)
209    {
210        float newCountdown = this->startCountdown_ - countDown;
211        // If we have switched integers or arrived at zero, we also count down the start countdown counter.
212        if(ceil(newCountdown) != ceil(this->startCountdown_) || newCountdown <= 0.0f)
213            this->countDown();
214        this->startCountdown_ = newCountdown;
215    }
216
217    /**
218    @brief
219        Count down the start countdown counter.
220    */
221    void GametypeInfo::countDown()
222    {
223        if(this->counter_ == 0)
224            return;
225       
226        this->counter_--;
227        this->changedCountdownCounter();
228    }
229
230    /**
231    @brief
232        Inform the GametypeInfo about the start of the start countdown.
233    */
234    void GametypeInfo::startStartCountdown(void)
235    {
236        if(GameMode::isMaster())
237        {
238            if(this->bStartCountdownRunning_)
239                return;
240
241            this->bStartCountdownRunning_ = true;
242            this->changedStartCountdownRunning();
243        }
244    }
245
246    /**
247    @brief
248        Inform the GametypeInfo about the stop of the start countdown.
249    */
250    void GametypeInfo::stopStartCountdown(void)
251    {
252        if(GameMode::isMaster())
253        {
254            if(!this->bStartCountdownRunning_)
255                return;
256
257            this->bStartCountdownRunning_ = false;
258            this->changedStartCountdownRunning();
259        }
260    }
261
262    /**
263    @brief
264        Inform the GametypeInfo about a player that is ready to spawn.
265    @param player
266        The player that is ready to spawn.
267    */
268    void GametypeInfo::playerReadyToSpawn(PlayerInfo* player)
269    {
270        if(GameMode::isMaster())
271        {
272            // If the player has spawned already.
273            if(this->spawnedPlayers_.find(player) != this->spawnedPlayers_.end())
274                return;
275
276            this->spawnedPlayers_.insert(player);
277            this->setReadyToSpawnHelper(player, true);
278        }
279    }
280
281    /**
282    @brief
283        Inform the GametypeInfo about a player whose Pawn has been killed.
284    @param player
285        The player whose Pawn has been killed.
286    */
287    void GametypeInfo::pawnKilled(PlayerInfo* player)
288    {
289        if(GameMode::isMaster())
290        {
291            NotificationListener::sendNotification("Press [Fire] to respawn", GametypeInfo::NOTIFICATION_SENDER, notificationMessageType::info, notificationSendMode::network, player->getClientID());
292            // Remove the player from the list of players that have spawned, since it currently is not.
293            this->spawnedPlayers_.erase(player);
294            this->setReadyToSpawnHelper(player, false);
295            this->setSpawnedHelper(player, false);
296        }
297    }
298
299    /**
300    @brief
301        Inform the GametypeInfo about a player that has spawned.
302    @param player
303        The player that has spawned.
304    */
305    void GametypeInfo::playerSpawned(PlayerInfo* player)
306    {
307        if(GameMode::isMaster())
308        {
309            if(this->hasStarted() && !this->hasEnded())
310
311                this->setSpawnedHelper(player, true);
312        }
313    }
314
315    /**
316    @brief
317        Inform the GametypeInfo that the local player has changed its spawned status.
318    @param spawned
319        Whether the local player has changed to spawned or to not spawned.
320    */
321    void GametypeInfo::changedSpawned(bool spawned)
322    {
323        if(this->spawned_ == spawned)
324            return;
325       
326        this->spawned_ = spawned;
327        // Clear the notifications if the Player has spawned.
328        if(this->spawned_ && !this->hasEnded())
329            NotificationListener::sendCommand("clear", GametypeInfo::NOTIFICATION_SENDER);
330    }
331
332    /**
333    @brief
334        Inform the GametypeInfo about a player that has entered,
335    @param player
336        The player that has entered.
337    */
338    void GametypeInfo::playerEntered(PlayerInfo* player)
339    {
340        if(GameMode::isMaster())
341        {
342            if( player->isHumanPlayer() )
343            {
344                // Display "Press [Fire] to start the match" if the game has not yet ended.
345                if(!this->hasEnded())
346                    NotificationListener::sendNotification("Press [Fire] to start the match", GametypeInfo::NOTIFICATION_SENDER, notificationMessageType::info, notificationSendMode::network, player->getClientID());
347                // Else display "Game has ended".
348                else
349                    NotificationListener::sendNotification("Game has ended", GametypeInfo::NOTIFICATION_SENDER, notificationMessageType::info, notificationSendMode::network, player->getClientID());
350            }
351        }
352    }
353
354    /**
355    @brief
356        Helper method. Sends changedReadyToSpawn notifiers over the network.
357    @param player
358        The player that has changed its ready to spawn status.
359    @param ready
360        The new ready to spawn status.
361    */
362    void GametypeInfo::setReadyToSpawnHelper(PlayerInfo* player, bool ready)
363    {
364        if(GameMode::isMaster())
365        {
366            if(player->getClientID() == CLIENTID_SERVER)
367                this->changedReadyToSpawn(ready);
368            else
369                callMemberNetworkFunction(GametypeInfo, changedReadyToSpawn, this->getObjectID(), player->getClientID(), ready);
370        }
371    }
372
373    /**
374    @brief
375        Helper method. Sends changedSpawned notifiers over the network.
376    @param player
377        The player that has changed its spawned status.
378    @param ready
379        The new spawned status.
380    */
381    void GametypeInfo::setSpawnedHelper(PlayerInfo* player, bool spawned)
382    {
383        if(GameMode::isMaster())
384        {
385            if(player->getClientID() == CLIENTID_SERVER)
386                    this->changedSpawned(spawned);
387            else
388                callMemberNetworkFunction(GametypeInfo, changedSpawned, this->getObjectID(), player->getClientID(), spawned);
389        }
390    }
391
392    // Announce messages.
393    // TODO: Replace with notifications.
394
395    void GametypeInfo::sendAnnounceMessage(const std::string& message)
396    {
397        if (GameMode::isMaster())
398        {
399            callMemberNetworkFunction(GametypeInfo, dispatchAnnounceMessage, this->getObjectID(), NETWORK_PEER_ID_BROADCAST, message);
400            this->dispatchAnnounceMessage(message);
401        }
402    }
403
404    void GametypeInfo::sendAnnounceMessage(const std::string& message, unsigned int clientID)
405    {
406        if (GameMode::isMaster())
407        {
408            if (clientID == CLIENTID_SERVER)
409                this->dispatchAnnounceMessage(message);
410            else
411                callMemberNetworkFunction(GametypeInfo, dispatchAnnounceMessage, this->getObjectID(), clientID, message);
412        }
413    }
414
415    void GametypeInfo::sendKillMessage(const std::string& message, unsigned int clientID)
416    {
417        if (GameMode::isMaster())
418        {
419            if (clientID == CLIENTID_SERVER)
420                this->dispatchKillMessage(message);
421            else
422                callMemberNetworkFunction(GametypeInfo, dispatchKillMessage, this->getObjectID(), clientID, message);
423        }
424    }
425
426    void GametypeInfo::sendDeathMessage(const std::string& message, unsigned int clientID)
427    {
428        if (GameMode::isMaster())
429        {
430            if (clientID == CLIENTID_SERVER)
431                this->dispatchDeathMessage(message);
432            else
433                callMemberNetworkFunction(GametypeInfo, dispatchDeathMessage, this->getObjectID(), clientID, message);
434        }
435    }
436
437    void GametypeInfo::sendStaticMessage(const std::string& message, unsigned int clientID, const ColourValue& colour)
438    {
439        if (GameMode::isMaster())
440        {
441            if (clientID == CLIENTID_SERVER)
442                this->dispatchStaticMessage(message, colour);
443            else
444                callMemberNetworkFunction(GametypeInfo, dispatchStaticMessage, this->getObjectID(), clientID, message, colour);
445        }
446    }
447
448    void GametypeInfo::sendFadingMessage(const std::string& message, unsigned int clientID)
449    {
450        if (GameMode::isMaster())
451        {
452            if (clientID == CLIENTID_SERVER)
453                this->dispatchFadingMessage(message);
454            else
455                callMemberNetworkFunction(GametypeInfo, dispatchFadingMessage, this->getObjectID(), clientID, message);
456        }
457    }
458
459    void GametypeInfo::dispatchAnnounceMessage(const std::string& message)
460    {
461        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
462            it->announcemessage(this, message);
463    }
464
465    void GametypeInfo::dispatchKillMessage(const std::string& message)
466    {
467        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
468            it->killmessage(this, message);
469    }
470
471    void GametypeInfo::dispatchDeathMessage(const std::string& message)
472    {
473        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
474            it->deathmessage(this, message);
475    }
476
477     void GametypeInfo::dispatchStaticMessage(const std::string& message, const ColourValue& colour)
478    {
479        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
480            it->staticmessage(this, message, colour);
481    }
482
483     void GametypeInfo::dispatchFadingMessage(const std::string& message)
484    {
485        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
486            it->fadingmessage(this, message);
487    }
488}
Note: See TracBrowser for help on using the repository browser.