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

  1. /***************************************************************************
  2.  * overworld.cpp  -  Overworld 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 "../core/main.h"
  18. #include "../overworld/overworld.h"
  19. #include "../audio/audio.h"
  20. #include "../core/game_core.h"
  21. #include "../level/level_editor.h"
  22. #include "../overworld/world_editor.h"
  23. #include "../core/camera.h"
  24. #include "../core/framerate.h"
  25. #include "../gui/menu.h"
  26. #include "../user/preferences.h"
  27. #include "../video/font.h"
  28. #include "../input/mouse.h"
  29. #include "../input/joystick.h"
  30. #include "../input/keyboard.h"
  31. #include "../level/level.h"
  32. #include "../core/sprite_manager.h"
  33. #include "../core/i18n.h"
  34. // boost filesystem
  35. #include "boost/filesystem/convenience.hpp"
  36. namespace fs = boost::filesystem;
  37.  
  38.  
  39. /* *** *** *** *** *** *** *** *** cOverworld_description *** *** *** *** *** *** *** *** *** */
  40.  
  41. cOverworld_description :: cOverworld_description( void )
  42. {
  43.     path = "world_1";
  44.     name = _("Unnamed");
  45.     visible = 1;
  46.     user = 0;
  47.  
  48.     comment = _("Empty");
  49. }
  50.  
  51. cOverworld_description :: ~cOverworld_description( void )
  52. {
  53.     //
  54. }
  55.  
  56. void cOverworld_description :: Load( void )
  57. {
  58.     string filename = Get_Full_Path() + "/description.xml";
  59.  
  60.     // filename not valid
  61.     if( !File_Exists( filename ) )
  62.     {
  63.         printf( "Error : Couldn't open World description file : %s\n", filename.c_str() );
  64.         return;
  65.     }
  66.  
  67.     // Load Description
  68.     CEGUI::System::getSingleton().getXMLParser()->parseXMLFile( *this, filename.c_str(), DATA_DIR "/" GAME_SCHEMA_DIR "/World/Description.xsd", "" );
  69. }
  70.  
  71. void cOverworld_description :: Save( void )
  72. {
  73.     string save_dir = user_data_dir + USER_WORLD_DIR + "/" + path;
  74.     string filename = save_dir + "/description.xml";
  75.  
  76.     ofstream file( filename.c_str(), ios::out | ios::trunc );
  77.  
  78.     if( !file )
  79.     {
  80.         debugdisplay->Set_Text( _("Couldn't save world description ") + filename );
  81.         return;
  82.     }
  83.  
  84.     // xml info
  85.     file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
  86.     // begin Description
  87.     file << "<Description>" << std::endl;
  88.  
  89.     // begin World
  90.     file << "\t<World>" << std::endl;
  91.         // name
  92.         file << "\t\t<Property Name=\"name\" Value=\"" << string_to_xml_string( name ) << "\" />" << std::endl;
  93.         // visible
  94.         file << "\t\t<Property Name=\"visible\" Value=\"" << visible << "\" />" << std::endl;
  95.     // end World
  96.     file << "\t</World>" << std::endl;
  97.  
  98.  
  99.     // end Description
  100.     file << "</Description>" << std::endl;
  101.     file.close();
  102. }
  103.  
  104. string cOverworld_description :: Get_Full_Path( void )
  105. {
  106.     // return user world if available
  107.     if( fs::exists( fs::path( user_data_dir + USER_WORLD_DIR + "/" + path + "/description.xml", fs::native ) ) )
  108.     {
  109.         return user_data_dir + USER_WORLD_DIR + "/" + path;
  110.     }
  111.  
  112.     // return game world
  113.     return DATA_DIR "/" GAME_OVERWORLD_DIR "/" + path;
  114. }
  115.  
  116. // XML element start
  117. void cOverworld_description :: elementStart( const CEGUI::String &element, const CEGUI::XMLAttributes &attributes )
  118. {
  119.     // Property of an Element
  120.     if( element == "Property" )
  121.     {
  122.         xml_attributes.add( attributes.getValueAsString( "Name" ), attributes.getValueAsString( "Value" ) );
  123.     }
  124. }
  125.  
  126. // XML element end
  127. void cOverworld_description :: elementEnd( const CEGUI::String &element )
  128. {
  129.     if( element != "Property" )
  130.     {
  131.         if( element == "World" )
  132.         {
  133.             handle_world( xml_attributes );
  134.         }
  135.         else if( element == "Description" )
  136.         {
  137.             // ignore
  138.         }
  139.         else if( element.length() )
  140.         {
  141.             printf( "Warning : World Description Unknown element : %s\n", element.c_str() );
  142.         }
  143.  
  144.         // clear
  145.         xml_attributes = CEGUI::XMLAttributes();
  146.     }
  147. }
  148.  
  149. void cOverworld_description :: handle_world( const CEGUI::XMLAttributes &attributes )
  150. {
  151.     name = attributes.getValueAsString( "name", name.c_str() ).c_str();
  152.     visible = attributes.getValueAsBool( "visible", 1 );
  153. }
  154.  
  155. /* *** *** *** *** *** *** *** *** cOverworld *** *** *** *** *** *** *** *** *** */
  156.  
  157. cOverworld :: cOverworld( void )
  158. {
  159.     sprite_manager = new cSprite_Manager( 500 );
  160.  
  161.     description = new cOverworld_description();
  162.     pLayer = new cLayer();
  163.  
  164.     background_color = Color();
  165.     musicfile = "overworld/land_1.ogg";
  166.     hud_world_name = new cHudSprite( NULL, 10, static_cast<float>(game_res_h) - 30, 0 );
  167.     hud_world_name->Set_Shadow( black, 1.5f );
  168.     hud_level_name = new cHudSprite( NULL, 350, 2, 0 );
  169.     hud_level_name->Set_Shadow( black, 1.5f );
  170.  
  171.     next_level = 0;
  172.  
  173.     player_start_waypoint = 0;
  174.     player_moving_state = STA_STAY;
  175. }
  176.  
  177. cOverworld :: ~cOverworld( void )
  178. {
  179.     Unload();
  180.  
  181.     delete sprite_manager;
  182.     delete description;
  183.     delete pLayer;
  184.     delete hud_level_name;
  185.     delete hud_world_name;
  186. }
  187.  
  188. void cOverworld :: Enter( bool delayed /* = 0 */ )
  189. {
  190.     if( game_exit )
  191.     {
  192.         return;
  193.     }
  194.  
  195.     // enter on the next update
  196.     if( delayed )
  197.     {
  198.         Game_Action = GA_ENTER_WORLD;
  199.         return;
  200.     }
  201.  
  202.     // unload level if possible
  203.     if( pActive_Level->delayed_unload )
  204.     {
  205.         pActive_Level->Unload();
  206.     }
  207.  
  208.     // if not loaded
  209.     if( !sprite_manager->size() )
  210.     {
  211.         return;
  212.     }
  213.  
  214.     // change game mode
  215.     Change_Game_Mode( MODE_OVERWORLD );
  216.  
  217.     // if player start waypoint not set
  218.     if( pOverworld_Player->current_waypoint < 0 )
  219.     {
  220.         pOverworld_Player->Reset();
  221.         pOverworld_Player->Set_Waypoint( player_start_waypoint, 1 );
  222.     }
  223.  
  224.     // if goto next level
  225.     if( next_level )
  226.     {
  227.         Goto_Next_Level();
  228.     }
  229.  
  230.     // if on start waypoint
  231.     if( pOverworld_Player->current_waypoint == static_cast<int>(player_start_waypoint) )
  232.     {
  233.         // if player state is walk
  234.         if( player_moving_state == STA_WALK )
  235.         {
  236.             // walk to the next Waypoint
  237.             pOverworld_Player->Start_Walk( waypoints[pOverworld_Player->current_waypoint]->direction_forward );
  238.         }
  239.     }
  240. }
  241.  
  242. bool cOverworld :: Key_Down( SDLKey key )
  243. {
  244.     if( key == SDLK_LEFT )
  245.     {
  246.         if( !pOverworld_Manager->cameramode && !editor_world_enabled )
  247.         {
  248.             pOverworld_Player->Action_Interact( INP_LEFT );
  249.         }
  250.         return 0;
  251.     }
  252.     else if( key == SDLK_RIGHT )
  253.     {
  254.         if( !pOverworld_Manager->cameramode && !editor_world_enabled )
  255.         {
  256.             pOverworld_Player->Action_Interact( INP_RIGHT );
  257.         }
  258.         return 0;
  259.     }
  260.     else if( key == SDLK_UP )
  261.     {
  262.         if( !pOverworld_Manager->cameramode && !editor_world_enabled )
  263.         {
  264.             pOverworld_Player->Action_Interact( INP_UP );
  265.         }
  266.         return 0;
  267.     }
  268.     else if( key == SDLK_DOWN )
  269.     {
  270.         if( !pOverworld_Manager->cameramode && !editor_world_enabled )
  271.         {
  272.             pOverworld_Player->Action_Interact( INP_DOWN );
  273.         }
  274.         return 0;
  275.     }
  276.     else if( key == SDLK_c && !editor_world_enabled )
  277.     {
  278.         pOverworld_Manager->cameramode = !pOverworld_Manager->cameramode;
  279.     }
  280.     else if( key == SDLK_F8 )
  281.     {
  282.         pWorld_Editor->Toggle();
  283.     }
  284.     else if( key == SDLK_d && ( input_event.key.keysym.mod & KMOD_LCTRL || input_event.key.keysym.mod & KMOD_RCTRL ) )
  285.     {
  286.         pOverworld_Manager->debugmode = !pOverworld_Manager->debugmode;
  287.         game_debug = pOverworld_Manager->debugmode;
  288.     }
  289.     else if( key == SDLK_l && pOverworld_Manager->debugmode )
  290.     {
  291.         // toggle layer drawing
  292.         pOverworld_Manager->draw_layer = !pOverworld_Manager->draw_layer;
  293.     }
  294.     else if( pKeyboard->keys[SDLK_g] && pKeyboard->keys[SDLK_o] && pKeyboard->keys[SDLK_d] )
  295.     {
  296.         // all waypoint access
  297.         pActive_Overworld->Set_Progress( pActive_Overworld->waypoints.size(), 1 );
  298.     }
  299.     else if( key == SDLK_F3 && pOverworld_Manager->debugmode )
  300.     {
  301.         pActive_Overworld->Goto_Next_Level();
  302.     }
  303.     // Exit
  304.     else if( key == SDLK_ESCAPE || key == SDLK_BACKSPACE )
  305.     {
  306.         pOverworld_Player->Action_Interact( INP_EXIT );
  307.     }
  308.     // Action
  309.     else if( key == SDLK_RETURN || key == SDLK_KP_ENTER || key == SDLK_SPACE )
  310.     {
  311.         pOverworld_Player->Action_Interact( INP_ACTION );
  312.     }
  313.     // ## editor
  314.     else if( pWorld_Editor->Key_Down( key ) )
  315.     {
  316.         // processed by the editor
  317.         return 1;
  318.     }
  319.     else
  320.     {
  321.         // not processed
  322.         return 0;
  323.     }
  324.  
  325.     // key got processed
  326.     return 1;
  327. }
  328.  
  329. bool cOverworld :: Key_Up( SDLKey key )
  330. {
  331.     // nothing yet
  332.     if( 0 )
  333.     {
  334.         //
  335.     }
  336.     else
  337.     {
  338.         // not processed
  339.         return 0;
  340.     }
  341.  
  342.     // key got processed
  343.     return 1;
  344. }
  345.  
  346. bool cOverworld :: Mouse_Down( Uint8 button )
  347. {
  348.     // ## editor
  349.     if( pWorld_Editor->Mouse_Down( button ) )
  350.     {
  351.         // processed by the editor
  352.         return 1;
  353.     }
  354.     else
  355.     {
  356.         // not processed
  357.         return 0;
  358.     }
  359.  
  360.     // button got processed
  361.     return 1;
  362. }
  363.  
  364. bool cOverworld :: Mouse_Up( Uint8 button )
  365. {
  366.     // ## editor
  367.     if( pWorld_Editor->Mouse_Up( button ) )
  368.     {
  369.         // processed by the editor
  370.         return 1;
  371.     }
  372.     else
  373.     {
  374.         // not processed
  375.         return 0;
  376.     }
  377.  
  378.     // button got processed
  379.     return 1;
  380. }
  381.  
  382. bool cOverworld :: Joy_Button_Down( Uint8 button )
  383. {
  384.     // Exit
  385.     if( button == pPreferences->joy_button_exit )
  386.     {
  387.         pOverworld_Player->Action_Interact( INP_EXIT );
  388.     }
  389.     // Action
  390.     else if( button == pPreferences->joy_button_action )
  391.     {
  392.         pOverworld_Player->Action_Interact( INP_ACTION );
  393.     }
  394.     else
  395.     {
  396.         // not processed
  397.         return 0;
  398.     }
  399.  
  400.     // key got processed
  401.     return 1;
  402. }
  403.  
  404. bool cOverworld :: Joy_Button_Up( Uint8 button )
  405. {
  406.     // nothing yet
  407.     if( 0 )
  408.     {
  409.         //
  410.     }
  411.     else
  412.     {
  413.         // not processed
  414.         return 0;
  415.     }
  416.  
  417.     // key got processed
  418.     return 1;
  419. }
  420.  
  421. bool cOverworld :: Load( void )
  422. {
  423.     Unload();
  424.  
  425.     // set active for loading
  426.     pActive_Overworld = this;
  427.  
  428.     // description
  429.     description->Load();
  430.  
  431.     // layer
  432.     string layer_filename = description->Get_Full_Path() + "/layer.xml";
  433.  
  434.     if( !File_Exists( layer_filename ) )
  435.     {
  436.         printf( "Couldn't find World Layer file : %s from %s\n", layer_filename.c_str(), description->path.c_str() );
  437.         return 0;
  438.     }
  439.  
  440.     pLayer->Load( layer_filename );
  441.  
  442.     // world
  443.     string world_filename = description->Get_Full_Path() + "/world.xml";
  444.  
  445.     if( !File_Exists( world_filename ) )
  446.     {
  447.         printf( "Couldn't find World file : %s from %s\n", world_filename.c_str(), description->path.c_str() );
  448.         return 0;
  449.     }
  450.  
  451.     try
  452.     {
  453.         // parse overworld
  454.         CEGUI::System::getSingleton().getXMLParser()->parseXMLFile( *this, world_filename.c_str(), DATA_DIR "/" GAME_SCHEMA_DIR "/World/World.xsd", "" );
  455.     }
  456.     // catch CEGUI Exceptions
  457.     catch( CEGUI::Exception &ex )
  458.     {
  459.         printf( "Loading World %s CEGUI Exception %s\n", world_filename.c_str(), ex.getMessage().c_str() );
  460.         debugdisplay->Set_Text( _("World Loading failed : ") + (string)ex.getMessage().c_str() );
  461.     }
  462.  
  463.     hud_world_name->Set_Image( pFont->Render_Text( pFont->font_normal, description->name, yellow ), 1, 1 );
  464.  
  465.     return 1;
  466. }
  467.  
  468. void cOverworld :: Unload( void )
  469. {
  470.     // set active for unloading
  471.     pActive_Overworld = this;
  472.  
  473.     // Waypoints
  474.     waypoints.clear();
  475.     // Layer
  476.     pLayer->Delete_All();
  477.     // Objects
  478.     sprite_manager->Delete_All();
  479.  
  480.     pActive_Overworld = NULL;
  481. }
  482.  
  483. void cOverworld :: Save( void )
  484. {
  485.     pAudio->Play_Sound( "editor/save.ogg" );
  486.  
  487.     string save_dir = user_data_dir + USER_WORLD_DIR + "/" + description->path;
  488.     // Create directory if new world
  489.     if( !fs::exists( fs::path( save_dir, fs::native ) ) )
  490.     {
  491.         fs::create_directory( fs::path( save_dir, fs::native ) );
  492.     }
  493.  
  494.     string filename = save_dir + "/world.xml";
  495.  
  496.     ofstream file( filename.c_str(), ios::out | ios::trunc );
  497.  
  498.     if( !file )
  499.     {
  500.         debugdisplay->Set_Text( _("Couldn't save world ") + filename );
  501.         return;
  502.     }
  503.  
  504.     // xml info
  505.     file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
  506.     // begin overworld
  507.     file << "<overworld>" << std::endl;
  508.  
  509.     // begin info
  510.     file << "\t<information>" << std::endl;
  511.         // game version
  512.         file << "\t\t<Property name=\"game_version\" value=\"" << smc_version << "\" />" << std::endl;
  513.         // engine version
  514.         file << "\t\t<Property name=\"engine_version\" value=\"" << 1 << "\" />" << std::endl;
  515.         // time ( seconds since 1970 )
  516.         file << "\t\t<Property name=\"save_time\" value=\"" << time( NULL ) << "\" />" << std::endl;
  517.     // end info
  518.     file << "\t</information>" << std::endl;
  519.  
  520.     // begin settings
  521.     file << "\t<settings>" << std::endl;
  522.         // music
  523.         file << "\t\t<Property name=\"music\" value=\"" << string_to_xml_string( musicfile ) << "\" />" << std::endl;
  524.     // end settings
  525.     file << "\t</settings>" << std::endl;
  526.  
  527.     // begin background
  528.     file << "\t<background>" << std::endl;
  529.         // color
  530.         file << "\t\t<Property name=\"color_red\" value=\"" << static_cast<int>(background_color.red) << "\" />" << std::endl;
  531.         file << "\t\t<Property name=\"color_green\" value=\"" << static_cast<int>(background_color.green) << "\" />" << std::endl;
  532.         file << "\t\t<Property name=\"color_blue\" value=\"" << static_cast<int>(background_color.blue) << "\" />" << std::endl;
  533.     // end background
  534.     file << "\t</background>" << std::endl;
  535.  
  536.     // begin player
  537.     file << "\t<player>" << std::endl;
  538.         // start waypoint
  539.         file << "\t\t<Property name=\"waypoint\" value=\"" << player_start_waypoint << "\" />" << std::endl;
  540.         // moving state
  541.         file << "\t\t<Property name=\"moving_state\" value=\"" << static_cast<int>(player_moving_state) << "\" />" << std::endl;
  542.     // end player
  543.     file << "\t</player>" << std::endl;
  544.     // objects
  545.     for( SpriteList::iterator itr = sprite_manager->objects.begin(), itr_end = sprite_manager->objects.end(); itr != itr_end; ++itr )
  546.     {
  547.         cSprite *obj = (*itr);
  548.  
  549.         // skip spawned and destroyed objects
  550.         if( obj->spawned || obj->destroy )
  551.         {
  552.             continue;
  553.         }
  554.  
  555.         // save to file stream
  556.         obj->Save_to_Stream( file );
  557.     }
  558.  
  559.     // end overworld
  560.     file << "</overworld>" << std::endl;
  561.     file.close();
  562.  
  563.     // save Layer
  564.     if( pLayer->Save( save_dir + "/layer.xml" ) )
  565.     {
  566.         debugdisplay->Set_Text( _("World ") + description->name + _(" saved") );
  567.     }
  568.  
  569.     // save description
  570.     description->Save();
  571. }
  572.  
  573. void cOverworld :: Set_Progress( unsigned int normal_level, bool force /* = 1 */ )
  574. {
  575.     unsigned int level_num = 0;
  576.  
  577.     for( WaypointList::iterator itr = waypoints.begin(), itr_end = waypoints.end(); itr != itr_end; ++itr )
  578.     {
  579.         cWaypoint *obj = (*itr);
  580.  
  581.         // accessible
  582.         if( normal_level >= level_num )
  583.         {
  584.             obj->Set_Access( 1 );
  585.         }
  586.         // force unset
  587.         else if( force )
  588.         {
  589.             obj->Set_Access( 0 );
  590.         }
  591.  
  592.         level_num++;
  593.     }
  594. }
  595.  
  596. cWaypoint *cOverworld :: Get_Waypoint( string name )
  597. {
  598.     for( WaypointList::iterator itr = waypoints.begin(), itr_end = waypoints.end(); itr != itr_end; ++itr )
  599.     {
  600.         cWaypoint *obj = (*itr);
  601.  
  602.         // accessible
  603.         if( obj->destination.compare( name ) == 0 )
  604.         {
  605.             return obj;
  606.         }
  607.     }
  608.  
  609.     return NULL;
  610. }
  611.  
  612. cWaypoint *cOverworld :: Get_Waypoint( unsigned int num )
  613. {
  614.     if( num >= waypoints.size() )
  615.     {
  616.         // out of bounds
  617.         return NULL;
  618.     }
  619.  
  620.     // available
  621.     return waypoints[num];
  622. }
  623.  
  624. int cOverworld :: Get_Level_Waypoint_Num( string level_name )
  625. {
  626.     // erase file type if set
  627.     if( level_name.rfind( ".txt" ) != string::npos || level_name.rfind( ".smclvl" ) != string::npos )
  628.     {
  629.         level_name.erase( level_name.rfind( "." ) );
  630.     }
  631.  
  632.     return Get_Waypoint_Num( level_name );
  633. }
  634.  
  635. int cOverworld :: Get_Waypoint_Num( string name )
  636. {
  637.     // search waypoint
  638.     for( unsigned int i = 0; i < waypoints.size(); i++ )
  639.     {
  640.         if( waypoints[i]->destination.compare( name ) == 0 )
  641.         {
  642.             // found
  643.             return i;
  644.         }
  645.     }
  646.  
  647.     // not found
  648.     return -1;
  649. }
  650.  
  651. int cOverworld :: Get_Waypoint_Collision( GL_rect *rect_2 )
  652. {
  653.     for( unsigned int i = 0; i < waypoints.size(); i++ )
  654.     {
  655.         if( Col_Box( rect_2, &waypoints[i]->rect ) )
  656.         {
  657.             return i;
  658.         }
  659.     }
  660.  
  661.     return -1;
  662. }
  663.  
  664. int cOverworld :: Get_Last_Valid_Waypoint( void )
  665. {
  666.     // no waypoints
  667.     if( !waypoints.size() )
  668.     {
  669.         return -1;
  670.     }
  671.  
  672.     for( unsigned int i = waypoints.size() - 1; i > 0; i-- )
  673.     {
  674.         if( waypoints[i]->access )
  675.         {
  676.             return i;
  677.         }
  678.     }
  679.  
  680.     return -1;
  681. }
  682.  
  683. void cOverworld :: Update_Waypoint_text( void )
  684. {
  685.     // get waypoint
  686.     cWaypoint *waypoint = waypoints[pOverworld_Player->current_waypoint];
  687.  
  688.     // set color
  689.     Color color = static_cast<Uint8>(0);
  690.  
  691.     if( waypoint->waypoint_type == WAYPOINT_NORMAL )
  692.     {
  693.         color = lightblue;
  694.     }
  695.     else if( waypoint->waypoint_type == WAYPOINT_WORLD_LINK )
  696.     {
  697.         color = green;
  698.     }
  699.     
  700.     hud_level_name->Set_Image( pFont->Render_Text( pFont->font_normal, waypoint->Get_Destination(), color ), 1, 1 );
  701. }
  702.  
  703. bool cOverworld :: Goto_Next_Level( void )
  704. {
  705.     // if not in overworld only goto next level on overworld enter
  706.     if( Game_Mode != MODE_OVERWORLD )
  707.     {
  708.         next_level = 1;
  709.         return 0;
  710.     }
  711.  
  712.     next_level = 0;
  713.  
  714.     cWaypoint *current_waypoint = pOverworld_Player->Get_Waypoint();
  715.  
  716.     // no Waypoint
  717.     if( !current_waypoint )
  718.     {
  719.         return 0;
  720.     }
  721.  
  722.     // Waypoint forward direction is invalid/unset
  723.     if( current_waypoint->direction_forward == DIR_UNDEFINED )
  724.     {
  725.         return 0;
  726.     }
  727.  
  728.     // Get Layer Line in front
  729.     cLayer_Line *front_line = pOverworld_Player->Get_Front_Line( current_waypoint->direction_forward );
  730.  
  731.     if( !front_line )
  732.     {
  733.         return 0;
  734.     }
  735.  
  736.     // Get forward Waypoint
  737.     cWaypoint *next_waypoint = front_line->Get_End_Waypoint();
  738.  
  739.     // if no next waypoint available
  740.     if( !next_waypoint )
  741.     {
  742.         return 0;
  743.     }
  744.  
  745.     // if next waypoint is new
  746.     if( !next_waypoint->access )
  747.     {
  748.         next_waypoint->Set_Access( 1 );
  749.  
  750.         // animation
  751.         cParticle_Emitter *anim = new cParticle_Emitter();
  752.         anim->Set_Pos( next_waypoint->rect.x + ( next_waypoint->rect.w * 0.4f ), next_waypoint->rect.y + ( next_waypoint->rect.h * 0.4f ) );
  753.         anim->Set_Emitter_Time_to_Live( 1.5f );
  754.         anim->Set_Emitter_Iteration_Interval( 0.1f );
  755.         anim->Set_Quota( 2 );
  756.         anim->Set_Image( pVideo->Get_Surface( "animation/particles/light.png" ) );
  757.         anim->Set_Pos_Z( 0.081f );
  758.         anim->Set_Time_to_Live( 1.3f );
  759.         anim->Set_Speed( 1, 1 );
  760.         anim->Set_Scale( 0.5f, 0.4f );
  761.         anim->Set_Const_Rotation_Z( -6, 12 );
  762.  
  763.         // World Waypoint
  764.         if( next_waypoint->waypoint_type == WAYPOINT_WORLD_LINK )
  765.         {
  766.             anim->Set_Color( lightgreen, Color( static_cast<Uint8>(60), 0, 60 ) );
  767.         }
  768.         else
  769.         {
  770.             anim->Set_Color( orange, Color( static_cast<Uint8>(6), 60, 20 ) );
  771.         }
  772.  
  773.         // add animation
  774.         pAnimation_Manager->Add( anim );
  775.     }
  776.  
  777.     pOverworld_Player->Start_Walk( current_waypoint->direction_forward );
  778.  
  779.     return  1;
  780. }
  781.  
  782. void cOverworld :: Reset_Waypoints( void )
  783. {
  784.     for( WaypointList::iterator itr = waypoints.begin(), itr_end = waypoints.end(); itr != itr_end; ++itr )
  785.     {
  786.         cWaypoint *obj = (*itr);
  787.  
  788.         obj->Set_Access( obj->access_default );
  789.     }
  790. }
  791.  
  792. // XML element start
  793. void cOverworld :: elementStart( const CEGUI::String &element, const CEGUI::XMLAttributes &attributes )
  794. {
  795.     // Property of an Element
  796.     if( element == "Property" )
  797.     {
  798.         xml_attributes.add( attributes.getValueAsString( "name" ), attributes.getValueAsString( "value" ) );
  799.     }
  800. }
  801.  
  802. // XML element end
  803. void cOverworld :: elementEnd( const CEGUI::String &element )
  804. {
  805.     if( element != "Property" )
  806.     {
  807.         if( element == "information" )
  808.         {
  809.             //engine_version = xml_attributes.getValueAsInteger( "engine_version" );
  810.             //last_saved = xml_attributes.getValueAsInteger( "save_time" );
  811.         }
  812.         else if( element == "settings" )
  813.         {
  814.             // Author
  815.             //author = xml_attributes.getValueAsString( "author" ).c_str();
  816.             // Version
  817.             //version = xml_attributes.getValueAsString( "version" ).c_str();
  818.             // Music
  819.             musicfile = xml_attributes.getValueAsString( "music" ).c_str();
  820.             // Camera Limits
  821.             //pOverworld_Manager->camera->Set_Limits( GL_rect( static_cast<float>(xml_attributes.getValueAsInteger( "cam_limit_x" )), static_cast<float>(xml_attributes.getValueAsInteger( "cam_limit_y" )), static_cast<float>(xml_attributes.getValueAsInteger( "cam_limit_w" )), static_cast<float>(xml_attributes.getValueAsInteger( "cam_limit_h" )) ) );
  822.         }
  823.         else if( element == "player" )
  824.         {
  825.             // Start Waypoint
  826.             player_start_waypoint = xml_attributes.getValueAsInteger( "waypoint" );
  827.             // Moving State
  828.             player_moving_state = static_cast<Moving_state>(xml_attributes.getValueAsInteger( "moving_state" ));
  829.         }
  830.         else if( element == "background" )
  831.         {
  832.             background_color = Color( static_cast<Uint8>(xml_attributes.getValueAsInteger( "color_red" )), xml_attributes.getValueAsInteger( "color_green" ), xml_attributes.getValueAsInteger( "color_blue" ) );
  833.         }
  834.         else
  835.         {
  836.             // get World object
  837.             cSprite *object = Get_World_Object( element, xml_attributes );
  838.             
  839.             // valid
  840.             if( object )
  841.             {
  842.                 Add_Map_Object( object );
  843.             }
  844.             else if( element == "overworld" )
  845.             {
  846.                 // ignore
  847.             }
  848.             else if( element.length() )
  849.             {
  850.                 printf( "Warning : Overworld Unknown element : %s\n", element.c_str() );
  851.             }
  852.         }
  853.  
  854.         // clear
  855.         xml_attributes = CEGUI::XMLAttributes();
  856.     }
  857. }
  858.  
  859. void cOverworld :: Draw( void )
  860. {
  861.     // Background
  862.     pVideo->Clear_Screen();
  863.     pVideo->Draw_Rect( NULL, 0.00001f, &background_color );
  864.  
  865.     // Map
  866.     sprite_manager->Draw_Items();
  867.     // Animations
  868.     pAnimation_Manager->Draw();
  869.     // Player
  870.     pOverworld_Player->Draw();
  871.     // Hud
  872.     Draw_HUD();
  873.  
  874.     // Line Layer
  875.     pLayer->Draw();
  876.     // Editor
  877.     pWorld_Editor->Draw();
  878. }
  879.  
  880. void cOverworld :: Draw_HUD( void )
  881. {
  882.     // if not editor mode
  883.     if( !editor_world_enabled )
  884.     {
  885.         // Background
  886.         Color color = Color( static_cast<Uint8>(230), 170, 0, 128 );
  887.         pVideo->Draw_Rect( 0, 0, static_cast<float>(game_res_w), 30, 0.12f, &color );
  888.         // Line
  889.         color = Color( static_cast<Uint8>(200), 150, 0, 128 );
  890.         pVideo->Draw_Rect( 0, 30, static_cast<float>(game_res_w), 5, 0.121f, &color );
  891.  
  892.         // Overworld name and level
  893.         hud_world_name->Draw();
  894.         hud_level_name->Draw();
  895.     }
  896.  
  897.     // hud
  898.     pHud_Manager->Draw();
  899. }
  900.  
  901. void cOverworld :: Update( void )
  902. {
  903.     // editor
  904.     pWorld_Editor->Process_Input();
  905.  
  906.     if( !editor_world_enabled )
  907.     {
  908.         // Camera
  909.         Update_Camera();
  910.         // Map
  911.         sprite_manager->Update_Items();
  912.         // Player
  913.         pOverworld_Player->Update();
  914.         // Animations
  915.         pAnimation_Manager->Update();
  916.     }
  917.  
  918.     // hud
  919.     pHud_Manager->Update();
  920.     // Editor
  921.     pWorld_Editor->Update();
  922. }
  923.  
  924. void cOverworld :: Update_Camera( void )
  925. {
  926.     if( editor_world_enabled )
  927.     {
  928.         return;
  929.     }
  930.  
  931.     // todo : move to a Process_Input function
  932.     if( pOverworld_Manager->cameramode )
  933.     {
  934.         if( pKeyboard->keys[pPreferences->key_right] || ( pJoystick->right && pPreferences->joy_enabled ) )
  935.         {
  936.             pActive_Camera->Move( pFramerate->speedfactor * 15, 0 );
  937.         }
  938.         else if( pKeyboard->keys[pPreferences->key_left] || ( pJoystick->left && pPreferences->joy_enabled ) )
  939.         {
  940.             pActive_Camera->Move( pFramerate->speedfactor * -15, 0 );
  941.         }
  942.         if( pKeyboard->keys[pPreferences->key_up] || ( pJoystick->up && pPreferences->joy_enabled ) )
  943.         {
  944.             pActive_Camera->Move( 0, pFramerate->speedfactor * -15 );
  945.         }
  946.         else if( pKeyboard->keys[pPreferences->key_down] || ( pJoystick->down && pPreferences->joy_enabled ) )
  947.         {
  948.             pActive_Camera->Move( 0, pFramerate->speedfactor * 15 );
  949.         }
  950.     }
  951.     // default player camera
  952.     else
  953.     {
  954.         pActive_Camera->Update();
  955.     }
  956. }
  957.  
  958. void cOverworld :: Add_Map_Object( cSprite *object )
  959. {
  960.     // invalid
  961.     if( !object )
  962.     {
  963.         return;
  964.     }
  965.  
  966.     // no player range
  967.     object->player_range = 0;
  968.  
  969.     // add
  970.     sprite_manager->Add( object );
  971.  
  972.     // Add to Waypoints array
  973.     if( object->type == TYPE_OW_WAYPOINT )
  974.     {
  975.         waypoints.push_back( static_cast<cWaypoint *>(object) );
  976.     }
  977. }
  978.  
  979. cSprite *Get_World_Object( const CEGUI::String &element, CEGUI::XMLAttributes &attributes )
  980. {
  981.     if( element == "sprite" )
  982.     {
  983.         // old position name
  984.         if( attributes.exists( "filename" ) )
  985.         {
  986.             attributes.add( "image", attributes.getValueAsString( "filename" ) );
  987.             attributes.add( "posx", attributes.getValueAsString( "pos_x" ) );
  988.             attributes.add( "posy", attributes.getValueAsString( "pos_y" ) );
  989.         }
  990.  
  991.         // create sprite
  992.         cSprite *object = new cSprite( attributes );
  993.         // set sprite type
  994.         object->Set_Sprite_Type( TYPE_PASSIVE );
  995.  
  996.         return object;
  997.     }
  998.     else if( element == "waypoint" )
  999.     {
  1000.         return new cWaypoint( attributes );
  1001.     }
  1002.     else if( element == "sound" )
  1003.     {
  1004.         return new cRandom_Sound( attributes );
  1005.     }
  1006.  
  1007.     return NULL;
  1008. }
  1009.  
  1010. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  1011.  
  1012. cOverworld *pActive_Overworld = NULL;
  1013.