Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/Presentation_HS17/src/orxonox/infos/GametypeInfo.cc @ 11686

Last change on this file since 11686 was 11686, checked in by patricwi, 6 years ago

merged scriptable controller but not tested

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