/* * ORXONOX - the hottest 3D action shooter ever to exist * > www.orxonox.net < * * * License notice: * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Author: * Damian 'Mozork' Frick * Co-authors: * ... * */ /** @file @brief Implementation of the QuestEffectBeacon class. */ #include "QuestEffectBeacon.h" #include "core/CoreIncludes.h" #include "core/XMLPort.h" #include "core/EventIncludes.h" #include "worldentities/pawns/Pawn.h" #include "interfaces/PlayerTrigger.h" #include "objects/triggers/MultiTriggerContainer.h" #include "QuestEffect.h" namespace orxonox { CreateFactory(QuestEffectBeacon); /** @brief Constructor. Registers the object and initializes defaults. */ QuestEffectBeacon::QuestEffectBeacon(BaseObject* creator) : StaticEntity(creator) { RegisterObject(QuestEffectBeacon); this->status_ = QuestEffectBeaconStatus::Active; this->times_ = INFINITE_TIME; } /** Destructor. */ QuestEffectBeacon::~QuestEffectBeacon() { } /** @brief Method for creating a QuestEffectBeacon object through XML. */ void QuestEffectBeacon::XMLPort(Element& xmlelement, XMLPort::Mode mode) { SUPER(QuestEffectBeacon, XMLPort, xmlelement, mode); XMLPortParam(QuestEffectBeacon, "times", setTimes, getTimes, xmlelement, mode); XMLPortObject(QuestEffectBeacon, QuestEffect, "effects", addEffect, getEffect, xmlelement, mode); XMLPortEventSink(QuestEffectBeacon, BaseObject, "execute", execute, xmlelement, mode); //TODO: Change BaseObject to MultiTrigger as soon as MultiTrigger is the base of all triggers. COUT(4) << "New QuestEffectBeacon created." << std::endl; } void QuestEffectBeacon::XMLEventPort(Element& xmlelement, XMLPort::Mode mode) { SUPER(QuestEffectBeacon, XMLEventPort, xmlelement, mode); XMLPortEventSink(QuestEffectBeacon, BaseObject, "execute", execute, xmlelement, mode); } /** @brief Executes the QuestEffectBeacon. This means extracting the Pawn from the PlayerTrigger, provided by the Event causing the execution, and the extracting the PlayerInfo from the received Pawn and invoking the QuestEffectbeacon's QuestEffects on the received PlayerInfo. @param bTriggered true means the trigger was activated while false means it was deactivated @param trigger A pointer to the PlayerTrigger that threw the Event. @return Returns true if successfully executed, false if not. */ bool QuestEffectBeacon::execute(bool bTriggered, BaseObject* trigger) { if(!bTriggered) { return false; } if(!(this->isActive())) //!< If the QuestEffectBeacon is inactive it cannot be executed. { COUT(4) << "The QuestEffectBeacon is inactive." << std::endl; return false; } PlayerTrigger* pTrigger = orxonox_cast(trigger); MultiTriggerContainer* mTrigger = orxonox_cast(trigger); Pawn* pawn = NULL; //! If the trigger is neither a Playertrigger nor a MultiTrigger (i.e. a MultitriggerContainer) we can do anything with it. if(pTrigger == NULL && mTrigger == NULL) return false; // If the trigger is a PlayerTrigger. if(pTrigger != NULL) { if(!pTrigger->isForPlayer()) //!< The PlayerTrigger is not exclusively for Pawns which means we cannot extract one. return false; else pawn = pTrigger->getTriggeringPlayer(); } // If the trigger is a MultiTrigger (i.e. a MultiTriggerContainer) if(mTrigger != NULL) { pawn = orxonox_cast(mTrigger->getData()); } if(pawn == NULL) { COUT(4) << "The QuestEffectBeacon was triggered by an entity other than a Pawn. (" << trigger->getIdentifier()->getName() << ")" << std::endl; return false; } //! Extract the PlayerInfo from the Pawn. PlayerInfo* player = pawn->getPlayer(); if(player == NULL) { COUT(3) << "The PlayerInfo* is NULL." << std::endl; return false; } COUT(4) << "QuestEffectBeacon executed on player: " << player << " ." << std::endl; bool check = QuestEffect::invokeEffects(player, this->effects_); //!< Invoke the QuestEffects on the PlayerInfo. if(check) { this->decrementTimes(); //!< Decrement the number of times the beacon can be used. return true; } return false; } /** @brief Set the status of the QuestEffectBeacon. @param activate If true the QuestEffectBeacon is activated, if false it is deactivated. @return Returns whether the activation/deactivation was successful. */ bool QuestEffectBeacon::setActive(bool activate) { if(this->getTimes() == 0 && activate) //!< A QuestEffectBeacon that can be executed only 0 times is always inactive. { return false; } if(activate) { this->status_ = QuestEffectBeaconStatus::Active; return true; } this->status_ = QuestEffectBeaconStatus::Inactive; return true; } /** @brief Decrement the number of times the QuestEffectBeacon can be executed. @return Returns true if successful. */ bool QuestEffectBeacon::decrementTimes(void) { if(!(this->isActive())) //!< The QuestEffectBeacon mus be active to decrement the number of times it can be executed. { return false; } if(this->getTimes() == INFINITE_TIME) //!< If times is infinity the QuestEffectBeacon can be executed an infinite number fo times. { return true; } this->times_ = this->times_ - 1; //!< Decrement number of times the QuestEffectBeacon can be executed. if(this->getTimes() == 0) //!< Set the QuestEffectBeacon to inactive when the number of times it can be executed is reduced to 0. { this->status_ = QuestEffectBeaconStatus::Inactive; } return true; } /** @brief Set the number of times the QuestEffectBeacon can be executed. The number must be eighter <= 0, or INFINITY which is '-1'. @param n The number of times the QuestEffectBeacon can be executed. The number must be eighter <= 0, or INFINITY which is '-1'. @return Returns true if successful. */ bool QuestEffectBeacon::setTimes(const int & n) { if(n < 0 && n != INFINITE_TIME) { return false; } this->times_ = n; return true; } /** @brief Adds a QuestEffect to the QuestEffectBeacon. @param effect A pointer to the QuestEffect to be added. @return Returns true if successful. */ bool QuestEffectBeacon::addEffect(QuestEffect* effect) { if(effect == NULL) //!< NULL-pointers are not well liked here... { COUT(2) << "A NULL-QuestEffect was trying to be added" << std::endl; return false; } this->effects_.push_back(effect); COUT(4) << "A QuestEffect was added to a QuestEffectBeacon." << std::endl; return true; } /** @brief Returns the QuestEffect at the given index. @param index The index. @return Returns a pointer to the QuestEffect at the given index. */ const QuestEffect* QuestEffectBeacon::getEffect(unsigned int index) const { int i = index; for (std::list::const_iterator effect = this->effects_.begin(); effect != this->effects_.end(); ++effect) { if(i == 0) { return *effect; } i--; } return NULL; } }