Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/SOBv2_HS17/src/modules/docking/Dock.cc @ 11459

Last change on this file since 11459 was 11071, checked in by landauf, 9 years ago

merged branch cpp11_v3 back to trunk

  • Property svn:eol-style set to native
File size: 10.2 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 *      Sven Stucki
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file Dock.cc
31    @brief Docking system main class
32*/
33
34#include "Dock.h"
35
36#include "core/CoreIncludes.h"
37#include "core/LuaState.h"
38#include "core/GUIManager.h"
39#include "core/command/ConsoleCommandIncludes.h"
40#include "network/NetworkFunctionIncludes.h"
41
42#include "infos/HumanPlayer.h"
43#include "interfaces/PlayerTrigger.h"
44#include "worldentities/pawns/Pawn.h"
45
46namespace orxonox
47{
48    RegisterClass(Dock);
49
50    SetConsoleCommand("Dock", "dock",    &Dock::cmdDock).addShortcut().setAsInputCommand();
51    SetConsoleCommand("Dock", "undock",  &Dock::cmdUndock).addShortcut().setAsInputCommand();
52
53    registerStaticNetworkFunction(Dock::showDockingDialog);
54
55    Dock::Dock(Context* context) : StaticEntity(context)
56    {
57        RegisterObject(Dock);
58    }
59
60    Dock::~Dock()
61    {
62    }
63
64    void Dock::XMLPort(Element& xmlelement, XMLPort::Mode mode)
65    {
66        SUPER(Dock, XMLPort, xmlelement, mode);
67
68        XMLPortObject(Dock, DockingEffect, "effects", addEffect, getEffect, xmlelement, mode);
69        XMLPortObject(Dock, DockingAnimation, "animations", addAnimation, getAnimation, xmlelement, mode);
70        XMLPortEventSink(Dock, BaseObject, "execute", execute, xmlelement, mode);
71        XMLPortEventSink(Dock, BaseObject, "undocking", undocking, xmlelement, mode);
72
73    }
74
75    void Dock::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
76    {
77        SUPER(Dock, XMLEventPort, xmlelement, mode);
78
79        XMLPortEventSink(Dock, BaseObject, "execute", execute, xmlelement, mode);
80
81        XMLPortEventSink(Dock, BaseObject, "undocking", undocking, xmlelement, mode);
82    }
83
84
85    bool Dock::undocking(bool bTriggered, BaseObject* trigger)
86    {
87
88        PlayerTrigger* pTrigger = orxonox_cast<PlayerTrigger*>(trigger);
89        PlayerInfo* player = nullptr;
90
91        // Check whether it is a player trigger and extract pawn from it
92        if(pTrigger != nullptr)
93        {
94            if(!pTrigger->isForPlayer()) {  // The PlayerTrigger is not exclusively for Pawns which means we cannot extract one.
95            orxout(verbose, context::docking) << "Docking:execute PlayerTrigger was not triggered by a player.." << endl;
96            return false;
97            }
98            player = pTrigger->getTriggeringPlayer();
99        }
100        else
101        {
102            orxout(verbose, context::docking) << "Docking::execute Not a player trigger, can't extract pawn from it.." << endl;
103            return false;
104        }
105        if(player == nullptr)
106        {
107            orxout(verbose, context::docking) << "Docking::execute Can't retrieve PlayerInfo from Trigger. (" << trigger->getIdentifier()->getName() << ")" << endl;
108            return false;
109        }
110
111        if(bTriggered)
112        {
113            // Add player to this Docks candidates
114            candidates_.insert(player);
115
116            // Show docking dialog
117            this->showUndockingDialogHelper(player);
118        }
119        else
120        {
121            // Remove player from candidates list
122            candidates_.erase(player);
123        }
124
125        return true;
126    }
127
128
129
130    bool Dock::execute(bool bTriggered, BaseObject* trigger)
131    {
132        PlayerTrigger* pTrigger = orxonox_cast<PlayerTrigger*>(trigger);
133        PlayerInfo* player = nullptr;
134
135        // Check whether it is a player trigger and extract pawn from it
136        if(pTrigger != nullptr)
137        {
138            if(!pTrigger->isForPlayer()) {  // The PlayerTrigger is not exclusively for Pawns which means we cannot extract one.
139                orxout(verbose, context::docking) << "Docking:execute PlayerTrigger was not triggered by a player.." << endl;
140                return false;
141            }
142            player = pTrigger->getTriggeringPlayer();
143        }
144        else
145        {
146            orxout(verbose, context::docking) << "Docking::execute Not a player trigger, can't extract pawn from it.." << endl;
147            return false;
148        }
149        if(player == nullptr)
150        {
151            orxout(verbose, context::docking) << "Docking::execute Can't retrieve PlayerInfo from Trigger. (" << trigger->getIdentifier()->getName() << ")" << endl;
152            return false;
153        }
154
155        if(bTriggered)
156        {
157            // Add player to this Docks candidates
158            candidates_.insert(player);
159
160            // Show docking dialog
161            this->showDockingDialogHelper(player);
162        }
163        else
164        {
165            // Remove player from candidates list
166            candidates_.erase(player);
167        }
168
169        return true;
170    }
171
172
173    void Dock::showUndockingDialogHelper(PlayerInfo* player)
174        {
175            assert(player);
176
177            if(!player->isHumanPlayer())
178                return;
179
180            if(GameMode::isMaster())
181            {
182                if(GameMode::showsGraphics())
183                    GUIManager::showGUI("UndockingDialog");
184            }
185            else
186                callStaticNetworkFunction(&Dock::showDockingDialog, player->getClientID());
187
188        }
189
190    void Dock::showDockingDialogHelper(PlayerInfo* player)
191    {
192        assert(player);
193       
194        if(!player->isHumanPlayer())
195            return;
196       
197        if(GameMode::isMaster())
198        {
199            if(GameMode::showsGraphics())
200                GUIManager::showGUI("DockingDialog");
201        }
202        else
203            callStaticNetworkFunction(&Dock::showDockingDialog, player->getClientID());
204
205    }
206
207    /*static*/ void Dock::showDockingDialog()
208    {
209        if(GameMode::showsGraphics())
210            GUIManager::showGUI("DockingDialog");
211    }
212
213    void Dock::cmdDock()
214    {
215        PlayerInfo* player = HumanController::getLocalControllerSingleton()->getPlayer();
216        for(Dock* dock : ObjectList<Dock>())
217        {
218            if(dock->dock(player))
219                break;
220        }
221    }
222
223    void Dock::cmdUndock()
224    {
225        PlayerInfo* player = HumanController::getLocalControllerSingleton()->getPlayer();
226        for(Dock* dock : ObjectList<Dock>())
227        {
228            if(dock->undock(player))
229                break;
230        }
231    }
232
233    bool Dock::dock(PlayerInfo* player)
234    {
235        // Check if player is a candidate
236        if(candidates_.find(player) == candidates_.end())
237        {
238            orxout(internal_warning, context::docking) << "Dock::dock Player is not a candidate!" << endl;
239            return false;
240        }
241
242        candidates_.erase(player);
243        docked_.insert(player);
244
245        if (animations_.empty())
246            return dockingAnimationFinished(player);
247
248        else
249            DockingAnimation::invokeAnimation(true, player, animations_);
250
251        return true;
252    }
253
254    bool Dock::dockingAnimationFinished(PlayerInfo* player)
255    {
256        if(docked_.find(player) == docked_.end())
257        {
258            orxout(internal_warning, context::docking) << "Dock::dockingAnimationFinished Player is not currently docked." << endl;
259            return false;
260        }
261
262        DockingEffect::invokeEffect(true, player, effects_);
263        return true;
264    }
265
266    bool Dock::undock(PlayerInfo* player)
267    {
268        // Check if player is docked to this Dock
269        if(docked_.find(player) == docked_.end())
270        {
271            orxout(internal_warning, context::docking) << "Dock::undock Player is not docked to this Dock." << endl;
272            return false;
273        }
274
275        docked_.erase(player);
276        candidates_.insert(player);
277
278        DockingEffect::invokeEffect(false, player, effects_);
279
280        if (animations_.empty())
281            return undockingAnimationFinished(player);
282        else
283            DockingAnimation::invokeAnimation(false, player, animations_);
284
285        return true;
286    }
287
288    bool Dock::undockingAnimationFinished(PlayerInfo* player) {
289        orxout(verbose, context::docking) << "Dock::undockingAnimationFinished executed" << endl;
290        return true;
291    }
292
293    unsigned int Dock::getNumberOfActiveDocks()
294    {
295        int i = 0;
296        PlayerInfo* player = HumanController::getLocalControllerSingleton()->getPlayer();
297        for(Dock* dock : ObjectList<Dock>())
298        {
299            if(dock->candidates_.find(player) != dock->candidates_.end())
300                i++;
301        }
302        return i;
303    }
304
305    Dock* Dock::getActiveDockAtIndex(unsigned int index)
306    {
307        PlayerInfo* player = HumanController::getLocalControllerSingleton()->getPlayer();
308        for(Dock* dock : ObjectList<Dock>())
309        {
310            if(dock->candidates_.find(player) != dock->candidates_.end())
311            {
312                if(index == 0)
313                    return dock;
314                index--;
315            }
316        }
317        return nullptr;
318    }
319
320    bool Dock::addEffect(DockingEffect* effect)
321    {
322        assert(effect);
323        effects_.push_back(effect);
324        return true;
325    }
326
327    const DockingEffect* Dock::getEffect(unsigned int i) const
328    {
329        for (DockingEffect* effect : this->effects_)
330        {
331            if(i == 0)
332               return effect;
333            i--;
334        }
335        return nullptr;
336    }
337
338    bool Dock::addAnimation(DockingAnimation* animation)
339    {
340        assert(animation);
341        animation->setParent(this);
342        animations_.push_back(animation);
343        return true;
344    }
345
346    const DockingAnimation* Dock::getAnimation(unsigned int i) const
347    {
348        for (DockingAnimation* animation : this->animations_)
349        {
350            if(i == 0)
351               return animation;
352            i--;
353        }
354        return nullptr;
355    }
356}
Note: See TracBrowser for help on using the repository browser.