Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/SuperOrxoBros_HS18/src/orxonox/infos/GametypeInfo.cc @ 12177

Last change on this file since 12177 was 12177, checked in by siramesh, 5 years ago

Super Orxo Bros Final (Sidharth Ramesh, Nisa Balta, Jeff Ren)

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