home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / enemies / enemy.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2008-05-04  |  6.2 KB  |  252 lines

  1. /***************************************************************************
  2.  * enemy.cpp  -  base class for all enemies
  3.  *
  4.  * Copyright (C) 2003 - 2008 Florian Richter
  5.  ***************************************************************************/
  6. /*
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 3 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. #include "../enemies/enemy.h"
  17. #include "../core/camera.h"
  18. #include "../video/animation.h"
  19. #include "../user/savegame.h"
  20. #include "../core/game_core.h"
  21.  
  22. /* *** *** *** *** *** *** cEnemy *** *** *** *** *** *** *** *** *** *** *** */
  23.  
  24. cEnemy :: cEnemy( float x /* = 0 */, float y /* = 0 */ )
  25. : cImageObjectSprite( x, y )
  26. {
  27.     sprite_array = ARRAY_ENEMY;
  28.     type = TYPE_ENEMY;
  29.  
  30.     player_range = 1500;
  31.  
  32.     massivetype = MASS_MASSIVE;
  33.     state = STA_FALL;
  34.     dead = 0;
  35.  
  36.     counter = 0;
  37.     walk_count = 0;
  38.  
  39.     kill_sound = "enemy/furball/die.ogg";
  40.     kill_points = 10;
  41.  
  42.     fire_resistant = 0;
  43. }
  44.  
  45. cEnemy :: ~cEnemy( void )
  46. {
  47.  
  48. }
  49.  
  50. void cEnemy :: Load_from_Savegame( cSave_Level_Object *save_object )
  51. {
  52.     // direction
  53.     if( save_object->exists( "direction" ) )
  54.     {
  55.         direction = (ObjectDirection)string_to_int( save_object->Get_Value( "direction" ) );
  56.     }
  57.  
  58.     // state
  59.     if( save_object->exists( "state" ) )
  60.     {
  61.         state = (Moving_state)string_to_int( save_object->Get_Value( "state" ) );
  62.     }
  63.  
  64.     // new position x
  65.     if( save_object->exists( "new_posx" ) )
  66.     {
  67.         Set_Pos_X( string_to_float( save_object->Get_Value( "new_posx" ) ) );
  68.     }
  69.  
  70.     // new position y
  71.     if( save_object->exists( "new_posy" ) )
  72.     {
  73.         Set_Pos_Y( string_to_float( save_object->Get_Value( "new_posy" ) ) );
  74.     }
  75.  
  76.     // velocity x
  77.     if( save_object->exists( "velx" ) )
  78.     {
  79.         velx = string_to_float( save_object->Get_Value( "velx" ) );
  80.     }
  81.  
  82.     // velocity y
  83.     if( save_object->exists( "vely" ) )
  84.     {
  85.         vely = string_to_float( save_object->Get_Value( "vely" ) );
  86.     }
  87.  
  88.     // visible
  89.     if( save_object->exists( "visible" ) )
  90.     {
  91.         Set_Visible( string_to_int( save_object->Get_Value( "visible" ) ) > 0 );
  92.     }
  93.  
  94.     // dead
  95.     if( save_object->exists( "dead" ) )
  96.     {
  97.         Set_Dead( string_to_int( save_object->Get_Value( "dead" ) ) > 0 );
  98.     }
  99. }
  100.  
  101. cSave_Level_Object *cEnemy :: Save_to_Savegame( void )
  102. {
  103.     cSave_Level_Object *save_object = new cSave_Level_Object();
  104.  
  105.     // default values
  106.     save_object->type = type;
  107.     save_object->properties.push_back( cSave_Level_Object_Property( "posx", int_to_string( static_cast<int>(startposx) ) ) );
  108.     save_object->properties.push_back( cSave_Level_Object_Property( "posy", int_to_string( static_cast<int>(startposy) ) ) );
  109.  
  110.     // direction
  111.     save_object->properties.push_back( cSave_Level_Object_Property( "direction", int_to_string( direction ) ) );
  112.  
  113.     // state
  114.     save_object->properties.push_back( cSave_Level_Object_Property( "state", int_to_string( state ) ) );
  115.  
  116.     // new position ( only save if needed )
  117.     if( startposx != posx || startposy != posy )
  118.     {
  119.         save_object->properties.push_back( cSave_Level_Object_Property( "new_posx", int_to_string( static_cast<int>(posx) ) ) );
  120.         save_object->properties.push_back( cSave_Level_Object_Property( "new_posy", int_to_string( static_cast<int>(posy) ) ) );
  121.     }
  122.  
  123.     // velocity
  124.     save_object->properties.push_back( cSave_Level_Object_Property( "velx", float_to_string( velx ) ) );
  125.     save_object->properties.push_back( cSave_Level_Object_Property( "vely", float_to_string( vely ) ) );
  126.  
  127.     // visible ( only save if needed )
  128.     if( !visible )
  129.     {
  130.         save_object->properties.push_back( cSave_Level_Object_Property( "visible", int_to_string( visible ) ) );
  131.     }
  132.  
  133.     // dead ( only save if needed )
  134.     if( dead )
  135.     {
  136.         save_object->properties.push_back( cSave_Level_Object_Property( "dead", int_to_string( dead ) ) );
  137.     }
  138.  
  139.     return save_object;
  140. }
  141.  
  142. void cEnemy :: Set_Dead( bool enable /* = 1 */ )
  143. {
  144.     dead = enable;
  145.  
  146.     Update_Valid_Update();
  147. }
  148.  
  149. void cEnemy :: DieStep( void )
  150. {
  151.     // virtual
  152. }
  153.  
  154. void cEnemy :: Update( void )
  155. {
  156.     cMovingSprite::Update();
  157.  
  158.     // another object controls me
  159.     if( state == STA_OBJ_LINKED )
  160.     {
  161.         massivetype = MASS_MASSIVE;
  162.         Collision_Check( &col_rect );
  163.         Parse_Collisions();
  164.         massivetype = MASS_PASSIVE;
  165.         return;
  166.     }
  167.  
  168.     // dying animation
  169.     if( dead && visible )
  170.     {
  171.         DieStep();
  172.     }
  173.  
  174.     // frozen
  175.     if( freeze_counter )
  176.     {
  177.         // update gravity
  178.         if( type == TYPE_FURBALL || type == TYPE_TURTLE || type == TYPE_KRUSH || type == TYPE_SPIKA )
  179.         {
  180.             Update_Gravity();
  181.             Col_Move( 0, vely );
  182.         }
  183.     }
  184. }
  185.  
  186. void cEnemy :: Update_Gravity( void )
  187. {
  188.     if( !ground_object && vely < 25 )
  189.     {
  190.         Add_Velocity( 0, 1.5f );
  191.     }
  192.     else if( ground_object && vely > 0 )
  193.     {
  194.         vely = 0;
  195.     }
  196. }
  197.  
  198. void cEnemy :: Generate_Hit_Animation( cParticle_Emitter *anim /* = NULL */ )
  199. {
  200.     bool create_anim = 0;
  201.  
  202.     if( !anim )
  203.     {
  204.         create_anim = 1;
  205.         // create animation
  206.         anim = new cParticle_Emitter();
  207.     }
  208.  
  209.     anim->Set_Emitter_Rect( col_rect.x, posy + ( col_rect.h / 3 ), col_rect.w );
  210.     anim->Set_Image( pVideo->Get_Surface( "animation/particles/light.png" ) );
  211.     anim->Set_Quota( 4 );
  212.     anim->Set_Pos_Z( posz - 0.000001f );
  213.     anim->Set_Time_to_Live( 0.3f );
  214.     anim->Set_Color( Color( static_cast<Uint8>(150), 150, 150, 200 ), Color( static_cast<Uint8>( rand() % 155 ), rand() % 155, rand() % 155 ) );
  215.     anim->Set_Speed( 3, 0.6f );
  216.     anim->Set_Scale( 0.6f );
  217.     anim->Set_Direction_Range( 180, 180 );
  218.     anim->Set_Fading_Alpha( 1 );
  219.     anim->Set_Fading_Size( 1 );
  220.     anim->Set_Blending( BLEND_DRIVE );
  221.     
  222.     if( create_anim )
  223.     {
  224.         // add animation
  225.         pAnimation_Manager->Add( anim );
  226.     }
  227. }
  228.  
  229. void cEnemy :: Handle_Collision( cObjectCollision *collision )
  230. {
  231.     if( dead )
  232.     {
  233.         return;
  234.     }
  235.  
  236.     cImageObjectSprite::Handle_Collision( collision );
  237. }
  238.  
  239. void cEnemy :: Handle_out_of_Level( ObjectDirection dir )
  240. {
  241.     if( dir == DIR_LEFT )
  242.     {
  243.         Set_Pos_X( pActive_Camera->limit_rect.x - col_pos.x );
  244.     }
  245.     else if( dir == DIR_RIGHT )
  246.     {
  247.         Set_Pos_X( pActive_Camera->limit_rect.x + pActive_Camera->limit_rect.w - col_pos.x - col_rect.w - 0.01f );
  248.     }
  249.  
  250.     Turn_Around( dir );
  251. }
  252.