1 /* $Id$ */
2 
3 #ifndef  _BONUS_HPP_
4 #define  _BONUS_HPP_
5 
6 /**********************************************************/
7 
8 #include <iostream>
9 #include  "collidableobject.hpp"
10 
11 /**********************************************************/
12 class Avatar;
13 /**********************************************************/
14 
15 //! base object for bonus objects
16 
17 /*! \b Implementation \b hints: <br>
18  *  The member functions registerAtManager and unregisterAtManager
19  *  must be invoked at creation time and at destruction time
20  *  respectively by every object derived from Bonus. Unfortunately
21  *  this cannot be done in the constructor and the destructor of
22  *  class Bonus, since both functions use the method Object::getID(),
23  *  which is pure virtual in Object and implemented at the end of
24  *  each branch of the inheritance hierarchy, in particular not
25  *  in class Bonus. Therefore a call of getID() in the constructor
26  *  or destructor of Bonus is not possible, and therefore <b>each
27  *  class derived from Bonus must invore registerAtManager() in its
28  *  constructor and unregisterAtManager() in its destructor.</b>
29  */
30 class Bonus : public CollidableObject
31 {
32 	public:
33 
34 		virtual ~Bonus();
35 
36 		//! returns true, if this bonus is a weapon
37 		virtual bool isWeapon() const = 0;
38 
39 		//! \name registration processes at bonus manager
40 		//@{
41 		//! returns the registration flag
getRegistrationFlag() const42 		bool getRegistrationFlag() const { return m_registered; }
43 		//! sets the registration flag
setRegistrationFlag(const bool flag=true)44 		void setRegistrationFlag( const bool flag = true ) {
45 			m_registered = flag; }
46 		//! register the bonus object at the manager
47 		void registerAtManager();
48 		//! "unregister" the bonus object at the manager
49 		void unregisterAtManager();
50 		//@}
51 
52 		//! \name functions for the interaction with avatars
53 		//@{
54 		//! returns true, if it can be picked up by the passed avatar
55 
56 		/*! Not all boni could be picked up by every avatar at a
57 		 *  arbitrary time. For example we do not want an avatar, that
58 		 *  is not hurted at all, to pick up a health bonus. Therefore
59 		 *  A bonus can test, if it could be picked up by an avatar.
60 		 */
canBePickedUpByAvatar(const Avatar * const avatar)61 		virtual bool canBePickedUpByAvatar( const Avatar* const avatar ) {
62 			return true; }
63 
64 		//! checks, if this bonus is picked up by an avatar
65 		Avatar* checkPicking();
66 
67 		//! routine is called just before the bonus is picked up
68 
69 		/*! Avatar::pickUp calls this routine just befor the bonus
70 		 *  object is applied to the avatar and either destroyed or
71 		 *  put into the avatar's bonus pack. It allows each bonus
72 		 *  type to implement its own behaviour while being picked
73 		 *  up (e.g. generating some blue glow).
74 		 */
75 		virtual void beingPickedUp( const Avatar* const avatar );
76 
77 		//! adds another bonus to this bonus
78 
79 		/*! If an avatar picks up a bonus object, it either consumes
80 		 *  the bonus immediately or puts the bonus in its bonus pack
81 		 *  (class BonusPack), where it might consume itself time by
82 		 *  time (e.g. an inivisibility bonus) or is consumend
83 		 *  explicitely by the avatar (e.g. bonus weapon). For the
84 		 *  later case we need the possibility to add boni of the
85 		 *  same type (e.g. to increase the time for invisibility,
86 		 *  if an invisibility bonus is picked up, while the avatar
87 		 *  is already invisible).
88 		 */
add(const Bonus * const bonus)89 		virtual void add( const Bonus *const bonus ) {};
90 
91 		//! applies the bonus to the passed avatar
92 
93 		/*! This method is responsible for the \b direct effect
94 		 *  on the avatar, which is applied \b once, when it is
95 		 *  picked up by the avatar (for example healing effect
96 		 *  of the health bonus).
97 		 */
apply(Avatar * const avatar)98 		virtual void apply( Avatar *const avatar ) {};
99 
100 		//! indicates, whether the bonus must be kept in the avatar's bag
101 		virtual bool mustBePutIntoPack() const = 0;
102 
103 		//! indicates, whether the bonus survives the avatar in its bag
persistentInPack() const104 		virtual bool persistentInPack() const { return false; }
105 
106 		//! update function, if the bonus is placed in a bonus pack
107 
108 		/*! Object::update is responsible for the update of an object
109 		 *  inside the world. If a bonus is picked up, it might live
110 		 *  furtheron, but not inside the world, but inside the bonus
111 		 *  pack of an avatar. Nevertheless it must be updated, and this
112 		 *  update is done in this function.
113 		 *  \return \c true, if the bonus is still valid after this update,
114 		 *          \c false, if the bonus is consumed after this update
115 		 *          and can (and will) be removed from the bonus pack and
116 		 *          destroyed.
117 		 */
updateInBonusPack(Avatar * const avatar)118 		virtual bool updateInBonusPack( Avatar *const avatar ) {
119 			return true; };
120 		//@}
121 
122 		//! update function, reimplemented from class Object
123 		virtual void update();
124 		//! apply damage by particles
125 		virtual int applyDamage( const Particles::ParticleData& p );
126 
127 		//! returns the number of different boni types in the world
getNumTypes()128 		static Sint32 getNumTypes() {
129 			return LAST_BONUS - FIRST_BONUS + 1; }
130 
131 		//! \name (de)serialization
132 		//@{
133 		virtual Uint32 getSerializeBufferSize() const;
134 		virtual void serialize( Uint8*& bufferPointer ) const;
135 		virtual void deserialize( Uint8*& bufferPointer );
136 		//@}
137 
138 		virtual void dump( std::ostream& out ) const;
139 
140 	protected:
141 
142 		//! forbid the generation of pure Bonus objects
143 		Bonus();
144 
145 		//! standard update of the sprite frame index
146 		virtual void updateSprite();
147 
148 		//! is true, if the bonus is registered at the moment
149 		bool m_registered;
150 
151 		//! \name control members for the graphics
152 		//@{
153 		//! reciprocal value of sprite frames per update cycle
154 		Sint32  m_updatesPerFrame;
155 		//! counter for the updates, left to the next sprite frame
156 		Sint32  m_numUpdates;
157 		//@}
158 
159 		//! number of left updates in the bonus' life
160 		Sint32  m_timeToLive;
161 };
162 
163 /**********************************************************/
164 
165 #endif // _BONUS_HPP_
166