Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/resource/src/orxonox/objects/quest/QuestManager.cc @ 3366

Last change on this file since 3366 was 3366, checked in by rgrieder, 15 years ago

Derived all singletons implemented in a usual manner from orxonox::Singleton<T>.
This resolves inconsistencies with the singletonPtr_s variable in case of exceptions (asserts were being triggered then).
And while at it replaced singletonRef_s with singletonPtr_s for it to be less misleading (as fabian has already pointed out).

  • Property svn:eol-style set to native
File size: 10.6 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 *      Damian 'Mozork' Frick
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file
31    @brief Implementation of the QuestManager class.
32*/
33
34#include "QuestManager.h"
35
36#include "util/Exception.h"
37#include "core/CoreIncludes.h"
38
39#include "objects/infos/PlayerInfo.h"
40#include "objects/infos/PlayerInfo.h"
41#include "overlays/GUIOverlay.h"
42#include "Quest.h"
43#include "QuestHint.h"
44#include "QuestItem.h"
45
46namespace orxonox
47{
48    //! Pointer to the current (and single) instance of this class.
49    /*static*/ QuestManager* QuestManager::singletonPtr_s = NULL;
50
51    /**
52    @brief
53        Constructor. Registers the object.
54    @todo
55        Is inheriting from BaseObject proper?
56    */
57    QuestManager::QuestManager()
58    {
59        RegisterRootObject(QuestManager);
60    }
61
62    /**
63    @brief
64        Destructor.
65    */
66    QuestManager::~QuestManager()
67    {
68
69    }
70
71    /**
72    @brief
73        Registers a Quest with the QuestManager to make it globally accessable.
74        Uses it's id to make sure to be able to be identify and retrieve it later.
75    @param quest
76        The Quest that is to be registered.
77    @return
78        Returns true if successful, false if not.
79    */
80    bool QuestManager::registerQuest(Quest* quest)
81    {
82        if(quest == NULL) //!< Doh! Just as if there were actual quests behind NULL-pointers.
83        {
84            COUT(2) << "Registration of Quest in QuestManager failed, because inserted Quest-pointer was NULL." << std::endl;
85            return false;
86        }
87
88        std::pair<std::map<std::string, Quest*>::iterator,bool> result;
89        result = this->questMap_.insert( std::pair<std::string,Quest*>(quest->getId(),quest) ); //!< Inserting the Quest.
90
91        if(result.second) //!< If inserting was a success.
92        {
93            COUT(3) << "Quest with questId {" << quest->getId() << "} successfully inserted." << std::endl;
94            return true;
95        }
96        else
97        {
98           COUT(2) << "Quest with the same id was already present." << std::endl;
99           return false;
100        }
101    }
102
103    /**
104    @brief
105        Registers a QuestHint with the QuestManager to make it globally accessable.
106        Uses it's id to make sure to be able to be identify and retrieve it later.
107    @param hint
108        The QuestHint to be registered.
109    @return
110        Returns true if successful, false if not.
111    */
112    bool QuestManager::registerHint(QuestHint* hint)
113    {
114        if(hint == NULL) //!< Still not liking NULL-pointers.
115        {
116            COUT(2) << "Registration of QuestHint in QuestManager failed, because inserted QuestHint-pointer was NULL." << std::endl;
117            return false;
118        }
119
120        std::pair<std::map<std::string, QuestHint*>::iterator,bool> result;
121        result = this->hintMap_.insert ( std::pair<std::string,QuestHint*>(hint->getId(),hint) ); //!< Inserting the QuestHSint.
122
123        if(result.second) //!< If inserting was a success.
124        {
125            COUT(3) << "QuestHint with hintId {" << hint->getId() << "} successfully inserted." << std::endl;
126            return true;
127        }
128        else
129        {
130           COUT(2) << "QuestHint with the same id was already present." << std::endl;
131           return false;
132        }
133    }
134
135    /**
136    @brief
137        Finds a Quest with the given id.
138    @param questId
139        The id of the Quest sought for.
140    @return
141        Returns a pointer to the Quest with the input id.
142        Returns NULL if there is no Quest with the given questId.
143    @throws
144        Throws an exception if the given questId is invalid.
145    */
146    Quest* QuestManager::findQuest(const std::string & questId)
147    {
148        if(!QuestItem::isId(questId)) //!< Check vor validity of the given id.
149        {
150            ThrowException(Argument, "Invalid questId.");
151        }
152
153        Quest* quest;
154        std::map<std::string, Quest*>::iterator it = this->questMap_.find(questId);
155        if (it != this->questMap_.end()) //!< If the Quest is registered.
156        {
157            quest = it->second;
158        }
159        else
160        {
161           quest = NULL;
162           COUT(2) << "The quest with id {" << questId << "} is nowhere to be found." << std::endl;
163        }
164
165        return quest;
166
167    }
168
169    /**
170    @brief
171        Finds a QuestHint with the given id.
172    @param hintId
173        The id of the QuestHint sought for.
174    @return
175        Returns a pointer to the QuestHint with the input id.
176        Returns NULL if there is no QuestHint with the given hintId.
177    @throws
178        Throws an exception if the given hintId is invalid.
179    */
180    QuestHint* QuestManager::findHint(const std::string & hintId)
181    {
182        if(!QuestItem::isId(hintId)) //!< Check vor validity of the given id.
183        {
184            ThrowException(Argument, "Invalid hintId.");
185        }
186
187        QuestHint* hint;
188        std::map<std::string, QuestHint*>::iterator it = this->hintMap_.find(hintId);
189        if (it != this->hintMap_.end()) //!< If the QuestHint is registered.
190        {
191            hint = it->second;
192        }
193        else
194        {
195           hint = NULL;
196           COUT(2) << "The hint with id {" << hintId << "} is nowhere to be found." << std::endl;
197        }
198
199        return hint;
200
201    }
202
203    /**
204    @brief
205       
206    @param name
207    @return
208    */
209    QuestContainer* QuestManager::getQuestTree(std::string & name)
210    {
211        GUIOverlay* gui = NULL;
212        for (ObjectList<GUIOverlay>::iterator it = ObjectList<GUIOverlay>::begin(); it != ObjectList<GUIOverlay>::end(); ++it)
213            if (it->getGUIName() == name)
214                gui = *it;
215
216        PlayerInfo* player;
217        if(gui == NULL)
218        {
219            COUT(1) << "Error: No GUIOverlay with the given name '" << name << "' present." << std::endl;
220            return NULL;
221        }
222        BaseObject* obj = gui->getOwner();
223        if(obj == NULL)
224        {
225            COUT(1) << "Error: GUIOverlay has no owner. " << std::endl;
226            return NULL;
227        }
228        player = orxonox_cast<PlayerInfo*>(obj);
229   
230        QuestContainer* root = NULL;
231        QuestContainer* current = NULL;
232       
233        std::list<Quest*>* rootQuests = new std::list<Quest*>();
234        getRootQuests(player, *rootQuests);
235       
236        for(std::list<Quest*>::iterator it = rootQuests->begin(); it != rootQuests->end(); it++)
237        {
238            QuestContainer* container = addSubQuest(*it, player);
239
240            if(root == NULL)
241            {
242                root = container;
243            }
244            else
245            {
246                current->next = container;
247            }
248           
249            current = container;
250
251        }
252        if(current != NULL)
253            current->next = NULL;
254
255        delete rootQuests;
256
257        return root;
258    }
259
260    /**
261    @brief
262       
263    @param player
264    @param list
265    @return
266    */
267    void QuestManager::getRootQuests(const PlayerInfo* player, std::list<Quest*> & list)
268    {
269        for(std::map<std::string, Quest*>::iterator it=this->questMap_.begin(); it!=this->questMap_.end(); it++)
270        {
271            Quest* quest = (*it).second;
272            if(quest->getParentQuest() == NULL && !quest->isInactive(player))
273            {
274                list.push_back(quest);
275            }
276        }
277    }
278
279    /**
280    @brief
281       
282    @param quest
283    @param player
284    @return
285    */
286    QuestContainer* QuestManager::addSubQuest(Quest* quest, const PlayerInfo* player)
287    {
288        if(quest == NULL)
289            return NULL;
290
291        QuestContainer* container = new QuestContainer;
292        container->description = quest->getDescription();
293        container->hint = addHints(quest, player);
294
295        if(quest->isActive(player))
296        {
297            container->status = "active";
298        }
299        else if(quest->isCompleted(player))
300        {
301            container->status = "completed";
302        }
303        else if(quest->isFailed(player))
304        {
305            container->status = "failed";
306        }
307        else
308        {
309            container->status = "";
310            COUT(1) << "An error occurred. A Quest of un-specified status wanted to be displayed." << std::endl;
311        }
312       
313        std::list<Quest*> quests = quest->getSubQuestList();
314        QuestContainer* current = NULL;
315        QuestContainer* first = NULL;
316        for(std::list<Quest*>::iterator it = quests.begin(); it != quests.end(); it++)
317        {
318            Quest* subQuest = *it;
319            if(!subQuest->isInactive(player))
320            {
321                QuestContainer* subContainer = addSubQuest(subQuest, player);
322
323                if(first == NULL)
324                {
325                    first = subContainer;
326                }
327                else
328                {
329                    current->next = subContainer;
330                }
331               
332                current = subContainer;
333            }
334        }
335        if(current != NULL)
336            current->next = NULL;
337        container->subQuests = first;
338       
339        return container;
340    }
341
342    /**
343    @brief
344       
345    @param quest
346    @param player
347    @return
348    */
349    HintContainer* QuestManager::addHints(Quest* quest, const PlayerInfo* player)
350    {
351        HintContainer* current = NULL;
352        HintContainer* first = NULL;
353
354        std::list<QuestHint*> hints = quest->getHintsList();
355        for(std::list<QuestHint*>::iterator it = hints.begin(); it != hints.end(); it++)
356        {
357            if((*it)->isActive(player))
358            {
359                HintContainer* hint = new HintContainer;
360                hint->description = (*it)->getDescription();
361
362                if(first == NULL)
363                {
364                    first = hint;
365                }
366                else
367                {
368                    current->next = hint;
369                }
370               
371                current = hint;
372            }
373        }
374
375        if(current != NULL)
376            current->next = NULL;
377        return first;
378    }
379
380
381}
Note: See TracBrowser for help on using the repository browser.