Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation3/src/modules/questsystem/Quest.cc @ 6943

Last change on this file since 6943 was 6940, checked in by dafrick, 15 years ago

Resolved issue with the Questsystem causing a segfault when a level with Quests was loaded twice. The issue still persists, but not with the Questsystem anymore and it will be addressed with my next commit.
Also removed restrictions to the number of characters a quest/hint identifier must have.

  • Property svn:eol-style set to native
File size: 13.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 *      Damian 'Mozork' Frick
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file
31    @brief Implementation of the Quest class.
32*/
33
34#include "Quest.h"
35
36#include "core/CoreIncludes.h"
37#include "core/XMLPort.h"
38#include "QuestManager.h"
39#include "QuestDescription.h"
40#include "QuestHint.h"
41#include "QuestEffect.h"
42#include "QuestListener.h"
43
44namespace orxonox
45{
46    /**
47    @brief
48        Constructor. Registers and initializes object.
49    */
50    Quest::Quest(BaseObject* creator) : QuestItem(creator)
51    {
52        RegisterObject(Quest);
53
54        this->parentQuest_ = NULL;
55    }
56
57    /**
58    @brief
59        Destructor.
60    */
61    Quest::~Quest()
62    {
63        if(this->isRegistered())
64            QuestManager::getInstance().unregisterQuest(this);
65    }
66
67    /**
68    @brief
69        Method for creating a Quest object through XML.
70    */
71    void Quest::XMLPort(Element& xmlelement, XMLPort::Mode mode)
72    {
73        SUPER(Quest, XMLPort, xmlelement, mode);
74
75        XMLPortObject(Quest, Quest, "subquests", addSubQuest, getSubQuest, xmlelement, mode);
76        XMLPortObject(Quest, QuestHint, "hints", addHint, getHint, xmlelement, mode);
77        XMLPortObject(Quest, QuestEffect, "fail-effects", addFailEffect, getFailEffect, xmlelement, mode);
78        XMLPortObject(Quest, QuestEffect, "complete-effects", addCompleteEffect, getCompleteEffect, xmlelement, mode);
79
80        QuestManager::getInstance().registerQuest(this); //!<Registers the Quest with the QuestManager.
81    }
82
83    /**
84    @brief
85        Sets the parentquest of the Quest.
86    @param quest
87        A pointer to the Quest to be set as parentquest.
88    @return
89        Returns true if the parentquest could be set.
90    */
91    bool Quest::setParentQuest(Quest* quest)
92    {
93        if(quest == NULL) //!< We don't want to set NULL-Pointers.
94        {
95            COUT(2) << "The parentquest to be added to quest {" << this->getId() << "} was NULL." << std::endl;
96            return false;
97        }
98
99        this->parentQuest_ = quest;
100
101        COUT(3) << "Parent Quest {" << quest->getId() << "} was added to Quest {" << this->getId() << "}." << std::endl;
102        return true;
103    }
104
105    /**
106    @brief
107        Adds a subquest to the Quest.
108    @param quest
109        A pointer to the Quest to be set as subquest.
110    @return
111        Returns true if the subquest could be set.
112    */
113    bool Quest::addSubQuest(Quest* quest)
114    {
115        if(quest == NULL) //!< We don't want to set NULL-Pointers.
116        {
117            COUT(2) << "The subquest to be added to quest {" << this->getId() << "} was NULL." << std::endl;
118            return false;
119        }
120
121        quest->setParentQuest(this); //!< Sets the currentQuest (this) as parentquest for the added subquest.
122        this->subQuests_.push_back(quest); //!< Adds the Quest to the end of the list of subquests.
123
124        COUT(3) << "Sub Quest {" << quest->getId() << "} was added to Quest {" << this->getId() << "}." << std::endl;
125        return true;
126    }
127
128
129    /**
130    @brief
131        Adds a QuestHint to the list of QuestHints
132    @param hint
133        The QuestHint that should be added to the list of QuestHints.
134    @return
135        Returns true if the hint was successfully added.
136    */
137    bool Quest::addHint(QuestHint* hint)
138    {
139        if(hint == NULL) //!< We don't want to set NULL-Pointers. Seriously!
140        {
141            COUT(2) << "A NULL-QuestHint was trying to be added." << std::endl;
142            return false;
143        }
144
145        hint->setQuest(this); //!< Sets the current Quest (this) as Quest for the added QuestHint.
146        this->hints_.push_back(hint); //!< Adds the QuestHint to the end of the list of QuestHints.
147
148        COUT(3) << "QuestHint {" << hint->getId() << "} was added to Quest {" << this->getId() << "}." << std::endl;
149        return true;
150    }
151
152    /**
153    @brief
154        Adds an QuestEffect to the list of fail QuestEffects.
155    @param effect
156        The QuestEffect to be added.
157    @return
158        Returns true if successful.
159    */
160    bool Quest::addFailEffect(QuestEffect* effect)
161    {
162        if(effect == NULL) //!< We don't want to set NULL-Pointers.
163        {
164            COUT(2) << "A NULL-QuestEffect was trying to be added" << std::endl;
165            return false;
166        }
167
168        this->failEffects_.push_back(effect); //!< Adds the QuestEffect to the end of the list of fail QuestEffects.
169
170        COUT(3) << "A FailEffect was added to Quest {" << this->getId() << "}." << std::endl;
171        return true;
172    }
173
174    /**
175    @brief
176        Adds an QuestEffect to the list of complete QuestEffects.
177    @param effect
178        The QuestEffect to be added.
179    @return
180        Returns true if successful.
181    */
182    bool Quest::addCompleteEffect(QuestEffect* effect)
183    {
184        if(effect == NULL) //!< We don't want to set NULL-Pointers.
185        {
186            COUT(2) << "A NULL-QuestEffect was trying to be added" << std::endl;
187            return false;
188        }
189
190        this->completeEffects_.push_back(effect); //!< Adds the QuestEffect to the end of the list of complete QuestEffects.
191
192        COUT(3) << "A CompleteEffect was added to Quest {" << this->getId() << "}." << std::endl;
193        return true;
194    }
195
196    /**
197    @brief
198        Returns the subquest at the given index.
199    @param
200        The index.
201    @return
202        Returns a pointer to the subquest at the given index. NULL if there is no element at the given index.
203    */
204    const Quest* Quest::getSubQuest(unsigned int index) const
205    {
206        int i = index;
207
208        //! Iterate through all subquests.
209        for (std::list<Quest*>::const_iterator subQuest = this->subQuests_.begin(); subQuest != this->subQuests_.end(); ++subQuest)
210        {
211            if(i == 0) //!< We're counting down...
212            {
213               return *subQuest;
214            }
215            i--;
216        }
217
218        return NULL; //!< If the index is greater than the number of elements in the list.
219    }
220
221    /**
222    @brief
223        Returns the QuestHint at the given index.
224    @param
225        The index.
226    @return
227        Returns a pointer to the QuestHint at the given index. NULL if there is no element at the given index.
228    */
229    const QuestHint* Quest::getHint(unsigned int index) const
230    {
231        int i = index;
232
233        //! Iterate through all QuestHints.
234        for (std::list<QuestHint*>::const_iterator hint = this->hints_.begin(); hint != this->hints_.end(); ++hint)
235        {
236            if(i == 0) //!< We're counting down...
237            {
238               return *hint;
239            }
240            i--;
241        }
242        return NULL; //!< If the index is greater than the number of elements in the list.
243    }
244
245    /**
246    @brief
247        Returns the fail QuestEffect at the given index.
248    @param
249        The index.
250    @return
251        Returns a pointer to the fail QuestEffect at the given index. NULL if there is no element at the given index.
252    */
253    const QuestEffect* Quest::getFailEffect(unsigned int index) const
254    {
255        int i = index;
256
257        //! Iterate through all fail QuestEffects.
258        for (std::list<QuestEffect*>::const_iterator effect = this->failEffects_.begin(); effect != this->failEffects_.end(); ++effect)
259        {
260            if(i == 0) //!< We're counting down...
261            {
262               return *effect;
263            }
264            i--;
265        }
266        return NULL; //!< If the index is greater than the number of elements in the list.
267    }
268
269    /**
270    @brief
271        Returns the complete QuestEffect at the given index.
272    @param
273        The index.
274    @return
275        Returns a pointer to the complete QuestEffect at the given index. NULL if there is no element at the given index.
276    */
277    const QuestEffect* Quest::getCompleteEffect(unsigned int index) const
278    {
279        int i = index;
280
281        //! Iterate through all complete QuestEffects.
282        for (std::list<QuestEffect*>::const_iterator effect = this->completeEffects_.begin(); effect != this->completeEffects_.end(); ++effect)
283        {
284            if(i == 0) //!< We're counting down...
285            {
286               return *effect;
287            }
288            i--;
289        }
290        return NULL; //!< If the index is greater than the number of elements in the list.
291    }
292
293    /**
294    @brief
295        Returns true if the quest status for the specific player is 'inactive'.
296    @param player
297        The player.
298    @return
299        Returns true if the quest status for the specific player is 'inactive'.
300    @throws
301        Throws an exception if getStatus throws one.
302    */
303    bool Quest::isInactive(const PlayerInfo* player) const
304    {
305        return this->getStatus(player) == QuestStatus::Inactive;
306    }
307
308    /**
309    @brief
310        Returns true if the quest status for the specific player is 'active'.
311    @param player
312        The player.
313    @return
314        Returns true if the quest status for the specific player is 'active'.
315    @throws
316        Throws an exception if getStatus throws one.
317    */
318    bool Quest::isActive(const PlayerInfo* player) const
319    {
320
321        return this->getStatus(player) == QuestStatus::Active;
322    }
323
324    /**
325    @brief
326        Returns true if the quest status for the specific player is 'failed'.
327    @param player
328        The player.
329    @return
330        Returns true if the quest status for the specific player is 'failed'.
331    @throws
332        Throws an exception if getStatus throws one.
333    */
334    bool Quest::isFailed(const PlayerInfo* player) const
335    {
336        return this->getStatus(player) == QuestStatus::Failed;
337    }
338
339    /**
340    @brief
341        Returns true if the quest status for the specific player is 'completed'.
342    @param player
343        The player.
344    @return
345        Returns true if the quest status for the specific player is 'completed'.
346    @throws
347        Throws an exception if getStatus throws one.
348    */
349    bool Quest::isCompleted(const PlayerInfo* player) const
350    {
351        return this->getStatus(player) == QuestStatus::Completed;
352    }
353
354    /**
355    @brief
356        Fails the Quest for an input player.
357    @param player
358        The player.
359    @return
360        Returns true if the Quest could be failed, false if not.
361    */
362    bool Quest::fail(PlayerInfo* player)
363    {
364        QuestListener::advertiseStatusChange(this->listeners_, "fail"); //!< Tells the QuestListeners, that the status has changed to failed.
365        this->setStatus(player, QuestStatus::Failed);
366
367        COUT(4) << "Quest {" << this->getId() << "} is failed for player: " << player << " ." <<std::endl;
368
369        this->getDescription()->sendFailQuestNotification();
370        return true;
371    }
372
373    /**
374    @brief
375        Completes the Quest for an input player.
376    @param player
377        The player.
378    @return
379        Returns true if the Quest could be completed, false if not.
380    */
381    bool Quest::complete(PlayerInfo* player)
382    {
383        QuestListener::advertiseStatusChange(this->listeners_, "complete"); //!< Tells the QuestListeners, that the status has changed to completed.
384        this->setStatus(player, QuestStatus::Completed);
385
386        COUT(4) << "Quest {" << this->getId() << "} is completed for player: " << player << " ." <<std::endl;
387
388        this->getDescription()->sendCompleteQuestNotification();
389        return true;
390    }
391
392    /**
393    @brief
394        Starts the Quest for an input player.
395    @param player
396        The player.
397    @return
398        Returns true if the Quest could be started, false if not.
399    */
400    bool Quest::start(PlayerInfo* player)
401    {
402        if(!this->isStartable(player)) //!< Checks whether the quest can be started.
403        {
404            COUT(4) << "A non-startable quest was trying to be started." << std::endl;
405            return false;
406        }
407
408        COUT(4) << "Quest {" << this->getId() << "} is started for player: " << player << " ." <<std::endl;
409
410        QuestListener::advertiseStatusChange(this->listeners_, "start"); //!< Tells the QuestListeners, that the status has changed to active.
411
412        this->setStatus(player, QuestStatus::Active);
413
414        this->getDescription()->sendAddQuestNotification();
415        return true;
416    }
417
418    /**
419    @brief
420        Adds a QuestListener to the list of QuestListeners listening to this Quest.
421    @param listener
422        The QuestListener to be added.
423    @return
424        Returns true if successful, false if not.
425    */
426    bool Quest::addListener(QuestListener* listener)
427    {
428        if(listener == NULL)
429        {
430            COUT(2) << "A NULL-QuestListener was trying to be added to a Quests listeners." << std::endl;
431            return false;
432        }
433
434        this->listeners_.push_back(listener);
435        return true;
436    }
437
438}
Note: See TracBrowser for help on using the repository browser.