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

  1. /***************************************************************************
  2.  * krush.cpp  -  The little dinosaur
  3.  *
  4.  * Copyright (C) 2004 - 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/krush.h"
  17. #include "../core/game_core.h"
  18. #include "../video/animation.h"
  19. #include "../gui/hud.h"
  20. #include "../player/player.h"
  21. #include "../video/gl_surface.h"
  22. #include "../user/savegame.h"
  23. #include "../core/i18n.h"
  24.  
  25. /* *** *** *** *** *** cKrush *** *** *** *** *** *** *** *** *** *** *** *** */
  26.  
  27. cKrush :: cKrush( float x, float y )
  28. : cEnemy( x, y )
  29. {
  30.     cKrush::Init();
  31. }
  32.  
  33. cKrush :: cKrush( CEGUI::XMLAttributes &attributes )
  34. : cEnemy()
  35. {
  36.     cKrush::Init();
  37.     cKrush::Create_from_Stream( attributes );
  38. }
  39.  
  40. cKrush :: ~cKrush( void )
  41. {
  42.     //
  43. }
  44.  
  45. void cKrush :: Init( void  )
  46. {
  47.     type = TYPE_KRUSH;
  48.     posz = 0.093f;
  49.  
  50.     state = STA_WALK;
  51.     krush_state = KRUSH_WALK;
  52.  
  53.     speed = 6;
  54.  
  55.     images.push_back( pVideo->Get_Surface( "enemy/krush/big_1.png" ) );
  56.     images.push_back( pVideo->Get_Surface( "enemy/krush/big_2.png" ) );
  57.     images.push_back( pVideo->Get_Surface( "enemy/krush/big_3.png" ) );
  58.     images.push_back( pVideo->Get_Surface( "enemy/krush/big_4.png" ) );
  59.     images.push_back( pVideo->Get_Surface( "enemy/krush/small_1.png" ) );
  60.     images.push_back( pVideo->Get_Surface( "enemy/krush/small_2.png" ) );
  61.     images.push_back( pVideo->Get_Surface( "enemy/krush/small_3.png" ) );
  62.     images.push_back( pVideo->Get_Surface( "enemy/krush/small_4.png" ) );
  63.  
  64.     Set_Direction( DIR_RIGHT );
  65.  
  66.     Set_Image( 0, 1 );
  67.  
  68.     kill_sound = "enemy/krush/die.ogg";
  69.     kill_points = 20;
  70. }
  71.  
  72. cKrush *cKrush :: Copy( void )
  73. {
  74.     cKrush *krush = new cKrush( startposx, startposy );
  75.     krush->Set_Direction( start_direction );
  76.  
  77.     return krush;
  78. }
  79.  
  80. void cKrush :: Create_from_Stream( CEGUI::XMLAttributes &attributes )
  81. {
  82.     // position
  83.     Set_Pos( static_cast<float>(attributes.getValueAsInteger( "posx" )), static_cast<float>(attributes.getValueAsInteger( "posy" )), 1 );
  84.     // direction
  85.     Set_Direction( Get_Direction_Id( attributes.getValueAsString( "direction", Get_Direction_Name( start_direction ) ).c_str() ) );
  86. }
  87.  
  88. void cKrush :: Save_to_Stream( ofstream &file )
  89. {
  90.     // begin enemy
  91.     file << "\t<enemy>" << std::endl;
  92.  
  93.     // name
  94.     file << "\t\t<Property name=\"type\" value=\"krush\" />" << std::endl;
  95.     // position
  96.     file << "\t\t<Property name=\"posx\" value=\"" << static_cast<int>(startposx) << "\" />" << std::endl;
  97.     file << "\t\t<Property name=\"posy\" value=\"" << static_cast<int>(startposy) << "\" />" << std::endl;
  98.     // direction
  99.     file << "\t\t<Property name=\"direction\" value=\"" << Get_Direction_Name( start_direction ) << "\" />" << std::endl;
  100.  
  101.     // end enemy
  102.     file << "\t</enemy>" << std::endl;
  103. }
  104.  
  105. void cKrush :: Load_from_Savegame( cSave_Level_Object *save_object )
  106. {
  107.     cEnemy::Load_from_Savegame( save_object );
  108.  
  109.     // krush_state
  110.     if( save_object->exists( "krush_state" ) )
  111.     {
  112.         krush_state = static_cast<Krush_state>(string_to_int( save_object->Get_Value( "krush_state" ) ));
  113.  
  114.         if( krush_state == KRUSH_SMALL )
  115.         {
  116.             // todo : create a Set_State function
  117.             // set small image without position changes
  118.             cSprite::Set_Image( images[4] );
  119.             kill_points = 40;
  120.         }
  121.     }
  122.  
  123.     Update_Rotation_Hor_velx();
  124. }
  125.  
  126. cSave_Level_Object *cKrush :: Save_to_Savegame( void )
  127. {
  128.     cSave_Level_Object *save_object = cEnemy::Save_to_Savegame();
  129.  
  130.     // krush_state ( only save if needed )
  131.     if( krush_state != KRUSH_WALK )
  132.     {
  133.         save_object->properties.push_back( cSave_Level_Object_Property( "krush_state", int_to_string( krush_state ) ) );
  134.     }
  135.  
  136.     return save_object;
  137. }
  138.  
  139. void cKrush :: Set_Direction( ObjectDirection dir )
  140. {
  141.     // already set
  142.     if( start_direction == dir )
  143.     {
  144.         return;
  145.     }
  146.  
  147.     cEnemy::Set_Direction( dir, 1 );
  148.  
  149.     name = "Krush ";
  150.     name += _(Get_Direction_Name( start_direction ).c_str());
  151.  
  152.     if( start_direction == DIR_RIGHT )
  153.     {
  154.         velx = 2.5f;
  155.     }
  156.     else
  157.     {
  158.         velx = -2.5f;
  159.     }
  160.  
  161.     Update_Rotation_Hor_velx( 1 );
  162. }
  163.  
  164. void cKrush :: DownGrade( bool force /* = 0 */ )
  165. {
  166.     // default stomp downgrade
  167.     if( !force )
  168.     {
  169.         // big to small walking
  170.         if( krush_state == KRUSH_WALK )
  171.         {
  172.             krush_state = KRUSH_SMALL;
  173.             state = STA_RUN;
  174.             velx = ( direction == DIR_RIGHT ) ? (speed) : (-speed);
  175.             counter = 4;
  176.             kill_points = 40;
  177.  
  178.             Set_Image( static_cast<int>(counter) );
  179.             Col_Move( 0, images[3]->col_h - images[4]->col_h, 1, 1 );
  180.             Update_Direction();
  181.  
  182.             // animation
  183.             cParticle_Emitter *anim = new cParticle_Emitter();
  184.             anim->Set_Pos( posx + ( col_rect.w / 2 ), posy + ( col_rect.h / 4 ) );
  185.             Generate_Hit_Animation( anim );
  186.  
  187.             anim->Set_Speed( 3.5f, 0.6f );
  188.             anim->Set_Fading_Alpha( 1 );
  189.             // add animation
  190.             pAnimation_Manager->Add( anim );
  191.         }
  192.         else if( krush_state == KRUSH_SMALL )
  193.         {
  194.             Set_Scale_Directions( 1, 0, 1, 1 );
  195.             Set_Dead( 1 );
  196.  
  197.             // animation
  198.             cParticle_Emitter *anim = new cParticle_Emitter();
  199.             anim->Set_Pos( posx + ( col_rect.w / 2 ), posy + ( col_rect.h / 2 ) );
  200.             Generate_Hit_Animation( anim );
  201.  
  202.             anim->Set_Speed( 4.5f, 1.6f );
  203.             anim->Set_Scale( 0.6f );
  204.             // add animation
  205.             pAnimation_Manager->Add( anim );
  206.         }
  207.     }
  208.     // falling death
  209.     else
  210.     {
  211.         Set_Dead( 1 );
  212.         Set_Rotation_Z( 180 );
  213.     }
  214.  
  215.     if( dead )
  216.     {
  217.         krush_state = KRUSH_DEAD;
  218.         state = STA_STAY;
  219.         massivetype = MASS_PASSIVE;
  220.         counter = 0;
  221.         velx = 0;
  222.         vely = 0;
  223.     }
  224. }
  225.  
  226. void cKrush :: DieStep( void )
  227. {
  228.     counter += pFramerate->speedfactor;
  229.  
  230.     // stomp death
  231.     if( rotz != 180 )
  232.     {
  233.         float speed = pFramerate->speedfactor * 0.05f;
  234.  
  235.         Add_Scale_X( -speed * 0.5f );
  236.         Add_Scale_Y( -speed );
  237.  
  238.         if( scaley < 0.01f )
  239.         {
  240.             Set_Scale( 1 );
  241.             Set_Visible( 0 );
  242.         }
  243.     }
  244.     // falling death
  245.     else
  246.     {
  247.         // a little bit upwards first
  248.         if( counter < 5 )
  249.         {
  250.             Move( 0, -5 );
  251.         }
  252.         // if not below the screen fall
  253.         else if( posy < game_res_h + col_rect.h )
  254.         {
  255.             Move( 0, 20 );
  256.         }
  257.         // if below disable
  258.         else
  259.         {
  260.             rotz = 0;
  261.             Set_Visible( 0 );
  262.         }
  263.     }
  264. }
  265.  
  266. void cKrush :: Update( void )
  267. {
  268.     cEnemy::Update();
  269.  
  270.     if( !valid_update || !is_Player_range() )
  271.     {
  272.         return;
  273.     }
  274.  
  275.     if( krush_state == KRUSH_WALK )
  276.     {
  277.         counter += pFramerate->speedfactor * 0.3f;
  278.  
  279.         if( counter >= 4 )
  280.         {
  281.             counter = 0;
  282.         }
  283.     }
  284.     else
  285.     {
  286.         counter += pFramerate->speedfactor * 0.5f;
  287.  
  288.         if( counter >= 8 )
  289.         {
  290.             counter = 4;
  291.         }
  292.     }
  293.  
  294.     Set_Image( static_cast<int>(counter) );
  295.  
  296.     // gravity
  297.     Update_Gravity();
  298.  
  299.     Update_Rotation_Hor_velx();
  300. }
  301.  
  302. bool cKrush :: Is_Update_Valid( void )
  303. {
  304.     if( dead || freeze_counter )
  305.     {
  306.         return 0;
  307.     }
  308.  
  309.     return 1;
  310. }
  311.  
  312. unsigned int cKrush :: Validate_Collision( cSprite *obj )
  313. {
  314.     // basic validation checking
  315.     int basic_valid = Validate_Collision_Ghost( obj );
  316.  
  317.     // found valid collision
  318.     if( basic_valid > -1 )
  319.     {
  320.         return basic_valid;
  321.     }
  322.  
  323.     if( obj->massivetype == MASS_MASSIVE )
  324.     {
  325.         if( obj->type == TYPE_JPIRANHA )
  326.         {
  327.             return 0;
  328.         }
  329.         if( obj->type == TYPE_ROKKO )
  330.         {
  331.             return 0;
  332.         }
  333.         if( obj->type == TYPE_GEE )
  334.         {
  335.             return 0;
  336.         }
  337.  
  338.         return 2;
  339.     }
  340.     if( obj->type == TYPE_ENEMY_STOPPER )
  341.     {
  342.         return 2;
  343.     }
  344.     if( obj->massivetype == MASS_HALFMASSIVE )
  345.     {
  346.         // if moving downwards and object is on top
  347.         if( vely >= 0 && Is_on_Top( obj ) )
  348.         {
  349.             return 2;
  350.         }
  351.     }
  352.  
  353.     return 0;
  354. }
  355.  
  356. void cKrush :: Handle_Collision_Player( cObjectCollision *collision )
  357. {
  358.     // invalid
  359.     if( collision->direction == DIR_UNDEFINED )
  360.     {
  361.         return;
  362.     }
  363.  
  364.     if( collision->direction == DIR_TOP && pPlayer->state != STA_FLY )
  365.     {
  366.         pointsdisplay->Add_Points( kill_points, pPlayer->posx, pPlayer->posy, "", static_cast<Uint8>(255), 1 );
  367.         pAudio->Play_Sound( kill_sound );
  368.  
  369.  
  370.         // big walking
  371.         if( krush_state == KRUSH_WALK )
  372.         {
  373.             DownGrade();
  374.         }
  375.         // small walking
  376.         else if( krush_state == KRUSH_SMALL )
  377.         {
  378.             DownGrade();
  379.             pPlayer->Add_Kill_Multiplier();
  380.         }
  381.  
  382.         pPlayer->Action_Jump( 1 );
  383.     }
  384.     else
  385.     {
  386.         pPlayer->DownGrade();
  387.         Turn_Around( collision->direction );
  388.     }
  389. }
  390.  
  391. void cKrush :: Handle_Collision_Enemy( cObjectCollision *collision )
  392. {
  393.     Turn_Around( collision->direction );
  394.     Send_Collision( collision );
  395. }
  396.  
  397. void cKrush :: Handle_Collision_Massive( cObjectCollision *collision )
  398. {
  399.     Turn_Around( collision->direction );
  400. }
  401.