Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Position/velocity setting works now, relative script paths not, added test script

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