Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/orxonox/infos/GametypeInfo.cc @ 8648

Last change on this file since 8648 was 8648, checked in by scheusso, 13 years ago

some network related fixes

  • Property svn:eol-style set to native
File size: 16.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 *      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       
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                //NotificationListener::sendCommand("clear", GametypeInfo::NOTIFICATION_SENDER, notificationSendMode::network, player->getClientID());
312                this->setSpawnedHelper(player, true);
313            }
314        }
315    }
316
317    /**
318    @brief
319        Inform the GametypeInfo that the local player has changed its spawned status.
320    @param spawned
321        Whether the local player has changed to spawned or to not spawned.
322    */
323    void GametypeInfo::changedSpawned(bool spawned)
324    {
325        if(this->spawned_ == spawned)
326            return;
327       
328        this->spawned_ = spawned;
329        // Clear the notifications if the Player has spawned.
330        if(this->spawned_ && !this->hasEnded())
331            NotificationListener::sendCommand("clear", GametypeInfo::NOTIFICATION_SENDER);
332    }
333
334    /**
335    @brief
336        Inform the GametypeInfo about a player that has entered,
337    @param player
338        The player that has entered.
339    */
340    void GametypeInfo::playerEntered(PlayerInfo* player)
341    {
342        if(GameMode::isMaster())
343        {
344            if( player->isHumanPlayer() )
345            {
346                // Display "Press [Fire] to start the match" if the game has not yet ended.
347                if(!this->hasEnded())
348                    NotificationListener::sendNotification("Press [Fire] to start the match", GametypeInfo::NOTIFICATION_SENDER, notificationMessageType::info, notificationSendMode::network, player->getClientID());
349                // Else display "Game has ended".
350                else
351                    NotificationListener::sendNotification("Game has ended", GametypeInfo::NOTIFICATION_SENDER, notificationMessageType::info, notificationSendMode::network, player->getClientID());
352            }
353        }
354    }
355
356    /**
357    @brief
358        Helper method. Sends changedReadyToSpawn notifiers over the network.
359    @param player
360        The player that has changed its ready to spawn status.
361    @param ready
362        The new ready to spawn status.
363    */
364    void GametypeInfo::setReadyToSpawnHelper(PlayerInfo* player, bool ready)
365    {
366        if(GameMode::isMaster())
367        {
368            if(player->getClientID() == CLIENTID_SERVER)
369                this->changedReadyToSpawn(ready);
370            else
371                callMemberNetworkFunction(GametypeInfo, changedReadyToSpawn, this->getObjectID(), player->getClientID(), ready);
372        }
373    }
374
375    /**
376    @brief
377        Helper method. Sends changedSpawned notifiers over the network.
378    @param player
379        The player that has changed its spawned status.
380    @param ready
381        The new spawned status.
382    */
383    void GametypeInfo::setSpawnedHelper(PlayerInfo* player, bool spawned)
384    {
385        if(GameMode::isMaster())
386        {
387            if(player->getClientID() == CLIENTID_SERVER)
388                    this->changedSpawned(spawned);
389            else
390                callMemberNetworkFunction(GametypeInfo, changedSpawned, this->getObjectID(), player->getClientID(), spawned);
391        }
392    }
393
394    // Announce messages.
395    // TODO: Replace with notifications.
396
397    void GametypeInfo::sendAnnounceMessage(const std::string& message)
398    {
399        if (GameMode::isMaster())
400        {
401            callMemberNetworkFunction(GametypeInfo, dispatchAnnounceMessage, this->getObjectID(), NETWORK_PEER_ID_BROADCAST, message);
402            this->dispatchAnnounceMessage(message);
403        }
404    }
405
406    void GametypeInfo::sendAnnounceMessage(const std::string& message, unsigned int clientID)
407    {
408        if (GameMode::isMaster())
409        {
410            if (clientID == CLIENTID_SERVER)
411                this->dispatchAnnounceMessage(message);
412            else
413                callMemberNetworkFunction(GametypeInfo, dispatchAnnounceMessage, this->getObjectID(), clientID, message);
414        }
415    }
416
417    void GametypeInfo::sendKillMessage(const std::string& message, unsigned int clientID)
418    {
419        if (GameMode::isMaster())
420        {
421            if (clientID == CLIENTID_SERVER)
422                this->dispatchKillMessage(message);
423            else
424                callMemberNetworkFunction(GametypeInfo, dispatchKillMessage, this->getObjectID(), clientID, message);
425        }
426    }
427
428    void GametypeInfo::sendDeathMessage(const std::string& message, unsigned int clientID)
429    {
430        if (GameMode::isMaster())
431        {
432            if (clientID == CLIENTID_SERVER)
433                this->dispatchDeathMessage(message);
434            else
435                callMemberNetworkFunction(GametypeInfo, dispatchDeathMessage, this->getObjectID(), clientID, message);
436        }
437    }
438
439    void GametypeInfo::sendStaticMessage(const std::string& message, unsigned int clientID, const ColourValue& colour)
440    {
441        if (GameMode::isMaster())
442        {
443            if (clientID == CLIENTID_SERVER)
444                this->dispatchStaticMessage(message, colour);
445            else
446                callMemberNetworkFunction(GametypeInfo, dispatchStaticMessage, this->getObjectID(), clientID, message, colour);
447        }
448    }
449
450    void GametypeInfo::sendFadingMessage(const std::string& message, unsigned int clientID)
451    {
452        if (GameMode::isMaster())
453        {
454            if (clientID == CLIENTID_SERVER)
455                this->dispatchFadingMessage(message);
456            else
457                callMemberNetworkFunction(GametypeInfo, dispatchFadingMessage, this->getObjectID(), clientID, message);
458        }
459    }
460
461    void GametypeInfo::dispatchAnnounceMessage(const std::string& message)
462    {
463        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
464            it->announcemessage(this, message);
465    }
466
467    void GametypeInfo::dispatchKillMessage(const std::string& message)
468    {
469        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
470            it->killmessage(this, message);
471    }
472
473    void GametypeInfo::dispatchDeathMessage(const std::string& message)
474    {
475        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
476            it->deathmessage(this, message);
477    }
478
479     void GametypeInfo::dispatchStaticMessage(const std::string& message, const ColourValue& colour)
480    {
481        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
482            it->staticmessage(this, message, colour);
483    }
484
485     void GametypeInfo::dispatchFadingMessage(const std::string& message)
486    {
487        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
488            it->fadingmessage(this, message);
489    }
490}
Note: See TracBrowser for help on using the repository browser.