Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7038 was 6945, checked in by dafrick, 15 years ago

A lot of cleanup, mostly increasing output levels, which means, that the console is no longer cluttered by lots and lots of Quest-stuff (the log file still is, but that should be ok…).
Also some possible bugs (or let's say pitfalls) removed, which have been around for a long time and didn't cause any problems so far. Now they never will.
Also, regarding my previous commit. Quests seem tu work just fine, even the second time the level is loaded, which is awesome.

Ergo: Questsystem/Notificationsystem segfault upon loading a level with Quests/Notifications in it twice is now officially resolved.

  • Property svn:eol-style set to native
File size: 13.2 KB
RevLine 
[1992]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 */
[6417]28
[2261]29/**
[3196]30    @file
[2662]31    @brief Implementation of the Quest class.
[2261]32*/
[1992]33
[2105]34#include "Quest.h"
35
[1992]36#include "core/CoreIncludes.h"
[3196]37#include "core/XMLPort.h"
[2068]38#include "QuestManager.h"
[2095]39#include "QuestDescription.h"
40#include "QuestHint.h"
41#include "QuestEffect.h"
[2662]42#include "QuestListener.h"
[1992]43
[2662]44namespace orxonox
45{
[2261]46    /**
47    @brief
48        Constructor. Registers and initializes object.
49    */
[2092]50    Quest::Quest(BaseObject* creator) : QuestItem(creator)
[2021]51    {
[2092]52        RegisterObject(Quest);
53
[2261]54        this->parentQuest_ = NULL;
[2021]55    }
[2092]56
[1992]57    /**
58    @brief
59        Destructor.
60    */
61    Quest::~Quest()
62    {
[6940]63        if(this->isRegistered())
64            QuestManager::getInstance().unregisterQuest(this);
[1992]65    }
[2092]66
[2261]67    /**
68    @brief
69        Method for creating a Quest object through XML.
70    */
[2076]71    void Quest::XMLPort(Element& xmlelement, XMLPort::Mode mode)
72    {
73        SUPER(Quest, XMLPort, xmlelement, mode);
[2092]74
[2261]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);
[2092]79
[2911]80        QuestManager::getInstance().registerQuest(this); //!<Registers the Quest with the QuestManager.
[2076]81    }
[2092]82
[1992]83    /**
84    @brief
[2261]85        Sets the parentquest of the Quest.
[1996]86    @param quest
[2261]87        A pointer to the Quest to be set as parentquest.
[2068]88    @return
[2261]89        Returns true if the parentquest could be set.
[1996]90    */
[2021]91    bool Quest::setParentQuest(Quest* quest)
[1996]92    {
[2261]93        if(quest == NULL) //!< We don't want to set NULL-Pointers.
[2068]94        {
95            COUT(2) << "The parentquest to be added to quest {" << this->getId() << "} was NULL." << std::endl;
96            return false;
97        }
[2092]98
[1996]99        this->parentQuest_ = quest;
[2092]100
[6945]101        COUT(4) << "Parent Quest {" << quest->getId() << "} was added to Quest {" << this->getId() << "}." << std::endl;
[1996]102        return true;
103    }
[2092]104
[1996]105    /**
106    @brief
[2261]107        Adds a subquest to the Quest.
[1996]108    @param quest
[2261]109        A pointer to the Quest to be set as subquest.
[2068]110    @return
[2261]111        Returns true if the subquest could be set.
[1996]112    */
[2021]113    bool Quest::addSubQuest(Quest* quest)
[1996]114    {
[2261]115        if(quest == NULL) //!< We don't want to set NULL-Pointers.
[2068]116        {
117            COUT(2) << "The subquest to be added to quest {" << this->getId() << "} was NULL." << std::endl;
118            return false;
119        }
[2092]120
[2261]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.
[2092]123
[6945]124        COUT(4) << "Sub Quest {" << quest->getId() << "} was added to Quest {" << this->getId() << "}." << std::endl;
[1996]125        return true;
126    }
[2092]127
128
[2068]129    /**
130    @brief
[2261]131        Adds a QuestHint to the list of QuestHints
[2076]132    @param hint
[2261]133        The QuestHint that should be added to the list of QuestHints.
[2076]134    @return
135        Returns true if the hint was successfully added.
136    */
137    bool Quest::addHint(QuestHint* hint)
138    {
[2261]139        if(hint == NULL) //!< We don't want to set NULL-Pointers. Seriously!
[2076]140        {
141            COUT(2) << "A NULL-QuestHint was trying to be added." << std::endl;
142            return false;
143        }
[2092]144
[2261]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.
[2092]147
[6945]148        COUT(4) << "QuestHint {" << hint->getId() << "} was added to Quest {" << this->getId() << "}." << std::endl;
[2093]149        return true;
[2076]150    }
[2092]151
[2076]152    /**
153    @brief
[2261]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.
[2076]159    */
160    bool Quest::addFailEffect(QuestEffect* effect)
161    {
[2261]162        if(effect == NULL) //!< We don't want to set NULL-Pointers.
[2076]163        {
164            COUT(2) << "A NULL-QuestEffect was trying to be added" << std::endl;
165            return false;
166        }
[2092]167
[2261]168        this->failEffects_.push_back(effect); //!< Adds the QuestEffect to the end of the list of fail QuestEffects.
[2092]169
[6945]170        COUT(4) << "A FailEffect was added to Quest {" << this->getId() << "}." << std::endl;
[2076]171        return true;
172    }
[2092]173
[2076]174    /**
175    @brief
[2261]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.
[2076]181    */
182    bool Quest::addCompleteEffect(QuestEffect* effect)
183    {
[2261]184        if(effect == NULL) //!< We don't want to set NULL-Pointers.
[2076]185        {
186            COUT(2) << "A NULL-QuestEffect was trying to be added" << std::endl;
187            return false;
188        }
[2092]189
[2261]190        this->completeEffects_.push_back(effect); //!< Adds the QuestEffect to the end of the list of complete QuestEffects.
[2092]191
[6945]192        COUT(4) << "A CompleteEffect was added to Quest {" << this->getId() << "}." << std::endl;
[2076]193        return true;
194    }
[2092]195
[2076]196    /**
197    @brief
[2261]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.
[2076]203    */
[2261]204    const Quest* Quest::getSubQuest(unsigned int index) const
[2076]205    {
206        int i = index;
[6417]207
[2261]208        //! Iterate through all subquests.
[2076]209        for (std::list<Quest*>::const_iterator subQuest = this->subQuests_.begin(); subQuest != this->subQuests_.end(); ++subQuest)
[2093]210        {
[2261]211            if(i == 0) //!< We're counting down...
[2093]212            {
213               return *subQuest;
214            }
215            i--;
216        }
[6417]217
[2261]218        return NULL; //!< If the index is greater than the number of elements in the list.
[2076]219    }
[2092]220
[2076]221    /**
222    @brief
[2261]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.
[2076]228    */
[2261]229    const QuestHint* Quest::getHint(unsigned int index) const
[2076]230    {
231        int i = index;
[6417]232
[2261]233        //! Iterate through all QuestHints.
[2076]234        for (std::list<QuestHint*>::const_iterator hint = this->hints_.begin(); hint != this->hints_.end(); ++hint)
[2093]235        {
[2261]236            if(i == 0) //!< We're counting down...
[2093]237            {
238               return *hint;
239            }
240            i--;
241        }
[2261]242        return NULL; //!< If the index is greater than the number of elements in the list.
[2076]243    }
[2092]244
[2076]245    /**
246    @brief
[2261]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.
[2076]252    */
[2261]253    const QuestEffect* Quest::getFailEffect(unsigned int index) const
[2076]254    {
255        int i = index;
[6417]256
[2261]257        //! Iterate through all fail QuestEffects.
[2076]258        for (std::list<QuestEffect*>::const_iterator effect = this->failEffects_.begin(); effect != this->failEffects_.end(); ++effect)
[2093]259        {
[2261]260            if(i == 0) //!< We're counting down...
[2093]261            {
262               return *effect;
263            }
264            i--;
265        }
[2261]266        return NULL; //!< If the index is greater than the number of elements in the list.
[2076]267    }
[2092]268
[2076]269    /**
270    @brief
[2261]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.
[2076]276    */
[2261]277    const QuestEffect* Quest::getCompleteEffect(unsigned int index) const
[2076]278    {
279        int i = index;
[6417]280
[2261]281        //! Iterate through all complete QuestEffects.
[2076]282        for (std::list<QuestEffect*>::const_iterator effect = this->completeEffects_.begin(); effect != this->completeEffects_.end(); ++effect)
[2093]283        {
[2261]284            if(i == 0) //!< We're counting down...
[2093]285            {
286               return *effect;
287            }
288            i--;
289        }
[2261]290        return NULL; //!< If the index is greater than the number of elements in the list.
[2076]291    }
[2092]292
[2076]293    /**
294    @brief
[2068]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    */
[2261]303    bool Quest::isInactive(const PlayerInfo* player) const
[2068]304    {
[3280]305        return this->getStatus(player) == QuestStatus::Inactive;
[2068]306    }
[2092]307
[2068]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    */
[2261]318    bool Quest::isActive(const PlayerInfo* player) const
[2068]319    {
[1996]320
[3280]321        return this->getStatus(player) == QuestStatus::Active;
[2068]322    }
[2092]323
[1996]324    /**
325    @brief
[2068]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    */
[2261]334    bool Quest::isFailed(const PlayerInfo* player) const
[2068]335    {
[3280]336        return this->getStatus(player) == QuestStatus::Failed;
[2068]337    }
[2092]338
[2068]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    */
[2261]349    bool Quest::isCompleted(const PlayerInfo* player) const
[2068]350    {
[3280]351        return this->getStatus(player) == QuestStatus::Completed;
[2068]352    }
[6417]353
[2662]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.
[3280]365        this->setStatus(player, QuestStatus::Failed);
[6417]366
[2662]367        COUT(4) << "Quest {" << this->getId() << "} is failed for player: " << player << " ." <<std::endl;
[6417]368
[2662]369        this->getDescription()->sendFailQuestNotification();
370        return true;
371    }
[6417]372
[2662]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.
[3280]384        this->setStatus(player, QuestStatus::Completed);
[6417]385
[2662]386        COUT(4) << "Quest {" << this->getId() << "} is completed for player: " << player << " ." <<std::endl;
[6417]387
[2662]388        this->getDescription()->sendCompleteQuestNotification();
389        return true;
390    }
[2092]391
[1992]392    /**
393    @brief
[2261]394        Starts the Quest for an input player.
[1992]395    @param player
396        The player.
[1996]397    @return
[2261]398        Returns true if the Quest could be started, false if not.
[1992]399    */
[2261]400    bool Quest::start(PlayerInfo* player)
[1992]401    {
[2662]402        if(!this->isStartable(player)) //!< Checks whether the quest can be started.
[1992]403        {
[2662]404            COUT(4) << "A non-startable quest was trying to be started." << std::endl;
405            return false;
[1992]406        }
[6417]407
[2662]408        COUT(4) << "Quest {" << this->getId() << "} is started for player: " << player << " ." <<std::endl;
[6417]409
[2662]410        QuestListener::advertiseStatusChange(this->listeners_, "start"); //!< Tells the QuestListeners, that the status has changed to active.
[6417]411
[3280]412        this->setStatus(player, QuestStatus::Active);
[6417]413
[2662]414        this->getDescription()->sendAddQuestNotification();
415        return true;
[1992]416    }
[6417]417
[2662]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        }
[6417]433
[2662]434        this->listeners_.push_back(listener);
435        return true;
436    }
[2092]437
[1992]438}
Note: See TracBrowser for help on using the repository browser.