/* $Id: bonusinvisible.cpp,v 1.8 2005/10/16 17:53:05 pohlt Exp $ */ #include "bonusinvisible.hpp" #include "avatar.hpp" /**********************************************************/ #define INVISIBLEBONUS_PROTECTION_TIME 400 #define INVISIBLEBONUS_HEALTH 300000 /**********************************************************/ BonusInvisible::BonusInvisible( World* wp ) : m_protectionTime( INVISIBLEBONUS_PROTECTION_TIME ), m_corona( NULL ) { m_worldPointer = wp; // set health for the health bonus m_health = INVISIBLEBONUS_HEALTH; // for mass and collission rectangle take the // default values from base class Bonus // THIS CALL MUST BE PART OF EACH CONSTRUCTOR // OF BONI, DERIVED FROM ITS BASE CLASS Bonus registerAtManager(); } /**********************************************************/ BonusInvisible::~BonusInvisible() { // remove corona object from world if( m_corona ) m_corona->setRemoveMeAfterUpdate( true ); // THIS CALL MUST BE PART OF EACH DESTRUCTOR // OF BONI, DERIVED FROM ITS BASE CLASS Bonus unregisterAtManager(); } /**********************************************************/ void BonusInvisible::add( const Bonus *const bonus ) { const BonusInvisible *const invisible = dynamic_cast(bonus); DBG(1) ASSERT( invisible != NULL, "BonusInvisible::add: attempt to add a bonus of type " "%s to an invisible bonus", bonus->getIDString() ); if( m_protectionTime <= 0 ) { m_protectionTime = invisible->m_protectionTime; if( m_corona ) m_corona->reboot(); } else { m_protectionTime += invisible->m_protectionTime; } } /**********************************************************/ void BonusInvisible::apply( Avatar *const avatar ) { avatar->setState( WEAPON_VISIBLE, false ); if( ! avatar->getPlayer()->isLocalPlayer() ) { avatar->setState( VISIBLE, false ); } } /**********************************************************/ bool BonusInvisible::updateInBonusPack( Avatar *const avatar ) { // check, whether there already exists a corona object if( m_corona == NULL ) { // if the avatar and the corona have been deserialized, // we have to find the pointer to the corresponding // invisible corona object for( int i = 0; i < avatar->getNAttachedObjects(); i++ ) { if( INVISIBLE_CORONA == avatar->getAttachedObject(i)->getID() ) { m_corona = (InvisibleCorona*)avatar->getAttachedObject( i ); break; } } // if there is not a corona object yet if( m_corona == NULL ) { // create a new corona object ... m_corona = (InvisibleCorona*)m_worldPointer->newObject( INVISIBLE_CORONA ); // ... make it invisible of not local player ... if( ! avatar->getPlayer()->isLocalPlayer() ) { m_corona->setState( VISIBLE, false ); } // ... and attach it to the protected avatar m_corona->attachTo( avatar ); } } // set the coordinates in the corona object m_corona->setPos( avatar->getPos() + Vector( avatar->getCollRectX() + 0.5 * avatar->getCollRectWidth(), avatar->getCollRectY() + 0.5 * avatar->getCollRectHeight() )); // if the effect of the bonus is gone if( --m_protectionTime == 0 ) { // set the avatar visible again avatar->setState( VISIBLE | WEAPON_VISIBLE, true ); // initialize the shutdown of the corona m_corona->signalShutdown(); // return true; // corona is shutting down at the moment } else if( m_protectionTime < 0 ) { // check, if the corona is down // NOTE: returning false will cause the bonus pack to // delete this bonus, and the destructor of this bonus // removes the corona object from the world. return m_corona->getFrame() > 0; } return m_protectionTime > 0; } /**********************************************************/ Uint32 BonusInvisible::getSerializeBufferSize() const { return Bonus::getSerializeBufferSize() + Serialize::sizeOf( m_protectionTime ) // adds additional size for debugging (see serialize.hpp), // but only, if the tags are used PLUS_TAG_SIZE( 1 ); } /**********************************************************/ void BonusInvisible::serialize( Uint8*& bufferPointer ) const { // expands to a check of the buffer movement START_OBJECT_SERIALIZED_SIZE_CHECK( bufferPointer ); Bonus::serialize( bufferPointer ); Serialize::serialize( m_protectionTime, bufferPointer ); // expands to tag serialization SERIALIZE_OBJECT_TAG( bufferPointer ); // expands to a check of the buffer movement END_OBJECT_SERIALIZED_SIZE_CHECK( bufferPointer, BonusInvisible ); } /**********************************************************/ void BonusInvisible::deserialize( Uint8*& bufferPointer ) { Bonus::deserialize( bufferPointer ); Serialize::deserialize( bufferPointer, m_protectionTime ); // expands to tag deserialization DESERIALIZE_OBJECT_TAG( bufferPointer ); } /**********************************************************/