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

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