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

  1. /***************************************************************************
  2.  * levelexit.cpp  -  area to exit the current level
  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 "../objects/levelexit.h"
  17. #include "../player/player.h"
  18. #include "../core/game_core.h"
  19. #include "../user/preferences.h"
  20. #include "../core/camera.h"
  21. #include "../audio/audio.h"
  22. #include "../core/framerate.h"
  23. #include "../core/main.h"
  24. #include "../video/gl_surface.h"
  25. #include "../video/font.h"
  26. #include "../video/renderer.h"
  27. #include "../level/level.h"
  28. #include "../core/i18n.h"
  29.  
  30. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  31.  
  32. cLevel_Exit :: cLevel_Exit( float x, float y )
  33. : cImageObjectSprite( x, y )
  34. {
  35.     cLevel_Exit::Init();
  36. }
  37.  
  38. cLevel_Exit :: cLevel_Exit( CEGUI::XMLAttributes &attributes )
  39. : cImageObjectSprite()
  40. {
  41.     cLevel_Exit::Init();
  42.     cLevel_Exit::Create_from_Stream( attributes );
  43. }
  44.  
  45. cLevel_Exit :: ~cLevel_Exit( void )
  46. {
  47.     if( editor_entry_name )
  48.     {
  49.         delete editor_entry_name;
  50.         editor_entry_name = NULL;
  51.     }
  52. }
  53.  
  54. void cLevel_Exit :: Init( void )
  55. {
  56.     sprite_array = ARRAY_ACTIVE;
  57.     type = TYPE_LEVEL_EXIT;
  58.     massivetype = MASS_PASSIVE;
  59.     editor_posz = 0.111f;
  60.     player_range = 1000;
  61.  
  62.     rect.w = 10;
  63.     rect.h = 20;
  64.     col_rect.w = rect.w;
  65.     col_rect.h = rect.h;
  66.     start_rect.w = rect.w;
  67.     start_rect.h = rect.h;
  68.  
  69.     exit_type = LEVELEXIT_BEAM;
  70.  
  71.     Set_Direction( DIR_DOWN );
  72.  
  73.     editor_color = red;
  74.     editor_color.alpha = 128;
  75.  
  76.     editor_entry_name = NULL;
  77. }
  78.  
  79. cLevel_Exit *cLevel_Exit :: Copy( void )
  80. {
  81.     cLevel_Exit *level_exit = new cLevel_Exit( startposx, startposy );
  82.     level_exit->Set_Type( exit_type );
  83.     level_exit->Set_Direction( start_direction );
  84.     level_exit->Set_Level( dest_level );
  85.     level_exit->Set_Entry( dest_entry );
  86.  
  87.     return level_exit;
  88. }
  89.  
  90. void cLevel_Exit :: Create_from_Stream( CEGUI::XMLAttributes &attributes )
  91. {
  92.     // position
  93.     Set_Pos( static_cast<float>(attributes.getValueAsInteger( "posx" )), static_cast<float>(attributes.getValueAsInteger( "posy" )), 1 );
  94.     // type
  95.     Set_Type( static_cast<Level_Exit_type>(attributes.getValueAsInteger( "type", exit_type )) );
  96.     // destination level
  97.     Set_Level( attributes.getValueAsString( "level_name" ).c_str() );
  98.     // destination entry
  99.     Set_Entry( attributes.getValueAsString( "entry" ).c_str() );
  100.     // direction
  101.     if( exit_type == LEVELEXIT_WARP )
  102.     {
  103.         Set_Direction( Get_Direction_Id( attributes.getValueAsString( "direction", Get_Direction_Name( start_direction ) ).c_str() ) );
  104.     }
  105. }
  106.  
  107. void cLevel_Exit :: Save_to_Stream( ofstream &file )
  108. {
  109.     // begin levelexit
  110.     file << "\t<levelexit>" << std::endl;
  111.  
  112.     // position
  113.     file << "\t\t<Property name=\"posx\" value=\"" << static_cast<int>(startposx) << "\" />" << std::endl;
  114.     file << "\t\t<Property name=\"posy\" value=\"" << static_cast<int>(startposy) << "\" />" << std::endl;
  115.     // type
  116.     file << "\t\t<Property name=\"type\" value=\"" << exit_type << "\" />" << std::endl;
  117.  
  118.     // destination level name
  119.     string str_level = Get_Level( 0, 0 );
  120.     if( !str_level.empty() )
  121.     {
  122.         file << "\t\t<Property name=\"level_name\" value=\"" << string_to_xml_string( str_level ) << "\" />" << std::endl;
  123.     }
  124.  
  125.     // destination entry name
  126.     if( !dest_entry.empty() )
  127.     {
  128.         file << "\t\t<Property name=\"entry\" value=\"" << string_to_xml_string( dest_entry ) << "\" />" << std::endl;
  129.     }
  130.  
  131.     if( exit_type == LEVELEXIT_WARP )
  132.     {
  133.         // direction
  134.         file << "\t\t<Property name=\"direction\" value=\"" << Get_Direction_Name( start_direction ) << "\" />" << std::endl;
  135.     }
  136.  
  137.     // end levelexit
  138.     file << "\t</levelexit>" << std::endl;
  139. }
  140.  
  141. void cLevel_Exit :: Set_Direction( ObjectDirection dir )
  142. {
  143.     // already set
  144.     if( direction == dir )
  145.     {
  146.         return;
  147.     }
  148.  
  149.     cImageObjectSprite::Set_Direction( dir, 1 );
  150.  
  151.     Create_Name();
  152. }
  153.  
  154. void cLevel_Exit :: Create_Name( void )
  155. {
  156.     name = _("Level");
  157.  
  158.     if( exit_type == LEVELEXIT_BEAM )
  159.     {
  160.         name += _(" Beam");
  161.     }
  162.     else if( exit_type == LEVELEXIT_WARP )
  163.     {
  164.         name += _(" Warp");
  165.  
  166.         if( direction == DIR_UP )
  167.         {
  168.             name += " U";
  169.         }
  170.         else if( direction == DIR_LEFT )
  171.         {
  172.             name += " L";
  173.         }
  174.         else if( direction == DIR_DOWN )
  175.         {
  176.             name += " D";
  177.         }
  178.         else if( direction == DIR_RIGHT )
  179.         {
  180.             name += " R";
  181.         }
  182.     }
  183. }
  184.  
  185. void cLevel_Exit :: Draw( cSurfaceRequest *request /* = NULL */ )
  186. {
  187.     if( !valid_draw )
  188.     {
  189.         return;
  190.     }
  191.  
  192.     // draw color rect
  193.     pVideo->Draw_Rect( col_rect.x - pActive_Camera->x, col_rect.y - pActive_Camera->y, col_rect.w, col_rect.h, editor_posz, &editor_color );
  194.  
  195.     // draw destination entry name
  196.     if( editor_entry_name )
  197.     {
  198.         // create request
  199.         cSurfaceRequest *surface_request = new cSurfaceRequest();
  200.         // blit
  201.         editor_entry_name->Blit( col_rect.x + col_rect.w + 5 - pActive_Camera->x, col_rect.y - pActive_Camera->y, editor_posz, surface_request );
  202.         surface_request->shadow_pos = 2;
  203.         surface_request->shadow_color = lightgreyalpha64;
  204.         // add request
  205.         pRenderer->Add( surface_request );
  206.     }
  207. }
  208.  
  209. void cLevel_Exit :: Activate( void )
  210. {
  211.     // if leaving level
  212.     if( dest_level.empty() && dest_entry.empty() )
  213.     {
  214.         // fade out music
  215.         pAudio->Fadeout_Music( 500 );
  216.     }
  217.  
  218.     // warp player out
  219.     if( exit_type == LEVELEXIT_WARP )
  220.     {
  221.         pAudio->Play_Sound( "enter_pipe.ogg" );
  222.  
  223.         pPlayer->Set_Moving_State( STA_FALL );
  224.         pPlayer->Set_Image( pPlayer->Get_Image() + pPlayer->direction );
  225.         pPlayer->Stop_Ducking();
  226.         pPlayer->Reset_on_Ground();
  227.  
  228.         // set position and image
  229.         if( direction == DIR_UP || direction == DIR_DOWN )
  230.         {
  231.             pPlayer->Set_Pos_X( col_rect.x - pPlayer->col_pos.x + ( col_rect.w * 0.5f ) - ( pPlayer->col_rect.w * 0.5f ) );
  232.         }
  233.         else if( direction == DIR_LEFT || direction == DIR_RIGHT )
  234.         {
  235.             pPlayer->Set_Pos_Y( col_rect.y - pPlayer->col_pos.y + ( col_rect.h * 0.5f ) - ( pPlayer->col_rect.h * 0.5f ) );
  236.  
  237.             // set rotation
  238.             if( direction == DIR_RIGHT )
  239.             {
  240.                 pPlayer->Set_Rotation_Z( 90 );
  241.             }
  242.             else if( direction == DIR_LEFT )
  243.             {
  244.                 pPlayer->Set_Rotation_Z( 270 );
  245.             }
  246.         }
  247.  
  248.         float player_posz = pPlayer->posz;
  249.         // posz just before massive
  250.         pPlayer->posz = 0.0799f;
  251.  
  252.         for( float i = 0; i < ( speedfactor_fps * 0.9f ); i += pFramerate->speedfactor )
  253.         {
  254.             if( direction == DIR_DOWN )
  255.             {
  256.                 pPlayer->Move( 0, 2.7f );
  257.             }
  258.             else if( direction == DIR_UP )
  259.             {
  260.                 pPlayer->Move( 0, -2.7f );
  261.             }
  262.             else if( direction == DIR_RIGHT )
  263.             {
  264.                 pPlayer->Move( 2.7f, 0 );
  265.             }
  266.             else if( direction == DIR_LEFT )
  267.             {
  268.                 pPlayer->Move( -2.7f, 0 );
  269.             }
  270.  
  271.             // draw
  272.             Draw_Game();
  273.  
  274.             pVideo->Render();
  275.             pFramerate->Update();
  276.         }
  277.  
  278.         // set position z back
  279.         pPlayer->posz = player_posz;
  280.         // set invisible
  281.         pPlayer->Set_Visible( 0 );
  282.  
  283.         if( direction == DIR_RIGHT || direction == DIR_LEFT )
  284.         {
  285.             pPlayer->Set_Rotation_Z( 0 );
  286.         }
  287.     }
  288.  
  289.     pPlayer->Collisions_Clear();
  290.  
  291.     // exit level
  292.     if( dest_level.empty() && dest_entry.empty() )
  293.     {
  294.         pAudio->Play_Music( "game/courseclear.ogg" );
  295.         pPlayer->Goto_Next_Level();
  296.     }
  297.     // enter entry
  298.     else
  299.     {
  300.         pPlayer->Goto_Sub_Level( dest_level, dest_entry );
  301.     }
  302. }
  303.  
  304. void cLevel_Exit :: Set_Type( Level_Exit_type ltype )
  305. {
  306.     exit_type = ltype;
  307.  
  308.     Create_Name();
  309. }
  310.  
  311. void cLevel_Exit :: Set_Level( string filename )
  312. {
  313.     if( filename.empty() && dest_entry.empty() )
  314.     {
  315.         dest_level.clear();
  316.         // red for no destination level
  317.         editor_color = red;
  318.         editor_color.alpha = 128;
  319.         return;
  320.     }
  321.  
  322.     // lila for set destination level
  323.     editor_color = lila;
  324.     editor_color.alpha = 128;
  325.  
  326.     // erase file type and directory if set
  327.     dest_level = Get_Filename( filename, 0, 0 );
  328. }
  329.  
  330. void cLevel_Exit :: Set_Entry( string entry_name )
  331. {
  332.     if( editor_entry_name )
  333.     {
  334.         delete editor_entry_name;
  335.         editor_entry_name = NULL;
  336.     }
  337.  
  338.     // Set new name
  339.     dest_entry = entry_name;
  340.  
  341.     // if empty don't create editor image
  342.     if( dest_entry.empty() )
  343.     {
  344.         return;
  345.     }
  346.  
  347.     editor_entry_name = pFont->Render_Text( pFont->font_small, dest_entry, white );
  348. }
  349.  
  350. string cLevel_Exit :: Get_Level( bool with_dir /* = 1 */, bool with_end /* = 1 */ )
  351. {
  352.     string name = dest_level;
  353.  
  354.     // Get level
  355.     pActive_Level->Get_Path( name );
  356.  
  357.     // return
  358.     return Get_Filename( name, with_dir, with_end );
  359. }
  360.  
  361. bool cLevel_Exit :: Is_Draw_Valid( void )
  362. {
  363.     // if editor not enabled
  364.     if( !editor_enabled )
  365.     {
  366.         return 0;
  367.     }
  368.  
  369.     // if not visible on the screen
  370.     if( !visible || !Is_Visible_on_Screen() )
  371.     {
  372.         return 0;
  373.     }
  374.  
  375.     return 1;
  376. }
  377.  
  378. void cLevel_Exit :: Editor_Activate( void )
  379. {
  380.     CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();
  381.  
  382.     // warp
  383.     if( exit_type == LEVELEXIT_WARP )
  384.     {
  385.         // direction
  386.         CEGUI::Combobox *combobox = static_cast<CEGUI::Combobox *>(wmgr.createWindow( "TaharezLook/Combobox", "level_exit_direction" ));
  387.         Editor_Add( UTF8_("Direction"), UTF8_("Direction to move in"), combobox, 100, 105 );
  388.  
  389.         combobox->addItem( new CEGUI::ListboxTextItem( "up" ) );
  390.         combobox->addItem( new CEGUI::ListboxTextItem( "down" ) );
  391.         combobox->addItem( new CEGUI::ListboxTextItem( "right" ) );
  392.         combobox->addItem( new CEGUI::ListboxTextItem( "left" ) );
  393.         combobox->setText( Get_Direction_Name( start_direction ) );
  394.  
  395.         combobox->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cLevel_Exit::Editor_Direction_Select, this ) );
  396.     }
  397.  
  398.     // destination level
  399.     CEGUI::Editbox *editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "level_exit_destination_level" ));
  400.     Editor_Add( UTF8_("Destination Level"), UTF8_("Name of the level that should be entered. If empty uses the current level."), editbox, 150 );
  401.  
  402.     editbox->setText( Get_Level( 0, 0 ) );
  403.     editbox->subscribeEvent( CEGUI::Editbox::EventKeyUp, CEGUI::Event::Subscriber( &cLevel_Exit::Editor_Destination_Level_Key, this ) );
  404.  
  405.     // destination entry
  406.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "level_exit_destination_entry" ));
  407.     Editor_Add( UTF8_("Destination Entry"), UTF8_("Name of the Entry in the destination level. If empty the entry point is the player start position."), editbox, 150 );
  408.  
  409.     editbox->setText( dest_entry.c_str() );
  410.     editbox->subscribeEvent( CEGUI::Editbox::EventKeyUp, CEGUI::Event::Subscriber( &cLevel_Exit::Editor_Destination_Entry_Key, this ) );
  411.  
  412.     // init
  413.     Editor_Init();
  414. }
  415.  
  416. bool cLevel_Exit :: Editor_Direction_Select( const CEGUI::EventArgs &event )
  417. {
  418.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  419.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox *>( windowEventArgs.window )->getSelectedItem();
  420.  
  421.     Set_Direction( Get_Direction_Id( item->getText().c_str() ) );
  422.  
  423.     return 1;
  424. }
  425.  
  426. bool cLevel_Exit :: Editor_Destination_Level_Key( const CEGUI::EventArgs &event )
  427. {
  428.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  429.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  430.  
  431.     Set_Level( str_text );
  432.  
  433.     return 1;
  434. }
  435.  
  436. bool cLevel_Exit :: Editor_Destination_Entry_Key( const CEGUI::EventArgs &event )
  437. {
  438.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  439.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  440.  
  441.     Set_Entry( str_text );
  442.  
  443.     return 1;
  444. }
  445.