home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / overworld / world_player.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2008-08-23  |  20.3 KB  |  863 lines

  1. /***************************************************************************
  2.  * ow_player.cpp  - Overworld 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 "../overworld/world_player.h"
  17. #include "../core/game_core.h"
  18. #include "../core/framerate.h"
  19. #include "../core/camera.h"
  20. #include "../overworld/overworld.h"
  21. #include "../level/level.h"
  22. #include "../video/font.h"
  23. #include "../audio/audio.h"
  24. #include "../gui/menu.h"
  25. #include "../video/renderer.h"
  26.  
  27. /* *** *** *** *** *** *** *** *** cOverworld_Player *** *** *** *** *** *** *** *** *** */
  28.  
  29. cOverworld_Player :: cOverworld_Player( void )
  30. : cImageObjectSprite()
  31. {
  32.     type = TYPE_PLAYER;
  33.     posz = 0.0999f;
  34.     massivetype = MASS_MASSIVE;
  35.     player_range = 0;
  36.     name = "Maryo";
  37.  
  38.     maryo_state = MARYO_SMALL;
  39.     current_waypoint = -2; // no waypoint
  40.     line_waypoint = 0;
  41.     current_line = -2;
  42.  
  43.     anim_counter = 0;
  44.     anim_speed = 0;
  45.     anim_max = 0;
  46.  
  47.     fixed_walking = 0;
  48.  
  49.     line_hor = cLine_collision();
  50.     line_ver = cLine_collision();
  51.  
  52.     debug_current_line_last = -100;
  53.     debug_lines_last = -100;
  54.     debug_current_waypoint_last = -100;
  55.  
  56.     debug_lines = new cHudSprite( NULL, 150, game_res_h * 0.97f );
  57.     debug_current_line = new cHudSprite( NULL, 300, game_res_h * 0.97f );
  58.     debug_current_waypoint = new cHudSprite( NULL, 500, game_res_h * 0.97f );
  59.  
  60.     Load_Images();
  61. }
  62.  
  63. cOverworld_Player :: ~cOverworld_Player( void )
  64. {
  65.     delete debug_lines;
  66.     delete debug_current_line;
  67.     delete debug_current_waypoint;
  68.  
  69.     Unload_Images();
  70. }
  71.  
  72. void cOverworld_Player :: Load_Images( void )
  73. {
  74.     Unload_Images();
  75.  
  76.     if( maryo_state == MARYO_SMALL )
  77.     {
  78.         // todo : load all direction images at once so we can set the correct direction down start/editor image
  79.         if( direction == DIR_DOWN || direction == DIR_UNDEFINED )
  80.         {
  81.             images.push_back( pVideo->Get_Surface( "world/maryo/small/down.png" ) );
  82.             images.push_back( pVideo->Get_Surface( "world/maryo/small/down_1.png" ) );
  83.             images.push_back( pVideo->Get_Surface( "world/maryo/small/down.png" ) );
  84.             images.push_back( pVideo->Get_Surface( "world/maryo/small/down_2.png" ) );
  85.             
  86.             anim_max = 4;
  87.             anim_speed = 2;
  88.         }
  89.         else if( direction == DIR_UP )
  90.         {
  91.             images.push_back( pVideo->Get_Surface( "world/maryo/small/up_1.png" ) );
  92.             images.push_back( pVideo->Get_Surface( "world/maryo/small/up.png" ) );
  93.             images.push_back( pVideo->Get_Surface( "world/maryo/small/up_1.png" ) );
  94.             images.push_back( pVideo->Get_Surface( "world/maryo/small/up_2.png" ) );
  95.             
  96.             anim_max = 4;
  97.             anim_speed = 2;
  98.         }
  99.         else if( direction == DIR_LEFT )
  100.         {
  101.             images.push_back( pVideo->Get_Surface( "world/maryo/small/left.png" ) );
  102.             images.push_back( pVideo->Get_Surface( "world/maryo/small/left_1.png" ) );
  103.             images.push_back( pVideo->Get_Surface( "world/maryo/small/left.png" ) );
  104.             images.push_back( pVideo->Get_Surface( "world/maryo/small/left_2.png" ) );
  105.  
  106.             anim_max = 4;
  107.             anim_speed = 1.7f;
  108.         }
  109.         else if( direction == DIR_RIGHT )
  110.         {
  111.             images.push_back( pVideo->Get_Surface( "world/maryo/small/right.png" ) );
  112.             images.push_back( pVideo->Get_Surface( "world/maryo/small/right_1.png" ) );
  113.             images.push_back( pVideo->Get_Surface( "world/maryo/small/right.png" ) );
  114.             images.push_back( pVideo->Get_Surface( "world/maryo/small/right_2.png" ) );
  115.  
  116.             anim_max = 4;
  117.             anim_speed = 1.7f;
  118.         }
  119.     }
  120.     else
  121.     {
  122.         printf( "Unsupported Maryo state : %d\n", static_cast<unsigned int>(maryo_state) );
  123.         maryo_state = MARYO_SMALL;
  124.         return;
  125.     }
  126.     
  127.     Set_Image( 0, 1 );    
  128. }
  129.  
  130. void cOverworld_Player :: Unload_Images( void )
  131. {
  132.     Clear_Images();
  133.  
  134.     anim_counter = 0;
  135.     anim_speed = 0;
  136.     anim_max = 0;
  137. }
  138.  
  139. void cOverworld_Player :: Update( void )
  140. {
  141.     cImageObjectSprite::Update();
  142.  
  143.     anim_counter += pFramerate->speedfactor;
  144.  
  145.     if( maryo_state == MARYO_SMALL )
  146.     {
  147.         // uhm ... CLEANUP !
  148.         for( unsigned int i = 0; i < 5; i++ )
  149.         {
  150.             if( anim_counter < anim_max * ( ( i + 1 ) * anim_speed ) )
  151.             {
  152.                 // reset
  153.                 if( anim_max < i + 1 )
  154.                 {
  155.                     anim_counter = 0;
  156.                     break;
  157.                 }
  158.                 else
  159.                 {
  160.                     Set_Image( i );
  161.                     break;
  162.                 }
  163.             }
  164.         }
  165.     }
  166.     else
  167.     {
  168.         printf( "Error : Unknown Overworld Animation state %d\n", static_cast<unsigned int>(maryo_state) );
  169.     }
  170.  
  171.     if( direction == DIR_UNDEFINED )
  172.     {
  173.         return;
  174.     }
  175.  
  176.     Update_Vel();
  177.  
  178.     // default walking
  179.     if( !fixed_walking )
  180.     {
  181.         Update_Walk();
  182.     } 
  183.     // fixed walking
  184.     else
  185.     {
  186.         Update_Waypoint_Walk();
  187.     }
  188. }
  189.  
  190. void cOverworld_Player :: Draw( cSurfaceRequest *request /* = NULL */ )
  191. {
  192.     bool create_request = 0;
  193.  
  194.     if( !request )
  195.     {
  196.         create_request = 1;
  197.         // create request
  198.         request = new cSurfaceRequest();
  199.     }
  200.  
  201.     // Draw player
  202.     cImageObjectSprite::Draw( request );
  203.     // alpha in debug mode
  204.     if( pOverworld_Manager->debugmode )
  205.     {
  206.         request->color.alpha = 64;
  207.     }
  208.  
  209.     if( create_request )
  210.     {
  211.         // add request
  212.         pRenderer->Add( request );
  213.     }
  214.  
  215.     // Draw debug text
  216.     Draw_Debug_Text();
  217. }
  218.  
  219. void cOverworld_Player :: Draw_Debug_Text( void )
  220. {
  221.     if( !pOverworld_Manager->debugmode )
  222.     {
  223.         return;
  224.     }
  225.  
  226.     // Update Lines Texts
  227.     if( static_cast<int>(pActive_Overworld->pLayer->size()) != debug_lines_last )
  228.     {
  229.         debug_lines->Set_Image( pFont->Render_Text( pFont->font_small, "Lines : " + int_to_string( pActive_Overworld->pLayer->size() ), blue ), 1, 1 );
  230.     }
  231.     // Update Current Line Texts
  232.     if( current_line != debug_current_line_last )
  233.     {
  234.         debug_current_line->Set_Image( pFont->Render_Text( pFont->font_small, "Curr Line : " + int_to_string( current_line ), green ), 1, 1 );
  235.     }
  236.     // Update Current Waypoint Texts
  237.     if( current_waypoint != debug_current_waypoint_last )
  238.     {
  239.         debug_current_waypoint->Set_Image( pFont->Render_Text( pFont->font_small, "Curr Waypoint : " + int_to_string( current_waypoint ), green ), 1, 1 );
  240.     }
  241.  
  242.     // Draw Line count
  243.     cSurfaceRequest *request = new cSurfaceRequest();
  244.     debug_lines->Draw( request );
  245.     request->shadow_pos = 1;
  246.     request->shadow_color = black;
  247.     // add request
  248.     pRenderer->Add( request );
  249.  
  250.     // Draw Current Line
  251.     request = new cSurfaceRequest();
  252.     debug_current_line->Draw( request );
  253.     request->shadow_pos = 1;
  254.     request->shadow_color = black;
  255.     // add request
  256.     pRenderer->Add( request );
  257.     
  258.     // Draw Current Waypoint
  259.     request = new cSurfaceRequest();
  260.     debug_current_waypoint->Draw( request );
  261.     request->shadow_pos = 1;
  262.     request->shadow_color = black;
  263.     // add request
  264.     pRenderer->Add( request );
  265. }
  266.  
  267. void cOverworld_Player :: Reset( void )
  268. {
  269.     current_waypoint = -2;
  270.     line_waypoint = 0;
  271.     current_line = -2;
  272.  
  273.     fixed_walking = 0;
  274.     direction = DIR_UNDEFINED;
  275.  
  276.     Load_Images();
  277. }
  278.  
  279. void cOverworld_Player :: Action_Interact( input_identifier key_type )
  280. {
  281.     // Left
  282.     if( key_type == INP_LEFT )
  283.     {
  284.         pOverworld_Player->Start_Walk( DIR_LEFT );
  285.     }
  286.     // Right
  287.     else if( key_type == INP_RIGHT )
  288.     {
  289.         pOverworld_Player->Start_Walk( DIR_RIGHT );
  290.     }
  291.     // Up
  292.     else if( key_type == INP_UP )
  293.     {
  294.         pOverworld_Player->Start_Walk( DIR_UP );
  295.     }
  296.     // Down
  297.     else if( key_type == INP_DOWN )
  298.     {
  299.         pOverworld_Player->Start_Walk( DIR_DOWN );
  300.     }
  301.     // Action
  302.     else if( key_type == INP_ACTION )
  303.     {
  304.         // enter
  305.         pOverworld_Player->Activate_Waypoint();
  306.         Clear_Input_Events();
  307.     }
  308.     // Exit
  309.     else if( key_type == INP_EXIT )
  310.     {
  311.         Game_Action = GA_ENTER_MENU;
  312.     }
  313. }
  314.  
  315. void cOverworld_Player :: Action_Stop_Interact( input_identifier key_type )
  316. {
  317.     // nothing yet
  318. }
  319.  
  320. void cOverworld_Player :: Activate_Waypoint( void )
  321. {
  322.     // if no waypoint or already walking
  323.     if( current_waypoint < 0 || direction != DIR_UNDEFINED )
  324.     {
  325.         return;
  326.     }
  327.  
  328.     // get waypoint
  329.     cWaypoint *waypoint = Get_Waypoint();
  330.  
  331.     // normal level waypoint
  332.     if( waypoint->waypoint_type == WAYPOINT_NORMAL )
  333.     {
  334.         pActive_Level->Load( waypoint->Get_Destination() );
  335.         
  336.         // valid level
  337.         if( pActive_Level->Is_Loaded() )
  338.         {
  339.             // Enter Level
  340.             Game_Action = GA_ENTER_LEVEL;
  341.         }
  342.         // not a valid level - just walk to the next
  343.         else
  344.         {
  345.             printf( "Error : Overworld level not found %s\n", waypoint->Get_Destination().c_str() );
  346.             pActive_Overworld->Goto_Next_Level();
  347.         }
  348.     }
  349.     // world link waypoint
  350.     else if( waypoint->waypoint_type == WAYPOINT_WORLD_LINK )
  351.     {
  352.         // remember Overworld origin
  353.         cOverworld *overworld_origin = pActive_Overworld;
  354.  
  355.         // world string
  356.         string str_world = waypoint->Get_Destination();
  357.  
  358.         // Enter Credits Menu ( World End )
  359.         if( str_world.compare( "credits" ) == 0 )
  360.         {
  361.             Draw_Effect_Out( EFFECT_OUT_HORIZONTAL_VERTICAL );
  362.             Game_Action = GA_ENTER_MENU_CREDITS;
  363.         }
  364.         // world link
  365.         else
  366.         {
  367.             cOverworld *new_world = pOverworld_Manager->Get( str_world );
  368.  
  369.             if( new_world )
  370.             {
  371.                 Game_Action = GA_ENTER_WORLD;
  372.                 Game_Action_Data.add( "world", str_world.c_str() );
  373.                 Game_Action_Data.add( "player_waypoint", overworld_origin->description->path.c_str() );
  374.             }
  375.             else
  376.             {
  377.                 printf( "Warning : Overworld not found %s\n", str_world.c_str() );
  378.             }
  379.         }
  380.     }
  381. }
  382.  
  383. void cOverworld_Player :: Update_Vel( void )
  384. {
  385.     if( direction == DIR_UP )
  386.     {
  387.         velx = 0;
  388.         vely = -3;
  389.     }
  390.     else if( direction == DIR_DOWN )
  391.     {
  392.         velx = 0;
  393.         vely = 3;
  394.     }
  395.     else if( direction == DIR_RIGHT )
  396.     {
  397.         velx = 3;
  398.         vely = 0;
  399.     }
  400.     else if( direction == DIR_LEFT )
  401.     {
  402.         velx = -3;
  403.         vely = 0;
  404.     }
  405. }
  406.  
  407. bool cOverworld_Player :: Start_Walk( ObjectDirection new_direction )
  408. {
  409.     // already walking into the given direction
  410.     if( new_direction == direction )
  411.     {
  412.         return 0;
  413.     }
  414.  
  415.     // invalid direction
  416.     if( !( new_direction == DIR_LEFT || new_direction == DIR_RIGHT || new_direction == DIR_UP || new_direction == DIR_DOWN ) )
  417.     {
  418.         printf( "Warning : New direction is invalid : %d\n", new_direction );
  419.         return 0;
  420.     }
  421.  
  422.     // print debug info
  423.     if( pOverworld_Manager->debugmode )
  424.     {
  425.         printf( "Current Maryo Direction : %d\n", direction );
  426.  
  427.         if( current_waypoint > 0 )
  428.         {
  429.             printf( "Waypoint Direction Forward : %d Backward : %d\n", Get_Waypoint()->direction_forward, Get_Waypoint()->direction_backward );
  430.         }
  431.     }
  432.  
  433.     // a start from waypoint
  434.     if( current_waypoint >= 0 && direction == DIR_UNDEFINED )
  435.     {
  436.         // Get Layer Line in front
  437.         cLayer_Line *front_line = Get_Front_Line( new_direction );
  438.  
  439.         if( !front_line )
  440.         {
  441.             if( pOverworld_Manager->debugmode )
  442.             {
  443.                 printf( "Waypoint Front line not detected\n" );
  444.             }
  445.  
  446.             return 0;
  447.         }
  448.  
  449.         if( pOverworld_Manager->debugmode )
  450.         {
  451.             printf( "Waypoint Front line id %d, origin id %d\n", pActive_Overworld->pLayer->Get_Array_Num( front_line ), front_line->origin );
  452.         }
  453.  
  454.         // forward
  455.         if( Get_Waypoint()->direction_forward == new_direction )
  456.         {
  457.             cWaypoint *next_waypoint = front_line->Get_End_Waypoint();
  458.  
  459.             if( !next_waypoint )
  460.             {
  461.                 printf( "Next waypoint not detected\n" );
  462.                 return 0;
  463.             }
  464.  
  465.             // next waypoint is not accessible
  466.             if( !next_waypoint->access )
  467.             {
  468.                 if( pOverworld_Manager->debugmode )
  469.                 {
  470.                     printf( "No access to next waypoint\n" );
  471.                 }
  472.  
  473.                 return 0;
  474.             }
  475.  
  476.             if( pOverworld_Manager->debugmode )
  477.             {
  478.                 printf( "Next waypoint id : %d\n", current_waypoint );
  479.             }
  480.  
  481.             // set line waypoint
  482.             line_waypoint = front_line->origin;
  483.         }
  484.         // backward
  485.         else if( Get_Waypoint()->direction_backward == new_direction )
  486.         {
  487.             // set line waypoint
  488.             line_waypoint = front_line->origin;
  489.         }
  490.         // invalid direction
  491.         else
  492.         {
  493.             return 0;
  494.         }
  495.     }
  496.  
  497.     // remember current direction
  498.     ObjectDirection direction_old = direction;
  499.  
  500.     // if already walking
  501.     if( direction != DIR_UNDEFINED )
  502.     {
  503.         if( direction == Get_Opposite_Direction( new_direction ) && !fixed_walking && pActive_Overworld->Get_Waypoint_Collision( &col_rect ) < 0 )
  504.         {
  505.             direction = new_direction;
  506.             Load_Images();
  507.         }
  508.     }
  509.     // start walking
  510.     else
  511.     {
  512.         direction = new_direction;
  513.         Load_Images();
  514.         
  515.         // force a small move into the new direction
  516.         Update_Vel();
  517.         Move( velx, vely, 1 );
  518.     }
  519.  
  520.     // if maryo is not on his current waypoint collide with every waypoint
  521.     if( current_waypoint >= 0 && !Col_Box( &col_rect, &Get_Waypoint()->rect ) )
  522.     {
  523.         current_waypoint = -1;
  524.     }
  525.  
  526.     if( direction_old != direction )
  527.     {
  528.         return 1; // return true if maryo is walking into a new direction
  529.     }
  530.  
  531.     return 0; // no direction change
  532. }
  533.  
  534. void cOverworld_Player :: Update_Walk( void )
  535. {
  536.     Move( velx, vely );
  537.     Update_Path_Diff();
  538.  
  539.     /* Check if Maryo is too far away from the line in the current direction
  540.      * or if no line is anymore connected
  541.      * if true change direction
  542.     */
  543.     if( ( ( direction == DIR_UP || direction == DIR_DOWN ) && line_hor.line_number >= 0 && ( line_hor.difference > 20 || line_hor.difference < -20 ) ) || 
  544.         ( ( direction == DIR_LEFT || direction == DIR_RIGHT ) && line_ver.line_number >= 0 && ( line_ver.difference > 20 || line_ver.difference < -20 ) ) ||
  545.          ( line_hor.line_number < 0 && line_ver.line_number < 0 ) )
  546.     {
  547.         if( pOverworld_Manager->debugmode )
  548.         {
  549.             if( direction == DIR_UP || direction == DIR_DOWN )
  550.             {
  551.                 printf( "horizontal line connection broken : num %d diff %f\n", line_hor.line_number, line_hor.difference );
  552.             }
  553.             else if( direction == DIR_LEFT || direction == DIR_RIGHT )
  554.             {
  555.                 printf( "vertical line connection broken : num %d diff %f\n", line_ver.line_number, line_ver.difference );
  556.             }
  557.         }
  558.  
  559.         current_waypoint = -1;
  560.  
  561.         Change_Direction();
  562.         Load_Images();
  563.     }
  564.  
  565.     Auto_Pos_Correction();
  566.  
  567.     // check if a new waypoint is near maryo
  568.     for( unsigned int i = 0; i < pActive_Overworld->waypoints.size(); i++ )
  569.     {
  570.         // skip the start waypoint
  571.         if( static_cast<int>(i) == current_waypoint )
  572.         {
  573.             continue;
  574.         }
  575.  
  576.         if( Col_Box( &pActive_Overworld->waypoints[i]->rect, &col_rect ) )
  577.         {
  578.             Start_Waypoint_Walk( i );
  579.             break;
  580.         }
  581.     }
  582. }
  583.  
  584. void cOverworld_Player :: Start_Waypoint_Walk( unsigned int new_waypoint )
  585. {
  586.     fixed_walking = 1;
  587.     current_waypoint = new_waypoint;
  588.     current_line = -2;
  589.  
  590.     pActive_Overworld->Update_Waypoint_text();
  591. }
  592.  
  593. void cOverworld_Player :: Update_Waypoint_Walk( void )
  594. {
  595.     // invalid current waypoint
  596.     if( current_waypoint < 0 )
  597.     {
  598.         return;
  599.     }
  600.  
  601.     unsigned int reached = 0;
  602.     cWaypoint *waypoint = Get_Waypoint();
  603.  
  604.     // horizontal position to waypoint
  605.     float x = col_rect.x + ( col_rect.w * 0.5f );
  606.  
  607.     if( waypoint->rect.x + ( waypoint->rect.w * 0.4f ) > x )
  608.     {
  609.         Move( 3, 0 );
  610.     }
  611.     else if( waypoint->rect.x + ( waypoint->rect.w * 0.7f ) < x )
  612.     {
  613.         Move( -3, 0 );
  614.     }
  615.     else
  616.     {
  617.         reached++;
  618.     }
  619.  
  620.     // vertical position to waypoint
  621.     float y = col_rect.y + ( col_rect.h * 0.5f );
  622.  
  623.     if( waypoint->rect.y + ( waypoint->rect.h * 0.4f ) > y )
  624.     {
  625.         Move( 0, 3 );
  626.     }
  627.     else if( waypoint->rect.y + ( waypoint->rect.h * 0.7f ) < y )
  628.     {
  629.         Move( 0, -3 );
  630.     }
  631.     else
  632.     {
  633.         reached++;
  634.     }
  635.  
  636.     if( reached == 2 )
  637.     {
  638.         fixed_walking = 0;
  639.  
  640.         direction = DIR_DOWN;
  641.         Load_Images();
  642.         direction = DIR_UNDEFINED;
  643.         Set_Waypoint( current_waypoint );
  644.  
  645.         pAudio->Play_Sound( "waypoint_reached.ogg" );
  646.     }
  647. }
  648.  
  649. bool cOverworld_Player :: Set_Waypoint( unsigned int waypoint, bool new_startpos /* = 0 */ )
  650. {
  651.     if( waypoint > pActive_Overworld->waypoints.size() ) 
  652.     {
  653.         return 0;
  654.     }
  655.  
  656.     cWaypoint *wp = pActive_Overworld->waypoints[waypoint];
  657.  
  658.     Set_Pos( wp->rect.x - col_pos.x + ( ( wp->rect.w - col_rect.w ) * 0.5f ), wp->rect.y - col_pos.y + ( ( wp->rect.h - col_rect.h ) * 0.5f ), new_startpos );
  659.     current_waypoint = waypoint;
  660.  
  661.     // Update Camera
  662.     pActive_Camera->Update();
  663.     // Update Waypoint text
  664.     pActive_Overworld->Update_Waypoint_text();
  665.  
  666.     return 1;
  667. }
  668.  
  669. cWaypoint *cOverworld_Player :: Get_Waypoint( void )
  670. {
  671.     if( current_waypoint < 0 )
  672.     {
  673.         return NULL;
  674.     }
  675.  
  676.     return pActive_Overworld->Get_Waypoint( current_waypoint );
  677. }
  678.  
  679. cLayer_Line *cOverworld_Player :: Get_Front_Line( ObjectDirection dir )
  680. {
  681.     return pActive_Overworld->pLayer->Get_Line_Collision_Direction( col_rect.x + ( col_rect.w * 0.5f ), col_rect.y + ( col_rect.h * 0.5f ), dir ).line;
  682. }
  683.  
  684. void cOverworld_Player :: Update_Path_Diff( unsigned int csize /* = 25 */ )
  685. {
  686.     float x = col_rect.x + ( col_rect.w * 0.5f ) + velx;
  687.     float y = col_rect.y + ( col_rect.h * 0.5f ) + vely;
  688.  
  689.     // bigger direction check size
  690.     unsigned int hor_advance = 0;
  691.     unsigned int ver_advance = 0;
  692.     if( direction == DIR_LEFT || direction == DIR_RIGHT )
  693.     {
  694.         ver_advance += 10;
  695.     }
  696.     else if( direction == DIR_UP || direction == DIR_DOWN )
  697.     {
  698.         hor_advance += 10;
  699.     }
  700.  
  701.     // get nearest lines
  702.     line_hor = pActive_Overworld->pLayer->Get_Nearest( x, y, DIR_HORIZONTAL, csize + hor_advance, line_waypoint );
  703.      line_ver = pActive_Overworld->pLayer->Get_Nearest( x, y, DIR_VERTICAL, csize + ver_advance, line_waypoint );
  704. }
  705.  
  706. void cOverworld_Player :: Change_Direction( void )
  707. {
  708.     line_hor = cLine_collision();
  709.     line_ver = cLine_collision();
  710.  
  711.     float x = col_rect.x + ( col_rect.w * 0.5f );
  712.     float y = col_rect.y + ( col_rect.h * 0.5f );
  713.  
  714.     /* check with a big collision line the difference to the next layer line behind maryo
  715.      * if no line is found turn around
  716.      * if a line is found walk into it's direction
  717.     */
  718.     if( direction == DIR_RIGHT || direction == DIR_LEFT )
  719.     {
  720.         // search for a line with increasing distance
  721.         for( unsigned int i = 0; i < 30; i++ )
  722.         {
  723.             line_ver = pActive_Overworld->pLayer->Get_Nearest( x - i, y, DIR_VERTICAL, 80, line_waypoint );
  724.  
  725.             // found
  726.             if( line_ver.line_number >= 0 )
  727.             {
  728.                 break;
  729.             }
  730.  
  731.             line_ver = pActive_Overworld->pLayer->Get_Nearest( x + i, y, DIR_VERTICAL, 80, line_waypoint );
  732.  
  733.             // found
  734.             if( line_ver.line_number >= 0 )
  735.             {
  736.                 break;
  737.             }
  738.         }
  739.  
  740.         // if line is found
  741.         if( line_ver.line_number >= 0 )
  742.         {
  743.             if( line_ver.difference < 0 )
  744.             {
  745.                 direction = DIR_UP;
  746.             }
  747.             else if( line_ver.difference > 0 )
  748.             {
  749.                 direction = DIR_DOWN;
  750.             }
  751.         }
  752.         // if no line found walk in to the opposite direction
  753.         else
  754.         {
  755.             direction = Get_Opposite_Direction( direction );
  756.         }
  757.     }
  758.     else if( direction == DIR_UP || direction == DIR_DOWN )
  759.     {
  760.         // search for a line with increasing distance
  761.         for( unsigned int i = 0; i < 30; i++ )
  762.         {
  763.             line_hor = pActive_Overworld->pLayer->Get_Nearest( x, y + i, DIR_HORIZONTAL, 80, line_waypoint );
  764.  
  765.             // found
  766.             if( line_hor.line_number >= 0 )
  767.             {
  768.                 break;
  769.             }
  770.  
  771.             line_hor = pActive_Overworld->pLayer->Get_Nearest( x, y - i, DIR_HORIZONTAL, 80, line_waypoint );
  772.  
  773.             // found
  774.             if( line_hor.line_number >= 0 )
  775.             {
  776.                 break;
  777.             }
  778.         }
  779.  
  780.         // if line is found
  781.         if( line_hor.line_number >= 0 )
  782.         {
  783.             if( line_hor.difference < 0 )
  784.             {
  785.                 direction = DIR_LEFT;
  786.             }
  787.             else if( line_hor.difference > 0 )
  788.             {
  789.                 direction = DIR_RIGHT;
  790.             }
  791.         }
  792.         // if no line found walk in to the opposite direction
  793.         else
  794.         {
  795.             direction = Get_Opposite_Direction( direction );
  796.         }
  797.     }
  798.     else
  799.     {
  800.         printf( "Warning : Unknown Maryo direction %d\n", static_cast<int>(direction) );
  801.         direction = DIR_DOWN;
  802.     }
  803.  
  804.     if( pOverworld_Manager->debugmode )
  805.     {
  806.         printf( "Changed direction to %s\n", Get_Direction_Name( direction ).c_str() );
  807.     }
  808.  
  809.     Update_Vel();
  810. }
  811.  
  812. void cOverworld_Player :: Auto_Pos_Correction( float size /* = 1.7f */, float min_distance /* = 5 */ )
  813. {
  814.     // if colliding with an waypoint
  815.     if( pActive_Overworld->Get_Waypoint_Collision( &col_rect ) != -1 )
  816.     {
  817.         return;
  818.     }
  819.  
  820.     if( direction == DIR_LEFT || direction == DIR_RIGHT )
  821.     {
  822.         // up and down correction
  823.         if( line_ver.difference > min_distance )
  824.         {
  825.             Move( 0, size );
  826.         }
  827.         else if( line_ver.difference < -min_distance )
  828.         {
  829.             Move( 0, -size );
  830.         }
  831.  
  832.         // Set current line number
  833.         if( current_line != line_ver.line_number )
  834.         {
  835.             current_line = line_ver.line_number;
  836.         }
  837.     }
  838.     else if( direction == DIR_UP || direction == DIR_DOWN )
  839.     { 
  840.         // left correction
  841.         if( line_hor.difference < -min_distance )
  842.         {
  843.             Move( -size, 0 );
  844.         }
  845.         // right correction
  846.         else if( line_hor.difference > min_distance )
  847.         {
  848.             Move( size, 0 );
  849.         }
  850.  
  851.         // Set current line number
  852.         if( current_line != line_hor.line_number )
  853.         {
  854.             current_line = line_hor.line_number;
  855.         }
  856.     }
  857. }
  858.  
  859. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  860.  
  861. cOverworld_Player *pOverworld_Player = NULL;
  862.  
  863.