1 /* $Id: bonusinvisible.cpp,v 1.8 2005/10/16 17:53:05 pohlt Exp $ */
2 
3 #include "bonusinvisible.hpp"
4 #include "avatar.hpp"
5 
6 /**********************************************************/
7 #define  INVISIBLEBONUS_PROTECTION_TIME     400
8 #define  INVISIBLEBONUS_HEALTH           300000
9 /**********************************************************/
10 
BonusInvisible(World * wp)11 BonusInvisible::BonusInvisible( World* wp )
12             : m_protectionTime( INVISIBLEBONUS_PROTECTION_TIME ),
13               m_corona( NULL )
14 {
15 	m_worldPointer = wp;
16 	// set health for the health bonus
17 	m_health = INVISIBLEBONUS_HEALTH;
18 	// for mass and collission rectangle take the
19 	// default values from base class Bonus
20 
21 	// THIS CALL MUST BE PART OF EACH CONSTRUCTOR
22 	// OF BONI, DERIVED FROM ITS BASE CLASS Bonus
23 	registerAtManager();
24 }
25 
26 /**********************************************************/
27 
~BonusInvisible()28 BonusInvisible::~BonusInvisible()
29 {
30 	// remove corona object from world
31 	if( m_corona )  m_corona->setRemoveMeAfterUpdate( true );
32 
33 	// THIS CALL MUST BE PART OF EACH DESTRUCTOR
34 	// OF BONI, DERIVED FROM ITS BASE CLASS Bonus
35 	unregisterAtManager();
36 }
37 
38 /**********************************************************/
39 
add(const Bonus * const bonus)40 void BonusInvisible::add( const Bonus *const bonus )
41 {
42 	const BonusInvisible *const invisible =
43 		dynamic_cast<const BonusInvisible*>(bonus);
44 
45 	DBG(1) ASSERT( invisible != NULL,
46 	               "BonusInvisible::add: attempt to add a bonus of type "
47 	               "%s to an invisible bonus", bonus->getIDString() );
48 
49 	if( m_protectionTime <= 0 ) {
50 		m_protectionTime = invisible->m_protectionTime;
51 		if( m_corona )  m_corona->reboot();
52 	} else {
53 		m_protectionTime += invisible->m_protectionTime;
54 	}
55 }
56 
57 /**********************************************************/
58 
apply(Avatar * const avatar)59 void BonusInvisible::apply( Avatar *const avatar ) {
60 	avatar->setState( WEAPON_VISIBLE, false );
61 
62 	if( ! avatar->getPlayer()->isLocalPlayer() ) {
63 		avatar->setState( VISIBLE, false );
64 	}
65 }
66 
67 /**********************************************************/
68 
updateInBonusPack(Avatar * const avatar)69 bool BonusInvisible::updateInBonusPack( Avatar *const avatar )
70 {
71 	// check, whether there already exists a corona object
72 	if( m_corona == NULL ) {
73 		// if the avatar and the corona have been deserialized,
74 		// we have to find the pointer to the corresponding
75 		// invisible corona object
76 		for( int i = 0; i < avatar->getNAttachedObjects(); i++ ) {
77 			if( INVISIBLE_CORONA == avatar->getAttachedObject(i)->getID() ) {
78 				m_corona = (InvisibleCorona*)avatar->getAttachedObject( i );
79 				break;
80 			}
81 		}
82 		// if there is not a corona object yet
83 		if( m_corona == NULL ) {
84 			// create a new corona object ...
85 			m_corona = (InvisibleCorona*)m_worldPointer->newObject( INVISIBLE_CORONA );
86 			// ... make it invisible of not local player ...
87 			if( ! avatar->getPlayer()->isLocalPlayer() ) {
88 				m_corona->setState( VISIBLE, false );
89 			}
90 			// ... and attach it to the protected avatar
91 			m_corona->attachTo( avatar );
92 		}
93 	}
94 
95 	// set the coordinates in the corona object
96 	m_corona->setPos( avatar->getPos() +
97 	                  Vector( avatar->getCollRectX() + 0.5 * avatar->getCollRectWidth(),
98 	                          avatar->getCollRectY() + 0.5 * avatar->getCollRectHeight() ));
99 
100 	// if the effect of the bonus is gone
101 	if( --m_protectionTime == 0 ) {
102 		// set the avatar visible again
103 		avatar->setState( VISIBLE | WEAPON_VISIBLE, true );
104 		// initialize the shutdown of the corona
105 		m_corona->signalShutdown();
106 		//
107 		return true;
108 	// corona is shutting down at the moment
109 	} else if( m_protectionTime < 0 ) {
110 		// check, if the corona is down
111 		// NOTE: returning false will cause the bonus pack to
112 		// delete this bonus, and the destructor of this bonus
113 		// removes the corona object from the world.
114 		return m_corona->getFrame() > 0;
115 	}
116 
117 	return m_protectionTime > 0;
118 }
119 
120 /**********************************************************/
121 
getSerializeBufferSize() const122 Uint32 BonusInvisible::getSerializeBufferSize() const
123 {
124 	return   Bonus::getSerializeBufferSize()
125 	       + Serialize<Sint32>::sizeOf( m_protectionTime )
126 	         // adds additional size for debugging (see serialize.hpp),
127 	         // but only, if the tags are used
128 	         PLUS_TAG_SIZE( 1 );
129 }
130 
131 /**********************************************************/
132 
serialize(Uint8 * & bufferPointer) const133 void BonusInvisible::serialize( Uint8*& bufferPointer ) const
134 {
135 	// expands to a check of the buffer movement
136 	START_OBJECT_SERIALIZED_SIZE_CHECK( bufferPointer );
137 
138 	Bonus::serialize( bufferPointer );
139 
140 	Serialize<Sint32>::serialize( m_protectionTime, bufferPointer );
141 
142 	// expands to tag serialization
143 	SERIALIZE_OBJECT_TAG( bufferPointer );
144 	// expands to a check of the buffer movement
145 	END_OBJECT_SERIALIZED_SIZE_CHECK( bufferPointer, BonusInvisible );
146 }
147 
148 /**********************************************************/
149 
deserialize(Uint8 * & bufferPointer)150 void BonusInvisible::deserialize( Uint8*& bufferPointer )
151 {
152 	Bonus::deserialize( bufferPointer );
153 
154 	Serialize<Sint32>::deserialize( bufferPointer, m_protectionTime );
155 
156 	// expands to tag deserialization
157 	DESERIALIZE_OBJECT_TAG( bufferPointer );
158 }
159 
160 /**********************************************************/
161