home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / player / player.cpp next >
Encoding:
C/C++ Source or Header  |  2008-09-26  |  93.6 KB  |  4,074 lines

  1. /***************************************************************************
  2.  * player.cpp  -  Level player class
  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 "../core/globals.h"
  17. #include "../player/player.h"
  18. #include "../core/main.h"
  19. #include "../video/animation.h"
  20. #include "../core/game_core.h"
  21. #include "../user/preferences.h"
  22. #include "../input/joystick.h"
  23. #include "../core/sprite_manager.h"
  24. #include "../core/framerate.h"
  25. #include "../audio/audio.h"
  26. #include "../enemies/turtle.h"
  27. #include "../overworld/overworld.h"
  28. #include "../level/level.h"
  29. #include "../gui/menu.h"
  30. #include "../core/camera.h"
  31. #include "../objects/levelexit.h"
  32. #include "../objects/level_entry.h"
  33. #include "../objects/box.h"
  34. #include "../input/keyboard.h"
  35. #include "../video/gl_surface.h"
  36. #include "../core/math/utilities.h"
  37. #include "../core/i18n.h"
  38.  
  39. // Milliseconds to enable power jump when ducking
  40. const int power_jump_delta = 1000;
  41.  
  42.  
  43. /* *** *** *** *** *** *** *** *** cPlayer *** *** *** *** *** *** *** *** *** */
  44.  
  45. cPlayer :: cPlayer( float x /* = 120 */, float y /* = 0 */ )
  46. : cImageObjectSprite( x, y )
  47. {
  48.     type = TYPE_PLAYER;
  49.     massivetype = MASS_MASSIVE;
  50.     state = STA_FALL;
  51.  
  52.     maryo_type = MARYO_SMALL;
  53.     maryo_type_temp_power = MARYO_DEAD;
  54.     name = "Maryo";    
  55.  
  56.     images.reserve( 20 );
  57.     posz = 0.0999f;
  58.     ducked = 0;
  59.     ducked_animation_counter = 0;
  60.     parachute = 0;
  61.     throwing_counter = 0;
  62.  
  63.     // invincible data
  64.     invincible = 0;
  65.     invincible_star = 0;
  66.     invincible_mod = 0;
  67.     invincible_starcounter = 0;
  68.  
  69.     walk_count = 0;
  70.     running_particle_counter = 0;
  71.  
  72.     godmode = 0;
  73.  
  74.     walk_time = 0;
  75.     ghost_time = 0;
  76.     ghost_time_mod = 0;
  77.  
  78.     // Starting with 3 lives 
  79.     lives = 3;
  80.     goldpieces = 0;
  81.     points = 0;
  82.     kill_multiplier = 1;
  83.     last_kill_counter = 0;
  84.  
  85.     // jump data
  86.     UpKeytime = 0;
  87.     force_jump = 0;
  88.     next_jump_sound = 1;
  89.     next_jump_power = 17;
  90.     next_jump_accel = 4;
  91.     jump_power = 0;
  92.     jump_accel_up = 4.5f;
  93.     jump_vel_deaccel = 0.06f;
  94.  
  95.     // no movement timer
  96.     no_velx_counter = 0;
  97.     no_vely_counter = 0;
  98.  
  99.     shoot_counter = 0;
  100.     active_object = NULL;
  101. }
  102.  
  103. cPlayer :: ~cPlayer( void )
  104. {
  105.     Ball_Clear();
  106. }
  107.  
  108. cPlayer *cPlayer :: Copy( void )
  109. {
  110.     // non copyable
  111.     return NULL;
  112. }
  113.  
  114. void cPlayer :: Init( void )
  115. {
  116.     Load_Images();
  117.     // default direction : right
  118.     Set_Direction( DIR_RIGHT, 1 );
  119. }
  120.  
  121. void cPlayer :: Create_from_Stream( CEGUI::XMLAttributes &attributes )
  122. {
  123.     // position
  124.     Set_Pos( static_cast<float>(attributes.getValueAsInteger( "posx", 50 )), static_cast<float>(attributes.getValueAsInteger( "posy", 300 )), 1 );
  125.     // direction
  126.     ObjectDirection dir = Get_Direction_Id( attributes.getValueAsString( "direction" ).c_str() );
  127.  
  128.     // if invalid set default
  129.     if( dir != DIR_LEFT && dir != DIR_RIGHT )
  130.     {
  131.         dir = DIR_RIGHT;
  132.     }
  133.     Set_Direction( dir, 1 );
  134.  
  135.     // ## change position to the current state height
  136.     // level engine version 2 and lower
  137.     if( pActive_Level->engine_version <= 2 )
  138.     {
  139.         Set_Pos( posx, posy - col_rect.h, 1 );
  140.     }
  141.     // higher as 2
  142.     else
  143.     {
  144.         Col_Move( 0, start_image->col_h - col_rect.h, 1, 1 );
  145.     }
  146. }
  147.  
  148. void cPlayer :: Save_to_Stream( ofstream &file )
  149. {
  150.     // begin player
  151.     file << "\t<player>" << std::endl;
  152.  
  153.     // position
  154.     file << "\t\t<Property name=\"posx\" value=\"" << static_cast<int>(startposx) << "\" />" << std::endl;
  155.     file << "\t\t<Property name=\"posy\" value=\"" << static_cast<int>(startposy) << "\" />" << std::endl;
  156.     // direction
  157.     file << "\t\t<Property name=\"direction\" value=\"" << Get_Direction_Name( start_direction ) << "\" />" << std::endl;
  158.  
  159.     // end player
  160.     file << "\t</player>" << std::endl;
  161. }
  162.  
  163. void cPlayer :: Hold( void )
  164. {
  165.     if( !ground_object || ( state != STA_WALK && state != STA_RUN ) )
  166.     {
  167.         return;
  168.     }
  169.     
  170.     Set_Moving_State( STA_STAY );
  171. }
  172.  
  173. void cPlayer :: Set_Direction( ObjectDirection dir, bool new_start_direction /* = 0 */ )
  174. {
  175.     // set start image
  176.     if( new_start_direction )
  177.     {
  178.         cMovingSprite::Set_Image( pVideo->Get_Surface( "maryo/small/stand_" + Get_Direction_Name( dir ) + ".png" ), 1 );
  179.  
  180.         // set back current image
  181.         curr_img = -1;
  182.         Set_Image( Get_Image() + direction );
  183.     }
  184.  
  185.     cImageObjectSprite::Set_Direction( dir, new_start_direction );
  186. }
  187.  
  188. void cPlayer :: Set_on_Ground( cSprite *obj )
  189. {
  190.     cMovingSprite::Set_on_Ground( obj );
  191.  
  192.     // if valid ground
  193.     if( ground_object )
  194.     {
  195.         // if moving
  196.         if( velx )
  197.         {
  198.             if( state != STA_STAY && state != STA_RUN )
  199.             {
  200.                 Set_Moving_State( STA_WALK );
  201.             }
  202.         }
  203.         // not moving
  204.         else if( !velx )
  205.         {
  206.             Set_Moving_State( STA_STAY );
  207.         }
  208.  
  209.         // if massive ground and ducking key is pressed
  210.         if( ground_object->massivetype == MASS_MASSIVE && pKeyboard->keys[pPreferences->key_down] )
  211.         {
  212.             Start_Ducking();
  213.         }
  214.     }
  215. }
  216.  
  217. void cPlayer :: DownGrade( bool delayed /* = 1 */, bool force /* = 0 */ )
  218. {
  219.     if( godmode || invincible )
  220.     {
  221.         return;
  222.     }
  223.  
  224.     if( delayed )
  225.     {
  226.         Game_Action = GA_DOWNGRADE_PLAYER;
  227.         Game_Action_Data.add( "force", CEGUI::PropertyHelper::boolToString( force ) );
  228.         return;
  229.     }
  230.  
  231.     // if not weakest state or not forced 
  232.     if( maryo_type != MARYO_SMALL && !force )
  233.     {
  234.         pAudio->Play_Sound( "player/powerdown.ogg", RID_MARYO_POWERDOWN );
  235.  
  236.         // power down
  237.         Set_Type( MARYO_SMALL );
  238.  
  239.         invincible = speedfactor_fps * 2.5f;
  240.         invincible_mod = 0;
  241.  
  242.         Itembox->Request_Item();
  243.         
  244.         return;
  245.     }
  246.  
  247.     Set_Type( MARYO_DEAD, 0, 0 );
  248.     pointsdisplay->Clear();
  249.     Ball_Clear();
  250.     livedisplay->Add_Lives( -1 );
  251.     pAudio->Fadeout_Music( 1700 );
  252.  
  253.     // lost a live
  254.     if( lives >= 0 )
  255.     {
  256.         pAudio->Play_Sound( "player/dead.ogg", RID_MARYO_DEATH );
  257.     }
  258.     // game over
  259.     else
  260.     {
  261.         pAudio->Play_Sound( DATA_DIR "/" GAME_MUSIC_DIR "/game/lost_1.ogg", RID_MARYO_DEATH );
  262.     }
  263.     
  264.     // dying animation
  265.     Set_Image( MARYO_IMG_DEAD + 1 );
  266.  
  267.     // draw
  268.     Draw_Game();
  269.     // render
  270.     pVideo->Render();
  271.  
  272.     // wait
  273.     SDL_Delay( 500 );
  274.     pFramerate->Reset();
  275.     
  276.     Set_Image( MARYO_IMG_DEAD );
  277.  
  278.     float i;
  279.  
  280.     for( i = 0; i < 7; i += pFramerate->speedfactor )
  281.     {
  282.         // move up
  283.         Move( 0, -13 );
  284.         // draw
  285.         Draw_Game();
  286.         // render
  287.         pVideo->Render();
  288.         pFramerate->Update();
  289.     }
  290.  
  291.     // very small delay until falling animation
  292.     SDL_Delay( 300 );
  293.  
  294.     pFramerate->Reset();
  295.     walk_count = 0;
  296.     
  297.     for( i = 0; posy < game_res_h + pActive_Camera->y + col_rect.h; i++ )
  298.     {
  299.         walk_count += pFramerate->speedfactor * 0.75f;
  300.  
  301.         if( walk_count > 4 )
  302.         {
  303.             walk_count = 0;
  304.         }
  305.         
  306.         // move down
  307.         Move( 0, 14 );
  308.  
  309.         if( walk_count > 2 )
  310.         {
  311.             Set_Image( MARYO_IMG_DEAD );
  312.         }
  313.         else
  314.         {
  315.             Set_Image( MARYO_IMG_DEAD + 1 );
  316.         }
  317.         
  318.         // draw
  319.         Draw_Game();
  320.         // render
  321.         pVideo->Render();
  322.         pFramerate->Update();
  323.     }
  324.  
  325.     // lost a live
  326.     if( lives >= 0 )
  327.     {
  328.         // unload level
  329.         pActive_Level->Unload( 1 );
  330.     }
  331.     // game over
  332.     else
  333.     {
  334.         GL_Surface *game_over = pVideo->Get_Surface( "game/game_over.png" );
  335.         cSprite *sprite = new cSprite( game_over, ( game_res_w * 0.5f ) - ( game_over->w * 0.5f ), ( game_res_h * 0.5f ) - ( game_over->h * 0.5f ) );
  336.         sprite->posz = 0.8f;
  337.         sprite->spawned = 1;
  338.         sprite->Set_Ignore_Camera( 1 );
  339.         pActive_Sprite_Manager->Add( sprite );
  340.  
  341.         cParticle_Emitter *anim = new cParticle_Emitter();
  342.         anim->Set_Emitter_Rect( sprite->rect.x + pActive_Camera->x, sprite->rect.y + pActive_Camera->y, sprite->rect.w ,sprite->rect.h );
  343.         anim->Set_Emitter_Time_to_Live( 24 );
  344.         anim->Set_Emitter_Iteration_Interval( 0.1f );
  345.         anim->Set_Quota( 1 );
  346.         anim->Set_Pos_Z( 0.79f );
  347.         anim->Set_Image( pVideo->Get_Surface( "animation/particles/axis.png" ) );
  348.         anim->Set_Time_to_Live( 10 );
  349.         anim->Set_Fading_Alpha( 1 );
  350.         anim->Set_Speed( 2, 0.5f );
  351.         anim->Set_Scale( 0.9f );
  352.         anim->Set_Color( Color( static_cast<Uint8>(250), 140, 90 ), Color( static_cast<Uint8>(5), 100, 0 ) );
  353.         anim->Set_Const_Rotation_Z( -2, 4 );
  354.  
  355.         anim->Init();
  356.  
  357.         for( float i = 1; i > 0; i -= 0.0011f * pFramerate->speedfactor )
  358.         {
  359.             // update pressed keys
  360.             SDL_PumpEvents();
  361.             Uint8 *keys = SDL_GetKeyState( NULL );
  362.             // Escape stops
  363.             if( keys[SDLK_ESCAPE] || keys[SDLK_RETURN] || keys[SDLK_SPACE] || keys[pPreferences->key_action] )
  364.             {
  365.                 break;
  366.             }
  367.  
  368.             // if joystick enabled and exit pressed
  369.             if( pPreferences->joy_enabled && SDL_JoystickGetButton( pJoystick->joystick, pPreferences->joy_button_exit ) )
  370.             {
  371.                  break;
  372.             }
  373.  
  374.             // update animation
  375.             anim->Update();
  376.             
  377.             // draw
  378.             Draw_Game();
  379.             anim->Draw();
  380.  
  381.             pVideo->Render();
  382.             pFramerate->Update();
  383.         }
  384.  
  385.         delete anim;
  386.         pAudio->Stop_Sounds();
  387.     }
  388.     
  389.     // clear
  390.     Set_Type( MARYO_SMALL, 0, 0 );
  391.     Clear_Input_Events();
  392.     pFramerate->Reset();
  393.  
  394.     // game over - reset
  395.     if( lives < 0 )
  396.     {
  397.         Reset_Save();
  398.         Game_Action = GA_ENTER_MENU;
  399.     }
  400.     // custom level
  401.     else if( Game_Mode_Type == MODE_TYPE_LEVEL_CUSTOM )
  402.     {
  403.         Game_Action = GA_ENTER_MENU;
  404.     }
  405.     // back to overworld
  406.     else
  407.     {
  408.         Game_Action = GA_ENTER_WORLD;
  409.     }
  410. }
  411.  
  412. void cPlayer :: Move_Player( float velocity, float vel_wrongway )
  413. {
  414.     if( direction == DIR_LEFT )
  415.     {
  416.         velocity *= -1;
  417.         vel_wrongway *= -1;
  418.     }
  419.  
  420.     // collision count
  421.     unsigned int col_count = Collision_Check_Relative( velocity, 0, 0, 0, COLLIDE_ALLOW_BLOCKING ).size();
  422.     // if collision with a blocking object
  423.     bool is_col = 0;
  424.  
  425.     // check collisions
  426.     for( unsigned int i = 0; i < col_count; i++ )
  427.     {
  428.         cObjectCollision *collision = Collision_Get_last();
  429.  
  430.         // massive or active object is blocking
  431.         if( collision->type == CO_MASSIVE || collision->type == CO_ACTIVE )
  432.         {
  433.             is_col = 1;
  434.         }
  435.         // special enemies
  436.         else if( collision->type == CO_ENEMY )
  437.         {
  438.             cEnemy *enemy = static_cast<cEnemy *>(pActive_Sprite_Manager->Get_Pointer( collision->number ));
  439.  
  440.             // blocking enemies
  441.             if( enemy->type == TYPE_EATO )
  442.             {
  443.                 is_col = 1;
  444.             }
  445.         }
  446.  
  447.         Collision_Delete( collision );
  448.     }
  449.  
  450.     // don't move if colliding
  451.     if( is_col )
  452.     {
  453.         if( !velx )
  454.         {
  455.             Set_Moving_State( STA_STAY );
  456.         }
  457.  
  458.         return;
  459.     }
  460.  
  461.     // move right
  462.     if( direction == DIR_RIGHT )
  463.     {
  464.         if( velx > 0 )
  465.         {
  466.             Add_Velocity( velocity, 0 );
  467.  
  468.             if( velx > 10 * Get_Vel_Modifier() )
  469.             {
  470.                 velx = 10 * Get_Vel_Modifier();
  471.             }
  472.         }
  473.         else
  474.         {
  475.             // small smoke clouds under foots
  476.             if( velx < 0 )
  477.             {
  478.                 Generate_Feet_Clouds();
  479.             }
  480.  
  481.             // slow down
  482.             Add_Velocity( vel_wrongway, 0 );
  483.         }
  484.     }
  485.     // move left
  486.     else if( direction == DIR_LEFT )
  487.     {
  488.         if( velx < 0 )
  489.         {
  490.             Add_Velocity( velocity, 0 );
  491.  
  492.             if( velx < -10 * Get_Vel_Modifier() )
  493.             {
  494.                 velx = -10 * Get_Vel_Modifier();
  495.             }
  496.         }
  497.         else
  498.         {
  499.             // small smoke clouds under foots
  500.             if( velx > 0 )
  501.             {
  502.                 Generate_Feet_Clouds();
  503.             }
  504.  
  505.             // slow down
  506.             Add_Velocity( vel_wrongway, 0 );
  507.         }
  508.     }
  509.  
  510.     // start walking
  511.     if( state == STA_STAY )
  512.     {
  513.         Set_Moving_State( STA_WALK );
  514.     }
  515. }
  516.  
  517. void cPlayer :: Generate_Feet_Clouds( cParticle_Emitter *anim /* = NULL */ )
  518. {
  519.     // check if valid
  520.     if( !ground_object || !ground_object->image || ground_object->image->ground_type == GROUND_NORMAL )
  521.     {
  522.         return;
  523.     }
  524.  
  525.     bool create_anim = 0;
  526.  
  527.     if( !anim )
  528.     {
  529.         create_anim = 1;
  530.         // create animation
  531.         anim = new cParticle_Emitter();
  532.     }
  533.  
  534.     anim->Set_Emitter_Rect( col_rect.x, col_rect.y + col_rect.h - 2, col_rect.w );
  535.     anim->Set_Pos_Z( posz - 0.000001f );
  536.  
  537.     float vel = ( velx > 0 ? velx : -velx );
  538.  
  539.     // ground type
  540.     switch( ground_object->image->ground_type )
  541.     {
  542.         case GROUND_EARTH:
  543.         {
  544.             anim->Set_Image( pVideo->Get_Surface( "animation/particles/dirt.png" ) );
  545.             anim->Set_Time_to_Live( 0.3f );
  546.             anim->Set_Scale( 0.5f );
  547.             anim->Set_Speed( 0.08f + vel * 0.1f, vel * 0.05f );
  548.             break;
  549.         }
  550.         case GROUND_ICE:
  551.         {
  552.             anim->Set_Image( pVideo->Get_Surface( "animation/particles/ice_1.png" ) );
  553.             anim->Set_Time_to_Live( 0.6f );
  554.             anim->Set_Scale( 0.3f );
  555.             anim->Set_Speed( 0.1f + vel * 0.05f, vel * 0.04f );
  556.             break;
  557.         }
  558.         case GROUND_SAND:
  559.         {
  560.             anim->Set_Emitter_Iteration_Interval( 4 );
  561.             anim->Set_Image( pVideo->Get_Surface( "animation/particles/cloud.png" ) );
  562.             anim->Set_Time_to_Live( 0.3f );
  563.             anim->Set_Scale( 0.2f );
  564.             anim->Set_Color( lightorange );
  565.             anim->Set_Speed( 0.2f + vel * 0.15f, vel * 0.15f );
  566.             break;
  567.         }
  568.         case GROUND_STONE:
  569.         {
  570.             anim->Set_Image( pVideo->Get_Surface( "animation/particles/smoke_black.png" ) );
  571.             anim->Set_Time_to_Live( 0.3f );
  572.             anim->Set_Scale( 0.3f );
  573.             anim->Set_Speed( vel * 0.08f, 0.1f + vel * 0.1f );
  574.             break;
  575.         }
  576.         case GROUND_PLASTIC:
  577.         {
  578.             anim->Set_Image( pVideo->Get_Surface( "animation/particles/light.png" ) );
  579.             anim->Set_Time_to_Live( 0.2f );
  580.             anim->Set_Scale( 0.2f );
  581.             anim->Set_Color( lightgrey );
  582.             anim->Set_Speed( 0.05f, vel * 0.05f );
  583.             break;
  584.         }
  585.         default:
  586.         {
  587.             anim->Set_Image( pVideo->Get_Surface( "animation/particles/smoke.png" ) );
  588.             anim->Set_Time_to_Live( 0.3f );
  589.             anim->Set_Speed( 0.1f + vel * 0.1f, vel * 0.1f );
  590.             break;
  591.         }
  592.     }
  593.  
  594.     if( direction == DIR_RIGHT )
  595.     {
  596.         anim->Set_Direction_Range( 180, 90 );
  597.     }
  598.     else
  599.     {
  600.         anim->Set_Direction_Range( 270, 90 );
  601.     }
  602.  
  603.     if( create_anim )
  604.     {
  605.         // add animation
  606.         pAnimation_Manager->Add( anim );
  607.     }
  608. }
  609.  
  610. void cPlayer :: Update_Walking( void )
  611. {
  612.     if( ducked || !ground_object || ( state != STA_STAY && state != STA_WALK && state != STA_RUN ) )
  613.     {
  614.         return;
  615.     }
  616.  
  617.     // validate ground object
  618.     if( ( ground_object->type == TYPE_EATO || ground_object->type == TYPE_SPIKA || ground_object->type == TYPE_ROKKO ) && invincible <= 0 )
  619.     {
  620.         Reset_on_Ground();
  621.     }
  622.  
  623.     // only if left or right is pressed
  624.     if( pKeyboard->keys[pPreferences->key_left] || pKeyboard->keys[pPreferences->key_right] || pJoystick->left || pJoystick->right )
  625.     {
  626.         float ground_mod = 1;
  627.  
  628.         if( ground_object && ground_object->image )
  629.         {
  630.             // ground type
  631.             switch( ground_object->image->ground_type )
  632.             {
  633.                 case GROUND_ICE:
  634.                 {
  635.                     ground_mod = 0.5f;
  636.                     break;
  637.                 }
  638.                 case GROUND_SAND:
  639.                 {
  640.                     ground_mod = 0.7f;
  641.                     break;
  642.                 }
  643.                 case GROUND_PLASTIC:
  644.                 {
  645.                     ground_mod = 0.85f;
  646.                     break;
  647.                 }
  648.                 default:
  649.                 {
  650.                     break;
  651.                 }
  652.             }
  653.         }
  654.  
  655.         Move_Player( ( 0.6f * ground_mod * Get_Vel_Modifier() ), ( 1.2f * ground_mod * Get_Vel_Modifier() ) );
  656.     }
  657.  
  658.     // update walking time
  659.     if( state == STA_WALK )
  660.     {
  661.         // update
  662.         if( velx > 10 || velx < -10 )
  663.         {
  664.             walk_time += pFramerate->speedfactor;
  665.  
  666.             if( walk_time > speedfactor_fps )
  667.             {
  668.                 Set_Moving_State( STA_RUN );
  669.             }
  670.         }
  671.         // reset
  672.         else if( walk_time )
  673.         {
  674.             walk_time = 0;
  675.         }
  676.     }
  677. }
  678.  
  679. void cPlayer :: Update_Running( void )
  680. {
  681.     if( ducked || !ground_object || state != STA_RUN )
  682.     {
  683.         return;
  684.     }
  685.  
  686.     running_particle_counter += pFramerate->speedfactor * 0.5f;
  687.  
  688.     // create particles
  689.     while( running_particle_counter > 1 )
  690.     {
  691.         float vel = ( velx > 0 ? velx : -velx );
  692.  
  693.         // start on high velocity
  694.         if( vel > 17 )
  695.         {
  696.             // light particles
  697.             cParticle_Emitter *anim = new cParticle_Emitter();
  698.             anim->Set_Emitter_Rect( col_rect.x + col_rect.w * 0.25f, col_rect.y + col_rect.h * 0.1f, col_rect.w * 0.5f, col_rect.h * 0.8f );
  699.             anim->Set_Image( pVideo->Get_Surface( "animation/particles/light.png" ) );
  700.             anim->Set_Pos_Z( posz + 0.000001f );
  701.             anim->Set_Time_to_Live( 0.1f + vel * 0.03f );
  702.             anim->Set_Fading_Alpha( 1 );
  703.             anim->Set_Fading_Size( 1 );
  704.             anim->Set_Speed( vel * 0.9f, 0 );
  705.             // right
  706.             if( velx > 0 )
  707.             {
  708.                 anim->Set_Direction_Range( 0, 0 );
  709.             }
  710.             // left
  711.             else
  712.             {
  713.                 anim->Set_Direction_Range( 180, 0 );
  714.             }
  715.             anim->Set_Scale( 0.15f );
  716.  
  717.             anim->Set_Blending( BLEND_ADD );
  718.             pAnimation_Manager->Add( anim );
  719.         }
  720.  
  721.         // smoke clouds under foots
  722.         Generate_Feet_Clouds();
  723.  
  724.         running_particle_counter--;
  725.     }
  726. }
  727.  
  728. void cPlayer :: Update_Staying( void )
  729. {
  730.     // only if player is onground
  731.     if( !ground_object || ducked || state == STA_JUMP )
  732.     {
  733.         return;
  734.     }
  735.  
  736.     // if left and right is not pressed
  737.     if( !pKeyboard->keys[pPreferences->key_left] && !pKeyboard->keys[pPreferences->key_right] && !pJoystick->left && !pJoystick->right )
  738.     {
  739.         // walking
  740.         if( velx )
  741.         {
  742.             if( ground_object->image && ground_object->image->ground_type == GROUND_ICE )
  743.             {
  744.                 Auto_Slow_Down( 1.1f / 5.0f );
  745.             }
  746.             else
  747.             {
  748.                 Auto_Slow_Down( 1.1f );
  749.             }
  750.  
  751.             // stopped walking
  752.             if( !velx )
  753.             {
  754.                 Set_Moving_State( STA_STAY );
  755.             }
  756.         }
  757.  
  758.         // walk on spika
  759.         if( ground_object->type == TYPE_SPIKA )
  760.         {
  761.             cMovingSprite *moving_ground_object = static_cast<cMovingSprite *>(ground_object);
  762.  
  763.             if( moving_ground_object->velx < 0 )
  764.             {
  765.                 walk_count -= moving_ground_object->velx * pFramerate->speedfactor * 0.1f;
  766.             }
  767.             else if( moving_ground_object->velx > 0 )
  768.             {
  769.                 walk_count += moving_ground_object->velx * pFramerate->speedfactor * 0.1f;
  770.             }
  771.         }
  772.         // if not moving anymore
  773.         else if( velx == 0 )
  774.         {
  775.             walk_count = 0;
  776.         }
  777.     }
  778.  
  779.     // if staying don't move vertical
  780.     if( vely > 0 )
  781.     {
  782.         vely = 0;
  783.     }
  784. }
  785.  
  786. void cPlayer :: Update_Flying( void )
  787. {
  788.     /* only if not onground
  789.      * if jumping update jump is already used
  790.     */
  791.     if( ground_object || state == STA_CLIMB || state == STA_JUMP )
  792.     {
  793.         return;
  794.     }
  795.  
  796.     // flying
  797.     if( state == STA_FLY )
  798.     {
  799.         if( direction == DIR_LEFT )
  800.         {
  801.             if( velx > -15 * Get_Vel_Modifier() )
  802.             {
  803.                 Add_Velocity( -1.1f, 0 );
  804.             }
  805.         }
  806.         else
  807.         {
  808.             if( velx < 15 * Get_Vel_Modifier() )
  809.             {
  810.                 Add_Velocity( 1.1f, 0 );
  811.             }
  812.         }
  813.  
  814.         // move down 
  815.         if( pKeyboard->keys[pPreferences->key_down] || pJoystick->down )
  816.         {
  817.             if( vely < 5 * Get_Vel_Modifier() )
  818.             {
  819.                 Add_Velocity( 0, 0.6f );
  820.             }
  821.         }
  822.         // move up
  823.         else if( pKeyboard->keys[pPreferences->key_up] || pJoystick->up )
  824.         {
  825.             if( vely > -5 * Get_Vel_Modifier() )
  826.             {
  827.                 Add_Velocity( 0, -0.6f );
  828.             }
  829.         }
  830.         // slow down if not pressed
  831.         else
  832.         {
  833.             Auto_Slow_Down( 0, 0.4f );
  834.         }
  835.  
  836.         // set flying rotation
  837.         float fly_rot = vely * 2.5f;
  838.  
  839.         // limit angle
  840.         if( fly_rot > 70 )
  841.         {
  842.             fly_rot = 70;
  843.         }
  844.         else if( fly_rot < -70 )
  845.         {
  846.             fly_rot = -70;
  847.         }
  848.  
  849.         Set_Rotation_Z( fly_rot );
  850.     }
  851.     // falling
  852.     else
  853.     {
  854.         // move left
  855.         if( ( pKeyboard->keys[pPreferences->key_left] || pJoystick->left ) && !ducked )
  856.         {
  857.             if( !parachute )
  858.             {
  859.                 if( velx > -10 * Get_Vel_Modifier() )
  860.                 {
  861.                     Add_Velocity( -1.2f, 0 );
  862.                 }
  863.             }
  864.             // slow fall/parachute
  865.             else
  866.             {
  867.                 if( velx > -5 * Get_Vel_Modifier() )
  868.                 {
  869.                     Add_Velocity( -0.6f, 0 );
  870.                 }
  871.             }
  872.  
  873.         }
  874.         // move right
  875.         else if( ( pKeyboard->keys[pPreferences->key_right] || pJoystick->right ) && !ducked )
  876.         {
  877.             if( !parachute )
  878.             {
  879.                 if( velx < 10 * Get_Vel_Modifier() )
  880.                 {
  881.                     Add_Velocity( 1.2f, 0 );
  882.                 }
  883.             }
  884.             // slow fall/parachute
  885.             else
  886.             {
  887.                 if( velx < 5 * Get_Vel_Modifier() )
  888.                 {
  889.                     Add_Velocity( 0.6f, 0 );
  890.                 }
  891.             }
  892.         }
  893.         // slow down if not pressed
  894.         else
  895.         {
  896.             Auto_Slow_Down( 0.4f );
  897.         }
  898.     }
  899. }
  900.  
  901. void cPlayer :: Stop_Flying( bool nparachute /* = 1 */ )
  902. {
  903.     if( state != STA_FLY )
  904.     {
  905.         return;
  906.     }
  907.  
  908.     if( nparachute )
  909.     {
  910.         parachute = 1;
  911.     }
  912.  
  913.     Set_Moving_State( STA_FALL );
  914. }
  915.  
  916. void cPlayer :: Start_Falling( void )
  917. {
  918.     Move( 0, 1.9f, 1 );
  919.     Set_Moving_State( STA_FALL );
  920. }
  921.  
  922. void cPlayer :: Update_Falling( void )
  923. {
  924.     // only if not on ground
  925.     if( ground_object || state == STA_CLIMB || state == STA_FLY )
  926.     {
  927.         return;
  928.     }
  929.  
  930.     // Add Gravitation
  931.     if( !parachute )
  932.     {
  933.         if( vely < 25 )
  934.         {
  935.             Add_Velocity( 0, 2.8f );
  936.         }
  937.     }
  938.     // slow fall/parachute
  939.     else
  940.     {
  941.         if( vely < 10 )
  942.         {
  943.             Add_Velocity( 0, 0.6f );
  944.         }
  945.     }
  946.  
  947.  
  948.     if( state != STA_JUMP && state != STA_FALL )
  949.     {
  950.         Set_Moving_State( STA_FALL );
  951.     }
  952. }
  953.  
  954. void cPlayer :: Start_Ducking( void )
  955.     // only if massive ground
  956.     if( ( state != STA_STAY && state != STA_WALK && state != STA_RUN ) || state == STA_CLIMB || !ground_object || ground_object->massivetype == MASS_HALFMASSIVE || ducked )
  957.     {
  958.         return;
  959.     }
  960.  
  961.     Release_Item( 1, 1 );
  962.  
  963.     // set ducking image ( without Check_OutofLevel from cMovingSprite )
  964.     cSprite::Move( 0, image->col_h - images[MARYO_IMG_DUCK]->col_h, 1 );
  965.     Set_Image( MARYO_IMG_DUCK + direction );
  966.  
  967.     ducked = SDL_GetTicks();
  968.     Set_Moving_State( STA_STAY );
  969. }
  970.  
  971. void cPlayer :: Stop_Ducking( void )
  972. {
  973.     if( !ducked )
  974.     {
  975.         return;
  976.     }
  977.  
  978.     // unset ducking image ( without Check_OutofLevel from cMovingSprite )
  979.     cSprite::Move( 0, -( images[MARYO_IMG_STAND]->col_h - image->col_h ), 1 );
  980.     Set_Image( MARYO_IMG_STAND + direction );
  981.  
  982.     ducked = 0;
  983.     ducked_animation_counter = 0;
  984.     Set_Moving_State( STA_STAY );
  985. }
  986.  
  987. void cPlayer :: Update_Ducking( void )
  988. {
  989.     if( !ducked )
  990.     {
  991.         return;
  992.     }
  993.  
  994.     // lost ground object
  995.     if( !ground_object )
  996.     {
  997.         Stop_Ducking();
  998.         return;
  999.     }
  1000.  
  1001.     if( SDL_GetTicks() - ducked > power_jump_delta )
  1002.     {
  1003.         // particle animation
  1004.         ducked_animation_counter += pFramerate->speedfactor * 2;
  1005.  
  1006.         while( ducked_animation_counter > 1 )
  1007.         {
  1008.             // create particle
  1009.             cParticle_Emitter *anim = new cParticle_Emitter();
  1010.             anim->Set_Pos( col_rect.x + Get_Random_Float( 0, col_rect.w * 0.9f ), col_rect.y + ( col_rect.h * 0.6f ) + Get_Random_Float( 0, col_rect.h * 0.1f ) );
  1011.             anim->Set_Image( pVideo->Get_Surface( "animation/particles/star_2.png" ) );
  1012.             anim->Set_Pos_Z( posz - 0.000001f, 0.000002f );
  1013.             anim->Set_Time_to_Live( 0.3f );
  1014.             anim->Set_Fading_Alpha( 1 );
  1015.             anim->Set_Fading_Size( 1 );
  1016.             anim->Set_Const_Rotation_Z( -5, 10 );
  1017.             anim->Set_Direction_Range( 90, 20 );
  1018.             anim->Set_Speed( 1.5f, 0.5f );
  1019.             anim->Set_Scale( 0.2f );
  1020.             anim->Set_Color( whitealpha128 );
  1021.             anim->Set_Blending( BLEND_ADD );
  1022.             pAnimation_Manager->Add( anim );
  1023.  
  1024.             ducked_animation_counter--;
  1025.         }
  1026.     }
  1027.  
  1028.     // slow down
  1029.     if( velx )
  1030.     {
  1031.         Auto_Slow_Down( 0.6f );
  1032.     }
  1033. }
  1034.  
  1035. void cPlayer :: Start_Climbing( void )
  1036. {
  1037.     if( ducked || state == STA_CLIMB )
  1038.     {
  1039.         return;
  1040.     }
  1041.  
  1042.     Release_Item( 1, 1 );
  1043.     Set_Moving_State( STA_CLIMB );
  1044. }
  1045.  
  1046. void cPlayer :: Update_Climbing( void )
  1047. {
  1048.     if( state != STA_CLIMB )
  1049.     {
  1050.         return;
  1051.     }
  1052.  
  1053.     velx = 0;
  1054.     vely = 0;
  1055.  
  1056.     // collision testing
  1057.     Collision_Check( &col_rect );
  1058.  
  1059.     for( ObjectCollisionList::iterator itr = collisions.begin(), itr_end = collisions.end(); itr != itr_end; ++itr )
  1060.     {
  1061.         // get object pointer
  1062.         cObjectCollision *col = (*itr);
  1063.  
  1064.         // collides with the climbable object
  1065.         if( col && col->type == CO_ACTIVE && pActive_Sprite_Manager->Get_Pointer( col->number )->massivetype == MASS_CLIMBABLE )
  1066.         {
  1067.             Collisions_Clear();
  1068.  
  1069.             // set velocity
  1070.             if( pKeyboard->keys[pPreferences->key_left] || pJoystick->left )
  1071.             {
  1072.                 velx = -2 * Get_Vel_Modifier();
  1073.             }
  1074.             else if( pKeyboard->keys[pPreferences->key_right] || pJoystick->right )
  1075.             {
  1076.                 velx = 2 * Get_Vel_Modifier();
  1077.             }
  1078.  
  1079.             if( pKeyboard->keys[pPreferences->key_up] || pJoystick->up )
  1080.             {
  1081.                 vely = -4 * Get_Vel_Modifier();
  1082.             }
  1083.             else if( pKeyboard->keys[pPreferences->key_down] || pJoystick->down )
  1084.             {
  1085.                 vely = 4 * Get_Vel_Modifier();
  1086.             }
  1087.  
  1088.             // in contact testing
  1089.             Collision_Check_Relative( 0, -15 );
  1090.             col = Collision_Get_first();
  1091.  
  1092.             // do not climb further upwards if maryo will loose contact
  1093.             if( !( col && col->type == CO_ACTIVE && pActive_Sprite_Manager->Get_Pointer( col->number )->massivetype == MASS_CLIMBABLE ) )
  1094.             {
  1095.                 // only stop if loosing contact upwards
  1096.                 if( vely < 0 )
  1097.                 {
  1098.                     vely = 0;
  1099.                 }
  1100.             }
  1101.  
  1102.             Collisions_Clear();
  1103.             return;
  1104.         }
  1105.     }
  1106.  
  1107.     // lost contact
  1108.     Set_Moving_State( STA_FALL );
  1109.     Collisions_Clear();
  1110. }
  1111.  
  1112. void cPlayer :: Start_Jump_Keytime( void )
  1113. {
  1114.     if( godmode || state == STA_STAY || state == STA_WALK || state == STA_RUN || state == STA_FALL || state == STA_FLY || state == STA_JUMP || ( state == STA_CLIMB && !pKeyboard->keys[pPreferences->key_up] ) )
  1115.     {
  1116.         UpKeytime = speedfactor_fps / 4;
  1117.     }
  1118. }
  1119.  
  1120. void cPlayer :: Update_Jump_Keytime( void )
  1121. {
  1122.     // handle jumping start
  1123.     if( force_jump || ( UpKeytime && ( ground_object || godmode || state == STA_CLIMB ) ) )
  1124.     {
  1125.         Start_Jump();
  1126.     }
  1127. }
  1128.  
  1129. void cPlayer :: Start_Jump( float deaccel /* = 0.08f */ )
  1130. {
  1131.     // play sound
  1132.     if( next_jump_sound )
  1133.     {
  1134.         // small
  1135.         if( maryo_type == MARYO_SMALL )
  1136.         {
  1137.             if( force_jump )
  1138.             {
  1139.                 pAudio->Play_Sound( "player/jump_small_power.ogg", RID_MARYO_JUMP );
  1140.             }
  1141.             else
  1142.             {
  1143.                 pAudio->Play_Sound( "player/jump_small.ogg", RID_MARYO_JUMP );
  1144.             }
  1145.         }
  1146.         // ghost
  1147.         else if( maryo_type == MARYO_GHOST )
  1148.         {
  1149.             pAudio->Play_Sound( "player/jump_ghost.ogg", RID_MARYO_JUMP );
  1150.         }
  1151.         // big
  1152.         else
  1153.         {
  1154.             if( force_jump )
  1155.             {
  1156.                 pAudio->Play_Sound( "player/jump_big_power.ogg", RID_MARYO_JUMP );
  1157.             }
  1158.             else
  1159.             {
  1160.                 pAudio->Play_Sound( "player/jump_big.ogg", RID_MARYO_JUMP );
  1161.             }
  1162.         }
  1163.     }
  1164.  
  1165.     bool jump_key = 0;
  1166.  
  1167.     // if jump key pressed
  1168.     if( pKeyboard->keys[pPreferences->key_jump] || ( pPreferences->joy_analog_jump && pJoystick->up ) || pJoystick->Button( pPreferences->joy_button_jump ) )
  1169.     {
  1170.         jump_key = 1;
  1171.     }
  1172.  
  1173.     // avoid setting onground again
  1174.     Col_Move( 0, -1, 1, 1 );
  1175.  
  1176.     // fly
  1177.     if( maryo_type == MARYO_CAPE && !force_jump && state == STA_RUN && jump_key && ( ( direction == DIR_RIGHT && velx > 14 ) || ( direction == DIR_LEFT && velx < -14 ) ) )
  1178.     {
  1179.         vely = -next_jump_power * 0.5f;
  1180.         Set_Moving_State( STA_FLY );
  1181.     }
  1182.     // jump
  1183.     else
  1184.     {
  1185.         jump_accel_up = next_jump_accel;
  1186.         jump_vel_deaccel = deaccel;
  1187.  
  1188.         if( jump_key )
  1189.         {
  1190.             jump_power = next_jump_power * 0.59f;
  1191.         }
  1192.         else
  1193.         {
  1194.             jump_power = next_jump_power * 0.12f;
  1195.         }
  1196.         
  1197.         vely = -next_jump_power;
  1198.         Set_Moving_State( STA_JUMP );
  1199.     }
  1200.  
  1201.     // jump higher when running
  1202.     if( velx < 0 )
  1203.     {
  1204.         vely += velx / 9.5f;
  1205.     }
  1206.     else if( velx > 0 )
  1207.     {
  1208.         vely -= velx / 9.5f;
  1209.     }
  1210.  
  1211.     // slow down if running
  1212.     velx = velx * 0.9f;
  1213.  
  1214.     // reset variables
  1215.     UpKeytime = 0;
  1216.     force_jump = 0;
  1217.     next_jump_sound = 1;
  1218.     next_jump_power = 17;
  1219.     next_jump_accel = 4;
  1220. }
  1221.  
  1222. void cPlayer :: Update_Jump( void )
  1223. {
  1224.     // jumping keytime
  1225.     if( UpKeytime )
  1226.     {
  1227.         UpKeytime -= pFramerate->speedfactor;
  1228.  
  1229.         if( UpKeytime < 0 )
  1230.         {
  1231.             UpKeytime = 0;
  1232.         }
  1233.     }
  1234.     
  1235.     // only if jumping
  1236.     if( state != STA_JUMP )
  1237.     {
  1238.         return;
  1239.     }
  1240.  
  1241.     // jumping physics
  1242.     if( pKeyboard->keys[pPreferences->key_jump] || ( pPreferences->joy_analog_jump && pJoystick->up ) || pJoystick->Button( pPreferences->joy_button_jump ) )
  1243.     {
  1244.         Add_Velocity( 0, -( jump_accel_up + ( vely * jump_vel_deaccel ) / Get_Vel_Modifier() ) );
  1245.         jump_power -= pFramerate->speedfactor;
  1246.     }
  1247.     else
  1248.     {
  1249.         Add_Velocity( 0, 0.5f );
  1250.         jump_power -= 6 * pFramerate->speedfactor;
  1251.     }
  1252.     
  1253.     // left right physics
  1254.     if( ( pKeyboard->keys[pPreferences->key_left] || pJoystick->left ) && !ducked )
  1255.     {
  1256.         if( velx > -10 * Get_Vel_Modifier() )
  1257.         {
  1258.             Add_Velocity( ( -1.1f * Get_Vel_Modifier() ) - ( velx / 100 ), 0 );
  1259.         }
  1260.         
  1261.     }    
  1262.     else if( ( pKeyboard->keys[pPreferences->key_right] || pJoystick->right ) && !ducked && state != STA_STAY )
  1263.     {
  1264.         if( velx < 10 * Get_Vel_Modifier() )
  1265.         {
  1266.             Add_Velocity( ( 1.1f * Get_Vel_Modifier() ) + ( velx / 100 ), 0 );
  1267.         }
  1268.     }
  1269.     // slow down
  1270.     else 
  1271.     {
  1272.         Auto_Slow_Down( 0.2f );
  1273.     }
  1274.  
  1275.     // if no more jump power set to falling
  1276.     if( jump_power <= 0 )
  1277.     {
  1278.         Set_Moving_State( STA_FALL );
  1279.     }
  1280. }
  1281.  
  1282. void cPlayer :: Update_Item( void )
  1283. {
  1284.     // if active object item is available
  1285.     if( active_object )
  1286.     {
  1287.         // collision with something or activated
  1288.         if( active_object->type == TYPE_TURTLE && static_cast<cTurtle *>(active_object)->dead )
  1289.         {
  1290.             Release_Item( 0 );
  1291.         }
  1292.         else
  1293.         {
  1294.             // update the item position
  1295.             float pos_hor = 0;
  1296.  
  1297.             if( maryo_type == MARYO_SMALL )
  1298.             {
  1299.                 if( direction == DIR_LEFT )
  1300.                 {
  1301.                     pos_hor = rect.w * 0.13f - active_object->col_rect.w;
  1302.                 }
  1303.                 else
  1304.                 {
  1305.                     pos_hor = rect.w * 0.7f;
  1306.                 }
  1307.             }
  1308.             // big
  1309.             else
  1310.             {
  1311.                 if( direction == DIR_LEFT )
  1312.                 {
  1313.                     pos_hor = rect.w * 0.15f - active_object->col_rect.w;
  1314.                 }
  1315.                 else
  1316.                 {
  1317.                     pos_hor = rect.w * 0.70f;
  1318.                 }
  1319.             }
  1320.  
  1321.             active_object->Set_Pos( posx + pos_hor, posy + ( rect.h * 0.1f ) );
  1322.             active_object->Move( velx, vely );
  1323.         }
  1324.  
  1325.         return;
  1326.     }
  1327.  
  1328.     if( state == STA_FLY )
  1329.     {
  1330.         return;
  1331.     }
  1332.  
  1333.     // if control is pressed search for items in front of the player
  1334.     if( ( pKeyboard->keys[pPreferences->key_action] || pJoystick->Button( pPreferences->joy_button_action ) ) && !ducked && state != STA_CLIMB )
  1335.     {
  1336.         // next position velocity with extra size
  1337.         float check_x = ( velx > 0 ) ? (velx + 5) : ( velx - 5);
  1338.         
  1339.         // if wrong direction return
  1340.         if( ( direction == DIR_LEFT && check_x >= 0 ) || ( direction == DIR_RIGHT && check_x <= 0 ) )
  1341.         {
  1342.             return;
  1343.         }
  1344.  
  1345.         // check the next player position for objects
  1346.         unsigned int object_count = Collision_Check_Relative( ( direction == DIR_LEFT ) ? (check_x) : (col_rect.w), 0, ( direction == DIR_LEFT ) ? (-check_x) : (check_x) ).size();
  1347.  
  1348.         // possible objects
  1349.         for( unsigned int i = 0; i < object_count; i++ )
  1350.         {
  1351.             cObjectCollision *collision = Collision_Get_last();
  1352.  
  1353.             // if valid collision
  1354.             if( !collision )
  1355.             {
  1356.                 continue;
  1357.             }
  1358.  
  1359.             // collision found
  1360.             if( !active_object )
  1361.             {
  1362.                 // enemy item
  1363.                 if( collision->type == CO_ENEMY )
  1364.                 {
  1365.                     cEnemy *enemy = static_cast<cEnemy *>(pActive_Sprite_Manager->Get_Pointer( collision->number ));
  1366.  
  1367.                     if( enemy->type == TYPE_TURTLE && enemy->state == STA_STAY )
  1368.                     {
  1369.                         Get_Item( TYPE_TURTLE, 0, enemy );
  1370.                     }
  1371.                 }
  1372.                 // other items here
  1373.             }
  1374.             
  1375.             Collision_Delete( collision );
  1376.         }
  1377.     }
  1378. }
  1379.  
  1380. void cPlayer :: Release_Item( bool set_position /* = 1 */, bool no_action /* = 0 */ )
  1381. {
  1382.     if( !active_object )
  1383.     {
  1384.         return;
  1385.     }
  1386.  
  1387.     ObjectDirection kick_direction = DIR_UNDEFINED;
  1388.  
  1389.     // if flying : opposite direction
  1390.     if( state == STA_FLY )
  1391.     {
  1392.         kick_direction = Get_Opposite_Direction( direction );
  1393.     }
  1394.     // if jumping : upwards
  1395.     else if( jump_power > 0 )
  1396.     {
  1397.         kick_direction = DIR_UP;
  1398.     }
  1399.     // use current direction
  1400.     else
  1401.     {
  1402.         kick_direction = direction;
  1403.     }
  1404.  
  1405.     // if frozen
  1406.     if( active_object->freeze_counter )
  1407.     {
  1408.         no_action = 1;
  1409.     }
  1410.  
  1411.     // add back to level
  1412.     if( active_object->type == TYPE_TURTLE )
  1413.     {
  1414.         cTurtle *turtle = static_cast<cTurtle *>(active_object);
  1415.         
  1416.         // play kick sound if not dead
  1417.         if( !turtle->dead )
  1418.         {
  1419.             pAudio->Play_Sound( "enemy/turtle/shell/hit.ogg" );
  1420.         }
  1421.  
  1422.         // if object got kicked upwards use Stay
  1423.         if( kick_direction == DIR_UP || no_action )
  1424.         {
  1425.             turtle->state = STA_STAY;
  1426.             turtle->turtle_state = TURTLE_SHELL_STAND;
  1427.             
  1428.             // small direction acceleration if no object action
  1429.             if( kick_direction != DIR_UP && no_action )
  1430.             {
  1431.                 active_object->velx = ( kick_direction == DIR_LEFT ) ? (static_cast<float>(-5)) : (static_cast<float>(5));
  1432.             }
  1433.             // if jumping kick the object upwards
  1434.             else if( kick_direction == DIR_UP && !no_action )
  1435.             {
  1436.                 active_object->vely = -10 + vely;
  1437.             }
  1438.         }
  1439.         // default object horizontal kicking
  1440.         else
  1441.         {
  1442.             turtle->state = STA_RUN;
  1443.             turtle->turtle_state = TURTLE_SHELL_RUN;
  1444.             turtle->velx = ( kick_direction == DIR_LEFT ) ? (-turtle->speed_shell) : (turtle->speed_shell);
  1445.         }
  1446.  
  1447.         if( !turtle->dead )
  1448.         {
  1449.             turtle->massivetype = MASS_MASSIVE;
  1450.             turtle->direction = kick_direction;
  1451.  
  1452.             if( !turtle->freeze_counter )
  1453.             {
  1454.                 turtle->playercounter = speedfactor_fps * 0.5f;
  1455.             }
  1456.         }
  1457.  
  1458.         turtle->Update_Valid_Update();
  1459.     }
  1460.  
  1461.     // if the new object position is in the player ( e.g. add velx to move slowly out of the player position )
  1462.     bool position_in_player = 0;
  1463.  
  1464.     // set position
  1465.     if( set_position )
  1466.     {
  1467.         // middle the object
  1468.         float obj_diff_x = ( active_object->col_rect.w / 2 ) - ( col_rect.w / 2 );
  1469.  
  1470.         // set start position
  1471.         float start_posx = ( posx + obj_diff_x );
  1472.         // put in front if left or right
  1473.         if( kick_direction == DIR_LEFT || kick_direction == DIR_RIGHT )
  1474.         {
  1475.             start_posx += ( ( kick_direction == DIR_LEFT ) ? (-rect.w) : (rect.w) * 1.2f );
  1476.         }
  1477.         float start_posy = posy;
  1478.         // put on top if up
  1479.         if( kick_direction == DIR_UP )
  1480.         {
  1481.             start_posy -= rect.h * 0.9f;
  1482.         }
  1483.         active_object->Set_Pos( start_posx, start_posy );
  1484.         // set step size
  1485.         float step_x = 0;
  1486.         float step_y = 0;
  1487.     
  1488.         if( kick_direction == DIR_UP )
  1489.         {
  1490.             step_x = 2;
  1491.         }
  1492.         else if( kick_direction == DIR_LEFT )
  1493.         {
  1494.             step_x = 2;
  1495.         }
  1496.         else
  1497.         {
  1498.             step_x = -2;
  1499.         }
  1500.  
  1501.         // check for a valid position to release
  1502.         while( start_posx - 50 < active_object->posx && start_posx + 50 > active_object->posx && 
  1503.                start_posy - 50 < active_object->posy && start_posy + 50 > active_object->posy )
  1504.         {
  1505.             cObjectCollisionType col_list = active_object->Collision_Check_Relative( step_x, step_y, 0, 0, COLLIDE_ALLOW_BLOCKING );
  1506.             
  1507.             // check for blocking objects
  1508.             if( col_list.size() )
  1509.             {
  1510.                 // collides with a blocking object
  1511.                 if( col_list.find( ARRAY_MASSIVE ) || col_list.find( ARRAY_ACTIVE ) || col_list.find( ARRAY_ENEMY ) )
  1512.                 {
  1513.                     // move into the opposite kick direction
  1514.                     active_object->Move( step_x, step_y, 1 );
  1515.                     continue;
  1516.                 }
  1517.             }
  1518.  
  1519.             break;
  1520.         }
  1521.  
  1522.         cObjectCollisionType col_list = active_object->Collision_Check( &active_object->col_rect, COLLIDE_ALLOW_BLOCKING );
  1523.  
  1524.         // check for blocking objects on the final position
  1525.         if( col_list.size() )
  1526.         {
  1527.             // still collides with a blocking object
  1528.             if( col_list.find( ARRAY_MASSIVE ) || col_list.find( ARRAY_ACTIVE ) || col_list.find( ARRAY_ENEMY ) )
  1529.             {
  1530.                 if( active_object->type == TYPE_TURTLE )
  1531.                 {
  1532.                     // downgrade if collision with static blocking objects
  1533.                     if( active_object->state == STA_RUN && ( col_list.find( ARRAY_MASSIVE ) || col_list.find( ARRAY_ACTIVE ) ) )
  1534.                     {
  1535.                         active_object->DownGrade( 1 );
  1536.                     }
  1537.                     // downgrade always
  1538.                     else if( active_object->state == STA_STAY )
  1539.                     {
  1540.                         active_object->DownGrade( 1 );
  1541.                     }
  1542.                 }
  1543.             }
  1544.             // collides with player
  1545.             else if( col_list.find( TYPE_PLAYER ) )
  1546.             {
  1547.                 position_in_player = 1;
  1548.             }
  1549.         }
  1550.     }
  1551.  
  1552.     // if found position is in the player
  1553.     if( position_in_player )
  1554.     {
  1555.         if( active_object->type == TYPE_TURTLE )
  1556.         {
  1557.             cTurtle *turtle = static_cast<cTurtle *>(active_object);
  1558.             
  1559.             // if staying
  1560.             if( turtle->state == STA_STAY )
  1561.             {
  1562.                 // if not moving fast enough
  1563.                 if( active_object->velx > -5 && active_object->velx <= 0 )
  1564.                 {
  1565.                     active_object->velx -= 5;
  1566.                 }
  1567.                 else if( active_object->velx < 5 && active_object->velx >= 0 )
  1568.                 {
  1569.                     active_object->velx += 5;
  1570.                 }
  1571.             }
  1572.             else if( turtle->state == STA_RUN )
  1573.             {
  1574.                 turtle->playercounter = 10;
  1575.             }
  1576.         }
  1577.     }
  1578.  
  1579.     active_object->Collisions_Clear();
  1580.     active_object->Reset_on_Ground();
  1581.     active_object->Update_Direction();
  1582.  
  1583.     // unset link
  1584.     active_object = NULL;
  1585.     // load default images
  1586.     Load_Images();
  1587. }
  1588.  
  1589. void cPlayer :: Set_Type( SpriteType item_type, bool animation /* = 1 */, bool sound /* = 1 */ )
  1590. {
  1591.     if( item_type == TYPE_PLAYER )
  1592.     {
  1593.         Set_Type( MARYO_SMALL, animation, sound );
  1594.     }
  1595.     else if( item_type == TYPE_MUSHROOM_DEFAULT )
  1596.     {
  1597.         Set_Type( MARYO_BIG, animation, sound );
  1598.     }
  1599.     else if( item_type == TYPE_FIREPLANT )
  1600.     {
  1601.         Set_Type( MARYO_FIRE, animation, sound );
  1602.     }
  1603. }
  1604.  
  1605. void cPlayer :: Set_Type( Maryo_type new_type, bool animation /* = 1 */, bool sound /* = 1 */ )
  1606. {
  1607.     // already set
  1608.     if( maryo_type == new_type )
  1609.     {
  1610.         return;
  1611.     }
  1612.  
  1613.     // play sound
  1614.     if( sound )
  1615.     {
  1616.         if( new_type == MARYO_BIG )
  1617.         {
  1618.             pAudio->Play_Sound( "item/mushroom.ogg", RID_MUSHROOM );
  1619.         }
  1620.         else if( new_type == MARYO_FIRE )
  1621.         {
  1622.             pAudio->Play_Sound( "item/fireplant.ogg", RID_FIREPLANT );
  1623.         }
  1624.         else if( new_type == MARYO_ICE )
  1625.         {
  1626.             pAudio->Play_Sound( "item/mushroom_blue.ogg", RID_MUSHROOM_BLUE );
  1627.         }
  1628.         else if( new_type == MARYO_CAPE )
  1629.         {
  1630.             pAudio->Play_Sound( "item/feather.ogg", RID_FEATHER );
  1631.         }
  1632.         else if( new_type == MARYO_GHOST )
  1633.         {
  1634.             pAudio->Play_Sound( "item/mushroom_ghost.ogg", RID_MUSHROOM_GHOST );
  1635.         }
  1636.     }
  1637.  
  1638.     // was flying
  1639.     if( maryo_type == MARYO_CAPE )
  1640.     {
  1641.         Stop_Flying( 0 );
  1642.     }
  1643.  
  1644.     // remember old type
  1645.     Maryo_type old_type = maryo_type;
  1646.  
  1647.     // draw animation and set new type
  1648.     if( animation )
  1649.     {
  1650.         Draw_Animation( new_type );
  1651.     }
  1652.     // only set type
  1653.     else
  1654.     {
  1655.         maryo_type = new_type;
  1656.         Load_Images();
  1657.     }
  1658.  
  1659.     // to ghost
  1660.     if( maryo_type == MARYO_GHOST )
  1661.     {
  1662.         ghost_time = speedfactor_fps * 10;
  1663.         maryo_type_temp_power = old_type;
  1664.     }
  1665.     // was ghost
  1666.     else if( old_type == MARYO_GHOST )
  1667.     {
  1668.         ghost_time = 0;
  1669.         ghost_time_mod = 0;
  1670.         maryo_type_temp_power = MARYO_DEAD;
  1671.  
  1672.         // check for ghost ground
  1673.         if( ground_object )
  1674.         {
  1675.             cBaseBox *box = dynamic_cast<cBaseBox *>( ground_object );
  1676.  
  1677.             if( box )
  1678.             {
  1679.                 // ghost box
  1680.                 if( box->box_invisible == 2 )
  1681.                 {
  1682.                     Reset_on_Ground();
  1683.                 }
  1684.             }
  1685.         }
  1686.     }
  1687. }
  1688.  
  1689. void cPlayer :: Set_Moving_State( Moving_state new_state )
  1690. {
  1691.     if( new_state == state )
  1692.     {
  1693.         return;
  1694.     }
  1695.  
  1696.  
  1697.     // was falling
  1698.     if( state == STA_FALL )
  1699.     {
  1700.         // reset slow fall/parachute
  1701.         parachute = 0;
  1702.     }
  1703.     // was flying
  1704.     else if( state == STA_FLY )
  1705.     {
  1706.         Change_Size( 0, -( images[MARYO_IMG_FALL]->h - images[MARYO_IMG_FLY]->h ) );
  1707.         Set_Image( MARYO_IMG_FALL + direction );
  1708.  
  1709.         // reset flying rotation
  1710.         rotz = 0;
  1711.     }
  1712.     // was jumping
  1713.     else if( state == STA_JUMP )
  1714.     {
  1715.         // reset variables
  1716.         UpKeytime = 0;
  1717.         jump_power = 0;
  1718.         force_jump = 0;
  1719.         next_jump_sound = 1;
  1720.         next_jump_power = 17;
  1721.         next_jump_accel = 4;
  1722.     }
  1723.     // was running
  1724.     else if( state == STA_RUN )
  1725.     {
  1726.         walk_time = 0;
  1727.         running_particle_counter = 0;
  1728.     }
  1729.  
  1730.     // # before new state is set
  1731.     if( new_state == STA_STAY )
  1732.     {
  1733.         if( ground_object )
  1734.         {
  1735.             vely = 0;
  1736.         }
  1737.     }
  1738.     else if( new_state == STA_FALL )
  1739.     {
  1740.         Reset_on_Ground();
  1741.         walk_count = 0;
  1742.         jump_power = 0;
  1743.     }
  1744.     else if( new_state == STA_FLY )
  1745.     {
  1746.         Reset_on_Ground();
  1747.     }
  1748.     else if( new_state == STA_JUMP )
  1749.     {
  1750.         Reset_on_Ground();
  1751.     }
  1752.     else if( new_state == STA_CLIMB )
  1753.     {
  1754.         Reset_on_Ground();
  1755.         velx = 0;
  1756.         vely = 0;
  1757.     }
  1758.  
  1759.     state = new_state;
  1760.  
  1761.     // # after new state is set
  1762.     if( state == STA_FLY )
  1763.     {
  1764.         Release_Item( 1 );
  1765.     }
  1766. }
  1767.  
  1768. bool cPlayer :: Change_Size( float x, float y, bool only_check /* = 0 */ )
  1769. {
  1770.     bool valid_hor = 0;
  1771.     float check_pos = x;
  1772.  
  1773.     // no value
  1774.     if( x == 0 )
  1775.     {
  1776.         valid_hor = 1;
  1777.     }
  1778.  
  1779.     while( !valid_hor )
  1780.     {
  1781.         if( !Collision_Check_Relative( check_pos, 0, 0, 0, COLLIDE_ONLY_CHECK ).size() )
  1782.         {
  1783.             if( !only_check )
  1784.             {
  1785.                 Col_Move( check_pos, 0, 1, 1 );
  1786.             }
  1787.  
  1788.             valid_hor = 1;
  1789.         }
  1790.  
  1791.         // move to opposite direction
  1792.         if( x > 0 )
  1793.         {
  1794.             check_pos--;
  1795.  
  1796.             // nothing found
  1797.             if( check_pos < -x )
  1798.             {
  1799.                 break;
  1800.             }
  1801.         }
  1802.         else
  1803.         {
  1804.             check_pos++;
  1805.  
  1806.             // nothing found
  1807.             if( check_pos > x )
  1808.             {
  1809.                 break;
  1810.             }
  1811.         }
  1812.     }
  1813.  
  1814.     bool valid_ver = 0;
  1815.     check_pos = y;
  1816.  
  1817.     // no value
  1818.     if( y == 0 )
  1819.     {
  1820.         valid_ver = 1;
  1821.     }
  1822.  
  1823.     while( !valid_ver )
  1824.     {
  1825.         if( !Collision_Check_Relative( 0, check_pos, 0, 0, COLLIDE_ONLY_CHECK ).size() )
  1826.         {
  1827.             if( !only_check )
  1828.             {
  1829.                 Col_Move( 0, check_pos, 1, 1 );
  1830.             }
  1831.  
  1832.             valid_ver = 1;
  1833.         }
  1834.  
  1835.         // move to opposite direction
  1836.         if( y > 0 )
  1837.         {
  1838.             check_pos--;
  1839.  
  1840.             // nothing found
  1841.             if( check_pos < -y )
  1842.             {
  1843.                 break;
  1844.             }
  1845.         }
  1846.         else
  1847.         {
  1848.             check_pos++;
  1849.  
  1850.             // nothing found
  1851.             if( check_pos > y )
  1852.             {
  1853.                 break;
  1854.             }
  1855.         }
  1856.     }
  1857.  
  1858.  
  1859.     // if both directions valid
  1860.     if( valid_hor && valid_ver )
  1861.     {
  1862.         return 1;
  1863.     }
  1864.  
  1865.     return 0;
  1866. }
  1867.  
  1868. void cPlayer :: Reset_Save( void )
  1869. {
  1870.     pOverworld_Manager->Reset();
  1871.  
  1872.     pActive_Level->Unload();
  1873.     Reset();
  1874.     Ball_Clear();
  1875.  
  1876.     lives = 3;
  1877.     goldpieces = 0;
  1878.     points = 0;
  1879.     timedisplay->counter = 0;
  1880.     pHud_Manager->Update_Text();
  1881.  
  1882.     Set_Type( MARYO_SMALL, 0, 0 );
  1883.  
  1884.     Itembox->Reset();
  1885. }
  1886.  
  1887. void cPlayer :: Reset( bool full /* = 1 */ )
  1888. {
  1889.     // reset level states
  1890.     Set_Visible( 1 );
  1891.     Set_Pos( startposx, startposy + start_image->col_h - col_rect.h );
  1892.     Set_Direction( start_direction );
  1893.     ducked = 0;
  1894.     Set_Moving_State( STA_FALL );
  1895.     Set_Image( Get_Image() + direction );
  1896.     jump_power = 0;
  1897.     jump_accel_up = 0;
  1898.     jump_vel_deaccel = 0;
  1899.     no_velx_counter = 0;
  1900.     no_vely_counter = 0;
  1901.     UpKeytime = 0;
  1902.     velx = 0;
  1903.     vely = 0;
  1904.     Collisions_Clear();
  1905.     walk_count = 0;
  1906.     Reset_on_Ground();
  1907.     if( active_object )
  1908.     {
  1909.         active_object = NULL;
  1910.         Load_Images();
  1911.     }
  1912.     kill_multiplier = 1;
  1913.     last_kill_counter = 0;
  1914.  
  1915.     // reset item and camera
  1916.     if( full )
  1917.     {
  1918.         pActive_Camera->Center();
  1919.         invincible = 0;
  1920.         invincible_mod = 0;
  1921.         invincible_star = 0;
  1922.         Set_Color_Combine( 0, 0, 0, 0 );
  1923.         Itembox->Push_back();
  1924.     }
  1925. }
  1926.  
  1927. void cPlayer :: Goto_Next_Level( void )
  1928. {
  1929.     // custom level
  1930.     if( Game_Mode_Type == MODE_TYPE_LEVEL_CUSTOM )
  1931.     {
  1932.         // delay unload level
  1933.         pActive_Level->Unload( 1 );
  1934.         // Enter Menu
  1935.         Game_Action = GA_ENTER_MENU;
  1936.     }
  1937.     else
  1938.     {
  1939.         // Finish level
  1940.         pActive_Overworld->Goto_Next_Level();
  1941.         // Enter World
  1942.         Game_Action = GA_ENTER_WORLD;
  1943.     }
  1944. }
  1945.  
  1946. void cPlayer :: Goto_Sub_Level( string str_level, string str_entry, bool move_camera /* = 1 */ )
  1947. {
  1948.     // if empty use same level
  1949.     if( str_level.empty() )
  1950.     {
  1951.         str_level = Get_Filename( pActive_Level->data_file, 0, 0 );
  1952.     }
  1953.  
  1954.     // same level - scroll to the position
  1955.     if( str_level.compare( Get_Filename( pActive_Level->data_file, 0, 0 ) ) == 0 )
  1956.     {
  1957.         Reset( 0 );
  1958.         
  1959.         cLevel_Entry *entry = pActive_Level->Get_Entry( str_entry );
  1960.  
  1961.         // use entry position
  1962.         if( entry )
  1963.         {
  1964.             Set_Pos( entry->Get_Player_Pos_X(), entry->Get_Player_Pos_Y() );
  1965.             // set invisible for warp animation
  1966.             Set_Visible( 0 );
  1967.         }
  1968.         // not found
  1969.         else if( !str_entry.empty() )
  1970.         {
  1971.             printf( "Warning : Level entry %s not found\n", str_entry.c_str() );
  1972.         }
  1973.  
  1974.         pFramerate->speedfactor = 1;
  1975.  
  1976.         // move camera to new position
  1977.         if( move_camera )
  1978.         {
  1979.             for( float i = 0; i < 200; i += pFramerate->speedfactor )
  1980.             {
  1981.                 if( pActive_Camera->Move_to_Position_Gradually( pActive_Camera->Get_Center_Pos_X() , pActive_Camera->Get_Center_Pos_Y() ) == 0 )
  1982.                 {
  1983.                     break;
  1984.                 }
  1985.  
  1986.                 // keep global effect particles on screen
  1987.                 pActive_Level->pGlobal_effect->Update_Particles();
  1988.  
  1989.                 // draw
  1990.                 Draw_Game();
  1991.  
  1992.                 pVideo->Render();
  1993.                 pFramerate->Update();
  1994.             }
  1995.         }
  1996.  
  1997.         // warp animation
  1998.         if( entry )
  1999.         {
  2000.             // set back visible
  2001.             Set_Visible( 1 );
  2002.             // activate entry
  2003.             entry->Activate();
  2004.         }
  2005.     }
  2006.     // another level - load the level
  2007.     else
  2008.     {
  2009.         Game_Action = GA_ENTER_LEVEL;
  2010.         Game_Action_Data.add( "level", str_level.c_str() );
  2011.         Game_Action_Data.add( "entry", str_entry.c_str() );
  2012.     }
  2013. }
  2014.  
  2015. void cPlayer :: Update( void )
  2016. {
  2017.     if( editor_enabled )
  2018.     {
  2019.         return;
  2020.     }
  2021.  
  2022.     // check if got stuck
  2023.     if( !ducked )
  2024.     {
  2025.         Update_Anti_Stuck();
  2026.     }
  2027.  
  2028.     // check if starting a jump is possible
  2029.     Update_Jump_Keytime();
  2030.  
  2031.     // update states
  2032.     Update_Jump();
  2033.     Update_Climbing();
  2034.     Update_Falling();
  2035.     Update_Walking();
  2036.     Update_Running();
  2037.     Update_Ducking();
  2038.     Update_Staying();
  2039.     Update_Flying();
  2040.     // throw animation counter
  2041.     if( throwing_counter > 0 )
  2042.     {
  2043.         throwing_counter -= pFramerate->speedfactor;
  2044.  
  2045.         if( throwing_counter < 0 )
  2046.         {
  2047.             throwing_counter = 0;
  2048.         }
  2049.     }
  2050.     // shoot counter
  2051.     if( shoot_counter > 0 )
  2052.     {
  2053.         shoot_counter -= pFramerate->speedfactor;
  2054.  
  2055.         if( shoot_counter < 0 )
  2056.         {
  2057.             shoot_counter = 0;
  2058.         }
  2059.     }
  2060.     // ghost
  2061.     if( ghost_time > 0 )
  2062.     {
  2063.         ghost_time -= pFramerate->speedfactor;
  2064.  
  2065.         // ended
  2066.         if( ghost_time <= 0 )
  2067.         {
  2068.             pAudio->Play_Sound( "player/ghost_end.ogg", RID_MUSHROOM_GHOST );
  2069.             Set_Type( maryo_type_temp_power, 1, 0 );
  2070.         }
  2071.         // near end
  2072.         else if( ghost_time * 0.5f < speedfactor_fps * 3 )
  2073.         {
  2074.             ghost_time_mod = ( speedfactor_fps * 3 ) - ( ghost_time * 0.5f );
  2075.         }
  2076.     }
  2077.     // invincible
  2078.     if( invincible > 0 )
  2079.     {
  2080.         invincible -= pFramerate->speedfactor;
  2081.  
  2082.         if( invincible < 0 )
  2083.         {
  2084.             invincible = 0;
  2085.         }
  2086.  
  2087.         if( invincible_mod < 0 )
  2088.         {
  2089.             invincible_mod = invincible * 3;
  2090.  
  2091.             if( invincible_mod > 180 )
  2092.             {
  2093.                 invincible_mod = 180;
  2094.             }
  2095.         }
  2096.         
  2097.         invincible_mod -= pFramerate->speedfactor * 20;
  2098.     }
  2099.     // draw stars if in godmode or star invincible
  2100.     if( godmode || invincible_star > 0 )
  2101.     {
  2102.         if( editor_level_enabled )
  2103.         {
  2104.             Set_Color_Combine( 0, 0, 0, 0 );
  2105.         }
  2106.         else
  2107.         {
  2108.             // draw stars
  2109.             invincible_starcounter += pFramerate->speedfactor;
  2110.  
  2111.             if( invincible_star > 0 )
  2112.             {
  2113.                 invincible_star -= pFramerate->speedfactor;
  2114.  
  2115.                 if( invincible_star <= 0 )
  2116.                 {
  2117.                     Set_Color_Combine( 0, 0, 0, 0 );
  2118.                     invincible_star = 0;
  2119.                     pAudio->Fadeout_Music( 500 );
  2120.                 }
  2121.             }
  2122.  
  2123.             while( invincible_starcounter > 1 )
  2124.             {
  2125.                 // set particle color
  2126.                 Color particle_color = orange;
  2127.                 particle_color.green += static_cast<Uint8>( invincible_mod / 5 );
  2128.                 particle_color.blue += static_cast<Uint8>( invincible_mod / 1.5f );
  2129.  
  2130.                 // create particle
  2131.                 cParticle_Emitter *anim = new cParticle_Emitter();
  2132.                 anim->Set_Pos( posx + Get_Random_Float( 0, col_rect.w * 0.9f ), posy + Get_Random_Float( 0, col_rect.h * 0.9f ) );
  2133.                 anim->Set_Image( pVideo->Get_Surface( "animation/particles/star.png" ) );
  2134.                 anim->Set_Pos_Z( posz - 0.000001f );
  2135.                 anim->Set_Time_to_Live( 0.3f );
  2136.                 anim->Set_Fading_Alpha( 1 );
  2137.                 anim->Set_Fading_Size( 1 );
  2138.                 anim->Set_Const_Rotation_Z( -5, 10 );
  2139.                 // godmode stars
  2140.                 if( godmode )
  2141.                 {
  2142.                     anim->Set_Direction_Range( 180, 180 );
  2143.                     anim->Set_Speed( 3.5f, 2.5f );
  2144.                     anim->Set_Scale( 0.3f );
  2145.                     anim->Set_Color( lightblue );
  2146.                 }
  2147.                 // default
  2148.                 else
  2149.                 {
  2150.                     anim->Set_Time_to_Live( 2 );
  2151.                     anim->Set_Speed( 1, 1.5f );
  2152.                     anim->Set_Scale( 0.2f );
  2153.                     anim->Set_Color( particle_color );
  2154.                 }
  2155.  
  2156.                 anim->Set_Blending( BLEND_ADD );
  2157.                 pAnimation_Manager->Add( anim );
  2158.  
  2159.                 invincible_starcounter--;
  2160.             }
  2161.         }
  2162.     }
  2163.  
  2164.     // update active item
  2165.     Update_Item();
  2166.  
  2167.     // image counter
  2168.     if( state == STA_WALK || ( maryo_type != MARYO_CAPE && state == STA_RUN ) )
  2169.     {
  2170.         // 4 frames
  2171.         if( maryo_type == MARYO_SMALL )
  2172.         {
  2173.             walk_count += pFramerate->speedfactor * 0.35f;
  2174.         }
  2175.         // 4 frames
  2176.         else if( maryo_type == MARYO_BIG )
  2177.         {
  2178.             walk_count += pFramerate->speedfactor * 0.3f;
  2179.         }
  2180.         // 4 frames
  2181.         else
  2182.         {
  2183.             walk_count += pFramerate->speedfactor * 0.3f;
  2184.         }
  2185.  
  2186.         // ground type modification
  2187.         float vel = ( velx > 0 ? velx : -velx );
  2188.  
  2189.         if( vel && ground_object && ground_object->image)
  2190.         {
  2191.             float ground_mod = 0;
  2192.  
  2193.             switch( ground_object->image->ground_type )
  2194.             {
  2195.                 case GROUND_ICE:
  2196.                 {
  2197.                     ground_mod = 0.125f;
  2198.                     break;
  2199.                 }
  2200.                 case GROUND_SAND:
  2201.                 {
  2202.                     ground_mod = 0.075f;
  2203.                     break;
  2204.                 }
  2205.                 case GROUND_PLASTIC:
  2206.                 {
  2207.                     ground_mod = 0.03f;
  2208.                     break;
  2209.                 }
  2210.                 default:
  2211.                 {
  2212.                     break;
  2213.                 }
  2214.             }
  2215.  
  2216.             if( ground_mod )
  2217.             {
  2218.                 walk_count += ground_mod * ( 5 / vel ) * pFramerate->speedfactor;
  2219.             }
  2220.         }
  2221.     }
  2222.     else if( state == STA_RUN )
  2223.     {
  2224.         // ? frames
  2225.         if( maryo_type == MARYO_SMALL )
  2226.         {
  2227.             //walk_count += pFramerate->speedfactor * 0.35f;
  2228.         }
  2229.         // ? frames
  2230.         else if( maryo_type == MARYO_BIG )
  2231.         {
  2232.             //walk_count += pFramerate->speedfactor * 0.3f;
  2233.         }
  2234.         // 2 frames
  2235.         else if( maryo_type == MARYO_CAPE )
  2236.         {
  2237.             walk_count += pFramerate->speedfactor * 0.35f;
  2238.         }
  2239.         // ? frames
  2240.         else
  2241.         {
  2242.             //walk_count += pFramerate->speedfactor * 0.3f;
  2243.         }
  2244.     }
  2245.     /*else if( state == FALL || state == JUMP )
  2246.     {
  2247.         walk_count += pFramerate->speedfactor * 0.3f;
  2248.     }*/
  2249.     else if( state == STA_CLIMB )
  2250.     {
  2251.         if( vely != 0 || velx != 0 )
  2252.         {
  2253.             walk_count += pFramerate->speedfactor * 0.7f;
  2254.         }
  2255.     }
  2256.     else if( state == STA_FLY )
  2257.     {
  2258.         walk_count += pFramerate->speedfactor * 0.6f;
  2259.     }
  2260.  
  2261.     // add x velocity
  2262.     if( state == STA_WALK || state == STA_RUN || state == STA_CLIMB )
  2263.     {
  2264.         if( velx > 0 )
  2265.         {
  2266.             walk_count += ( velx * 0.05f ) * pFramerate->speedfactor;
  2267.         }
  2268.         else if( velx < 0 )
  2269.         {
  2270.             walk_count += ( -velx * 0.05f ) * pFramerate->speedfactor;
  2271.         }
  2272.     }
  2273.  
  2274.     if( state == STA_WALK || state == STA_STAY || ( maryo_type != MARYO_CAPE && state == STA_RUN ) )
  2275.     {
  2276.         // 4 frames
  2277.         if( maryo_type == MARYO_SMALL )
  2278.         {
  2279.             if( walk_count >= 8 )
  2280.             {
  2281.                 walk_count = 0;
  2282.             }
  2283.         }
  2284.         // 4 frames
  2285.         else if( maryo_type == MARYO_BIG )
  2286.         {
  2287.             if( walk_count >= 8 )
  2288.             {
  2289.                 walk_count = 0;
  2290.             }
  2291.         }
  2292.         // 4 frames
  2293.         else
  2294.         {
  2295.             if( walk_count >= 8 )
  2296.             {
  2297.                 walk_count = 0;
  2298.             }
  2299.         }
  2300.     }
  2301.     else if( state == STA_RUN )
  2302.     {
  2303.         // ? frames
  2304.         if( maryo_type == MARYO_SMALL )
  2305.         {
  2306.         }
  2307.         // ? frames
  2308.         else if( maryo_type == MARYO_BIG )
  2309.         {
  2310.         }
  2311.         // 2 frames
  2312.         else if( maryo_type == MARYO_CAPE )
  2313.         {
  2314.             if( walk_count >= 4 )
  2315.             {
  2316.                 walk_count = 0;
  2317.             }
  2318.         }
  2319.         // ? frames
  2320.         else
  2321.         {
  2322.         }
  2323.     }
  2324.     /*else if( state == STA_FALL || state == STA_JUMP )
  2325.     {
  2326.         if( walk_count > 6 )
  2327.         {
  2328.             walk_count = 6;
  2329.         }
  2330.     }*/
  2331.     else if( state == STA_FLY )
  2332.     {
  2333.         // 4 frames
  2334.         if( walk_count > 8 )
  2335.         {
  2336.             walk_count = 0;
  2337.         }
  2338.     }
  2339.     else
  2340.     {
  2341.         // 4 frames
  2342.         if( walk_count >= 8 )
  2343.         {
  2344.             walk_count = 0;
  2345.         }
  2346.     }
  2347.  
  2348.     // Set image
  2349.     if( state != STA_CLIMB )
  2350.     {
  2351.         Set_Image( Get_Image() + direction );
  2352.     }
  2353.     else
  2354.     {
  2355.         Set_Image( Get_Image() );
  2356.     }
  2357.  
  2358.     // Special
  2359.     Update_Kill_Multiplier();
  2360. }
  2361.  
  2362. void cPlayer :: Draw( cSurfaceRequest *request /* = NULL */ )
  2363. {
  2364.     if( !valid_draw )
  2365.     {
  2366.         return;
  2367.     }
  2368.  
  2369.     // invincible
  2370.     if( invincible > 0 )
  2371.     {
  2372.         // star invincible
  2373.         if( invincible_star > 0 )
  2374.         {
  2375.             Set_Color_Combine( invincible_mod / 130, invincible_mod / 130, invincible_mod / 180, GL_ADD );
  2376.         }
  2377.         // default invincible
  2378.         else
  2379.         {
  2380.             Set_Color( 255, 255, 255, 255 - static_cast<Uint8>(invincible_mod) );
  2381.         }
  2382.     }
  2383.     // ghost
  2384.     if( ghost_time > 0 )
  2385.     {
  2386.         // ghost shadows
  2387.         color.alpha = 32 + static_cast<int>(ghost_time_mod);
  2388.         float old_posx = posx, old_posy = posy, old_posz = posz;
  2389.  
  2390.         for( unsigned int i = 0; i < 5; i++ )
  2391.         {
  2392.             color.alpha -= 5;
  2393.             posx -= velx * 0.2f + Get_Random_Float( 0, 1 );
  2394.             posy -= vely * 0.2f + Get_Random_Float( 0, 1 );
  2395.             posz -= 0.000001f;
  2396.  
  2397.             cMovingSprite::Draw( request );
  2398.         }
  2399.  
  2400.         // set original values
  2401.         posx = old_posx;
  2402.         posy = old_posy;
  2403.         posz = old_posz;
  2404.         color.alpha = 48 + static_cast<int>(ghost_time_mod);
  2405.     }
  2406.  
  2407.     cMovingSprite::Draw( request );
  2408.  
  2409.     if( invincible > 0 || ghost_time > 0 )
  2410.     {
  2411.         Set_Color( white );
  2412.     }
  2413. }
  2414.  
  2415. void cPlayer :: Draw_Animation( Maryo_type new_mtype )
  2416. {
  2417.     // already set or invalid
  2418.     if( new_mtype == maryo_type || maryo_type == MARYO_DEAD || new_mtype == MARYO_DEAD )
  2419.     {
  2420.         return;
  2421.     }
  2422.  
  2423.     Maryo_type maryo_type_old = maryo_type;
  2424.     bool parachute_old = parachute;
  2425.  
  2426.     float posx_old = posx;
  2427.     float posy_old = posy;
  2428.  
  2429.     // Change_Size needs new state size
  2430.     maryo_type = maryo_type_old;
  2431.     parachute = parachute_old;
  2432.     Load_Images();
  2433.  
  2434.     // correct position for bigger maryo
  2435.     if( maryo_type_old == MARYO_SMALL && ( new_mtype == MARYO_BIG || new_mtype == MARYO_FIRE || new_mtype == MARYO_ICE || new_mtype == MARYO_CAPE || new_mtype == MARYO_GHOST ) )
  2436.     {
  2437.         Change_Size( -5, -12 );
  2438.         //Col_Move( 0, 12, 1, 1 );
  2439.     }
  2440.     // correct position for small maryo
  2441.     else if( ( maryo_type_old == MARYO_BIG || maryo_type_old == MARYO_FIRE || maryo_type_old == MARYO_ICE || new_mtype == MARYO_CAPE || maryo_type_old == MARYO_GHOST ) && new_mtype == MARYO_SMALL )
  2442.     {
  2443.         Change_Size( 5, 12 );
  2444.         //Col_Move( 0, -12, 1, 1 );
  2445.     }
  2446.  
  2447.     float posx_new = posx;
  2448.     float posy_new = posy;
  2449.  
  2450.     for( unsigned int i = 0; i < 7; i++ )
  2451.     {
  2452.         // draw current type
  2453.         if( i % 2 )
  2454.         {
  2455.             maryo_type = maryo_type_old;
  2456.             parachute = parachute_old;
  2457.             Load_Images();
  2458.             
  2459.             Set_Pos( posx_old, posy_old );
  2460.         }
  2461.         // draw animation/new type
  2462.         else
  2463.         {
  2464.             maryo_type = new_mtype;
  2465.             if( new_mtype != MARYO_CAPE )
  2466.             {
  2467.                 parachute = 0;
  2468.             }
  2469.             Load_Images();
  2470.             
  2471.             Set_Pos( posx_new, posy_new );
  2472.         }
  2473.  
  2474.         // draw
  2475.         Draw_Game();
  2476.         pVideo->Render();
  2477.  
  2478.         // frame delay
  2479.         SDL_Delay( 120 );
  2480.     }
  2481.  
  2482.     pFramerate->Reset();
  2483. }
  2484.  
  2485. unsigned int cPlayer :: Get_Image( void )
  2486. {
  2487.     // throwing
  2488.     if( throwing_counter && ( maryo_type == MARYO_FIRE || maryo_type == MARYO_ICE ) && !ducked && ( state == STA_FALL || state == STA_STAY || state == STA_WALK || state == STA_RUN || state == STA_JUMP ) )
  2489.     {
  2490.         int imgnum = 0;
  2491.  
  2492.         if( throwing_counter < speedfactor_fps * 0.2f )
  2493.         {
  2494.             imgnum = 2;
  2495.         }
  2496.  
  2497.         return MARYO_IMG_THROW + imgnum;
  2498.     }
  2499.  
  2500.     // ducked
  2501.     if( ducked && ( state == STA_STAY || state == STA_WALK || state == STA_RUN || state == STA_JUMP || state == STA_FALL ) )
  2502.     {
  2503.         return MARYO_IMG_DUCK;
  2504.     }
  2505.  
  2506.     // parachute
  2507.     if( parachute && state == STA_FALL )
  2508.     {
  2509.         return MARYO_IMG_SPECIAL_1;
  2510.     }
  2511.  
  2512.     if( state == STA_STAY || state == STA_WALK || ( maryo_type != MARYO_CAPE && state == STA_RUN ) )
  2513.     {
  2514.         unsigned int imgnum = static_cast<unsigned int>(walk_count);
  2515.  
  2516.         for( unsigned int i = 0; i < imgnum; i++ )
  2517.         {
  2518.             if( imgnum % 2 )
  2519.             {
  2520.                 imgnum--;
  2521.             }
  2522.         }
  2523.  
  2524.         return MARYO_IMG_WALK + imgnum;
  2525.     }
  2526.     else if( state == STA_RUN )
  2527.     {
  2528.         unsigned int imgnum = static_cast<unsigned int>(walk_count);
  2529.  
  2530.         for( unsigned int i = 0; i < imgnum; i++ )
  2531.         {
  2532.             if( imgnum % 2 )
  2533.             {
  2534.                 imgnum--;
  2535.             }
  2536.         }
  2537.  
  2538.         return MARYO_IMG_RUN + imgnum;
  2539.     }
  2540.     else if( state == STA_FALL )
  2541.     {
  2542.         /*unsigned int imgnum = static_cast<unsigned int>(walk_count);
  2543.  
  2544.         for( unsigned int i = 0; i < imgnum; i++ )
  2545.         {
  2546.             if( imgnum % 2 )
  2547.             {
  2548.                 imgnum--;
  2549.             }
  2550.         }
  2551.  
  2552.         return MARYO_IMG_FALL + imgnum;*/
  2553.         return MARYO_IMG_FALL;
  2554.     }
  2555.     /*else if( state == STAY )
  2556.     {
  2557.         return MARYO_IMG_STAND;
  2558.     }*/
  2559.     else if( state == STA_JUMP )
  2560.     {
  2561.         /*unsigned int imgnum = static_cast<unsigned int>(walk_count);
  2562.  
  2563.         for( unsigned int i = 0; i < imgnum; i++ )
  2564.         {
  2565.             if( imgnum % 2 )
  2566.             {
  2567.                 imgnum--;
  2568.             }
  2569.         }
  2570.  
  2571.         return MARYO_IMG_JUMP + imgnum;*/
  2572.         return MARYO_IMG_JUMP;
  2573.     }
  2574.     else if( state == STA_FLY )
  2575.     {
  2576.         unsigned int imgnum = static_cast<unsigned int>(walk_count);
  2577.  
  2578.         for( unsigned int i = 0; i < imgnum; i++ )
  2579.         {
  2580.             if( imgnum % 2 )
  2581.             {
  2582.                 imgnum--;
  2583.             }
  2584.         }
  2585.  
  2586.         return MARYO_IMG_FLY + imgnum;
  2587.     }
  2588.     else if( state == STA_CLIMB )
  2589.     {
  2590.         if( walk_count > 4 )
  2591.         {
  2592.             return MARYO_IMG_CLIMB;
  2593.         }
  2594.         else
  2595.         {
  2596.             return MARYO_IMG_CLIMB + 1;
  2597.         }
  2598.     }
  2599.  
  2600.     return MARYO_IMG_STAND;
  2601. }
  2602.  
  2603. void cPlayer :: Load_Images( void )
  2604. {
  2605.     // not valid
  2606.     if( maryo_type == MARYO_DEAD )
  2607.     {
  2608.         return;
  2609.     }
  2610.  
  2611.     Clear_Images();
  2612.  
  2613.     // special maryo images state
  2614.     string special_state;
  2615.     // if holding item
  2616.     if( active_object )
  2617.     {
  2618.         special_state = "_holding";
  2619.     }
  2620.  
  2621.     if( maryo_type == MARYO_SMALL )
  2622.     {
  2623.         /********************* Small **************************/
  2624.         // standing
  2625.         images.push_back( pVideo->Get_Surface( "maryo/small/stand_left" + special_state + ".png" ) );
  2626.         images.push_back( pVideo->Get_Surface( "maryo/small/stand_right" + special_state + ".png" ) );
  2627.         // walking
  2628.         images.push_back( pVideo->Get_Surface( "maryo/small/walk_left_1" + special_state + ".png" ) );
  2629.         images.push_back( pVideo->Get_Surface( "maryo/small/walk_right_1" + special_state + ".png" ) );
  2630.         images.push_back( pVideo->Get_Surface( "maryo/small/walk_left_2" + special_state + ".png" ) );
  2631.         images.push_back( pVideo->Get_Surface( "maryo/small/walk_right_2" + special_state + ".png" ) );
  2632.         images.push_back( pVideo->Get_Surface( "maryo/small/walk_left_1" + special_state + ".png" ) );
  2633.         images.push_back( pVideo->Get_Surface( "maryo/small/walk_right_1" + special_state + ".png" ) );
  2634.         // running
  2635.         images.push_back( NULL );
  2636.         images.push_back( NULL );
  2637.         images.push_back( NULL );
  2638.         images.push_back( NULL );
  2639.         // falling
  2640.         images.push_back( pVideo->Get_Surface( "maryo/small/fall_left" + special_state + ".png" ) );
  2641.         images.push_back( pVideo->Get_Surface( "maryo/small/fall_right" + special_state + ".png" ) );
  2642.         // jumping
  2643.         images.push_back( pVideo->Get_Surface( "maryo/small/jump_left" + special_state + ".png" ) );
  2644.         images.push_back( pVideo->Get_Surface( "maryo/small/jump_right" + special_state + ".png" ) );
  2645.         // dead
  2646.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_left.png" ) );
  2647.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_right.png" ) );
  2648.         // ducked
  2649.         images.push_back( pVideo->Get_Surface( "maryo/small/duck_left.png" ) );
  2650.         images.push_back( pVideo->Get_Surface( "maryo/small/duck_right.png" ) );
  2651.         // climbing
  2652.         images.push_back( pVideo->Get_Surface( "maryo/small/climb_left.png" ) );
  2653.         images.push_back( pVideo->Get_Surface( "maryo/small/climb_right.png" ) );
  2654.         /****************************************************/
  2655.     }
  2656.     else if( maryo_type == MARYO_BIG )
  2657.     {
  2658.         /********************* Big ****************************/
  2659.         // standing
  2660.         images.push_back( pVideo->Get_Surface( "maryo/big/stand_left" + special_state + ".png" ) );
  2661.         images.push_back( pVideo->Get_Surface( "maryo/big/stand_right" + special_state + ".png" ) );
  2662.         // walking
  2663.         images.push_back( pVideo->Get_Surface( "maryo/big/walk_left_1" + special_state + ".png" ) );
  2664.         images.push_back( pVideo->Get_Surface( "maryo/big/walk_right_1" + special_state + ".png" ) );
  2665.         images.push_back( pVideo->Get_Surface( "maryo/big/walk_left_2" + special_state + ".png" ) );
  2666.         images.push_back( pVideo->Get_Surface( "maryo/big/walk_right_2" + special_state + ".png" ) );
  2667.         images.push_back( pVideo->Get_Surface( "maryo/big/walk_left_1" + special_state + ".png" ) );
  2668.         images.push_back( pVideo->Get_Surface( "maryo/big/walk_right_1" + special_state + ".png" ) );
  2669.         // running
  2670.         images.push_back( NULL );
  2671.         images.push_back( NULL );
  2672.         images.push_back( NULL );
  2673.         images.push_back( NULL );
  2674.         // falling
  2675.         images.push_back( pVideo->Get_Surface( "maryo/big/fall_left" + special_state + ".png" ) );
  2676.         images.push_back( pVideo->Get_Surface( "maryo/big/fall_right" + special_state + ".png" ) );
  2677.         // jumping
  2678.         images.push_back( pVideo->Get_Surface( "maryo/big/jump_left" + special_state + ".png" ) );
  2679.         images.push_back( pVideo->Get_Surface( "maryo/big/jump_right" + special_state + ".png" ) );
  2680.         // dead
  2681.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_left.png" ) );
  2682.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_right.png" ) );
  2683.         // ducked
  2684.         images.push_back( pVideo->Get_Surface( "maryo/big/duck_left.png" ) );
  2685.         images.push_back( pVideo->Get_Surface( "maryo/big/duck_right.png" ) );
  2686.         // climbing
  2687.         images.push_back( pVideo->Get_Surface( "maryo/big/climb_left.png" ) );
  2688.         images.push_back( pVideo->Get_Surface( "maryo/big/climb_right.png" ) );
  2689.         // throwing
  2690.         images.push_back( NULL );
  2691.         images.push_back( NULL );
  2692.         images.push_back( NULL );
  2693.         images.push_back( NULL );
  2694.         /****************************************************/
  2695.     }
  2696.     else if( maryo_type == MARYO_FIRE )
  2697.     {
  2698.         /********************* Fire **************************/
  2699.         // standing
  2700.         images.push_back( pVideo->Get_Surface( "maryo/fire/stand_left" + special_state + ".png" ) );
  2701.         images.push_back( pVideo->Get_Surface( "maryo/fire/stand_right" + special_state + ".png" ) );
  2702.         // walking
  2703.         images.push_back( pVideo->Get_Surface( "maryo/fire/walk_left_1" + special_state + ".png" ) );
  2704.         images.push_back( pVideo->Get_Surface( "maryo/fire/walk_right_1" + special_state + ".png" ) );
  2705.         images.push_back( pVideo->Get_Surface( "maryo/fire/walk_left_2" + special_state + ".png" ) );
  2706.         images.push_back( pVideo->Get_Surface( "maryo/fire/walk_right_2" + special_state + ".png" ) );
  2707.         images.push_back( pVideo->Get_Surface( "maryo/fire/walk_left_1" + special_state + ".png" ) );
  2708.         images.push_back( pVideo->Get_Surface( "maryo/fire/walk_right_1" + special_state + ".png" ) );
  2709.         // running
  2710.         images.push_back( NULL );
  2711.         images.push_back( NULL );
  2712.         images.push_back( NULL );
  2713.         images.push_back( NULL );
  2714.         // falling
  2715.         images.push_back( pVideo->Get_Surface( "maryo/fire/fall_left" + special_state + ".png" ) );
  2716.         images.push_back( pVideo->Get_Surface( "maryo/fire/fall_right" + special_state + ".png" ) );
  2717.         // jumping
  2718.         images.push_back( pVideo->Get_Surface( "maryo/fire/jump_left" + special_state + ".png" ) );
  2719.         images.push_back( pVideo->Get_Surface( "maryo/fire/fall_right" + special_state + ".png" ) );
  2720.         // dead
  2721.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_left.png" ) );
  2722.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_right.png" ) );
  2723.         // ducked
  2724.         images.push_back( pVideo->Get_Surface( "maryo/fire/duck_left.png" ) );
  2725.         images.push_back( pVideo->Get_Surface( "maryo/fire/duck_right.png" ) );
  2726.         // climbing
  2727.         images.push_back( pVideo->Get_Surface( "maryo/fire/climb_left.png" ) );
  2728.         images.push_back( pVideo->Get_Surface( "maryo/fire/climb_right.png" ) );
  2729.         // throwing
  2730.         images.push_back( pVideo->Get_Surface( "maryo/fire/throw_left_1.png" ) );
  2731.         images.push_back( pVideo->Get_Surface( "maryo/fire/throw_right_1.png" ) );
  2732.         images.push_back( pVideo->Get_Surface( "maryo/fire/throw_left_2.png" ) );
  2733.         images.push_back( pVideo->Get_Surface( "maryo/fire/throw_right_2.png" ) );
  2734.         /****************************************************/
  2735.     }
  2736.     else if( maryo_type == MARYO_ICE )
  2737.     {
  2738.         /********************* Ice **************************/
  2739.         // standing
  2740.         images.push_back( pVideo->Get_Surface( "maryo/ice/stand_left" + special_state + ".png" ) );
  2741.         images.push_back( pVideo->Get_Surface( "maryo/ice/stand_right" + special_state + ".png" ) );
  2742.         // walking
  2743.         images.push_back( pVideo->Get_Surface( "maryo/ice/walk_left_1" + special_state + ".png" ) );
  2744.         images.push_back( pVideo->Get_Surface( "maryo/ice/walk_right_1" + special_state + ".png" ) );
  2745.         images.push_back( pVideo->Get_Surface( "maryo/ice/walk_left_2" + special_state + ".png" ) );
  2746.         images.push_back( pVideo->Get_Surface( "maryo/ice/walk_right_2" + special_state + ".png" ) );
  2747.         images.push_back( pVideo->Get_Surface( "maryo/ice/walk_left_1" + special_state + ".png" ) );
  2748.         images.push_back( pVideo->Get_Surface( "maryo/ice/walk_right_1" + special_state + ".png" ) );
  2749.         // running
  2750.         images.push_back( NULL );
  2751.         images.push_back( NULL );
  2752.         images.push_back( NULL );
  2753.         images.push_back( NULL );
  2754.         // falling
  2755.         images.push_back( pVideo->Get_Surface( "maryo/ice/fall_left" + special_state + ".png" ) );
  2756.         images.push_back( pVideo->Get_Surface( "maryo/ice/fall_right" + special_state + ".png" ) );
  2757.         // jumping
  2758.         images.push_back( pVideo->Get_Surface( "maryo/ice/jump_left" + special_state + ".png" ) );
  2759.         images.push_back( pVideo->Get_Surface( "maryo/ice/fall_right" + special_state + ".png" ) );
  2760.         // dead
  2761.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_left.png" ) );
  2762.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_right.png" ) );
  2763.         // ducked
  2764.         images.push_back( pVideo->Get_Surface( "maryo/ice/duck_left.png" ) );
  2765.         images.push_back( pVideo->Get_Surface( "maryo/ice/duck_right.png" ) );
  2766.         // climbing
  2767.         images.push_back( pVideo->Get_Surface( "maryo/ice/climb_left.png" ) );
  2768.         images.push_back( pVideo->Get_Surface( "maryo/ice/climb_right.png" ) );
  2769.         // throwing
  2770.         images.push_back( pVideo->Get_Surface( "maryo/ice/throw_left_1.png" ) );
  2771.         images.push_back( pVideo->Get_Surface( "maryo/ice/throw_right_1.png" ) );
  2772.         images.push_back( pVideo->Get_Surface( "maryo/ice/throw_left_2.png" ) );
  2773.         images.push_back( pVideo->Get_Surface( "maryo/ice/throw_right_2.png" ) );
  2774.         /****************************************************/
  2775.     }
  2776.     else if( maryo_type == MARYO_CAPE )
  2777.     {
  2778.         /********************* Cape **************************/
  2779.         // standing
  2780.         images.push_back( pVideo->Get_Surface( "maryo/flying/left" + special_state + ".png" ) );
  2781.         images.push_back( pVideo->Get_Surface( "maryo/flying/right" + special_state + ".png" ) );
  2782.         // walking
  2783.         images.push_back( pVideo->Get_Surface( "maryo/flying/walk_left_1" + special_state + ".png" ) );
  2784.         images.push_back( pVideo->Get_Surface( "maryo/flying/walk_right_1" + special_state + ".png" ) );
  2785.         images.push_back( pVideo->Get_Surface( "maryo/flying/walk_left_2" + special_state + ".png" ) );
  2786.         images.push_back( pVideo->Get_Surface( "maryo/flying/walk_right_2" + special_state + ".png" ) );
  2787.         images.push_back( pVideo->Get_Surface( "maryo/flying/walk_left_1" + special_state + ".png" ) );
  2788.         images.push_back( pVideo->Get_Surface( "maryo/flying/walk_right_1" + special_state + ".png" ) );
  2789.         // running
  2790.         images.push_back( pVideo->Get_Surface( "maryo/flying/run_left_1" + special_state + ".png" ) );
  2791.         images.push_back( pVideo->Get_Surface( "maryo/flying/run_right_1" + special_state + ".png" ) );
  2792.         images.push_back( pVideo->Get_Surface( "maryo/flying/run_left_2" + special_state + ".png" ) );
  2793.         images.push_back( pVideo->Get_Surface( "maryo/flying/run_right_2" + special_state + ".png" ) );
  2794.         // falling
  2795.         images.push_back( pVideo->Get_Surface( "maryo/flying/fall_left" + special_state + ".png" ) );
  2796.         images.push_back( pVideo->Get_Surface( "maryo/flying/fall_right" + special_state + ".png" ) );
  2797.         // jumping
  2798.         images.push_back( pVideo->Get_Surface( "maryo/flying/jump_left" + special_state + ".png" ) );
  2799.         images.push_back( pVideo->Get_Surface( "maryo/flying/fall_right" + special_state + ".png" ) );
  2800.         // dead
  2801.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_left.png" ) );
  2802.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_right.png" ) );
  2803.         // ducked
  2804.         images.push_back( pVideo->Get_Surface( "maryo/flying/duck_left.png" ) );
  2805.         images.push_back( pVideo->Get_Surface( "maryo/flying/duck_right.png" ) );
  2806.         // climbing
  2807.         images.push_back( pVideo->Get_Surface( "maryo/flying/climb_left.png" ) );
  2808.         images.push_back( pVideo->Get_Surface( "maryo/flying/climb_right.png" ) );
  2809.         // throwing
  2810.         images.push_back( NULL );
  2811.         images.push_back( NULL );
  2812.         images.push_back( NULL );
  2813.         images.push_back( NULL );
  2814.         // flying
  2815.         images.push_back( pVideo->Get_Surface( "maryo/flying/fly_left_1.png" ) );
  2816.         images.push_back( pVideo->Get_Surface( "maryo/flying/fly_right_1.png" ) );
  2817.         images.push_back( pVideo->Get_Surface( "maryo/flying/fly_left_2.png" ) );
  2818.         images.push_back( pVideo->Get_Surface( "maryo/flying/fly_right_2.png" ) );
  2819.         images.push_back( pVideo->Get_Surface( "maryo/flying/fly_left_3.png" ) );
  2820.         images.push_back( pVideo->Get_Surface( "maryo/flying/fly_right_3.png" ) );
  2821.         images.push_back( pVideo->Get_Surface( "maryo/flying/fly_left_4.png" ) );
  2822.         images.push_back( pVideo->Get_Surface( "maryo/flying/fly_right_4.png" ) );
  2823.         // slow fall/parachute
  2824.         images.push_back( pVideo->Get_Surface( "maryo/flying/slow_fall_left.png" ) );
  2825.         images.push_back( pVideo->Get_Surface( "maryo/flying/slow_fall_right.png" ) );
  2826.         /****************************************************/
  2827.     }
  2828.     else if( maryo_type == MARYO_GHOST )
  2829.     {
  2830.         /********************* Ghost **************************/
  2831.         // standing
  2832.         images.push_back( pVideo->Get_Surface( "maryo/ghost/stand_left" + special_state + ".png" ) );
  2833.         images.push_back( pVideo->Get_Surface( "maryo/ghost/stand_right" + special_state + ".png" ) );
  2834.         // walking
  2835.         images.push_back( pVideo->Get_Surface( "maryo/ghost/walk_left_1" + special_state + ".png" ) );
  2836.         images.push_back( pVideo->Get_Surface( "maryo/ghost/walk_right_1" + special_state + ".png" ) );
  2837.         images.push_back( pVideo->Get_Surface( "maryo/ghost/walk_left_2" + special_state + ".png" ) );
  2838.         images.push_back( pVideo->Get_Surface( "maryo/ghost/walk_right_2" + special_state + ".png" ) );
  2839.         images.push_back( pVideo->Get_Surface( "maryo/ghost/walk_left_1" + special_state + ".png" ) );
  2840.         images.push_back( pVideo->Get_Surface( "maryo/ghost/walk_right_1" + special_state + ".png" ) );
  2841.         // running
  2842.         images.push_back( NULL );
  2843.         images.push_back( NULL );
  2844.         images.push_back( NULL );
  2845.         images.push_back( NULL );
  2846.         // falling
  2847.         images.push_back( pVideo->Get_Surface( "maryo/ghost/fall_left" + special_state + ".png" ) );
  2848.         images.push_back( pVideo->Get_Surface( "maryo/ghost/fall_right" + special_state + ".png" ) );
  2849.         // jumping
  2850.         images.push_back( pVideo->Get_Surface( "maryo/ghost/jump_left" + special_state + ".png" ) );
  2851.         images.push_back( pVideo->Get_Surface( "maryo/ghost/fall_right" + special_state + ".png" ) );
  2852.         // dead
  2853.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_left.png" ) );
  2854.         images.push_back( pVideo->Get_Surface( "maryo/small/dead_right.png" ) );
  2855.         // ducked
  2856.         images.push_back( pVideo->Get_Surface( "maryo/ghost/duck_left.png" ) );
  2857.         images.push_back( pVideo->Get_Surface( "maryo/ghost/duck_right.png" ) );
  2858.         // climbing
  2859.         images.push_back( pVideo->Get_Surface( "maryo/ghost/climb_left.png" ) );
  2860.         images.push_back( pVideo->Get_Surface( "maryo/ghost/climb_right.png" ) );
  2861.         // throwing
  2862.         images.push_back( NULL );
  2863.         images.push_back( NULL );
  2864.         images.push_back( NULL );
  2865.         images.push_back( NULL );
  2866.         /****************************************************/
  2867.     }
  2868.  
  2869.     // set image
  2870.     Set_Image( Get_Image() + direction );
  2871. }
  2872.  
  2873. void cPlayer :: Get_Item( SpriteType item_type, bool force /* = 0 */, cMovingSprite *base /* = NULL */ )
  2874. {
  2875.     // Default Mushroom
  2876.     if( item_type == TYPE_MUSHROOM_DEFAULT ) 
  2877.     {
  2878.         if( ( maryo_type == MARYO_SMALL || force ) && Change_Size( -5, -12, 1 ) ) 
  2879.         {
  2880.             // change to big
  2881.             if( maryo_type == MARYO_SMALL )
  2882.             {
  2883.                 // set type
  2884.                 Set_Type( MARYO_BIG, 1, 1 );
  2885.             }
  2886.             // move item to itembox
  2887.             else if( maryo_type == MARYO_BIG )
  2888.             {
  2889.                 // item to itembox
  2890.                 Itembox->Set_Item( TYPE_MUSHROOM_DEFAULT );
  2891.             }
  2892.             // change to big
  2893.             else if( maryo_type == MARYO_FIRE )
  2894.             {
  2895.                 // set type
  2896.                 Set_Type( MARYO_BIG, 0, 1 );
  2897.                 // old item to itembox
  2898.                 Itembox->Set_Item( TYPE_FIREPLANT );
  2899.             }
  2900.         }
  2901.         // move item to itembox
  2902.         else
  2903.         {
  2904.             Itembox->Set_Item( TYPE_MUSHROOM_DEFAULT );
  2905.         }
  2906.     }
  2907.     // Fireplant
  2908.     else if( item_type == TYPE_FIREPLANT ) 
  2909.     {
  2910.         if( ( ( maryo_type == MARYO_SMALL || force ) && Change_Size( -5, -12, 1 ) ) || 
  2911.             ( ( maryo_type == MARYO_BIG || maryo_type == MARYO_ICE || force ) ) )
  2912.         {
  2913.             // move item to itembox
  2914.             if( maryo_type == MARYO_FIRE ) 
  2915.             {
  2916.                 // move item to itembox
  2917.                 Itembox->Set_Item( TYPE_FIREPLANT );
  2918.             }
  2919.             // change to fire
  2920.             else
  2921.             {
  2922.                 // set type
  2923.                 Set_Type( MARYO_FIRE, 1, 1 );
  2924.             }
  2925.         }
  2926.         // fire explosion
  2927.         else if( maryo_type == MARYO_FIRE && Itembox->item_id == TYPE_FIREPLANT )
  2928.         {
  2929.             Ball_Add( FIREBALL_EXPLOSION );
  2930.             pointsdisplay->Add_Points( 1000, posx + ( col_rect.w / 2 ), posy + 2 );    
  2931.         }
  2932.         // move item to itembox
  2933.         else
  2934.         {
  2935.             Itembox->Set_Item( TYPE_FIREPLANT );
  2936.         }
  2937.     }
  2938.     // Blue Mushroom
  2939.     else if( item_type == TYPE_MUSHROOM_BLUE ) 
  2940.     {
  2941.         if( ( ( maryo_type == MARYO_SMALL || force ) && Change_Size( -5, -20, 1 ) ) || 
  2942.             ( ( maryo_type == MARYO_BIG || maryo_type == MARYO_FIRE || force ) ) )
  2943.         {
  2944.             // move item to itembox
  2945.             if( maryo_type == MARYO_ICE ) 
  2946.             {
  2947.                 // move item to itembox
  2948.                 Itembox->Set_Item( TYPE_MUSHROOM_BLUE );
  2949.             }
  2950.             // change to ice
  2951.             else
  2952.             {
  2953.                 // set type
  2954.                 Set_Type( MARYO_ICE, 1, 1 );
  2955.             }
  2956.         }
  2957.         // ice explosion
  2958.         else if( maryo_type == MARYO_ICE && Itembox->item_id == TYPE_MUSHROOM_BLUE )
  2959.         {
  2960.             Ball_Add( ICEBALL_EXPLOSION );
  2961.             pointsdisplay->Add_Points( 1000, posx + ( col_rect.w / 2 ), posy + 2 );    
  2962.         }
  2963.         // move item to itembox
  2964.         else
  2965.         {
  2966.             Itembox->Set_Item( TYPE_MUSHROOM_BLUE );
  2967.         }
  2968.     }
  2969.     // Ghost Mushroom
  2970.     else if( item_type == TYPE_MUSHROOM_GHOST ) 
  2971.     {
  2972.         if( ( ( maryo_type == MARYO_SMALL || force ) && Change_Size( -5, -20, 1 ) ) || 
  2973.             maryo_type != MARYO_SMALL )
  2974.         {
  2975.             // set back ghost time
  2976.             if( maryo_type == MARYO_GHOST )
  2977.             {
  2978.                 ghost_time = speedfactor_fps * 10;
  2979.                 ghost_time_mod = 0;
  2980.             }
  2981.             // change to ghost
  2982.             else
  2983.             {
  2984.                 // set type
  2985.                 Set_Type( MARYO_GHOST, 1, 1 );
  2986.             }
  2987.         }
  2988.         // move item to itembox
  2989.         else
  2990.         {
  2991.             Itembox->Set_Item( TYPE_MUSHROOM_GHOST );
  2992.         }
  2993.     }
  2994.     // Mushroom 1-UP
  2995.     else if( item_type == TYPE_MUSHROOM_LIVE_1 ) 
  2996.     {
  2997.         pAudio->Play_Sound( "item/live_up.ogg", RID_1UP_MUSHROOM );
  2998.         livedisplay->Add_Lives( 1 );
  2999.     }
  3000.     // Mushroom Poison
  3001.     else if( item_type == TYPE_MUSHROOM_POISON ) 
  3002.     {
  3003.         DownGrade();
  3004.     }
  3005.     // Moon
  3006.     else if( item_type == TYPE_MOON ) 
  3007.     {
  3008.         pAudio->Play_Sound( "item/moon.ogg", RID_MOON );
  3009.         livedisplay->Add_Lives( 3 );
  3010.     }
  3011.     // Jumping Star
  3012.     else if( item_type == TYPE_JSTAR ) 
  3013.     {
  3014.         // todo : check if music is already playing
  3015.         pAudio->Play_Music( "game/star.ogg", 0, 1, 500 );
  3016.         pAudio->Play_Music( pActive_Level->musicfile, -1, 0 );
  3017.         pointsdisplay->Add_Points( 1000, posx + ( col_rect.w / 2 ), posy + 2 );
  3018.         invincible = speedfactor_fps * 16;
  3019.         invincible_star = speedfactor_fps * 15;
  3020.     }
  3021.     // Turtle Shell
  3022.     else if( item_type == TYPE_TURTLE ) 
  3023.     {
  3024.         active_object = base;
  3025.         active_object->massivetype = MASS_PASSIVE;
  3026.         active_object->state = STA_OBJ_LINKED;
  3027.         active_object->Update_Valid_Update();
  3028.         active_object->Reset_on_Ground();
  3029.         active_object->velx = 0;
  3030.         active_object->vely = 0;
  3031.         
  3032.         
  3033.         cTurtle *turtle = static_cast<cTurtle *>(active_object);
  3034.         // clear the standing counter
  3035.         turtle->counter = 0;
  3036.         // clear player counter
  3037.         turtle->playercounter = 0;
  3038.         turtle->Set_Image( 5 );
  3039.  
  3040.         // load holding images
  3041.         Load_Images();
  3042.     }
  3043. }
  3044.  
  3045. float cPlayer :: Get_Vel_Modifier( void )
  3046. {
  3047.     float vel_mod = 1;
  3048.  
  3049.     // if running key is pressed or always run
  3050.     if( pPreferences->always_run || pKeyboard->keys[pPreferences->key_action] || pJoystick->Button( pPreferences->joy_button_action ) )
  3051.     {
  3052.         vel_mod = 1.5f;
  3053.     }
  3054.  
  3055.     if( invincible_star > 0 )
  3056.     {
  3057.         vel_mod *= 1.2f;
  3058.     }
  3059.  
  3060.     if( state == STA_RUN )
  3061.     {
  3062.         vel_mod *= 1.2f;
  3063.     }
  3064.  
  3065.     return vel_mod;
  3066. }
  3067.  
  3068. void cPlayer :: Action_Jump( bool enemy_jump /* = 0 */ )
  3069. {
  3070.     if( ducked )
  3071.     {
  3072.         // power jump
  3073.         if( SDL_GetTicks() - ducked > power_jump_delta )
  3074.         {
  3075.             force_jump = 1;
  3076.             next_jump_power += 2;
  3077.             next_jump_accel += 0.2f;
  3078.         }
  3079.         // stop ducking after setting power jump
  3080.         Stop_Ducking();
  3081.     }
  3082.  
  3083.     // enemy jump
  3084.     if( enemy_jump )
  3085.     {
  3086.         force_jump = 1;
  3087.         next_jump_sound = 0;
  3088.         next_jump_power += 1;
  3089.         next_jump_accel += 0.1f;
  3090.     }
  3091.  
  3092.     // start keytime
  3093.     Start_Jump_Keytime();
  3094.     // check if starting a jump is possible
  3095.     Update_Jump_Keytime();
  3096. }
  3097.  
  3098. void cPlayer :: Action_Interact( input_identifier key_type )
  3099. {
  3100.     // Up
  3101.     if( key_type == INP_UP )
  3102.     {
  3103.         // Search for colliding level exit Objects
  3104.         for( SpriteList::iterator itr = pActive_Sprite_Manager->objects.begin(), itr_end = pActive_Sprite_Manager->objects.end(); itr != itr_end; ++itr )
  3105.         {
  3106.             cSprite *obj = (*itr);
  3107.  
  3108.             // levelexit
  3109.             if( obj->type == TYPE_LEVEL_EXIT && Col_Box( &col_rect, &obj->col_rect ) )
  3110.             {
  3111.                 cLevel_Exit *level_exit = static_cast<cLevel_Exit *>(obj);
  3112.  
  3113.                 // beam
  3114.                 if( level_exit->exit_type == LEVELEXIT_BEAM )
  3115.                 {
  3116.                     // needs to be on ground
  3117.                     if( ground_object )
  3118.                     {
  3119.                         Game_Action = GA_ACTIVATE_LEVEL_EXIT;
  3120.                         Game_Action_ptr = level_exit;
  3121.                         return;
  3122.                     }
  3123.                 }
  3124.                 // warp
  3125.                 else if( level_exit->exit_type == LEVELEXIT_WARP )
  3126.                 {
  3127.                     if( level_exit->direction == DIR_UP )
  3128.                     {
  3129.                         if( vely <= 0 )
  3130.                         {
  3131.                             Game_Action = GA_ACTIVATE_LEVEL_EXIT;
  3132.                             Game_Action_ptr = level_exit;
  3133.                             return;
  3134.                         }
  3135.                     }
  3136.                 }
  3137.             }
  3138.         }
  3139.     }
  3140.     // Down
  3141.     else if( key_type == INP_DOWN )
  3142.     {
  3143.         // Search for colliding Levelexit Objects
  3144.         for( SpriteList::iterator itr = pActive_Sprite_Manager->objects.begin(), itr_end = pActive_Sprite_Manager->objects.end(); itr != itr_end; ++itr )
  3145.         {
  3146.             cSprite *obj = (*itr);
  3147.  
  3148.             // levelexit
  3149.             if( obj->type == TYPE_LEVEL_EXIT && Col_Box( &col_rect, &obj->col_rect ) )
  3150.             {
  3151.                 cLevel_Exit *level_exit = static_cast<cLevel_Exit *>(obj);
  3152.  
  3153.                 // warp
  3154.                 if( level_exit->exit_type == LEVELEXIT_WARP )
  3155.                 {
  3156.                     if( level_exit->direction == DIR_DOWN )
  3157.                     {
  3158.                         // needs to be on ground
  3159.                         if( ground_object )
  3160.                         {
  3161.                             Game_Action = GA_ACTIVATE_LEVEL_EXIT;
  3162.                             Game_Action_ptr = level_exit;
  3163.                             return;
  3164.                         }
  3165.                     }
  3166.                 }
  3167.             }
  3168.         }
  3169.  
  3170.         // ducking / falling
  3171.         if( state != STA_FLY )
  3172.         {
  3173.             if( ground_object )
  3174.             {
  3175.                 if( ground_object->massivetype == MASS_MASSIVE )
  3176.                 {
  3177.                     Start_Ducking();
  3178.                 }
  3179.                 else if( ground_object->massivetype == MASS_HALFMASSIVE )
  3180.                 {
  3181.                     Start_Falling();
  3182.                 }
  3183.             }
  3184.         }
  3185.     }
  3186.     // Left
  3187.     else if( key_type == INP_LEFT )
  3188.     {
  3189.         // Search for colliding Levelexit Objects
  3190.         for( SpriteList::iterator itr = pActive_Sprite_Manager->objects.begin(), itr_end = pActive_Sprite_Manager->objects.end(); itr != itr_end; ++itr )
  3191.         {
  3192.             cSprite *obj = (*itr);
  3193.  
  3194.             // levelexit
  3195.             if( obj->type == TYPE_LEVEL_EXIT && Col_Box( &col_rect, &obj->col_rect ) )
  3196.             {
  3197.                 cLevel_Exit *level_exit = static_cast<cLevel_Exit *>(obj);
  3198.  
  3199.                 // warp
  3200.                 if( level_exit->exit_type == LEVELEXIT_WARP )
  3201.                 {
  3202.                     if( level_exit->direction == DIR_LEFT )
  3203.                     {
  3204.                         if( velx >= 0 )
  3205.                         {
  3206.                             Game_Action = GA_ACTIVATE_LEVEL_EXIT;
  3207.                             Game_Action_ptr = level_exit;
  3208.                             return;
  3209.                         }
  3210.                     }
  3211.                 }
  3212.             }
  3213.         }
  3214.  
  3215.         // direction
  3216.         if( state != STA_FLY )
  3217.         {
  3218.             if( direction != DIR_LEFT )
  3219.             {
  3220.                 // play stop sound if already running
  3221.                 if( velx > 12 && ground_object )
  3222.                 {
  3223.                     pAudio->Play_Sound( "player/maryo_stop.ogg", RID_MARYO_STOP );
  3224.                 }
  3225.  
  3226.                 direction = DIR_LEFT;
  3227.             }
  3228.         }
  3229.     }
  3230.     // Right
  3231.     else if( key_type == INP_RIGHT )
  3232.     {
  3233.         // Search for colliding Levelexit Objects
  3234.         for( SpriteList::iterator itr = pActive_Sprite_Manager->objects.begin(), itr_end = pActive_Sprite_Manager->objects.end(); itr != itr_end; ++itr )
  3235.         {
  3236.             cSprite *obj = (*itr);
  3237.  
  3238.             // levelexit
  3239.             if( obj->type == TYPE_LEVEL_EXIT && Col_Box( &col_rect, &obj->col_rect ) )
  3240.             {
  3241.                 cLevel_Exit *level_exit = static_cast<cLevel_Exit *>(obj);
  3242.  
  3243.                 // warp
  3244.                 if( level_exit->exit_type == LEVELEXIT_WARP )
  3245.                 {
  3246.                     if( level_exit->direction == DIR_RIGHT )
  3247.                     {
  3248.                         if( velx <= 0 )
  3249.                         {
  3250.                             Game_Action = GA_ACTIVATE_LEVEL_EXIT;
  3251.                             Game_Action_ptr = level_exit;
  3252.                             return;
  3253.                         }
  3254.                     }
  3255.                 }
  3256.             }
  3257.         }
  3258.  
  3259.         // direction
  3260.         if( state != STA_FLY )
  3261.         {
  3262.             if( direction != DIR_RIGHT )
  3263.             {
  3264.                 // play stop sound if already running
  3265.                 if( velx < -12 && ground_object )
  3266.                 {
  3267.                     pAudio->Play_Sound( "player/maryo_stop.ogg", RID_MARYO_STOP );
  3268.                 }
  3269.  
  3270.                 direction = DIR_RIGHT;
  3271.             }
  3272.         }
  3273.     }
  3274.     // Shoot
  3275.     else if( key_type == INP_SHOOT )
  3276.     {
  3277.         Action_Shoot();
  3278.     }
  3279.     // Jump
  3280.     else if( key_type == INP_JUMP )
  3281.     {
  3282.         Action_Jump();
  3283.     }
  3284.     // Request Item
  3285.     else if( key_type == INP_ITEM )
  3286.     {
  3287.         Itembox->Request_Item();
  3288.     }
  3289.     // Exit
  3290.     else if( key_type == INP_EXIT )
  3291.     {
  3292.         Game_Action = GA_ENTER_MENU;
  3293.     }
  3294. }
  3295.  
  3296. void cPlayer :: Action_Shoot( void )
  3297. {
  3298.     // add fire or ice-ball
  3299.     ball_effect ball_type = FIREBALL_DEFAULT;
  3300.     // if ice maryo
  3301.     if( maryo_type == MARYO_ICE )
  3302.     {
  3303.         ball_type = ICEBALL_DEFAULT;
  3304.     }
  3305.     // if added ball
  3306.     if( Ball_Add( ball_type ) )
  3307.     {
  3308.         throwing_counter = speedfactor_fps * 0.3f;
  3309.     }
  3310. }
  3311.  
  3312. void cPlayer :: Action_Stop_Jump( void )
  3313. {
  3314.     Stop_Flying();
  3315.     UpKeytime = 0;
  3316. }
  3317.  
  3318. void cPlayer :: Action_Stop_Interact( input_identifier key_type )
  3319. {
  3320.     // Action
  3321.     if( key_type == INP_ACTION )
  3322.     {
  3323.         Release_Item();
  3324.     }
  3325.     // Down
  3326.     else if( key_type == INP_DOWN )
  3327.     {
  3328.         Stop_Ducking();
  3329.     }
  3330.     // Left
  3331.     else if( key_type == INP_LEFT )
  3332.     {
  3333.         // if key in opposite direction is still pressed only change direction
  3334.         if( pKeyboard->keys[pPreferences->key_right] || pJoystick->right )
  3335.         {
  3336.             direction = DIR_RIGHT;
  3337.         }
  3338.         else
  3339.         {
  3340.             Hold();
  3341.         }
  3342.     }
  3343.     // Right
  3344.     else if( key_type == INP_RIGHT )
  3345.     {
  3346.         // if key in opposite direction is still pressed only change direction
  3347.         if( pKeyboard->keys[pPreferences->key_left] || pJoystick->left )
  3348.         {
  3349.             direction = DIR_LEFT;
  3350.         }
  3351.         else
  3352.         {
  3353.             Hold();
  3354.         }
  3355.     }
  3356.     // Jump
  3357.     else if( key_type == INP_JUMP )
  3358.     {
  3359.         Action_Stop_Jump();
  3360.     }
  3361.     // Shoot
  3362.     else if( key_type == INP_SHOOT )
  3363.     {
  3364.         Action_Stop_Shoot();
  3365.     }
  3366. }
  3367.  
  3368. void cPlayer :: Action_Stop_Shoot( void )
  3369. {
  3370.     // nothing
  3371. }
  3372.  
  3373. bool cPlayer :: Ball_Add( ball_effect effect_type /* = FIREBALL_DEFAULT */ )
  3374. {
  3375.     if( ( maryo_type != MARYO_FIRE && maryo_type != MARYO_ICE ) || ducked )
  3376.     {
  3377.         return 0;
  3378.     }
  3379.  
  3380.     // default fire/ice-ball
  3381.     if( effect_type == FIREBALL_DEFAULT || effect_type == ICEBALL_DEFAULT )
  3382.     {
  3383.         // if time not passed between last shot
  3384.         if( ( effect_type == FIREBALL_DEFAULT || effect_type == ICEBALL_DEFAULT ) && shoot_counter > 0 )
  3385.         {
  3386.             return 0;
  3387.         }
  3388.  
  3389.         // add ball
  3390.         cBall *ball = new cBall( (direction == DIR_RIGHT) ? (posx + 20) : (posx + 8), posy + 45, this, effect_type );
  3391.         pActive_Sprite_Manager->Add( ball );
  3392.  
  3393.         if( effect_type == ICEBALL_DEFAULT )
  3394.         {
  3395.             // iceball has slow horizontal speed
  3396.             float ball_vel_x = 12;
  3397.             // set speed
  3398.             if( direction == DIR_RIGHT )
  3399.             {
  3400.                 ball->Set_Velocity( ball_vel_x, 0 );
  3401.             }
  3402.             // left
  3403.             else
  3404.             {
  3405.                 ball->Set_Velocity( -ball_vel_x, 0 );
  3406.             }
  3407.             // sound
  3408.             pAudio->Play_Sound( "item/iceball.ogg", RID_MARYO_BALL );
  3409.         }
  3410.         // fireball
  3411.         else
  3412.         {
  3413.             // horizontal speed
  3414.             float ball_vel_x = 17;
  3415.             // set speed
  3416.             if( direction == DIR_RIGHT )
  3417.             {
  3418.                 ball->Set_Velocity( ball_vel_x, 0 );
  3419.             }
  3420.             // left
  3421.             else
  3422.             {
  3423.                 ball->Set_Velocity( -ball_vel_x, 0 );
  3424.             }
  3425.             // sound
  3426.             pAudio->Play_Sound( "item/fireball.ogg", RID_MARYO_BALL );
  3427.         }
  3428.     }
  3429.     // half circle fire/ice-ball explosion
  3430.     else if( effect_type == FIREBALL_EXPLOSION || effect_type == ICEBALL_EXPLOSION )
  3431.     {
  3432.         // start angle
  3433.         float ball_angle = -180;
  3434.  
  3435.         for( unsigned int i = 0; i < 10; i++ )
  3436.         {
  3437.             // 10 * 18 = 180 degrees
  3438.             ball_angle += 18;
  3439.  
  3440.             // add ball
  3441.             cBall *ball = new cBall( posx + col_rect.w / 2, posy + col_rect.h / 2, this, effect_type );
  3442.             ball->Set_Direction( ball_angle, 15 );
  3443.             ball->Col_Move( ball->velx * 2, ball->vely * 2, 1 );
  3444.             pActive_Sprite_Manager->Add( ball );
  3445.         }
  3446.  
  3447.         // explosion animation and sound
  3448.         if( effect_type == FIREBALL_EXPLOSION )
  3449.         {
  3450.             cAnimation_Fireball *anim = new cAnimation_Fireball( posx + ( col_rect.w / 2 ), posy + ( col_rect.h / 3 ), 10 );
  3451.             anim->Set_Fading_Speed( 0.3f );
  3452.             pAnimation_Manager->Add( anim );
  3453.  
  3454.             pAudio->Play_Sound( "item/fireball_2.ogg", RID_MARYO_BALL );
  3455.         }
  3456.         else
  3457.         {
  3458.             // create animation
  3459.             cParticle_Emitter *anim = new cParticle_Emitter();
  3460.             anim->Set_Pos( posx + col_rect.w / 2, posy + col_rect.h / 2 );
  3461.             anim->Set_Image( pVideo->Get_Surface( "animation/particles/light.png" ) );
  3462.             anim->Set_Quota( 10 );
  3463.             anim->Set_Time_to_Live( 1.5f );
  3464.             anim->Set_Pos_Z( posz + 0.0001f );
  3465.             anim->Set_Color( Color( static_cast<Uint8>(50), 50, 250 ) );
  3466.             anim->Set_Blending( BLEND_ADD );
  3467.             anim->Set_Speed( 0.8f, 0.7f );
  3468.             anim->Set_Scale( 0.4f, 0.2f );
  3469.             // add animation
  3470.             pAnimation_Manager->Add( anim );
  3471.  
  3472.             pAudio->Play_Sound( "item/iceball_2.ogg", RID_MARYO_BALL );
  3473.         }
  3474.     }
  3475.     // unknown type
  3476.     else
  3477.     {
  3478.         return 0;
  3479.     }
  3480.  
  3481.     return 1;
  3482. }
  3483.  
  3484. void cPlayer :: Ball_Clear( void )
  3485. {
  3486.     // destroy all fireballs from the player
  3487.     for( SpriteList::iterator itr = pActive_Sprite_Manager->objects.begin(), itr_end = pActive_Sprite_Manager->objects.end(); itr != itr_end; ++itr )
  3488.     {
  3489.         cSprite *obj = (*itr);
  3490.  
  3491.         if( obj->type == TYPE_BALL )
  3492.         {
  3493.             cBall *ball = static_cast<cBall *>(obj);
  3494.  
  3495.             // if from player
  3496.             if( ball->origin_type == TYPE_PLAYER )
  3497.             {
  3498.                 obj->Destroy();
  3499.             }
  3500.         }
  3501.     }
  3502. }
  3503.  
  3504. void cPlayer :: Add_Kill_Multiplier( void )
  3505. {
  3506.     kill_multiplier += 0.1f;
  3507.  
  3508.     // give lives after 10 continuous kills
  3509.     if( kill_multiplier >= 2 )
  3510.     {
  3511.         // only every fifth kill
  3512.         if( static_cast<int>( kill_multiplier * 10 ) % 5 == 0 )
  3513.         {
  3514.             // add 1 live
  3515.             golddisplay->Add_Gold( 100 );
  3516.         }
  3517.     }
  3518.  
  3519.     last_kill_counter = 0;
  3520. }
  3521.  
  3522. void cPlayer :: Update_Kill_Multiplier( void )
  3523. {
  3524.     last_kill_counter += pFramerate->speedfactor;
  3525.  
  3526.     if( kill_multiplier > 1 )
  3527.     {
  3528.         // if longer than a second reset the multiplier
  3529.         if( last_kill_counter > speedfactor_fps )
  3530.         {
  3531.             kill_multiplier = 1;
  3532.         }
  3533.     }
  3534. }
  3535.  
  3536. unsigned int cPlayer :: Validate_Collision( cSprite *obj )
  3537. {
  3538.     // don't collide with anything if dead
  3539.     if( maryo_type == MARYO_DEAD )
  3540.     {
  3541.         return 0;
  3542.     }
  3543.  
  3544.     if( obj->massivetype == MASS_MASSIVE )
  3545.     {
  3546.         if( obj->sprite_array == ARRAY_ENEMY )
  3547.         {
  3548.             // if invincible
  3549.             if( invincible )
  3550.             {
  3551.                 // jpiranha
  3552.                 if( obj->type == TYPE_JPIRANHA )
  3553.                 {
  3554.                     if( invincible_star > 0 )
  3555.                     {
  3556.                         return 1;
  3557.                     }
  3558.  
  3559.                     return 0;
  3560.                 }
  3561.                 // gee
  3562.                 else if( obj->type == TYPE_GEE )
  3563.                 {
  3564.                     if( invincible_star > 0 )
  3565.                     {
  3566.                         return 1;
  3567.                     }
  3568.  
  3569.                     // block if on top
  3570.                     if( vely >= 0 && Is_on_Top( obj ) )
  3571.                     {
  3572.                         return 2;
  3573.                     }
  3574.  
  3575.                     return 0;
  3576.                 }
  3577.                 // walk on spika and rokko
  3578.                 else if( obj->type == TYPE_SPIKA || obj->type == TYPE_ROKKO )
  3579.                 {
  3580.                     // block if on top
  3581.                     if( vely >= 0 && Is_on_Top( obj ) )
  3582.                     {
  3583.                         return 2;
  3584.                     }
  3585.  
  3586.                     if( invincible_star > 0 )
  3587.                     {
  3588.                         return 1;
  3589.                     }
  3590.  
  3591.                     return 0;
  3592.                 }
  3593.                 // eato
  3594.                 else if( obj->type == TYPE_EATO )
  3595.                 {
  3596.                     // block if on top
  3597.                     if( vely >= 0 && Is_on_Top( obj ) )
  3598.                     {
  3599.                         return 2;
  3600.                     }
  3601.  
  3602.                     if( invincible_star > 0 )
  3603.                     {
  3604.                         return 1;
  3605.                     }
  3606.                 }
  3607.                 // turtle
  3608.                 else if( obj->type == TYPE_TURTLE )
  3609.                 {
  3610.                     // block if on top
  3611.                     if( vely >= 0 && Is_on_Top( obj ) )
  3612.                     {
  3613.                         return 2;
  3614.                     }
  3615.  
  3616.                     if( invincible_star > 0 )
  3617.                     {
  3618.                         return 1;
  3619.                     }
  3620.                 }
  3621.             }
  3622.  
  3623.             // turtle
  3624.             if( obj->type == TYPE_TURTLE )
  3625.             {
  3626.                 cTurtle *turtle = static_cast<cTurtle *>(obj);
  3627.  
  3628.                 // if not on top
  3629.                 if( !( vely >= 0 && Is_on_Top( obj ) ) )
  3630.                 {
  3631.                     // if player counter active or invincible
  3632.                     if( turtle->playercounter || invincible )
  3633.                     {
  3634.                         return 0;
  3635.                     }
  3636.                 }
  3637.             }
  3638.         }
  3639.         else if( obj->type == TYPE_BALL )
  3640.         {
  3641.             return 0;
  3642.         }
  3643.         else if( obj->type == TYPE_BONUSBOX || obj->type == TYPE_SPINBOX )
  3644.         {
  3645.             cBaseBox *box = static_cast<cBaseBox *>(obj);
  3646.  
  3647.             // ghost
  3648.             if( box->box_invisible == 2 )
  3649.             {
  3650.                 // maryo is not ghost
  3651.                 if( maryo_type != MARYO_GHOST )
  3652.                 {
  3653.                     return 0;
  3654.                 }
  3655.             }
  3656.         }
  3657.  
  3658.         // don't collide with ground
  3659.         if( ground_object == obj )
  3660.         {
  3661.             return 0;
  3662.         }
  3663.  
  3664.         return 2;
  3665.     }
  3666.     if( obj->massivetype == MASS_HALFMASSIVE )
  3667.     {
  3668.         // fall through
  3669.         if( pKeyboard->keys[pPreferences->key_down] )
  3670.         {
  3671.             return 0;
  3672.         }
  3673.  
  3674.         // if moving downwards and object is on top
  3675.         if( vely >= 0 && Is_on_Top( obj ) )
  3676.         {
  3677.             // don't collide with ground
  3678.             if( ground_object == obj )
  3679.             {
  3680.                 return 0;
  3681.             }
  3682.  
  3683.             return 2;
  3684.         }
  3685.  
  3686.         return 0;
  3687.     }
  3688.     // allow climbing
  3689.     if( obj->massivetype == MASS_CLIMBABLE )
  3690.     {
  3691.         // if not climbing and player wants to climb
  3692.         if( state != STA_CLIMB && state != STA_FLY && ( ( pKeyboard->keys[pPreferences->key_up] || pJoystick->up ) || ( ( pKeyboard->keys[pPreferences->key_down] || pJoystick->down ) && !ground_object ) ) )
  3693.         {
  3694.             GL_rect climb_rect = obj->col_rect;
  3695.             climb_rect.x += climb_rect.w * 0.25f;
  3696.             climb_rect.y += climb_rect.h * 0.25f;
  3697.             climb_rect.w *= 0.5f;
  3698.             climb_rect.h *= 0.5f;
  3699.  
  3700.             // check if core collision
  3701.             if( Col_Box( &climb_rect, &col_rect ) )
  3702.             {
  3703.                 // start climbing
  3704.                 Start_Climbing();
  3705.             }
  3706.         }
  3707.  
  3708.         return 1;
  3709.     }
  3710.     // warp levelexit key check
  3711.     if( obj->type == TYPE_LEVEL_EXIT )
  3712.     {
  3713.         cLevel_Exit *levelexit = static_cast<cLevel_Exit *>(obj);
  3714.  
  3715.         if( levelexit->exit_type == LEVELEXIT_WARP )
  3716.         {
  3717.             // joystick events are sent as keyboard keys
  3718.             if( pKeyboard->keys[pPreferences->key_up] && levelexit->start_direction == DIR_UP )
  3719.             {
  3720.                 Action_Interact( INP_UP );
  3721.             }
  3722.             else if( pKeyboard->keys[pPreferences->key_down] && levelexit->start_direction == DIR_DOWN )
  3723.             {
  3724.                 Action_Interact( INP_DOWN );
  3725.             }
  3726.             else if( pKeyboard->keys[pPreferences->key_right] && levelexit->start_direction == DIR_RIGHT )
  3727.             {
  3728.                 Action_Interact( INP_RIGHT );
  3729.             }
  3730.             else if( pKeyboard->keys[pPreferences->key_left] && levelexit->start_direction == DIR_LEFT )
  3731.             {
  3732.                 Action_Interact( INP_LEFT );
  3733.             }
  3734.         }
  3735.  
  3736.         return 0;
  3737.     }
  3738.  
  3739.     return 0;
  3740. }
  3741.  
  3742. void cPlayer :: Handle_Collision_Enemy( cObjectCollision *collision )
  3743. {
  3744.     // if invalid
  3745.     if( collision->direction == DIR_UNDEFINED || maryo_type == MARYO_DEAD || !visible )
  3746.     {
  3747.         return;
  3748.     }
  3749.  
  3750.     cEnemy *enemy = static_cast<cEnemy *>(pActive_Sprite_Manager->Get_Pointer( collision->number ));
  3751.  
  3752.     // if enemy already dead
  3753.     if( enemy->dead )
  3754.     {
  3755.         return;
  3756.     }
  3757.  
  3758.     // if invincible
  3759.     if( invincible_star > 0 )
  3760.     {
  3761.         bool hit_enemy = 1;
  3762.  
  3763.         // spika and eato ignore top collisions
  3764.         if( ( enemy->type == TYPE_SPIKA || enemy->type == TYPE_EATO || enemy->type == TYPE_THROMP ) && collision->direction == DIR_DOWN )
  3765.         {
  3766.             hit_enemy = 0;
  3767.         }
  3768.         // rokko
  3769.         else if( enemy->type == TYPE_ROKKO )
  3770.         {
  3771.             hit_enemy = 0;
  3772.         }
  3773.         // turtle boss
  3774.         else if( enemy->type == TYPE_TURTLE_BOSS )
  3775.         {
  3776.             hit_enemy = 0;
  3777.         }
  3778.  
  3779.         // hit
  3780.         if( hit_enemy )
  3781.         {
  3782.             pAudio->Play_Sound( "item/star_kill.ogg" );
  3783.             pointsdisplay->Add_Points( static_cast<unsigned int>( enemy->kill_points * 1.2f ), posx, posy, "", yellow, 1 );
  3784.             // force complete downgrade
  3785.             enemy->DownGrade( 1 );
  3786.             Add_Kill_Multiplier();
  3787.             return;
  3788.         }
  3789.         // no hit
  3790.         else
  3791.         {
  3792.             // eato blocks
  3793.             if( enemy->type == TYPE_EATO )
  3794.             {
  3795.                 if( collision->direction == DIR_LEFT )
  3796.                 {
  3797.                     velx = 0;
  3798.                 }
  3799.                 else if( collision->direction == DIR_RIGHT )
  3800.                 {
  3801.                     velx = 0;
  3802.                 }
  3803.             }
  3804.         }
  3805.     }
  3806.  
  3807.     // enemy is frozen
  3808.     if( enemy->freeze_counter )
  3809.     {
  3810.         // enemy rect particle ice animation
  3811.         for( unsigned int w = 0; w < enemy->col_rect.w; w += 10 )
  3812.         {
  3813.             for( unsigned int h = 0; h < enemy->col_rect.h; h += 10 )
  3814.             {
  3815.                 // animation
  3816.                 cParticle_Emitter *anim = new cParticle_Emitter();
  3817.                 anim->Set_Pos( enemy->posx + w, enemy->posy + h );
  3818.                 anim->Set_Image( pVideo->Get_Surface( "animation/particles/light.png" ) );
  3819.                 anim->Set_Time_to_Live( 0.6f, 0.4f );
  3820.                 anim->Set_Color( Color( static_cast<Uint8>(160), 160, 240 ), Color( static_cast<Uint8>( rand() % 80 ), rand() % 80, rand() % 10 ) );
  3821.                 anim->Set_Fading_Alpha( 1 );
  3822.                 anim->Set_Fading_Size( 1 );
  3823.                 anim->Set_Speed( 0.5f, 0.2f );
  3824.                 anim->Set_Blending( BLEND_DRIVE );
  3825.                 // add animation
  3826.                 pAnimation_Manager->Add( anim );
  3827.             }
  3828.         }
  3829.  
  3830.         // ice sound
  3831.         pAudio->Play_Sound( "item/ice_kill.ogg" );
  3832.  
  3833.         // get points
  3834.         pointsdisplay->Add_Points( enemy->kill_points, enemy->posx, enemy->posy, "", static_cast<Uint8>(255), 1 );
  3835.         
  3836.         // kill enemy
  3837.         enemy->DownGrade( 1 );
  3838.         Add_Kill_Multiplier();
  3839.  
  3840.         // slow down
  3841.         velx *= 0.7f;
  3842.         vely *= 0.7f;
  3843.  
  3844.         // if enemy was ground object
  3845.         if( enemy == ground_object )
  3846.         {
  3847.             Reset_on_Ground();
  3848.         }
  3849.  
  3850.         return;
  3851.     }
  3852.  
  3853.     if( collision->direction == DIR_TOP )
  3854.     {
  3855.         vely = 0;
  3856.  
  3857.         if( state != STA_FLY )
  3858.         {
  3859.             if( state != STA_CLIMB )
  3860.             {
  3861.                 Set_Moving_State( STA_FALL );
  3862.                 UpKeytime = 0;
  3863.                 jump_power = 0;
  3864.             }
  3865.         }
  3866.     }
  3867.  
  3868.     // send collision
  3869.     Send_Collision( collision );
  3870. }
  3871.  
  3872. void cPlayer :: Handle_Collision_Massive( cObjectCollision *collision )
  3873. {
  3874.     // if invalid
  3875.     if( collision->direction == DIR_UNDEFINED )
  3876.     {
  3877.         return;
  3878.     }
  3879.  
  3880.     cSprite *col_obj = pActive_Sprite_Manager->Get_Pointer( collision->number );
  3881.  
  3882.     // ignore climbable
  3883.     if( col_obj->massivetype == MASS_CLIMBABLE )
  3884.     {
  3885.         return;
  3886.     }
  3887.  
  3888.     if( collision->direction == DIR_UP )
  3889.     {
  3890.         vely = 0;
  3891.  
  3892.         if( state != STA_FLY )
  3893.         {
  3894.             if( state != STA_CLIMB )
  3895.             {
  3896.                 Set_Moving_State( STA_FALL );
  3897.                 UpKeytime = 0;
  3898.                 jump_power = 0;
  3899.  
  3900.                 cMovingSprite *moving_object = dynamic_cast<cMovingSprite *>(col_obj);
  3901.  
  3902.                 // if valid moving sprite
  3903.                 if( moving_object )
  3904.                 {
  3905.                     if( moving_object->vely > 0 )
  3906.                     {
  3907.                         vely += moving_object->vely;
  3908.                     }
  3909.                 }
  3910.  
  3911.                 if( collision->type == CO_MASSIVE )
  3912.                 {
  3913.                     pAudio->Play_Sound( "tock.ogg", RID_MARYO_TOCK );
  3914.                 }
  3915.             }
  3916.         }
  3917.         // flying
  3918.         else
  3919.         {
  3920.             velx -= velx * 0.05f * pFramerate->speedfactor;
  3921.  
  3922.             // too slow
  3923.             if( velx > -5 && velx < 5 )
  3924.             {
  3925.                 Stop_Flying();
  3926.             }
  3927.         }
  3928.     }
  3929.     else if( collision->direction == DIR_DOWN )
  3930.     {
  3931.         vely = 0;
  3932.  
  3933.         // flying
  3934.         if( state == STA_FLY )
  3935.         {
  3936.             velx -= velx * 0.05f * pFramerate->speedfactor;
  3937.  
  3938.             // too slow
  3939.             if( velx > -5 && velx < 5 )
  3940.             {
  3941.                 Stop_Flying();
  3942.             }
  3943.         }
  3944.     }
  3945.     else if( collision->direction == DIR_LEFT )
  3946.     {
  3947.         velx = 0;
  3948.         vely -= vely * 0.01f * pFramerate->speedfactor;
  3949.  
  3950.         if( state == STA_WALK || state == STA_RUN )
  3951.         {
  3952.             walk_count = 0;
  3953.         }
  3954.         // flying
  3955.         else if( state == STA_FLY )
  3956.         {
  3957.             // box collision
  3958.             if( col_obj->type == TYPE_BONUSBOX || col_obj->type == TYPE_SPINBOX )
  3959.             {
  3960.                 cBaseBox *box = static_cast<cBaseBox *>(col_obj);
  3961.                 box->Activate_Collision( collision->direction );
  3962.             }
  3963.  
  3964.             Stop_Flying();
  3965.         }
  3966.     }
  3967.     else if( collision->direction == DIR_RIGHT )
  3968.     {
  3969.         velx = 0;
  3970.         vely -= vely * 0.01f * pFramerate->speedfactor;
  3971.  
  3972.         if( state == STA_WALK || state == STA_RUN )
  3973.         {
  3974.             walk_count = 0;
  3975.         }
  3976.         // flying
  3977.         else if( state == STA_FLY )
  3978.         {
  3979.             // box collision
  3980.             if( col_obj->type == TYPE_BONUSBOX || col_obj->type == TYPE_SPINBOX )
  3981.             {
  3982.                 cBaseBox *box = static_cast<cBaseBox *>(col_obj);
  3983.                 box->Activate_Collision( collision->direction );
  3984.             }
  3985.  
  3986.             Stop_Flying();
  3987.         }
  3988.     }
  3989.  
  3990.     if( collision->type == CO_ACTIVE )
  3991.     {
  3992.         // send collision
  3993.         Send_Collision( collision );
  3994.     }
  3995. }
  3996.  
  3997. void cPlayer :: Handle_out_of_Level( ObjectDirection dir )
  3998. {
  3999.     if( dir == DIR_LEFT )
  4000.     {
  4001.         Set_Pos_X( pActive_Camera->limit_rect.x - col_pos.x );
  4002.         velx = 0;
  4003.         Stop_Flying();
  4004.     }
  4005.     else if( dir == DIR_RIGHT )
  4006.     {
  4007.         Set_Pos_X( pActive_Camera->limit_rect.x + pActive_Camera->limit_rect.w - col_pos.x - col_rect.w - 0.01f );
  4008.         velx = 0;
  4009.         Stop_Flying();
  4010.     }
  4011.     else if( dir == DIR_TOP )
  4012.     {
  4013.         /*if( pActive_Level->limit_top_blocks )
  4014.         {
  4015.             Set_PosY( pActive_Camera->limit_rect.y + pActive_Camera->limit_rect.h + 0.01f );
  4016.             vely = 0;
  4017.         }*/
  4018.     }
  4019.     else if( dir == DIR_BOTTOM )
  4020.     {
  4021.         if( godmode )
  4022.         {
  4023.             vely = -35;
  4024.         }
  4025.         else
  4026.         {
  4027.             /*if( pActive_Level->limit_bottom_blocks )
  4028.             {
  4029.                 Set_PosY( pActive_Camera->limit_rect.y + game_res_h - col_pos.x - col_rect.w + 0.01f );
  4030.                 vely = 0;
  4031.             }
  4032.             // falling below ground
  4033.             else
  4034.             {*/
  4035.                 invincible = 0;
  4036.                 DownGrade( 1, 1 );
  4037.             //}
  4038.         }
  4039.     }
  4040. }
  4041.  
  4042. void cPlayer :: Editor_Activate( void )
  4043. {
  4044.     CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();
  4045.  
  4046.     // direction
  4047.     CEGUI::Combobox *combobox = static_cast<CEGUI::Combobox *>(wmgr.createWindow( "TaharezLook/Combobox", "editor_player_direction" ));
  4048.     Editor_Add( UTF8_("Direction"), UTF8_("Initial direction"), combobox, 100, 75 );
  4049.  
  4050.     combobox->addItem( new CEGUI::ListboxTextItem( "right" ) );
  4051.     combobox->addItem( new CEGUI::ListboxTextItem( "left" ) );
  4052.     combobox->setText( Get_Direction_Name( start_direction ) );
  4053.  
  4054.     combobox->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cPlayer::Editor_Direction_Select, this ) );
  4055.  
  4056.     // init
  4057.     Editor_Init();
  4058. }
  4059.  
  4060. bool cPlayer :: Editor_Direction_Select( const CEGUI::EventArgs &event )
  4061. {
  4062.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  4063.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox *>( windowEventArgs.window )->getSelectedItem();
  4064.  
  4065.     Set_Direction( Get_Direction_Id( item->getText().c_str() ), 1 );
  4066.  
  4067.     return 1;
  4068. }
  4069.  
  4070. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  4071.  
  4072. cPlayer *pPlayer = NULL;
  4073.