1 /* $Id: avatar.hpp,v 1.86.2.2 2006/01/20 11:33:52 chfreund Exp $ */ 2 3 #ifndef _AVATAR_HPP_ 4 #define _AVATAR_HPP_ 5 6 /**********************************************************/ 7 8 #include <vector> 9 #include <iostream> 10 11 #include "global.hpp" 12 #include "collidableobject.hpp" 13 #include "spriteset.hpp" 14 #include "player.hpp" 15 #include "vector.hpp" 16 #include "random.hpp" 17 #include "map.hpp" 18 #include "world.hpp" 19 #include "particles.hpp" 20 #include "flag.hpp" 21 #include "messages.hpp" 22 #include "bonuspack.hpp" 23 #include "counter.hpp" 24 25 #include <SDL_mixer.h> 26 27 /**********************************************************/ 28 class HomingMissile; 29 class StationaryGun; 30 /********************************************************** 31 * Base class for all avatars. 32 **********************************************************/ 33 34 //! the basic object for all avatars 35 36 /*! This is the base class for all avatars. 37 * For more information about the Avatar \f$\leftrightarrow\f$ 38 * Player connection see the description of class Player. 39 */ 40 class Avatar : public CollidableObject 41 { 42 friend void Player::attachAvatar( Avatar* const avatar ); 43 friend Avatar* Player::detachAvatar(); 44 45 public: 46 47 ////////////////////////////////////////// 48 //! \name aiming angle, aiming speed, aiming, direction ... 49 50 //@{ 51 //! returns the aiming angle getAimingAngle() const52 real getAimingAngle() const { return m_aimingAngle; } 53 //! returns the aiming speed getAimingSpeed() const54 real getAimingSpeed() const { return m_aimingSpeed; } 55 //! returns the aiming vector getAimingVector() const56 Vector getAimingVector() const { 57 return Vector( getAimingDX(), getAimingDY() ); } 58 //! returns the x component of the aiming vector getAimingDX() const59 real getAimingDX() const { 60 return (isFacingRight() ? 1 : -1) 61 * SIN_REAL( m_aimingAngle*AIMING_ANGLE_TO_RAD ); } 62 //! returns the y component of the aiming vector getAimingDY() const63 real getAimingDY() const { 64 return -COS_REAL( m_aimingAngle*AIMING_ANGLE_TO_RAD ); } 65 //! returns a randomly perturbated aiming vector getRandomizedAimingVector(const real maxTremble) const66 Vector getRandomizedAimingVector( const real maxTremble ) const { 67 real tremble = 0.5 - m_worldPointer->getRandom().getNormedReal(); 68 tremble *= (M_PI/180.0); 69 tremble *= maxTremble; 70 return Vector( (isFacingRight() ? 1 : -1) 71 * SIN_REAL( m_aimingAngle*AIMING_ANGLE_TO_RAD+tremble ), 72 -COS_REAL( m_aimingAngle*AIMING_ANGLE_TO_RAD+tremble ) ); 73 } 74 //! comment missing 75 Vector placeBesideCollRect( const int marginLeft = 0, 76 const int marginRight = 0, 77 const int marginTop = 0, 78 const int marginBottom = 0 ); 79 80 //! sets the aiming angle setAimingAngle(const real aimingAngle)81 bool setAimingAngle( const real aimingAngle ) { 82 if( aimingAngle > MAX_AIMING_ANGLE ) { 83 m_aimingAngle = MAX_AIMING_ANGLE; 84 updateSpriteSelection(); 85 return false; 86 } 87 else if( aimingAngle < 0.0 ) { 88 m_aimingAngle = 0.0; 89 updateSpriteSelection(); 90 return false; 91 } 92 else { 93 m_aimingAngle = aimingAngle; 94 updateSpriteSelection(); 95 return true; 96 } 97 } 98 99 //! sets turning of aiming 100 void setAimingDirection( const int dir ); 101 102 //! sets the direction (see enumeration type) 103 104 /*! Sets the new direction of the avatar. The passed direction 105 * must be in the range of defined (enumeration constants in 106 * this class) directions. If you add further directions, you 107 * must also adapt the method updateSequenceIndex(). 108 */ 109 void setDirection( const Uint32 direction ); 110 111 //! returns the direction (enumeration type) getDirection() const112 Uint32 getDirection() const { 113 return (isFacingRight() ? RIGHT : LEFT); } 114 //@} 115 116 ////////////////////////////////////////// 117 //! \name information about the action state 118 119 //@{ isMovingLeft(void) const120 bool isMovingLeft ( void ) const { return m_state & m_stateMask & MOVING_LEFT; } isMovingRight(void) const121 bool isMovingRight ( void ) const { return m_state & m_stateMask & MOVING_RIGHT; } isMovingAny(void) const122 bool isMovingAny ( void ) const { return m_state & m_stateMask & MOVING_ANY; } isJumping(void) const123 bool isJumping ( void ) const { return m_state & m_stateMask & JUMPING; } isDigging(void) const124 bool isDigging ( void ) const { return m_state & m_stateMask & DIGGING; } isShooting(void) const125 bool isShooting ( void ) const { return m_state & m_stateMask & SHOOTING; } isAimingUp(void) const126 bool isAimingUp ( void ) const { return m_state & m_stateMask & AIMING_UP; } isAimingDown(void) const127 bool isAimingDown ( void ) const { return m_state & m_stateMask & AIMING_DOWN; } isFacingRight(void) const128 bool isFacingRight ( void ) const { return m_state & m_stateMask & FACING_RIGHT; } isSetRopeOn(void) const129 bool isSetRopeOn ( void ) const { return m_state & m_stateMask & ROPE_ON; } isSetRopeOff(void) const130 bool isSetRopeOff ( void ) const { return m_state & m_stateMask & ROPE_OFF; } isSetRopeIn(void) const131 bool isSetRopeIn ( void ) const { return m_state & m_stateMask & ROPE_IN; } isSetRopeOut(void) const132 bool isSetRopeOut ( void ) const { return m_state & m_stateMask & ROPE_OUT; } isSetRopeRel(void) const133 bool isSetRopeRel ( void ) const { return m_state & m_stateMask & ROPE_REL; } isInGunMode(void) const134 bool isInGunMode ( void ) const { return m_state & MODE_GUN; } isInGMMode(void) const135 bool isInGMMode ( void ) const { return m_state & MODE_GM; } isInAnyMode(void) const136 bool isInAnyMode ( void ) const { return m_state & MODE_ANY; } isInSkwoermZone(void) const137 bool isInSkwoermZone( void ) const { return m_state & IN_SKWOERMZONE; } setStateMask(const Uint32 mask)138 void setStateMask( const Uint32 mask ) { m_stateMask = mask; } 139 140 //@} 141 142 ////////////////////////////////////////// 143 //! \name routines for special states 144 145 //@{ 146 //! the avatar takes a seat in the passed gun 147 virtual void sitDownInGun( StationaryGun *const gun ); 148 //! the avatar leaves gun, it is currently sitting in 149 virtual void leaveCurrentGun(); 150 //! the avatar takes the remote control 151 virtual void takeRemoteControl(); 152 //! the avatar drops the remote control 153 virtual void dropRemoteControl(); 154 //@} 155 156 ////////////////////////////////////////// 157 //! \name the avatar's health 158 159 //@{ 160 //! returns the avatar's maximal health value getMaxHealth() const161 Sint32 getMaxHealth() const { return m_maxHealth; } 162 //! sets the maximal health value setMaxHealth(const Sint32 H)163 void setMaxHealth( const Sint32 H ) { m_maxHealth = H; } 164 //! heals the avatar by \c addHealth points heal(const Sint32 addHealth)165 void heal( const Sint32 addHealth ) { 166 if( (m_health += addHealth) > m_maxHealth ) { 167 m_health = m_maxHealth; 168 } 169 } 170 //@} 171 172 ////////////////////////////////////////// 173 //! \name fuel for the jet pack 174 175 //@{ 176 //! returns the current fuel getFuel() const177 real getFuel() const { return m_fuel.getTimeToLive(); } 178 //! returns the tank size (maximal fuel) getMaxFuel() const179 real getMaxFuel() const { return m_maxFuel; } 180 //! fills fuel in the tank fillFuel(const real fuel)181 void fillFuel( const real fuel ) { 182 if( m_fuel.isElapsed() ) m_fuel.setTimeToLive( 0.0 ); 183 if( (m_fuel.getTimeToLive() + fuel) > m_maxFuel ) { 184 m_fuel.setTimeToLive( m_maxFuel ); 185 } 186 else { 187 m_fuel.setTimeToLive( m_fuel.getTimeToLive() + fuel ); 188 } 189 } 190 //@} 191 192 ////////////////////////////////////////// 193 //! \name connected player object 194 195 //@{ 196 //! returns the pointer to the connected player object 197 198 /*! Returns the pointer to the Player object (also see description 199 * of class Player), this avatar is attached to. Attaching and 200 * detaching can and should be done only by the two friend 201 * methods Player::attachAvatar and Player::detachAvatar. 202 */ getPlayer()203 Player* getPlayer() { return m_Player; } 204 //! the "const" version of getPlayer getPlayer() const205 const Player* getPlayer() const { return m_Player; } 206 //q} 207 208 ////////////////////////////////////////// 209 /*! \name functions concerning the graphic of the avatar 210 * \brief Besides the implementation of the functions 211 * Object::getColors() and Object::getNumColors class Avatar 212 * must provide an interface to set and get the skin color and 213 * the team color and the player color. This does not mean 214 * that these three colors differ pairwise (for example see 215 * class AvatarWorm). Als functions to set a color take an 216 * additional bool flag, which specifies, whether the game 217 * mode lets each player play alone or in a team. This is 218 * important, for example, if in team modes a different area 219 * of the avatar is used for the personal player color than 220 * in single player modes. 221 * <br> 222 * <b>Important</b>: Note that, no matter how these colors 223 * are organized, the implementations of Object::getColors() 224 * still must return a pointer to an array containing 225 * getNumColors() color values, exactly ordered like the 226 * layers in the avatars graphic, whereby getNumColors() and 227 * the number of layers must match! 228 */ 229 230 //@{ 231 //! a virtual interface to set the player color 232 virtual void setPlayerColor( const Uint32 color ) = 0; 233 /*! \brief a virtual interface to set the skin color 234 * NOTE: this function is a relict, and it is not clear, when 235 * it should be used. Before you use it, please check, if not 236 * setPlayerColor or setTeamColor is the function you want to 237 * use. 238 */ 239 virtual void setSkinColor( const Uint32 color ) = 0; 240 //! a virtual interface to set the team color 241 virtual void setTeamColor( const Uint32 color ) = 0; 242 //! a virtual interface to get the skin color 243 virtual Uint32 getSkinColor() const = 0; 244 //! a virtual interface to get the team color 245 virtual Uint32 getTeamColor() const = 0; 246 //! a virtual interface to get the player color 247 virtual Uint32 getPlayerColor() const = 0; 248 //@} 249 250 //! spawn the avatar at a randomly chosen position 251 void spawnAvatar( void ); 252 253 ////////////////////////////////////////// 254 //! \name functions concerning the avatar's movement 255 256 //@{ 257 //! digging in the dirt (P. Gabriel) 258 void dig( void ); 259 //! ???? 260 void testGrounded( bool& groundedMid, bool& groundedFW, 261 bool& groundedBW ); 262 testGrounded(void)263 virtual bool testGrounded( void ) { 264 bool groundedMid, groundedFW, groundedBW; 265 testGrounded( groundedMid, groundedFW, groundedBW ); 266 if( isGrounded() ) 267 return groundedMid | groundedFW | groundedBW; 268 else 269 return groundedMid; 270 } 271 testPassableRel(const int dx,const int dy)272 bool testPassableRel( const int dx, const int dy ) { 273 return m_worldPointer->getMap()->testPassableSmoothing( 274 ROUND( m_pos.x ) + dx, ROUND( m_pos.y ) + dy, 275 Flags::OBSTACLE_EARTH | Flags::OBSTACLE_OBJECT ); 276 } 277 //! ???? testLinePassableRel(const int dx1,const int dy1,const int dx2,const int dy2,int & pcx,int & pcy,int & cx,int & cy)278 bool testLinePassableRel( const int dx1, const int dy1, 279 const int dx2, const int dy2, 280 int& pcx, int& pcy, int& cx, int& cy ) { 281 return m_worldPointer->getMap()->testLinePassableSmoothing( 282 ROUND( m_pos.x ) + dx1, ROUND( m_pos.y ) + dy1, 283 ROUND( m_pos.x ) + dx2, ROUND( m_pos.y ) + dy2, 284 pcx, pcy, cx, cy, 285 Flags::OBSTACLE_EARTH | Flags::OBSTACLE_OBJECT ); 286 } 287 //@} 288 289 //! applies damage to the avatar (reimplemented from CollidableObject) 290 291 /*! This method applies damage to the avatar, caused by the passed 292 * passed particle. It is reimplemented here, for example because 293 * of shield boni, which beware the avatar of damage, but not of 294 * the particles recoil. 295 */ 296 virtual int applyDamage( const Particles::ParticleData& p ); 297 298 //! applies damage to the avatar (reimplemented from CollidableObject) 299 virtual int applyDamage( const int damage, Player* shooter ); 300 301 ////////////////////////////////////////// 302 //! /name methods concerning boni 303 304 //@{ 305 //! pick up the passed bonus 306 307 /*! The collission rectangle of the passed bonus must not be set 308 * at the moment, it is passed to this function. This function 309 * will remove the bonus from the world, since it is consumed 310 * and therefore also administrated by the avatar and therefore 311 * not longer existent in the world. In addition to this the 312 * bonus object might also be deleted by this function, depending 313 * on the specific bonus type and possibly already present boni 314 * in the avatar's bonus pack. <b>Do not use the bonus object after 315 * this call any more</b>, since you do not know, whether it 316 * still exists. But you also have not to care about it anyway, 317 * because it is administrated by the avatars bonus pack from 318 * now on! 319 */ 320 void pickUp( Bonus* bonus ); 321 322 //! returns the bonus pack getBonusPack()323 BonusPack& getBonusPack() { return m_bonusPack; } 324 //! returns the bonus pack getBonusPack() const325 const BonusPack& getBonusPack() const { return m_bonusPack; } 326 //@} 327 328 ////////////////////////////////////////// 329 //! \name methods concerning special weapons 330 331 //@{ 332 333 void getLockedByHomingMissile( HomingMissile *const missile, 334 const real distanceSquare ); 335 //@} 336 getWeaponPivotDY(void) const337 Sint32 getWeaponPivotDY( void ) const { return m_weaponPivotDY; } 338 setMessageSink(MessageSink * sink)339 void setMessageSink( MessageSink* sink ) { 340 m_messageSink = sink; 341 } 342 343 std::vector<Object*> getVisibleObjects() const; 344 345 virtual void dump( std::ostream& out ) const; 346 347 //! facing direction possibilities 348 enum { LEFT = 0, 349 RIGHT = 1, 350 NUM_DIRECTIONS }; 351 352 //! binary constants for avtar state 353 enum { FACING_RIGHT = LAST_OBJECT_STATE << 1, 354 MOVING_LEFT = LAST_OBJECT_STATE << 2, 355 MOVING_RIGHT = LAST_OBJECT_STATE << 3, 356 MOVING_ANY = MOVING_LEFT | MOVING_RIGHT, 357 JUMPING = LAST_OBJECT_STATE << 4, 358 DIGGING = LAST_OBJECT_STATE << 5, 359 SHOOTING = LAST_OBJECT_STATE << 6, 360 AIMING_UP = LAST_OBJECT_STATE << 7, 361 AIMING_DOWN = LAST_OBJECT_STATE << 8, 362 AIMING_ANY = AIMING_UP | AIMING_DOWN, 363 ROPE_ON = LAST_OBJECT_STATE << 9, 364 ROPE_OFF = LAST_OBJECT_STATE << 10, 365 ROPE_IN = LAST_OBJECT_STATE << 11, 366 ROPE_OUT = LAST_OBJECT_STATE << 12, 367 ROPE_REL = LAST_OBJECT_STATE << 13, 368 ROPE_ANY = ROPE_ON | ROPE_OFF | ROPE_IN | ROPE_OUT | ROPE_REL, 369 MODE_GUN = LAST_OBJECT_STATE << 14, 370 MODE_GM = LAST_OBJECT_STATE << 15, 371 MODE_ANY = MODE_GUN | MODE_GM, 372 IN_SKWOERMZONE = LAST_OBJECT_STATE << 16 373 }; 374 375 static const int MAX_FUEL = 500; 376 377 protected: 378 379 //! Avatar should only be created in derived classes 380 Avatar(); 381 virtual ~Avatar(); 382 383 static const real INIT_AIMING_SPEED, 384 AIMING_SPEED_INCREMENT, 385 MAX_AIMING_SPEED, 386 MAX_AIMING_ANGLE, 387 AIMING_ANGLE_TO_RAD; 388 static const real INIT_WALKING_SPEED, 389 MAX_WALKING_SPEED, 390 MAX_WALKING_SPEED_DIGGING; 391 392 Mix_Chunk* m_popupSample; 393 394 395 //! implementation of pure virtual Object::update() 396 virtual void update(); 397 398 //! serialization 399 virtual void serialize( Uint8*& bufferPointer ) const; 400 //! deserialization 401 virtual void deserialize( Uint8*& bufferPointer ); 402 //! size of the buffer, needed for (de)serialization 403 virtual Uint32 getSerializeBufferSize() const; 404 405 //! maximal health value (current health derived from class Object) 406 Sint32 m_maxHealth; 407 //! current fuel for jet pack 408 Counter m_fuel; 409 //! maximal fuel 410 real m_maxFuel; 411 //! object ID of the gun, that the avatar is occupying at the moment 412 Sint32 m_gunID; 413 414 real m_aimingAngle, //!< aiming angle 415 m_aimingSpeed, //!< aiming speed 416 m_walkingSpeed; //!< aiming speed 417 418 Uint32 m_stateMask; //!< masks away unwanted states, e.g., walking when in gun mode 419 420 //! bonus pack for keeping boni 421 BonusPack m_bonusPack; 422 423 Sint32 m_weaponPivotDY; 424 425 //! pointer to the player object of this avatar 426 Player *m_Player; 427 428 MessageSink m_defaultMessageSink; 429 MessageSink* m_messageSink; 430 }; 431 432 /**********************************************************/ 433 434 #endif // _AVATAR_HPP_ 435