/* $Id$ */ #ifndef _BONUS_HPP_ #define _BONUS_HPP_ /**********************************************************/ #include #include "collidableobject.hpp" /**********************************************************/ class Avatar; /**********************************************************/ //! base object for bonus objects /*! \b Implementation \b hints:
* The member functions registerAtManager and unregisterAtManager * must be invoked at creation time and at destruction time * respectively by every object derived from Bonus. Unfortunately * this cannot be done in the constructor and the destructor of * class Bonus, since both functions use the method Object::getID(), * which is pure virtual in Object and implemented at the end of * each branch of the inheritance hierarchy, in particular not * in class Bonus. Therefore a call of getID() in the constructor * or destructor of Bonus is not possible, and therefore each * class derived from Bonus must invore registerAtManager() in its * constructor and unregisterAtManager() in its destructor. */ class Bonus : public CollidableObject { public: virtual ~Bonus(); //! returns true, if this bonus is a weapon virtual bool isWeapon() const = 0; //! \name registration processes at bonus manager //@{ //! returns the registration flag bool getRegistrationFlag() const { return m_registered; } //! sets the registration flag void setRegistrationFlag( const bool flag = true ) { m_registered = flag; } //! register the bonus object at the manager void registerAtManager(); //! "unregister" the bonus object at the manager void unregisterAtManager(); //@} //! \name functions for the interaction with avatars //@{ //! returns true, if it can be picked up by the passed avatar /*! Not all boni could be picked up by every avatar at a * arbitrary time. For example we do not want an avatar, that * is not hurted at all, to pick up a health bonus. Therefore * A bonus can test, if it could be picked up by an avatar. */ virtual bool canBePickedUpByAvatar( const Avatar* const avatar ) { return true; } //! checks, if this bonus is picked up by an avatar Avatar* checkPicking(); //! routine is called just before the bonus is picked up /*! Avatar::pickUp calls this routine just befor the bonus * object is applied to the avatar and either destroyed or * put into the avatar's bonus pack. It allows each bonus * type to implement its own behaviour while being picked * up (e.g. generating some blue glow). */ virtual void beingPickedUp( const Avatar* const avatar ); //! adds another bonus to this bonus /*! If an avatar picks up a bonus object, it either consumes * the bonus immediately or puts the bonus in its bonus pack * (class BonusPack), where it might consume itself time by * time (e.g. an inivisibility bonus) or is consumend * explicitely by the avatar (e.g. bonus weapon). For the * later case we need the possibility to add boni of the * same type (e.g. to increase the time for invisibility, * if an invisibility bonus is picked up, while the avatar * is already invisible). */ virtual void add( const Bonus *const bonus ) {}; //! applies the bonus to the passed avatar /*! This method is responsible for the \b direct effect * on the avatar, which is applied \b once, when it is * picked up by the avatar (for example healing effect * of the health bonus). */ virtual void apply( Avatar *const avatar ) {}; //! indicates, whether the bonus must be kept in the avatar's bag virtual bool mustBePutIntoPack() const = 0; //! indicates, whether the bonus survives the avatar in its bag virtual bool persistentInPack() const { return false; } //! update function, if the bonus is placed in a bonus pack /*! Object::update is responsible for the update of an object * inside the world. If a bonus is picked up, it might live * furtheron, but not inside the world, but inside the bonus * pack of an avatar. Nevertheless it must be updated, and this * update is done in this function. * \return \c true, if the bonus is still valid after this update, * \c false, if the bonus is consumed after this update * and can (and will) be removed from the bonus pack and * destroyed. */ virtual bool updateInBonusPack( Avatar *const avatar ) { return true; }; //@} //! update function, reimplemented from class Object virtual void update(); //! apply damage by particles virtual int applyDamage( const Particles::ParticleData& p ); //! returns the number of different boni types in the world static Sint32 getNumTypes() { return LAST_BONUS - FIRST_BONUS + 1; } //! \name (de)serialization //@{ virtual Uint32 getSerializeBufferSize() const; virtual void serialize( Uint8*& bufferPointer ) const; virtual void deserialize( Uint8*& bufferPointer ); //@} virtual void dump( std::ostream& out ) const; protected: //! forbid the generation of pure Bonus objects Bonus(); //! standard update of the sprite frame index virtual void updateSprite(); //! is true, if the bonus is registered at the moment bool m_registered; //! \name control members for the graphics //@{ //! reciprocal value of sprite frames per update cycle Sint32 m_updatesPerFrame; //! counter for the updates, left to the next sprite frame Sint32 m_numUpdates; //@} //! number of left updates in the bonus' life Sint32 m_timeToLive; }; /**********************************************************/ #endif // _BONUS_HPP_