Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/modules/docking/Dock.cc @ 8667

Last change on this file since 8667 was 8667, checked in by dafrick, 13 years ago

Possible fix for segfaults due to player being NULL.

  • Property svn:eol-style set to native
File size: 7.8 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 "infos/HumanPlayer.h"
40#include "worldentities/pawns/Pawn.h"
41#include "interfaces/PlayerTrigger.h"
42#include "core/command/ConsoleCommand.h"
43
44#include "ToluaBindDocking.h"
45
46namespace orxonox
47{
48    // Register tolua_open function when loading the library
49    DeclareToluaInterface(Docking);
50
51    CreateFactory(Dock);
52
53    SetConsoleCommand("Dock", "dock",    &Dock::cmdDock).addShortcut().setAsInputCommand();
54    SetConsoleCommand("Dock", "undock",  &Dock::cmdUndock).addShortcut().setAsInputCommand();
55
56    Dock::Dock(BaseObject* creator) : StaticEntity(creator)
57    {
58        RegisterObject(Dock);
59    }
60
61    Dock::~Dock()
62    {
63    }
64
65
66    void Dock::XMLPort(Element& xmlelement, XMLPort::Mode mode)
67    {
68        SUPER(Dock, XMLPort, xmlelement, mode);
69
70        XMLPortObject(Dock, DockingEffect, "effects", addEffect, getEffect, xmlelement, mode);
71        XMLPortObject(Dock, DockingAnimation, "animations", addAnimation, getAnimation, xmlelement, mode);
72        XMLPortEventSink(Dock, BaseObject, "execute", execute, xmlelement, mode);
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
82
83    bool Dock::execute(bool bTriggered, BaseObject* trigger)
84    {
85        PlayerTrigger* pTrigger = orxonox_cast<PlayerTrigger*>(trigger);
86        PlayerInfo* player = NULL;
87
88        // Check whether it is a player trigger and extract pawn from it
89        if(pTrigger != NULL)
90        {
91            if(!pTrigger->isForPlayer()) {  // The PlayerTrigger is not exclusively for Pawns which means we cannot extract one.
92                COUT(4) << "Docking:execute PlayerTrigger was not triggered by a player.." << std::endl;
93                return false;
94            }
95            player = pTrigger->getTriggeringPlayer();
96        }
97        else
98        {
99            COUT(4) << "Docking::execute Not a player trigger, can't extract pawn from it.." << std::endl;
100            return false;
101        }
102        if(player == NULL)
103        {
104            COUT(4) << "Docking::execute Can't retrieve PlayerInfo from Trigger. (" << trigger->getIdentifier()->getName() << ")" << std::endl;
105            return false;
106        }
107
108        if(bTriggered)
109        {
110            // Add player to this Docks candidates
111            candidates.insert(player);
112
113            // Show docking dialog
114            GUIManager::showGUI("DockingDialog");
115        }
116        else
117        {
118            // Remove player from candidates list
119            candidates.erase(player);
120        }
121
122        return true;
123    }
124
125
126    void Dock::cmdDock()
127    {
128        PlayerInfo* player = HumanController::getLocalControllerSingleton()->getPlayer();
129        for(ObjectList<Dock>::iterator it = ObjectList<Dock>::begin(); it != ObjectList<Dock>::end(); ++it)
130        {
131            if(it->dock(player))
132                break;
133        }
134    }
135
136    void Dock::cmdUndock()
137    {
138        PlayerInfo* player = HumanController::getLocalControllerSingleton()->getPlayer();
139        for(ObjectList<Dock>::iterator it = ObjectList<Dock>::begin(); it != ObjectList<Dock>::end(); ++it)
140        {
141            if(it->undock(player))
142                break;
143        }
144    }
145
146
147    bool Dock::dock(PlayerInfo* player)
148    {
149        // Check if player is a candidate
150        if(candidates.find(player) == candidates.end())
151        {
152            COUT(2) << "Dock::dock Player is not a candidate!" << std::endl;
153            return false;
154        }
155
156        candidates.erase(player);
157        docked.insert(player);
158
159        if (animations.empty())
160            return dockingAnimationFinished(player);
161        else
162            DockingAnimation::invokeAnimation(true, player, animations);
163
164        return true;
165    }
166
167    bool Dock::dockingAnimationFinished(PlayerInfo* player)
168    {
169        if(docked.find(player) == docked.end())
170        {
171            COUT(2) << "Dock::dockingAnimationFinished Player is not currently docked." << std::endl;
172            return false;
173        }
174
175        DockingEffect::invokeEffect(true, player, effects);
176        return true;
177    }
178
179    bool Dock::undock(PlayerInfo* player)
180    {
181        // Check if player is docked to this Dock
182        if(docked.find(player) == docked.end())
183        {
184            COUT(2) << "Dock::undock Player is not docked to this Dock." << std::endl;
185            return false;
186        }
187
188        docked.erase(player);
189        candidates.insert(player);
190
191        DockingEffect::invokeEffect(false, player, effects);
192
193        if (animations.empty())
194            return undockingAnimationFinished(player);
195        else
196            DockingAnimation::invokeAnimation(false, player, animations);
197
198        return true;
199    }
200
201    bool Dock::undockingAnimationFinished(PlayerInfo* player) {
202        COUT(4) << "Dock::undockingAnimationFinished executed" << std::endl;
203        return true;
204    }
205
206
207    unsigned int Dock::getNumberOfActiveDocks()
208    {
209        int i = 0;
210        PlayerInfo* player = HumanController::getLocalControllerSingleton()->getPlayer();
211        for(ObjectList<Dock>::iterator it = ObjectList<Dock>::begin(); it != ObjectList<Dock>::end(); ++it)
212        {
213            if(it->candidates.find(player) != it->candidates.end())
214                i++;
215        }
216        return i;
217    }
218
219    Dock* Dock::getActiveDockAtIndex(unsigned int index)
220    {
221        PlayerInfo* player = HumanController::getLocalControllerSingleton()->getPlayer();
222        for(ObjectList<Dock>::iterator it = ObjectList<Dock>::begin(); it != ObjectList<Dock>::end(); ++it)
223        {
224            if(it->candidates.find(player) != it->candidates.end())
225            {
226                if(index == 0)
227                    return *it;
228                index--;
229            }
230        }
231        return NULL;
232    }
233
234
235    bool Dock::addEffect(DockingEffect* effect)
236    {
237        assert(effect);
238        effects.push_back(effect);
239        return true;
240    }
241
242    const DockingEffect* Dock::getEffect(unsigned int i) const
243    {
244        for (std::list<DockingEffect*>::const_iterator effect = this->effects.begin(); effect != this->effects.end(); ++effect)
245        {
246            if(i == 0)
247               return *effect;
248            i--;
249        }
250        return NULL;
251    }
252
253    bool Dock::addAnimation(DockingAnimation* animation)
254    {
255        assert(animation);
256        animation->setParent(this);
257        animations.push_back(animation);
258        return true;
259    }
260
261    const DockingAnimation* Dock::getAnimation(unsigned int i) const
262    {
263        for (std::list<DockingAnimation*>::const_iterator animation = this->animations.begin(); animation != this->animations.end(); ++animation)
264        {
265            if(i == 0)
266               return *animation;
267            i--;
268        }
269        return NULL;
270    }
271}
272
Note: See TracBrowser for help on using the repository browser.