Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10624 was 10624, checked in by landauf, 8 years ago

merged branch core7 back to trunk

  • 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/NetworkFunctionIncludes.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    RegisterUnloadableClass(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(Context* context) : Info(context)
68    {
69        RegisterObject(GametypeInfo);
70
71        this->bStarted_ = false;
72        this->bEnded_ = false;
73        this->startCountdown_ = 10.0f;
74        this->bStartCountdownRunning_ = false;
75        this->counter_ = 10;
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
174    /**
175    @brief
176        Inform the GametypeInfo that the game has ended.
177    */
178    void GametypeInfo::end(void)
179    {
180        if(this->bEnded_)
181            return;
182
183        this->bEnded_ = true;
184        this->changedEnded();
185    }
186
187    /**
188    @brief
189        Set the start countdown to the input value.
190    @param countdown
191        The countdown to be set.
192    */
193    void GametypeInfo::setStartCountdown(float countdown)
194    {
195        if(this->startCountdown_ == countdown || countdown < 0.0f)
196            return;
197
198        this->startCountdown_ = countdown;
199        // Set the counter to the ceiling of the current countdown.
200        this->counter_ = static_cast<unsigned int>(std::ceil(countdown));
201        this->changedCountdownCounter();
202    }
203
204    /**
205    @brief
206        Count down the start countdown by the specified value.
207    @param countDown
208        The amount by which we count down.
209    */
210    void GametypeInfo::countdownStartCountdown(float countDown)
211    {
212        float newCountdown = this->startCountdown_ - countDown;
213        // If we have switched integers or arrived at zero, we also count down the start countdown counter.
214        if(ceil(newCountdown) != ceil(this->startCountdown_) || newCountdown <= 0.0f)
215            this->countDown();
216        this->startCountdown_ = newCountdown;
217    }
218
219    /**
220    @brief
221        Count down the start countdown counter.
222    */
223    void GametypeInfo::countDown()
224    {
225        if(this->counter_ == 0)
226            return;
227
228        this->counter_--;
229        this->changedCountdownCounter();
230    }
231
232    /**
233    @brief
234        Inform the GametypeInfo about the start of the start countdown.
235    */
236    void GametypeInfo::startStartCountdown(void)
237    {
238        if(GameMode::isMaster())
239        {
240            if(this->bStartCountdownRunning_)
241                return;
242
243            this->bStartCountdownRunning_ = true;
244            this->changedStartCountdownRunning();
245        }
246    }
247
248    /**
249    @brief
250        Inform the GametypeInfo about the stop of the start countdown.
251    */
252    void GametypeInfo::stopStartCountdown(void)
253    {
254        if(GameMode::isMaster())
255        {
256            if(!this->bStartCountdownRunning_)
257                return;
258
259            this->bStartCountdownRunning_ = false;
260            this->changedStartCountdownRunning();
261        }
262    }
263
264    /**
265    @brief
266        Inform the GametypeInfo about a player that is ready to spawn.
267    @param player
268        The player that is ready to spawn.
269    */
270    void GametypeInfo::playerReadyToSpawn(PlayerInfo* player)
271    {
272        if(GameMode::isMaster())
273        {
274            // If the player has spawned already.
275            if(this->spawnedPlayers_.find(player) != this->spawnedPlayers_.end())
276                return;
277
278            this->spawnedPlayers_.insert(player);
279            this->setReadyToSpawnHelper(player, true);
280        }
281    }
282
283    /**
284    @brief
285        Inform the GametypeInfo about a player whose Pawn has been killed.
286    @param player
287        The player whose Pawn has been killed.
288    */
289    void GametypeInfo::pawnKilled(PlayerInfo* player)
290    {
291        if(GameMode::isMaster())
292        {
293            NotificationListener::sendNotification("Press [Fire] to respawn", GametypeInfo::NOTIFICATION_SENDER, notificationMessageType::info, notificationSendMode::network, player->getClientID());
294            // Remove the player from the list of players that have spawned, since it currently is not.
295            this->spawnedPlayers_.erase(player);
296            this->setReadyToSpawnHelper(player, false);
297            this->setSpawnedHelper(player, false);
298        }
299    }
300
301    /**
302    @brief
303        Inform the GametypeInfo about a player that has spawned.
304    @param player
305        The player that has spawned.
306    */
307    void GametypeInfo::playerSpawned(PlayerInfo* player)
308    {
309        if(GameMode::isMaster())
310        {
311            if(this->hasStarted() && !this->hasEnded())
312
313                this->setSpawnedHelper(player, true);
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) const
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) const
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) const
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) const
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) const
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) const
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) const
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) const
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) const
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) const
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) const
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.