Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ScriptableController_HS17/src/orxonox/infos/GametypeInfo.cc @ 11606

Last change on this file since 11606 was 11606, checked in by kohlia, 6 years ago

Pawn killing works too now

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