/* $Id: avatar.hpp,v 1.86.2.2 2006/01/20 11:33:52 chfreund Exp $ */ #ifndef _AVATAR_HPP_ #define _AVATAR_HPP_ /**********************************************************/ #include #include #include "global.hpp" #include "collidableobject.hpp" #include "spriteset.hpp" #include "player.hpp" #include "vector.hpp" #include "random.hpp" #include "map.hpp" #include "world.hpp" #include "particles.hpp" #include "flag.hpp" #include "messages.hpp" #include "bonuspack.hpp" #include "counter.hpp" #include /**********************************************************/ class HomingMissile; class StationaryGun; /********************************************************** * Base class for all avatars. **********************************************************/ //! the basic object for all avatars /*! This is the base class for all avatars. * For more information about the Avatar \f$\leftrightarrow\f$ * Player connection see the description of class Player. */ class Avatar : public CollidableObject { friend void Player::attachAvatar( Avatar* const avatar ); friend Avatar* Player::detachAvatar(); public: ////////////////////////////////////////// //! \name aiming angle, aiming speed, aiming, direction ... //@{ //! returns the aiming angle real getAimingAngle() const { return m_aimingAngle; } //! returns the aiming speed real getAimingSpeed() const { return m_aimingSpeed; } //! returns the aiming vector Vector getAimingVector() const { return Vector( getAimingDX(), getAimingDY() ); } //! returns the x component of the aiming vector real getAimingDX() const { return (isFacingRight() ? 1 : -1) * SIN_REAL( m_aimingAngle*AIMING_ANGLE_TO_RAD ); } //! returns the y component of the aiming vector real getAimingDY() const { return -COS_REAL( m_aimingAngle*AIMING_ANGLE_TO_RAD ); } //! returns a randomly perturbated aiming vector Vector getRandomizedAimingVector( const real maxTremble ) const { real tremble = 0.5 - m_worldPointer->getRandom().getNormedReal(); tremble *= (M_PI/180.0); tremble *= maxTremble; return Vector( (isFacingRight() ? 1 : -1) * SIN_REAL( m_aimingAngle*AIMING_ANGLE_TO_RAD+tremble ), -COS_REAL( m_aimingAngle*AIMING_ANGLE_TO_RAD+tremble ) ); } //! comment missing Vector placeBesideCollRect( const int marginLeft = 0, const int marginRight = 0, const int marginTop = 0, const int marginBottom = 0 ); //! sets the aiming angle bool setAimingAngle( const real aimingAngle ) { if( aimingAngle > MAX_AIMING_ANGLE ) { m_aimingAngle = MAX_AIMING_ANGLE; updateSpriteSelection(); return false; } else if( aimingAngle < 0.0 ) { m_aimingAngle = 0.0; updateSpriteSelection(); return false; } else { m_aimingAngle = aimingAngle; updateSpriteSelection(); return true; } } //! sets turning of aiming void setAimingDirection( const int dir ); //! sets the direction (see enumeration type) /*! Sets the new direction of the avatar. The passed direction * must be in the range of defined (enumeration constants in * this class) directions. If you add further directions, you * must also adapt the method updateSequenceIndex(). */ void setDirection( const Uint32 direction ); //! returns the direction (enumeration type) Uint32 getDirection() const { return (isFacingRight() ? RIGHT : LEFT); } //@} ////////////////////////////////////////// //! \name information about the action state //@{ bool isMovingLeft ( void ) const { return m_state & m_stateMask & MOVING_LEFT; } bool isMovingRight ( void ) const { return m_state & m_stateMask & MOVING_RIGHT; } bool isMovingAny ( void ) const { return m_state & m_stateMask & MOVING_ANY; } bool isJumping ( void ) const { return m_state & m_stateMask & JUMPING; } bool isDigging ( void ) const { return m_state & m_stateMask & DIGGING; } bool isShooting ( void ) const { return m_state & m_stateMask & SHOOTING; } bool isAimingUp ( void ) const { return m_state & m_stateMask & AIMING_UP; } bool isAimingDown ( void ) const { return m_state & m_stateMask & AIMING_DOWN; } bool isFacingRight ( void ) const { return m_state & m_stateMask & FACING_RIGHT; } bool isSetRopeOn ( void ) const { return m_state & m_stateMask & ROPE_ON; } bool isSetRopeOff ( void ) const { return m_state & m_stateMask & ROPE_OFF; } bool isSetRopeIn ( void ) const { return m_state & m_stateMask & ROPE_IN; } bool isSetRopeOut ( void ) const { return m_state & m_stateMask & ROPE_OUT; } bool isSetRopeRel ( void ) const { return m_state & m_stateMask & ROPE_REL; } bool isInGunMode ( void ) const { return m_state & MODE_GUN; } bool isInGMMode ( void ) const { return m_state & MODE_GM; } bool isInAnyMode ( void ) const { return m_state & MODE_ANY; } bool isInSkwoermZone( void ) const { return m_state & IN_SKWOERMZONE; } void setStateMask( const Uint32 mask ) { m_stateMask = mask; } //@} ////////////////////////////////////////// //! \name routines for special states //@{ //! the avatar takes a seat in the passed gun virtual void sitDownInGun( StationaryGun *const gun ); //! the avatar leaves gun, it is currently sitting in virtual void leaveCurrentGun(); //! the avatar takes the remote control virtual void takeRemoteControl(); //! the avatar drops the remote control virtual void dropRemoteControl(); //@} ////////////////////////////////////////// //! \name the avatar's health //@{ //! returns the avatar's maximal health value Sint32 getMaxHealth() const { return m_maxHealth; } //! sets the maximal health value void setMaxHealth( const Sint32 H ) { m_maxHealth = H; } //! heals the avatar by \c addHealth points void heal( const Sint32 addHealth ) { if( (m_health += addHealth) > m_maxHealth ) { m_health = m_maxHealth; } } //@} ////////////////////////////////////////// //! \name fuel for the jet pack //@{ //! returns the current fuel real getFuel() const { return m_fuel.getTimeToLive(); } //! returns the tank size (maximal fuel) real getMaxFuel() const { return m_maxFuel; } //! fills fuel in the tank void fillFuel( const real fuel ) { if( m_fuel.isElapsed() ) m_fuel.setTimeToLive( 0.0 ); if( (m_fuel.getTimeToLive() + fuel) > m_maxFuel ) { m_fuel.setTimeToLive( m_maxFuel ); } else { m_fuel.setTimeToLive( m_fuel.getTimeToLive() + fuel ); } } //@} ////////////////////////////////////////// //! \name connected player object //@{ //! returns the pointer to the connected player object /*! Returns the pointer to the Player object (also see description * of class Player), this avatar is attached to. Attaching and * detaching can and should be done only by the two friend * methods Player::attachAvatar and Player::detachAvatar. */ Player* getPlayer() { return m_Player; } //! the "const" version of getPlayer const Player* getPlayer() const { return m_Player; } //q} ////////////////////////////////////////// /*! \name functions concerning the graphic of the avatar * \brief Besides the implementation of the functions * Object::getColors() and Object::getNumColors class Avatar * must provide an interface to set and get the skin color and * the team color and the player color. This does not mean * that these three colors differ pairwise (for example see * class AvatarWorm). Als functions to set a color take an * additional bool flag, which specifies, whether the game * mode lets each player play alone or in a team. This is * important, for example, if in team modes a different area * of the avatar is used for the personal player color than * in single player modes. *
* Important: Note that, no matter how these colors * are organized, the implementations of Object::getColors() * still must return a pointer to an array containing * getNumColors() color values, exactly ordered like the * layers in the avatars graphic, whereby getNumColors() and * the number of layers must match! */ //@{ //! a virtual interface to set the player color virtual void setPlayerColor( const Uint32 color ) = 0; /*! \brief a virtual interface to set the skin color * NOTE: this function is a relict, and it is not clear, when * it should be used. Before you use it, please check, if not * setPlayerColor or setTeamColor is the function you want to * use. */ virtual void setSkinColor( const Uint32 color ) = 0; //! a virtual interface to set the team color virtual void setTeamColor( const Uint32 color ) = 0; //! a virtual interface to get the skin color virtual Uint32 getSkinColor() const = 0; //! a virtual interface to get the team color virtual Uint32 getTeamColor() const = 0; //! a virtual interface to get the player color virtual Uint32 getPlayerColor() const = 0; //@} //! spawn the avatar at a randomly chosen position void spawnAvatar( void ); ////////////////////////////////////////// //! \name functions concerning the avatar's movement //@{ //! digging in the dirt (P. Gabriel) void dig( void ); //! ???? void testGrounded( bool& groundedMid, bool& groundedFW, bool& groundedBW ); virtual bool testGrounded( void ) { bool groundedMid, groundedFW, groundedBW; testGrounded( groundedMid, groundedFW, groundedBW ); if( isGrounded() ) return groundedMid | groundedFW | groundedBW; else return groundedMid; } bool testPassableRel( const int dx, const int dy ) { return m_worldPointer->getMap()->testPassableSmoothing( ROUND( m_pos.x ) + dx, ROUND( m_pos.y ) + dy, Flags::OBSTACLE_EARTH | Flags::OBSTACLE_OBJECT ); } //! ???? bool testLinePassableRel( const int dx1, const int dy1, const int dx2, const int dy2, int& pcx, int& pcy, int& cx, int& cy ) { return m_worldPointer->getMap()->testLinePassableSmoothing( ROUND( m_pos.x ) + dx1, ROUND( m_pos.y ) + dy1, ROUND( m_pos.x ) + dx2, ROUND( m_pos.y ) + dy2, pcx, pcy, cx, cy, Flags::OBSTACLE_EARTH | Flags::OBSTACLE_OBJECT ); } //@} //! applies damage to the avatar (reimplemented from CollidableObject) /*! This method applies damage to the avatar, caused by the passed * passed particle. It is reimplemented here, for example because * of shield boni, which beware the avatar of damage, but not of * the particles recoil. */ virtual int applyDamage( const Particles::ParticleData& p ); //! applies damage to the avatar (reimplemented from CollidableObject) virtual int applyDamage( const int damage, Player* shooter ); ////////////////////////////////////////// //! /name methods concerning boni //@{ //! pick up the passed bonus /*! The collission rectangle of the passed bonus must not be set * at the moment, it is passed to this function. This function * will remove the bonus from the world, since it is consumed * and therefore also administrated by the avatar and therefore * not longer existent in the world. In addition to this the * bonus object might also be deleted by this function, depending * on the specific bonus type and possibly already present boni * in the avatar's bonus pack. Do not use the bonus object after * this call any more, since you do not know, whether it * still exists. But you also have not to care about it anyway, * because it is administrated by the avatars bonus pack from * now on! */ void pickUp( Bonus* bonus ); //! returns the bonus pack BonusPack& getBonusPack() { return m_bonusPack; } //! returns the bonus pack const BonusPack& getBonusPack() const { return m_bonusPack; } //@} ////////////////////////////////////////// //! \name methods concerning special weapons //@{ void getLockedByHomingMissile( HomingMissile *const missile, const real distanceSquare ); //@} Sint32 getWeaponPivotDY( void ) const { return m_weaponPivotDY; } void setMessageSink( MessageSink* sink ) { m_messageSink = sink; } std::vector getVisibleObjects() const; virtual void dump( std::ostream& out ) const; //! facing direction possibilities enum { LEFT = 0, RIGHT = 1, NUM_DIRECTIONS }; //! binary constants for avtar state enum { FACING_RIGHT = LAST_OBJECT_STATE << 1, MOVING_LEFT = LAST_OBJECT_STATE << 2, MOVING_RIGHT = LAST_OBJECT_STATE << 3, MOVING_ANY = MOVING_LEFT | MOVING_RIGHT, JUMPING = LAST_OBJECT_STATE << 4, DIGGING = LAST_OBJECT_STATE << 5, SHOOTING = LAST_OBJECT_STATE << 6, AIMING_UP = LAST_OBJECT_STATE << 7, AIMING_DOWN = LAST_OBJECT_STATE << 8, AIMING_ANY = AIMING_UP | AIMING_DOWN, ROPE_ON = LAST_OBJECT_STATE << 9, ROPE_OFF = LAST_OBJECT_STATE << 10, ROPE_IN = LAST_OBJECT_STATE << 11, ROPE_OUT = LAST_OBJECT_STATE << 12, ROPE_REL = LAST_OBJECT_STATE << 13, ROPE_ANY = ROPE_ON | ROPE_OFF | ROPE_IN | ROPE_OUT | ROPE_REL, MODE_GUN = LAST_OBJECT_STATE << 14, MODE_GM = LAST_OBJECT_STATE << 15, MODE_ANY = MODE_GUN | MODE_GM, IN_SKWOERMZONE = LAST_OBJECT_STATE << 16 }; static const int MAX_FUEL = 500; protected: //! Avatar should only be created in derived classes Avatar(); virtual ~Avatar(); static const real INIT_AIMING_SPEED, AIMING_SPEED_INCREMENT, MAX_AIMING_SPEED, MAX_AIMING_ANGLE, AIMING_ANGLE_TO_RAD; static const real INIT_WALKING_SPEED, MAX_WALKING_SPEED, MAX_WALKING_SPEED_DIGGING; Mix_Chunk* m_popupSample; //! implementation of pure virtual Object::update() virtual void update(); //! serialization virtual void serialize( Uint8*& bufferPointer ) const; //! deserialization virtual void deserialize( Uint8*& bufferPointer ); //! size of the buffer, needed for (de)serialization virtual Uint32 getSerializeBufferSize() const; //! maximal health value (current health derived from class Object) Sint32 m_maxHealth; //! current fuel for jet pack Counter m_fuel; //! maximal fuel real m_maxFuel; //! object ID of the gun, that the avatar is occupying at the moment Sint32 m_gunID; real m_aimingAngle, //!< aiming angle m_aimingSpeed, //!< aiming speed m_walkingSpeed; //!< aiming speed Uint32 m_stateMask; //!< masks away unwanted states, e.g., walking when in gun mode //! bonus pack for keeping boni BonusPack m_bonusPack; Sint32 m_weaponPivotDY; //! pointer to the player object of this avatar Player *m_Player; MessageSink m_defaultMessageSink; MessageSink* m_messageSink; }; /**********************************************************/ #endif // _AVATAR_HPP_