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